final from = Point<double>(0.0, 0.0);
final to = Point<double>(10.0, 5.0);
final distance = GoogleMapsUtils.spherical.computeDistanceBetween(from, to);
// 1241932.5985192063 meters
Heading (Bearing)
final heading = GoogleMapsUtils.spherical.computeHeading(from, to);
// 26.302486345342523 degrees (clockwise from North)
// Move 1000 meters east (heading 90°) from the originfinal origin = Point<double>(0.0, 0.0);
final destination = GoogleMapsUtils.spherical.computeOffset(origin, 1000.0, 90.0);
// Returns the Point at the new location
Compute Offset Origin (Reverse Lookup)
// Given a destination, distance, and heading — find where you startedfinal origin = GoogleMapsUtils.spherical.computeOffsetOrigin(destination, 1000.0, 90.0);
// Returns Point? (null if no solution exists)
Interpolation (SLERP)
// Find the point 25% of the way between two locationsfinal quarter = GoogleMapsUtils.spherical.interpolate(from, to, 0.25);
Path Length
final path = <Point<double>>[
Point(0.0, 0.0),
Point(1.0, 1.0),
Point(2.0, 0.0),
];
final length = GoogleMapsUtils.spherical.computeLength(path);
// Total distance in meters along the path
// Decode a Google Encoded Polyline string into coordinatesfinal path = GoogleMapsUtils.poly.decode(
'wjiaFz`hgQs}GmmBok@}vX|cOzKvvT`uNutJz|UgqAglAjr@ijBz]opA');
// Returns List<Point<double>> with 17 points
Polyline Encoding
// Encode coordinates back to a compact stringfinal encoded = GoogleMapsUtils.poly.encode(path);
Douglas-Peucker Simplification
// Reduce points while preserving shape (tolerance in meters)final simplified = GoogleMapsUtils.poly.simplify(path, 5000.0);
// 17 points → 6 points
Point-in-Polygon
final point = Point<double>(-31.623060, -60.686690);
final polygon = <Point<double>>[
Point(-31.624115, -60.688734),
Point(-31.624115, -60.684657),
Point(-31.621594, -60.686717),
Point(-31.624115, -60.688734),
];
final isInside = GoogleMapsUtils.poly.containsLocationPoly(point, polygon);
// true// Also supports geodesic (great-circle) edges:final isInsideGeodesic = GoogleMapsUtils.poly.containsLocationPoly(
point, polygon, geodesic: true,
);
Point-on-Path Detection
final route = <Point<double>>[
Point(0.0, 0.0),
Point(0.0, 10.0),
];
// Is the point on or near the polyline? (default tolerance: 0.1m)final isOnPath = GoogleMapsUtils.poly.isLocationOnPath(
Point(0.0, 5.0), route, true, // geodesic
);
// true// Get which segment the point falls onfinal segmentIndex = GoogleMapsUtils.poly.locationIndexOnPath(
Point(0.0, 5.0), route, true,
);
// 0 (between route[0] and route[1])
Point-on-Edge (Polygon Boundary)
final square = <Point<double>>[
Point(0.0, 0.0),
Point(0.0, 10.0),
Point(10.0, 10.0),
Point(10.0, 0.0),
];
// Includes the closing segment (last→first)final isOnEdge = GoogleMapsUtils.poly.isLocationOnEdge(
Point(5.0, 0.0), square, true,
);
// true
Distance to a Line Segment
final p = Point<double>(-23.54545, -23.898098);
final start = Point<double>(0.0, 0.0);
final end = Point<double>(10.0, 5.0);
final dist = GoogleMapsUtils.poly.distanceToLine(p, start, end);
// 3675538.019968191 meters
Compute Area
final area = GoogleMapsUtils.spherical.computeArea(polygon);
// Area in square metersfinal signedArea = GoogleMapsUtils.spherical.computeSignedArea(polygon);
// Positive = counter-clockwise, negative = clockwise
Bounding Boxes
// Create bounds from a center point + radius// Returns a LatLngBounds record: (ne: Point<double>, sw: Point<double>)final bounds = GoogleMapsUtils.spherical.toBounds(-23.55, -46.63, 1000.0);
print(bounds.ne); // north-east cornerprint(bounds.sw); // south-west corner// Create bounds from a list of pointsfinal bounds = GoogleMapsUtils.spherical.toBoundsFromPoints(path);
// Get the center of a boundsfinal center = GoogleMapsUtils.spherical.centerFromLatLngBounds(bounds);
// Split bounds into a grid (division² sub-bounds)final tiles = GoogleMapsUtils.spherical.toSubBounds(bounds, division: 3);
// Returns 9 sub-bounds
Closed Polygon Check
GoogleMapsUtils.poly.isClosedPolygon(polygon); // true if first == last point
Custom Tolerance (On-Path / On-Edge)
// Default tolerance is 0.1 meters. Use custom tolerance for proximity:final isNear = GoogleMapsUtils.poly.isLocationOnPathTolerance(
point, polyline, true, 50.0, // 50 meters tolerance
);
// Same for edges:final isNearEdge = GoogleMapsUtils.poly.isLocationOnEdgeTolerance(
point, polygon, true, 50.0,
);
// With index:final idx = GoogleMapsUtils.poly.locationIndexOnPathTolerance(
point, polyline, true, 50.0,
);
Math Helpers (Low-Level)
// Clamp a value to a rangeGoogleMapsUtils.math.clamp(15.0, 0.0, 10.0); // 10.0// Wrap a value into [min, max) — useful for longitudeGoogleMapsUtils.math.wrap(190.0, -180.0, 180.0); // -170.0// Non-negative moduloGoogleMapsUtils.math.mod(-1.0, 360.0); // 359.0// Mercator projection (radians)final y = GoogleMapsUtils.math.mercator(latInRadians);
final lat = GoogleMapsUtils.math.inverseMercator(y);
// Haversine / inverse haversinefinal h = GoogleMapsUtils.math.hav(angleInRadians);
final angle = GoogleMapsUtils.math.arcHav(h);
// Haversine distance on unit spherefinal havDist = GoogleMapsUtils.math.havDistance(lat1, lat2, dLng);
3 of 78 classes from android-maps-utils have been converted — these are the most widely used. Need another class? Open an issue and I'll prioritize it.