Changeset 3367 in josm


Ignore:
Timestamp:
2010-07-08T08:41:20+02:00 (13 years ago)
Author:
jttt
Message:

Fix filters

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/data_nodist/filterTests.osm

    r3358 r3367  
    3737  <node id='3738209' timestamp='2009-07-01T02:47:20Z' uid='60345' user='Mirko Küster' visible='true' version='2' changeset='4888' lat='51.297687546215265' lon='11.433031050752408'>
    3838    <tag k='highway' v='turning_circle' />
    39     <tag k='source:RESULT1' v='h' />
     39    <tag k='source:RESULT1' v='v' />
    4040    <tag k='source:RESULT2' v='v' />
    4141    <tag k='source:RESULT3' v='d' />
     
    243243    <tag k='source:RESULT13' v='v' />
    244244    <tag k='source:RESULT14' v='v' />
     245    <tag k='source:RESULT15' v='v' />
    245246  </way>
    246247  <way id='101642' visible='true' version='2' changeset='4889'>
     
    258259    <tag k='source:RESULT13' v='h' />
    259260    <tag k='source:RESULT14' v='h' />
     261    <tag k='source:RESULT15' v='h' />
    260262  </way>
    261263  <way id='101643' visible='true' version='2' changeset='4889'>
     
    272274    <tag k='source:RESULT13' v='v' />
    273275    <tag k='source:RESULT14' v='v' />
     276    <tag k='source:RESULT15' v='d' />
    274277    <tag k='waterway' v='canal' />
    275278  </way>
  • trunk/src/org/openstreetmap/josm/data/osm/FilterMatcher.java

    r3355 r3367  
    1717        final Match match;
    1818        final boolean isDelete;
     19        final boolean isInverted;
    1920
    2021        FilterInfo(Filter filter) throws ParseError {
     
    2728            Match compiled = SearchCompiler.compile(filter.text, filter.caseSensitive, filter.regexSearch);
    2829            this.match = filter.inverted?new Not(compiled):compiled;
     30            this.isInverted = filter.inverted;
    2931        }
    3032    }
     
    4345            }
    4446
    45             List<FilterInfo> list = filter.hiding?hiddenFilters:disabledFilters;
     47            FilterInfo fi = new FilterInfo(filter);
     48            if (fi.isDelete) {
     49                if (filter.hiding) {
     50                    // Remove only hide flag
     51                    hiddenFilters.add(fi);
     52                } else {
     53                    // Remove both flags
     54                    disabledFilters.add(fi);
     55                    hiddenFilters.add(fi);
     56                }
     57            } else {
     58                if (filter.mode == SearchMode.replace) {
     59                    if (filter.hiding) {
     60                        hiddenFilters.clear();
     61                        disabledFilters.clear();
     62                    }
     63                }
    4664
    47             if (filter.mode == SearchMode.replace) {
    48                 // No point in evalutaing filter when value will get replaced anyway (and yes, there is no point in using replace mode with filters)
    49                 list.clear();
     65                disabledFilters.add(fi);
     66                if (filter.hiding) {
     67                    hiddenFilters.add(fi);
     68                }
    5069            }
    51 
    52             list.add(new FilterInfo(filter));
    5370        }
    5471    }
    5572
    56     private boolean test(List<FilterInfo> filters, OsmPrimitive primitive) {
     73    private boolean getState(OsmPrimitive primitive, boolean hidden) {
     74        return hidden?primitive.isDisabledAndHidden():primitive.isDisabled();
     75    }
     76
     77    private boolean allParentWaysFiltered(OsmPrimitive primitive, boolean hidden) {
     78        List<OsmPrimitive> refs = primitive.getReferrers();
     79        if (refs.isEmpty())
     80            return false;
     81
     82        for (OsmPrimitive p: refs) {
     83            if (p instanceof Way && !getState(p, hidden))
     84                return false;
     85        }
     86
     87        return true;
     88    }
     89
     90    private boolean oneParentWayNotFiltered(OsmPrimitive primitive, boolean hidden) {
     91        List<OsmPrimitive> refs = primitive.getReferrers();
     92        for (OsmPrimitive p: refs) {
     93            if (p instanceof Way && !getState(p, hidden))
     94                return true;
     95        }
     96
     97        return false;
     98    }
     99
     100    private boolean test(List<FilterInfo> filters, OsmPrimitive primitive, boolean hidden) {
    57101        boolean selected = false;
     102        boolean onlyInvertedFilters = true;
     103
    58104        for (FilterInfo fi: filters) {
    59105            if (fi.isDelete && selected && fi.match.match(primitive)) {
    60106                selected = false;
    61             } else if (!fi.isDelete && !selected && fi.match.match(primitive)) {
     107            } else if (!fi.isDelete && (!selected || (onlyInvertedFilters && !fi.isInverted)) && fi.match.match(primitive)) {
    62108                selected = true;
     109                onlyInvertedFilters = onlyInvertedFilters && fi.isInverted;
    63110            }
    64111        }
    65         return selected;
     112
     113        if (primitive instanceof Node) {
     114            if (!selected)
     115                return !primitive.isTagged() && allParentWaysFiltered(primitive, hidden);
     116            if (onlyInvertedFilters)
     117                return selected && !oneParentWayNotFiltered(primitive, hidden);
     118            return true;
     119        } else
     120            return selected;
     121
    66122    }
    67123
    68124    public boolean isHidden(OsmPrimitive primitive) {
    69         return test(hiddenFilters, primitive);
     125        return test(hiddenFilters, primitive, true);
    70126    }
    71127
    72128    public boolean isDisabled(OsmPrimitive primitive) {
    73         return test(disabledFilters, primitive);
     129        return test(disabledFilters, primitive, false);
    74130    }
    75131
  • trunk/src/org/openstreetmap/josm/data/osm/FilterWorker.java

    r3356 r3367  
    3333     */
    3434    public static void executeFilters(Collection<OsmPrimitive> all, FilterMatcher filterMatcher) {
     35
     36        // First relation and ways
    3537        for (OsmPrimitive primitive: all) {
    36             if (filterMatcher.isHidden(primitive)) {
    37                 primitive.setDisabledState(true);
    38             } else if (filterMatcher.isDisabled(primitive)) {
    39                 primitive.setDisabledState(false);
    40             } else {
    41                 primitive.unsetDisabledState();
     38            if (!(primitive instanceof Node)) {
     39                if (filterMatcher.isHidden(primitive)) {
     40                    primitive.setDisabledState(true);
     41                } else if (filterMatcher.isDisabled(primitive)) {
     42                    primitive.setDisabledState(false);
     43                } else {
     44                    primitive.unsetDisabledState();
     45                }
    4246            }
    4347        }
    4448
     49        // Then nodes (because they state may depend on parent ways)
    4550        for (OsmPrimitive primitive: all) {
    46             if (primitive instanceof Way && primitive.isDisabled()) {
    47                 Way w = (Way)primitive;
    48                 for (Node n: w.getNodes()) {
    49 
    50                     if (n.isTagged()) {
    51                         continue;
    52                     }
    53 
    54                     boolean disabled = w.isDisabled();
    55                     boolean hidden = w.isDisabledAndHidden();
    56                     for (OsmPrimitive ref: n.getReferrers()) {
    57                         if (ref instanceof Way) {
    58                             disabled = disabled && ref.isDisabled();
    59                             hidden = hidden && ref.isDisabledAndHidden();
    60                         }
    61                     }
    62 
    63                     if (disabled) {
    64                         n.setDisabledState(hidden);
    65                     }
     51            if (primitive instanceof Node) {
     52                if (filterMatcher.isHidden(primitive)) {
     53                    primitive.setDisabledState(true);
     54                } else if (filterMatcher.isDisabled(primitive)) {
     55                    primitive.setDisabledState(false);
     56                } else {
     57                    primitive.unsetDisabledState();
    6658                }
    6759            }
  • trunk/test/unit/org/openstreetmap/josm/data/osm/FilterTest.java

    r3358 r3367  
    22package org.openstreetmap.josm.data.osm;
    33
     4import static org.junit.Assert.assertNotNull;
     5import static org.junit.Assert.assertTrue;
     6
    47import java.io.FileInputStream;
    58import java.io.FileNotFoundException;
    6 
    79import java.util.Arrays;
    810import java.util.Collection;
     
    1113import java.util.List;
    1214
    13 import static org.junit.Assert.assertEquals;
    14 import static org.junit.Assert.assertNotNull;
    15 import static org.junit.Assert.assertTrue;
    1615import org.junit.BeforeClass;
    1716import org.junit.Test;
    18 
    1917import org.openstreetmap.josm.Main;
    2018import org.openstreetmap.josm.actions.search.SearchAction.SearchMode;
     
    3129        Main.proj = new Mercator();
    3230    }
    33    
     31
    3432    @Test
    3533    public void basic_test() throws ParseError {
     
    4038        n2.put("fixme", "continue");
    4139        ds.addPrimitive(n1);
     40        ds.addPrimitive(n2);
    4241        OsmPrimitive p = ds.getPrimitiveById(1,OsmPrimitiveType.NODE);
    4342        assertNotNull(p);
     
    6362    @Test
    6463    public void filter_test() throws ParseError, IllegalDataException, FileNotFoundException {
    65         for (int i : new int [] {1,2,3, 11,12,13,14}) {
     64        for (int i : new int [] {1,2,3, 11,12,13,14, 15}) {
    6665            DataSet ds = OsmReader.parseDataSet(new FileInputStream("data_nodist/filterTests.osm"), NullProgressMonitor.INSTANCE);
    6766
    6867            List<Filter> filters = new LinkedList<Filter>();
    6968            switch (i) {
    70                 case 1: {
    71                     Filter f1 = new Filter();
    72                     f1.text = "power";
    73                     f1.hiding = true;
    74                     filters.add(f1);
    75                     break;
    76                 }
    77                 case 2: {
    78                     Filter f1 = new Filter();
    79                     f1.text = "highway";
    80                     f1.inverted = true;
    81                     filters.add(f1);
    82                     break;
    83                 }
    84                 case 3: {
    85                     Filter f1 = new Filter();
    86                     f1.text = "power";
    87                     f1.inverted = true;
    88                     f1.hiding = true;
    89                     Filter f2 = new Filter();
    90                     f2.text = "highway";
    91                     filters.addAll(Arrays.asList(new Filter[] {f1, f2}));
    92                     break;
    93                 }
    94                 case 11: {
    95                     Filter f1 = new Filter();
    96                     f1.text = "highway";
    97                     f1.inverted = true;
    98                     f1.hiding = true;
    99                     filters.add(f1);
    100                     break;
    101                 }
    102                 case 12: {
    103                     Filter f1 = new Filter();
    104                     f1.text = "highway";
    105                     f1.inverted = true;
    106                     f1.hiding = true;
    107                     Filter f2 = new Filter();
    108                     f2.text = "water";
    109                     f2.mode = SearchMode.remove;
    110                     filters.addAll(Arrays.asList(new Filter[] {f1, f2}));
    111                     break;
    112                 }
    113                 case 13: {
    114                     Filter f1 = new Filter();
    115                     f1.text = "highway";
    116                     f1.inverted = true;
    117                     f1.hiding = true;
    118                     Filter f2 = new Filter();
    119                     f2.text = "water";
    120                     f2.mode = SearchMode.remove;
    121                     Filter f3 = new Filter();
    122                     f3.text = "natural";
    123                     filters.addAll(Arrays.asList(new Filter[] {f1, f2, f3}));
    124                     break;
    125                 }
    126                 case 14: {
    127                     /* show all highways and all water features, but not lakes
    128                      * except those that have a name */
    129                     Filter f1 = new Filter();
    130                     f1.text = "highway";
    131                     f1.inverted = true;
    132                     f1.hiding = true;
    133                     Filter f2 = new Filter();
    134                     f2.text = "water";
    135                     f2.mode = SearchMode.remove;
    136                     Filter f3 = new Filter();
    137                     f3.text = "natural";
    138                     Filter f4 = new Filter();
    139                     f4.text = "name";
    140                     f4.mode = SearchMode.remove;
    141                     filters.addAll(Arrays.asList(new Filter[] {f1, f2, f3, f4}));
    142                     break;
    143                 }
     69            case 1: {
     70                Filter f1 = new Filter();
     71                f1.text = "power";
     72                f1.hiding = true;
     73                filters.add(f1);
     74                break;
     75            }
     76            case 2: {
     77                Filter f1 = new Filter();
     78                f1.text = "highway";
     79                f1.inverted = true;
     80                filters.add(f1);
     81                break;
     82            }
     83            case 3: {
     84                Filter f1 = new Filter();
     85                f1.text = "power";
     86                f1.inverted = true;
     87                f1.hiding = true;
     88                Filter f2 = new Filter();
     89                f2.text = "highway";
     90                filters.addAll(Arrays.asList(new Filter[] {f1, f2}));
     91                break;
     92            }
     93            case 11: {
     94                Filter f1 = new Filter();
     95                f1.text = "highway";
     96                f1.inverted = true;
     97                f1.hiding = true;
     98                filters.add(f1);
     99                break;
     100            }
     101            case 12: {
     102                Filter f1 = new Filter();
     103                f1.text = "highway";
     104                f1.inverted = true;
     105                f1.hiding = true;
     106                Filter f2 = new Filter();
     107                f2.text = "water";
     108                f2.mode = SearchMode.remove;
     109                filters.addAll(Arrays.asList(new Filter[] {f1, f2}));
     110                break;
     111            }
     112            case 13: {
     113                Filter f1 = new Filter();
     114                f1.text = "highway";
     115                f1.inverted = true;
     116                f1.hiding = true;
     117                Filter f2 = new Filter();
     118                f2.text = "water";
     119                f2.mode = SearchMode.remove;
     120                Filter f3 = new Filter();
     121                f3.text = "natural";
     122                filters.addAll(Arrays.asList(new Filter[] {f1, f2, f3}));
     123                break;
     124            }
     125            case 14: {
     126                /* show all highways and all water features, but not lakes
     127                 * except those that have a name */
     128                Filter f1 = new Filter();
     129                f1.text = "highway";
     130                f1.inverted = true;
     131                f1.hiding = true;
     132                Filter f2 = new Filter();
     133                f2.text = "water";
     134                f2.mode = SearchMode.remove;
     135                Filter f3 = new Filter();
     136                f3.text = "natural";
     137                Filter f4 = new Filter();
     138                f4.text = "name";
     139                f4.mode = SearchMode.remove;
     140                filters.addAll(Arrays.asList(new Filter[] {f1, f2, f3, f4}));
     141                break;
     142            }
     143            case 15: {
     144                Filter f1 = new Filter();
     145                f1.text = "highway";
     146                f1.inverted = true;
     147                f1.hiding = true;
     148                Filter f2 = new Filter();
     149                f2.text = "water";
     150                f2.mode = SearchMode.remove;
     151                f2.hiding = true; // Remove only hide flag so water should stay disabled
     152                filters.addAll(Arrays.asList(new Filter[] {f1, f2}));
     153                break;
     154            }
    144155            }
    145156
     
    151162            boolean foundAtLeastOne = false;
    152163            System.err.println("Run #"+i);
     164            StringBuilder failedPrimitives = new StringBuilder();
    153165            for (OsmPrimitive osm : ds.allPrimitives()) {
    154166                String key = "source:RESULT"+i; // use key that counts as untagged
    155167                if (osm.hasKey(key)) {
    156168                    foundAtLeastOne = true;
    157 //                    System.err.println("osm "+osm.getId()+" "+filterCode(osm)+" "+osm.get(key));
    158                     assertEquals(String.format("Run #%d Object %s", i,osm.toString()), filterCode(osm), osm.get(key));
     169                    if (!osm.get(key).equals(filterCode(osm))) {
     170                        failedPrimitives.append(String.format("Object %s. Expected [%s] but was [%s]\n", osm.toString(), osm.get(key), filterCode(osm)));
     171                    }
    159172                }
    160173            }
    161174            assertTrue(foundAtLeastOne);
     175            if (failedPrimitives.length() != 0)
     176                throw new AssertionError(String.format("Run #%d\n%s", i, failedPrimitives.toString()));
    162177        }
    163178    }
Note: See TracChangeset for help on using the changeset viewer.