Ticket #20130: 20130.2.patch

File 20130.2.patch, 10.5 KB (added by GerdP, 5 years ago)
  • resources/data/validator/geometry.mapcss

     
    200200  throwWarning: tr("Water area inside water area");
    201201}
    202202
     203/* #20130 Building crossing landuse (spatial test) */
     204area:closed:areaStyle[landuse=~ /^(commercial|farmyard|garages|industrial|retail|residential)$/] ⧉o area[building][building!~/no|entrance/] {
     205  throwWarning: tr("Building partly outside of landuse area");
     206}
     207
    203208area:closed:areaStyle ⧉ area:closed:areaStyle {
    204209  throwOther: tr("Overlapping Areas");
    205210}
  • src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java

     
    5656     * Type of way. Entries have to be declared in alphabetical order, see sort below.
    5757     */
    5858    private enum WayType {
    59         BARRIER, BUILDING, HIGHWAY, RAILWAY, RESIDENTIAL_AREA, WATERWAY, WAY;
     59        BARRIER, BUILDING, HIGHWAY, RAILWAY, WATERWAY, WAY;
    6060
    6161        static WayType of(Way w) {
    6262            if (w.hasKey(CrossingWays.BARRIER))
     
    6767                return HIGHWAY;
    6868            else if (isRailway(w))
    6969                return RAILWAY;
    70             else if (isResidentialArea(w))
    71                 return RESIDENTIAL_AREA;
    7270            else if (w.hasKey(CrossingWays.WATERWAY))
    7371                return WATERWAY;
    7472            else
     
    106104                    || isRailway(w)
    107105                    || isCoastline(w)
    108106                    || isBuilding(w)
    109                     || w.hasKey(BARRIER)
    110                     || isResidentialArea(w));
     107                    || w.hasKey(BARRIER));
    111108        }
    112109
    113110        @Override
     
    118115                return true;
    119116            if (isBuilding(w1) && isBuilding(w2))
    120117                return true; // handled by mapcss tests
    121             if (((isResidentialArea(w1) || w1.hasKey(BARRIER, HIGHWAY, RAILWAY, WATERWAY) || isWaterArea(w1))
    122                     && isResidentialArea(w2))
    123                     || ((isResidentialArea(w2) || w2.hasKey(BARRIER, HIGHWAY, RAILWAY, WATERWAY) || isWaterArea(w2))
    124                             && isResidentialArea(w1)))
    125                 return true;
    126118            if (isWaterArea(w1) && isWaterArea(w2))
    127119                return true; // handled by mapcss tests
    128120            if (w1.hasKey(RAILWAY) && w2.hasKey(RAILWAY) && w1.hasTag(RAILWAY, "yard") != w2.hasTag(RAILWAY, "yard")) {
     
    174166                        return new MessageHelper(tr("Crossing building/highway"), 612);
    175167                    case RAILWAY:
    176168                        return new MessageHelper(tr("Crossing building/railway"), 613);
    177                     case RESIDENTIAL_AREA:
    178                         return new MessageHelper(tr("Crossing building/residential area"), 614);
    179169                    case WATERWAY:
    180170                        return new MessageHelper(tr("Crossing building/waterway"), 615);
    181171                    case WAY:
     
    200190                    default:
    201191                        return new MessageHelper(tr("Crossing railway/way"), 631);
    202192                    }
    203                 case RESIDENTIAL_AREA:
    204                     return new MessageHelper(tr("Crossing residential area/way"), 641);
    205193                case WATERWAY:
    206194                default:
    207195                    return new MessageHelper(tr("Crossing waterway/way"), 651);
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj

     
    217217|   < SUPERSET_OR_EQUAL: "⊇" >
    218218|   < NOT_SUPERSET_OR_EQUAL: "⊉" >
    219219|   < CROSSING: "⧉" >
     220|   < CROSSING_OUTSIDE: "⧉o" >
    220221|   < PERCENT: "%" >
    221222|   < COMMENT_START: "/*" > : COMMENT
    222223|   < UNEXPECTED_CHAR : ~[] > // avoid TokenMgrErrors because they are hard to recover from
     
    633634                <NOT_SUPERSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.NOT_SUPERSET_OR_EQUAL; }
    634635            |
    635636                <CROSSING> { type = Selector.ChildOrParentSelectorType.CROSSING; }
     637            |
     638                <CROSSING_OUTSIDE> { type = Selector.ChildOrParentSelectorType.CROSSING_OUTSIDE; }
    636639            )
    637640            w()
    638641        |
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java

     
    126126     * @see ChildOrParentSelector
    127127     */
    128128    enum ChildOrParentSelectorType {
    129         CHILD, PARENT, SUBSET_OR_EQUAL, NOT_SUBSET_OR_EQUAL, SUPERSET_OR_EQUAL, NOT_SUPERSET_OR_EQUAL, CROSSING, SIBLING,
     129        CHILD, PARENT, SUBSET_OR_EQUAL, NOT_SUBSET_OR_EQUAL, SUPERSET_OR_EQUAL, NOT_SUPERSET_OR_EQUAL, CROSSING, SIBLING, CROSSING_OUTSIDE,
    130130    }
    131131
    132132    /**
     
    324324            private Area area;
    325325            /** Will contain all way segments, grouped by cells */
    326326            Map<Point2D, List<WaySegment>> cellSegments;
     327            private final boolean markOutsideArea;
    327328
    328             private CrossingFinder(Environment e) {
     329            private CrossingFinder(Environment e, boolean markOutside) {
    329330                super(e);
    330331                CheckParameterUtil.ensureThat(isArea(e.osm), "Only areas are supported");
    331332                layer = OsmUtils.getLayer(e.osm);
     333                this.markOutsideArea = markOutside;
    332334            }
    333335
    334336            private Area getAreaEastNorth(IPrimitive p, Environment e) {
     
    393395                    Pair<PolygonIntersection, Area> is = Geometry.polygonIntersectionResult(
    394396                            otherArea, area, Geometry.INTERSECTION_EPS_EAST_NORTH);
    395397                    if (Geometry.PolygonIntersection.CROSSING == is.a) {
     398                        final Area hiliteArea;
     399                        if (markOutsideArea) {
     400                            hiliteArea = new Area(area);
     401                            hiliteArea.subtract(otherArea);
     402                            if (hiliteArea.isEmpty()) {
     403                                return; // can happen with multipolygon if only a node is shared
     404                            }
     405                        } else {
     406                            hiliteArea = is.b;
     407                        }
    396408                        addToChildren(e, p);
    397409                        // store intersection area to improve highlight and zoom to problem
    398410                        if (e.intersections == null) {
    399411                            e.intersections = new HashMap<>();
    400412                        }
    401                         e.intersections.put(p, is.b);
     413                        e.intersections.put(p, hiliteArea);
    402414                    }
    403415                }
    404 
    405416            }
    406417
    407418            private void useFindCrossings(IPrimitive p) {
     
    545556                visitBBox(e, insideOrEqualFinder);
    546557                return ChildOrParentSelectorType.SUPERSET_OR_EQUAL == type ? e.children != null : e.children == null;
    547558
    548             } else if (ChildOrParentSelectorType.CROSSING == type) {
     559            } else if (ChildOrParentSelectorType.CROSSING == type || ChildOrParentSelectorType.CROSSING_OUTSIDE == type) {
    549560                e.parent = e.osm;
    550561                if (e.osm.getDataSet() != null && isArea(e.osm)) {
    551                     final CrossingFinder crossingFinder = new CrossingFinder(e);
     562                    boolean markOutside = ChildOrParentSelectorType.CROSSING_OUTSIDE == type;
     563                    final CrossingFinder crossingFinder = new CrossingFinder(e, markOutside);
    552564                    visitBBox(e, crossingFinder);
    553565                    return e.children != null;
    554566                }
  • test/unit/org/openstreetmap/josm/data/validation/tests/CrossingWaysTest.java

     
    133133        assertTrue(test.isPrimitiveUsable(newUsableWay("railway=rail")));
    134134        assertTrue(test.isPrimitiveUsable(newUsableWay("natural=water")));
    135135        assertTrue(test.isPrimitiveUsable(newUsableWay("building=yes")));
    136         assertTrue(test.isPrimitiveUsable(newUsableWay("landuse=residential")));
     136        assertFalse(test.isPrimitiveUsable(newUsableWay("landuse=residential")));
    137137        // createMessage
    138138        testMessage(601, test, "amenity=restaurant", "amenity=restaurant");
    139139        testMessage(611, test, "building=yes", "amenity=restaurant");
     
    140140        testMessage(611, test, "building=yes", "natural=water");
    141141        testMessage(612, test, "building=yes", "highway=road");
    142142        testMessage(613, test, "building=yes", "railway=rail");
    143         testMessage(614, test, "building=yes", "landuse=residential");
    144143        testMessage(615, test, "building=yes", "waterway=river");
    145144        testMessage(620, test, "highway=road", "highway=road");
    146145        testMessage(621, test, "highway=road", "amenity=restaurant");
     
    151150        testMessage(631, test, "railway=rail", "amenity=restaurant");
    152151        testMessage(631, test, "railway=rail", "natural=water");
    153152        testMessage(632, test, "railway=rail", "waterway=river");
    154         testMessage(641, test, "landuse=residential", "amenity=restaurant");
    155153        testMessage(650, test, "waterway=river", "waterway=river");
    156154        testMessage(651, test, "waterway=river", "amenity=restaurant");
    157155        testMessage(603, test, "barrier=hedge", "barrier=yes");
     
    161159        testMessage(664, test, "barrier=hedge", "waterway=river");
    162160        testMessage(665, test, "barrier=hedge", "natural=water");
    163161
    164         testIgnore(true, test, "landuse=residential", "natural=water");
    165         testIgnore(false, test, "landuse=residential", "building=yes");
    166 
    167162        assertFalse(test.isPrimitiveUsable(newUsableWay("amenity=restaurant")));
    168163        assertFalse(test.isPrimitiveUsable(TestUtils.newWay("barrier=yes"))); // Unusable (0 node)
    169164        assertTrue(test.isPrimitiveUsable(newUsableWay("barrier=yes"))); // Usable (2 nodes)