7

I have Polygons with WGS84/EPSG:4326 coordinates
(like 13.57933804767844,52.5126298984133)
and use the Polygon.getArea function to obtain the area of the polygon.
But the result I get is something like 7.695432394893684E-8 .

There were similiar questions (see here, here or here)
but although some of them are marked as answered,
there is not an answer which helped me.

I would like to convert the result to square meter.
How can I do this?

Selphiron
  • 775
  • 2
  • 11
  • 29
  • 1
    you will have to handle the projection yourself prior to running an area function. EPSG 4326 is a lat/lon GCS. Which means the coordinates are angles from mean not a surface coordinate. there are algorithms which allow some conversion to a surficial unit but from your question I would suggest you handle it through reprojection to a ground CRS with meters as the unit. There are many questions with this focus, and several with answers. http://gis.stackexchange.com/search?q=latitude+to+meters+area – Brad Nesom Dec 31 '14 at 21:46
  • 1
    Can you show a real polygon? If not, can you check if your polygons roughly 30 metres each side? If so, just transform your coordinates into an equal area projection that has metres. – BradHards Dec 31 '14 at 21:46
  • @BradNesom is there a CRS which you could recommend me? @BradHards Im an not sure what you mean by show a real polygon but here are the coordinates of one polygon: [ [ [ 13.632045970877657, 52.51028471023475 ], [ 13.631736612007554, 52.509817421791602 ], [ 13.632054749915945, 52.509817407463906 ], [ 13.632045970877657, 52.51028471023475 ] ] ] this site tells me that it has an area of about 560 square meters. – Selphiron Jan 01 '15 at 00:40
  • 1
    Maybe EPSG:5243. How much accuracy do you need? – BradHards Jan 01 '15 at 01:04
  • Well it doesn't have to be that accurate.. I have some polygons ranging from 100 m² to 10000 km² and maaaaany polygons around 1 m². The tiny polygons must be filtered out. Would EPSG:3068 be ok as well? – Selphiron Jan 01 '15 at 09:24

1 Answers1

4

As all of the questions you have linked to say JTS does not care about the units of your data and treats them all alike - so the answer to your question is square degrees. Now that is rarely (if ever) a good unit to measure areas in as it changes with latitude.

So to answer your real question how do I determine the area of my lat/lon polygons in square metres (or other unit)? - first you need to reproject your polygon to a local projection this is so you have a unit of metres going into the calculation and also because JTS assumes that all of your calculations are on a flat cartesian plane.

private Measure<Double, Area> calcArea(SimpleFeature feature) {
    Polygon p = (Polygon) feature.getDefaultGeometry();
    Point centroid = p.getCentroid();
    try {
      String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY();
      CoordinateReferenceSystem auto = CRS.decode(code);

      MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);

      Polygon projed = (Polygon) JTS.transform(p, transform);
      return Measure.valueOf(projed.getArea(), SI.SQUARE_METRE);
    } catch (MismatchedDimensionException | TransformException | FactoryException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return Measure.valueOf(0.0, SI.SQUARE_METRE);
  }

Will give an approximate answer (and it be closer for smaller polygons), a little bit of playing with the javax units library will give the units you want.

Measure<Double, Area> a = me.calcArea(feature);
System.out.println(feature.getDefaultGeometry());
System.out.println(a);

@SuppressWarnings("unchecked")
Unit<Area> sq_km = (Unit<Area>) SI.KILOMETER.pow(2);
System.out.println(a.to(sq_km));
@SuppressWarnings("unchecked")
Unit<Area> sq_mile = (Unit<Area>) NonSI.MILE.times(NonSI.MILE);
System.out.println(a.to(sq_mile));
System.out.println(a.to(NonSI.HECTARE));
@SuppressWarnings("unchecked")
Unit<Area> acre = (Unit<Area>) NonSI.MILE.divide(8.0).times(NonSI.FOOT).times(66.0);
UnitFormat.getInstance().label(acre, "acre");
System.out.println(a.to(acre));
System.out.println(a.doubleValue(NonSI.HECTARE)+NonSI.HECTARE.toString());
Ian Turton
  • 81,417
  • 6
  • 84
  • 185