Changeset 9952 in josm


Ignore:
Timestamp:
2016-03-07T23:29:30+01:00 (4 years ago)
Author:
simon04
Message:

see #11516 - Compute multipolygon area, include in MapCSS, JOSM search

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java

    r9940 r9952  
    13861386        @Override
    13871387        protected Long getNumber(OsmPrimitive osm) {
    1388             if (!(osm instanceof Way && ((Way) osm).isClosed()))
    1389                 return null;
    1390             Way way = (Way) osm;
    1391             return (long) Geometry.closedWayArea(way);
     1388            final Double area = Geometry.computeArea(osm);
     1389            return area == null ? null : area.longValue();
    13921390        }
    13931391
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java

    r9854 r9952  
    652652                }
    653653                if (extent != null) {
    654                     if (!usePartialFill(pd.getAreaAndPerimeter(), extent, extentThreshold)) {
     654                    if (!usePartialFill(pd.getAreaAndPerimeter(null), extent, extentThreshold)) {
    655655                        extent = null;
    656656                    } else if (!pd.isClosed()) {
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java

    r9077 r9952  
    2626import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
    2727import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
     28import org.openstreetmap.josm.data.projection.Projection;
    2829import org.openstreetmap.josm.tools.Geometry;
    2930import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter;
     
    375376        }
    376377
    377         public AreaAndPerimeter getAreaAndPerimeter() {
    378             AreaAndPerimeter ap = Geometry.getAreaAndPerimeter(nodes);
     378        /**
     379         * Calculate area and perimeter length in the given projection.
     380         *
     381         * @param projection the projection to use for the calculation, {@code null} defaults to {@link Main#getProjection()}
     382         * @return area and perimeter
     383         */
     384        public AreaAndPerimeter getAreaAndPerimeter(Projection projection) {
     385            AreaAndPerimeter ap = Geometry.getAreaAndPerimeter(nodes, projection);
    379386            double area = ap.getArea();
    380387            double perimeter = ap.getPerimeter();
    381388            for (PolyData inner : inners) {
    382                 AreaAndPerimeter apInner = inner.getAreaAndPerimeter();
     389                AreaAndPerimeter apInner = inner.getAreaAndPerimeter(projection);
    383390                area -= apInner.getArea();
    384391                perimeter += apInner.getPerimeter();
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java

    r9929 r9952  
    531531
    532532        /**
    533          * Returns the area of a closed way in square meters or {@code null}.
    534          * @param env the environment
    535          * @return the area of a closed way in square meters or {@code null}
    536          * @see Geometry#closedWayArea(Way)
     533         * Returns the area of a closed way or multipolygon in square meters or {@code null}.
     534         * @param env the environment
     535         * @return the area of a closed way or multipolygon in square meters or {@code null}
     536         * @see Geometry#computeArea(OsmPrimitive)
    537537         */
    538538        public static Float areasize(final Environment env) {
    539             if (env.osm instanceof Way && ((Way) env.osm).isClosed()) {
    540                 return (float) Geometry.closedWayArea((Way) env.osm);
    541             } else {
    542                 return null;
    543             }
     539            final Double area = Geometry.computeArea(env.osm);
     540            return area == null ? null : area.floatValue();
    544541        }
    545542
  • trunk/src/org/openstreetmap/josm/tools/Geometry.java

    r9951 r9952  
    2727import org.openstreetmap.josm.data.osm.Node;
    2828import org.openstreetmap.josm.data.osm.NodePositionComparator;
     29import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2930import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    3031import org.openstreetmap.josm.data.osm.Relation;
    3132import org.openstreetmap.josm.data.osm.RelationMember;
    3233import org.openstreetmap.josm.data.osm.Way;
     34import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
     35import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;
    3336import org.openstreetmap.josm.data.projection.Projection;
    3437import org.openstreetmap.josm.data.projection.Projections;
     
    638641    public static double closedWayArea(Way way) {
    639642        return getAreaAndPerimeter(way.getNodes(), Projections.getProjectionByCode("EPSG:54008")).getArea();
     643    }
     644
     645    /**
     646     * Returns area of a multipolygon in square meters.
     647     *
     648     * @param multipolygon the multipolygon to measure
     649     * @return area of the multipolygon.
     650     */
     651    public static double multipolygonArea(Relation multipolygon) {
     652        double area = 0.0;
     653        final Multipolygon mp = Main.map == null || Main.map.mapView == null
     654                ? new Multipolygon(multipolygon)
     655                : MultipolygonCache.getInstance().get(Main.map.mapView, multipolygon);
     656        for (Multipolygon.PolyData pd : mp.getCombinedPolygons()) {
     657            area += pd.getAreaAndPerimeter(Projections.getProjectionByCode("EPSG:54008")).getArea();
     658        }
     659        return area;
     660    }
     661
     662    /**
     663     * Computes the area of a closed way and multipolygon in square meters, or {@code null} for other primitives
     664     *
     665     * @param osm the primitive to measure
     666     * @return area of the primitive, or {@code null}
     667     */
     668    public static Double computeArea(OsmPrimitive osm) {
     669        if (osm instanceof Way && ((Way) osm).isClosed()) {
     670            return closedWayArea((Way) osm);
     671        } else if (osm instanceof Relation && ((Relation) osm).isMultipolygon() && !((Relation) osm).hasIncompleteMembers()) {
     672            return multipolygonArea((Relation) osm);
     673        } else {
     674            return null;
     675        }
    640676    }
    641677
  • trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java

    r9951 r9952  
    1313import org.openstreetmap.josm.data.coor.EastNorth;
    1414import org.openstreetmap.josm.data.osm.DataSet;
     15import org.openstreetmap.josm.data.osm.Relation;
    1516import org.openstreetmap.josm.data.osm.Way;
    1617import org.openstreetmap.josm.io.OsmReader;
     
    7273            Way closedWay = (Way) Utils.filter(ds.allPrimitives(), SearchCompiler.compile("landuse=forest")).iterator().next();
    7374            Assert.assertEquals(5760015.7353515625, Geometry.closedWayArea(closedWay), 1e-3);
     75            Assert.assertEquals(5760015.7353515625, Geometry.computeArea(closedWay), 1e-3);
     76        }
     77    }
     78
     79    /**
     80     * Test of {@link Geometry#multipolygonArea(Relation)}} method.
     81     *
     82     * @throws Exception if an error occurs
     83     */
     84    @Test
     85    public void testMultipolygonArea() throws Exception {
     86        try (FileInputStream in = new FileInputStream(TestUtils.getTestDataRoot() + "multipolygon.osm")) {
     87            DataSet ds = OsmReader.parseDataSet(in, null);
     88            final Relation r = ds.getRelations().iterator().next();
     89            Assert.assertEquals(4401735.20703125, Geometry.multipolygonArea(r), 1e-3);
     90            Assert.assertEquals(4401735.20703125, Geometry.computeArea(r), 1e-3);
    7491        }
    7592    }
Note: See TracChangeset for help on using the changeset viewer.