#11516 closed enhancement (fixed)
Compute areasize() for multipolygons
Reported by: | naoliv | Owned by: | team |
---|---|---|---|
Priority: | normal | Milestone: | 16.04 |
Component: | Core validator | Version: | |
Keywords: | mapcss area relation multipolygon | Cc: | Klumbumbus |
Description
Shouldn't areasize()
also return the area size of relations?
The area
selector matches "any area regardless of whether the area border is only modelled with a single way or with a set of ways glued together with a relation" while areasize()
only works with a closed way.
Attachments (4)
Change History (25)
Changed 6 years ago by
Attachment: | example.osm added |
---|
comment:1 Changed 6 years ago by
comment:2 Changed 6 years ago by
Keywords: | area relation multipolygon added |
---|---|
Milestone: | → 16.02 |
comment:3 Changed 6 years ago by
An implementation could be taken from or be inspired by the measurement plugin, MeasurementDialog.java
comment:4 follow-up: 6 Changed 6 years ago by
Or this:
Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, r); double area = 0; for (PolyData pd : multipolygon.getCombinedPolygons()) { area += pd.getAreaAndPerimeter().getArea(); }
comment:5 Changed 6 years ago by
Cc: | Klumbumbus added |
---|
comment:6 follow-up: 7 Changed 6 years ago by
Replying to bastiK:
org.openstreetmap.josm.tools.Geometry#getAreaAndPerimeter
returns the area wrt to the current projection. Thus, the value cannot be directly represented in the user's SystemOfMeasurement
. Can we somehow handle this?
comment:7 Changed 6 years ago by
To get a meaningful area in square meters, the coordinates need to be projected using an equal-area projection. Measurement plugin uses Sinusoidal projection. Cylindrical equal-area projection is even simpler.
The way this is done in Geometry
(calcX
/calcY
) is incorrect: The author invented a funny projection that calculates the easting of a point (lat/lon) as great circle distance to the point (lat/0.0) and northing as great circle distance to the point (0.0/lon). This is more complicated and less correct than the projections mentioned above. Plus it is broken for areas crossing the prime meridian. I committed the code myself in [4085], so unfortunately, I have no one to blame. ;-)
Replying to simon04:
org.openstreetmap.josm.tools.Geometry#getAreaAndPerimeter
returns the area wrt to the current projection. Thus, the value cannot be directly represented in the user'sSystemOfMeasurement
. Can we somehow handle this?
Right, the values are needed in units of the current projection for map rendering. Not sure if this can be merged somehow, but it may be simpler to add an extra method to Geometry
which copies and adapts the code in PolyData.getAreaAndPerimeter
.
Changed 6 years ago by
Attachment: | _11516___Sinusoidal_projection.patch added |
---|
Changed 6 years ago by
Attachment: | _11516___implementation_from_the_measurement_plugin.patch added |
---|
comment:9 follow-up: 10 Changed 6 years ago by
For the outer ring of source:trunk/test/data/create_multipolygon.osm,
- the current implementation gives 5721923.660644531
- the implementation from the measurement plugin gives 5736957.869628906
- my attempt to implement https://en.wikipedia.org/wiki/Sinusoidal_projection gives 5757045.313964844
comment:10 follow-up: 13 Changed 6 years ago by
Replying to simon04:
For the outer ring of source:trunk/test/data/create_multipolygon.osm,
- the current implementation gives 5721923.660644531
- the implementation from the measurement plugin gives 5736957.869628906
- my attempt to implement https://en.wikipedia.org/wiki/Sinusoidal_projection gives 5757045.313964844
The difference of the last two comes from different earth radii used as input. Regarding the patch: The EastNorth coordinates in the current projection are cached and should be used in this calculation (runs during rendering). Implementation of sinusoidal should either include ellipsoidal case (see geotools implementation) or throw an error when ellipsoid is not spherical.
comment:11 Changed 6 years ago by
Milestone: | 16.02 → 16.03 |
---|
comment:12 Changed 6 years ago by
Summary: | areasize() not working with relations → Compute areasize() for multipolygons |
---|---|
Type: | defect → enhancement |
Changed 6 years ago by
Attachment: | _11516___Sinusoidal_projection-v2.patch added |
---|
comment:13 Changed 6 years ago by
bastiK, thank you for the review.
- _11516___Sinusoidal_projection-v2.patch computes 5760015.7353515625
What do you think? Is the order phi/lambda and east/north correct in the (inv-)project methods?
comment:14 Changed 6 years ago by
Without testing, I would say
return new double[]{east / cos(north), north};
should be
return new double[]{north, east / cos(north)};
Otherwise +1.
As you may be aware, with this patch it uses ellipsoidal case of the projection, which is even more precise than the method of measurement plugin. The efficiency is fine too - the forward projections is fairly simple and overall it should be faster that what we have at the moment.
comment:20 Changed 6 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
Using the attached example file and this example mapcss rule it should match all the 3 areas.