Calculate the area of a polygon drawn on google ma

2019-01-26 01:57发布

问题:

I would like to calculate the are of a polygon drawn in a map fragment for a college project.

This is how I draw my polygon.

@Override
    public void onMapClick(LatLng point) {
        //tvLocInfo.setText("New marker added@" + point.toString());
        map.addMarker(new MarkerOptions().position(point).draggable(true).title(point.toString()));

        markerClicked = false;
    }

    @Override
    public void onMapLongClick(LatLng point) {
        //tvLocInfo.setText("New marker added@" + point.toString());
        map.clear();
    }

    @Override
    public boolean onMarkerClick(Marker marker) {

        if(markerClicked){

            if(polygon != null){
                polygon.remove();
                polygon = null;
            }

            polygonOptions.add(marker.getPosition());
            polygonOptions.strokeColor(Color.RED);
            polygonOptions.fillColor(Color.BLUE);
            polygon = map.addPolygon(polygonOptions);
            //Area = google.maps.geometry.spherical.computeArea(polygon.getPath().getArray());
        }else{
            if(polygon != null){
                polygon.remove();
                polygon = null;
            }

            polygonOptions = new PolygonOptions().add(marker.getPosition());
            markerClicked = true;
        }

I have seen this code on how to calculate the area but I am unsure how to implement it in my application and calculate the area of my polygon.

I use this code to calculate an area of a GPS with Android:

  private static final double EARTH_RADIUS = 6371000;// meters

  public static double calculateAreaOfGPSPolygonOnEarthInSquareMeters(final List<Location> locations) {
    return calculateAreaOfGPSPolygonOnSphereInSquareMeters(locations, EARTH_RADIUS);
  }

  private static double calculateAreaOfGPSPolygonOnSphereInSquareMeters(final List<Location> locations, final double radius) {
    if (locations.size() < 3) {
      return 0;
    }

    final double diameter = radius * 2;
    final double circumference = diameter * Math.PI;
    final List<Double> listY = new ArrayList<Double>();
    final List<Double> listX = new ArrayList<Double>();
    final List<Double> listArea = new ArrayList<Double>();
    // calculate segment x and y in degrees for each point
    final double latitudeRef = locations.get(0).getLatitude();
    final double longitudeRef = locations.get(0).getLongitude();
    for (int i = 1; i < locations.size(); i++) {
      final double latitude = locations.get(i).getLatitude();
      final double longitude = locations.get(i).getLongitude();
      listY.add(calculateYSegment(latitudeRef, latitude, circumference));
      Log.d(LOG_TAG, String.format("Y %s: %s", listY.size() - 1, listY.get(listY.size() - 1)));
      listX.add(calculateXSegment(longitudeRef, longitude, latitude, circumference));
      Log.d(LOG_TAG, String.format("X %s: %s", listX.size() - 1, listX.get(listX.size() - 1)));
    }

    // calculate areas for each triangle segment
    for (int i = 1; i < listX.size(); i++) {
      final double x1 = listX.get(i - 1);
      final double y1 = listY.get(i - 1);
      final double x2 = listX.get(i);
      final double y2 = listY.get(i);
      listArea.add(calculateAreaInSquareMeters(x1, x2, y1, y2));
      Log.d(LOG_TAG, String.format("area %s: %s", listArea.size() - 1, listArea.get(listArea.size() - 1)));
    }

    // sum areas of all triangle segments
    double areasSum = 0;
    for (final Double area : listArea) {
      areasSum = areasSum + area;
    }

    // get abolute value of area, it can't be negative
    return Math.abs(areasSum);// Math.sqrt(areasSum * areasSum);
  }

  private static Double calculateAreaInSquareMeters(final double x1, final double x2, final double y1, final double y2) {
    return (y1 * x2 - x1 * y2) / 2;
  }

  private static double calculateYSegment(final double latitudeRef, final double latitude, final double circumference) {
    return (latitude - latitudeRef) * circumference / 360.0;
  }

  private static double calculateXSegment(final double longitudeRef, final double longitude, final double latitude,
      final double circumference) {
    return (longitude - longitudeRef) * circumference * Math.cos(Math.toRadians(latitude)) / 360.0;
  } 

I could also use the following polygon which is static if calculating the area of the drawn polygon is not possible.

Polygon UCCpolygon = map.addPolygon(new PolygonOptions()
    .add(new LatLng(51.893728, -8.491865), 
         new LatLng(51.893550, -8.492479), 
         new LatLng(51.893216, -8.492224), 
         new LatLng(51.893404, -8.491598))
 .strokeColor(Color.RED)
 .fillColor(Color.BLUE));

Thanks for the help!

Sean

回答1:

There's already a library for that.

import com.google.maps.android.SphericalUtil;

//...

List<LatLng> latLngs = new ArrayList<>();
latLngs.add(new LatLng(51.893728, -8.491865));
latLngs.add(new LatLng(51.893550, -8.492479));
latLngs.add(new LatLng(51.893216, -8.492224));
latLngs.add(new LatLng(51.893404, -8.491598));
Log.i(TAG, "computeArea " + SphericalUtil.computeArea(latLngs));

For me the output is computeArea 1920.8879882782069