call method

  1. @override
LatLng call(
  1. Polygon<Object> polygon
)
override

Given a polygon (and its points), calculate a single position at which the center of the label should be placed

Polygon.points is not guaranteed to be non-empty. If empty, this may throw.

Implementation

@override
LatLng call(Polygon polygon) {
  final points = polygon.points;

  if (points.isEmpty) {
    throw ArgumentError('Polygon must contain at least one point');
  }

  if (points.length == 1) return points[0];

  double signedArea = 0;
  double centroidX = 0;
  double centroidY = 0;

  // For all vertices except last
  for (int i = 0; i < points.length - 1; i++) {
    final double x0 = points[i].longitude;
    final double y0 = points[i].latitude;
    final double x1 = points[i + 1].longitude;
    final double y1 = points[i + 1].latitude;

    // Calculate signed area contribution of current vertex
    final double a = x0 * y1 - x1 * y0;
    signedArea += a;

    // Accumulate centroid components weighted by signed area
    centroidX += (x0 + x1) * a;
    centroidY += (y0 + y1) * a;
  }

  // Close the polygon by connecting last vertex to first
  final double x0 = points.last.longitude;
  final double y0 = points.last.latitude;
  final double x1 = points.first.longitude;
  final double y1 = points.first.latitude;
  final double a = x0 * y1 - x1 * y0;
  signedArea += a;
  centroidX += (x0 + x1) * a;
  centroidY += (y0 + y1) * a;

  // Complete the signed area calculation
  signedArea *= 0.5;

  // Calculate centroid coordinates
  centroidX /= 6 * signedArea;
  centroidY /= 6 * signedArea;

  // Handle special case of zero area (collinear points)
  if (signedArea == 0) {
    // Default to average of all points
    double sumX = 0;
    double sumY = 0;
    for (final point in points) {
      sumX += point.longitude;
      sumY += point.latitude;
    }
    return LatLng(sumY / points.length, sumX / points.length);
  }

  return LatLng(centroidY, centroidX);
}