Reputation: 1175
It doesn't need to be 100% correct, it can be the center of the bounding rectangle.
Upvotes: 76
Views: 119085
Reputation: 441
Getting the center of a polygon with multiple points and setting it on a map
=== Start of Coordinates ===
const polyCoords = [
{lat:7.47107077, lng:8.63921547},
{lat:7.46994686, lng:8.63547325},
{lat:7.46309805, lng:8.62589836},
{lat:7.46286821, lng:8.62590313},
{lat:7.45313215, lng:8.60899639},
{lat:7.43740988, lng:8.59334755},
{lat:7.42844009, lng:8.58104324},
{lat:7.41945982, lng:8.56827736},
{lat:7.40859699, lng:8.55323505},
{lat:7.40289497, lng:8.54318237},
{lat:7.392138, lng:8.53482914},
{lat:7.37328196, lng:8.52523136},
{lat:7.35658979, lng:8.52090073},
{lat:7.34258223, lng:8.51121902},
{lat:7.33046389, lng:8.50427532},
{lat:7.31578684, lng:8.49598789},
{lat:7.3011179, lng:8.48839378},
{lat:7.28741598, lng:8.4833231},
{lat:7.27968311, lng:8.4763031},
{lat:7.26344395, lng:8.47150517},
{lat:7.23888779, lng:8.46638584},
{lat:7.21805, lng:8.46258926},
{lat:7.20483398, lng:8.45912266},
{lat:7.18925285, lng:8.45223522},
{lat:7.17993593, lng:8.4470892},
{lat:7.15788603, lng:8.43984985},
{lat:7.13150883, lng:8.43637943},
{lat:7.11252594, lng:8.43324089},
{lat:7.09124422, lng:8.43060589},
{lat:7.06365919, lng:8.42369366},
{lat:7.0361681, lng:8.42277718},
{lat:7.02137899, lng:8.42187691},
{lat:7.00718498, lng:8.41496658},
{lat:6.98336077, lng:8.41237545},
{lat:6.97815323, lng:8.41181469},
{lat:6.96920681, lng:8.41085052},
{lat:6.96485901, lng:8.41038322},
{lat:6.95552588, lng:8.40431404},
{lat:6.94989014, lng:8.40449047},
{lat:6.93937397, lng:8.40481758},
{lat:6.92389822, lng:8.40438938},
{lat:6.90868998, lng:8.40626526},
{lat:6.89626408, lng:8.40878296},
{lat:6.88465405, lng:8.40741062},
{lat:6.88261604, lng:8.4071703},
{lat:6.87496519, lng:8.40522289},
{lat:6.87435913, lng:8.40444374},
{lat:6.874259, lng:8.40431404},
{lat:6.86711407, lng:8.40512753},
{lat:6.85861206, lng:8.40488625},
{lat:6.85695124, lng:8.40484142},
{lat:6.84681988, lng:8.4066267},
{lat:6.83782721, lng:8.40724277},
{lat:6.83494997, lng:8.40681171},
{lat:6.82532978, lng:8.40537834},
{lat:6.81447697, lng:8.40533257},
{lat:6.80816412, lng:8.40398979},
{lat:6.80544186, lng:8.40341187},
{lat:6.80309677, lng:8.40415192},
{lat:6.79915714, lng:8.4053936},
{lat:6.79694414, lng:8.40609169},
{lat:6.79487896, lng:8.40666771},
{lat:6.79399681, lng:8.40691471},
{lat:6.79165602, lng:8.40756893},
{lat:6.79155779, lng:8.40760326},
{lat:6.78247595, lng:8.41095257},
{lat:6.77746391, lng:8.42351627},
{lat:6.76626587, lng:8.45157433},
{lat:6.75096416, lng:8.48992825},
{lat:6.75101185, lng:8.49293423},
{lat:6.75103521, lng:8.49443054},
{lat:6.75106716, lng:8.49638653},
{lat:6.7513752, lng:8.49816227},
{lat:6.75229788, lng:8.5035038},
{lat:6.75233889, lng:8.50374794},
{lat:6.75729084, lng:8.51012325},
{lat:6.75758314, lng:8.51057243},
{lat:6.75847387, lng:8.51194859},
{lat:6.75807714, lng:8.5156126},
{lat:6.7578721, lng:8.51749611},
{lat:6.75769711, lng:8.51795578},
{lat:6.75742817, lng:8.51865578},
{lat:6.75132704, lng:8.97139263},
{lat:6.7482481, lng:8.98090267},
{lat:6.74862814, lng:8.98276329},
{lat:6.74871206, lng:8.9831686},
{lat:6.74890804, lng:8.98458385},
{lat:6.74876881, lng:8.98458672},
{lat:6.74830914, lng:8.98459339},
{lat:6.74822187, lng:8.98898792},
{lat:6.74818087, lng:8.9910574},
{lat:6.74633312, lng:8.99746799},
{lat:6.74763012, lng:8.99746132},
{lat:6.74740887, lng:9.00071144},
{lat:6.74718285, lng:9.00401211},
{lat:6.7468462, lng:9.00896358},
{lat:6.74784899, lng:9.03189945},
{lat:6.74912691, lng:9.04191589},
{lat:6.749506, lng:9.04487896},
{lat:6.7501688, lng:9.06040001},
{lat:6.74998713, lng:9.06665802},
{lat:6.7495532, lng:9.08146954},
{lat:6.75030279, lng:9.10532761},
{lat:6.75147676, lng:9.11876583},
{lat:6.75115299, lng:9.12830734},
{lat:6.751019, lng:9.13230419},
{lat:6.75097609, lng:9.13358688},
{lat:6.75030613, lng:9.15766907},
{lat:6.74956512, lng:9.18568802},
{lat:6.74977493, lng:9.20027924},
{lat:6.75178003, lng:9.20677471},
{lat:6.75207376, lng:9.21673679},
{lat:6.75762796, lng:9.22278786},
{lat:6.76703405, lng:9.22469616},
{lat:6.77835321, lng:9.22522545},
{lat:6.78895092, lng:9.22644424},
{lat:6.80095482, lng:9.22813511},
{lat:6.80803204, lng:9.22840595},
{lat:6.81769705, lng:9.2289257},
{lat:6.8349371, lng:9.2283287},
{lat:6.85686684, lng:9.22915077},
{lat:6.86674404, lng:9.23106098},
{lat:6.87596607, lng:9.23018837},
{lat:6.88755703, lng:9.22863388},
{lat:6.90605688, lng:9.22916317},
{lat:6.92060709, lng:9.22969246},
{lat:6.93092918, lng:9.23265743},
{lat:6.94083691, lng:9.23125458},
{lat:6.96318817, lng:9.23240376},
{lat:6.97901201, lng:9.23571301},
{lat:6.99151802, lng:9.23115253},
{lat:7.00751305, lng:9.22559357},
{lat:7.01615286, lng:9.21457386},
{lat:7.03671312, lng:9.19904041},
{lat:7.04957199, lng:9.18851852},
{lat:7.06313276, lng:9.17939568},
{lat:7.07376099, lng:9.16631126},
{lat:7.09011078, lng:9.15050983},
{lat:7.10480881, lng:9.13908195},
{lat:7.11774111, lng:9.12994957},
{lat:7.12020206, lng:9.12689114},
{lat:7.12678719, lng:9.1187048},
{lat:7.13768578, lng:9.10678005},
{lat:7.14586782, lng:9.09899521},
{lat:7.15596008, lng:9.09561729},
{lat:7.16383696, lng:9.0976162},
{lat:7.16397095, lng:9.09764957},
{lat:7.16446781, lng:9.09777832},
{lat:7.16467285, lng:9.09782982},
{lat:7.16668797, lng:9.0983429},
{lat:7.17027283, lng:9.09925175},
{lat:7.17104816, lng:9.0994482},
{lat:7.17748404, lng:9.11013699},
{lat:7.1852951, lng:9.12178135},
{lat:7.18590498, lng:9.12269306},
{lat:7.19736004, lng:9.14105415},
{lat:7.20605278, lng:9.1508379},
{lat:7.21073914, lng:9.15619564},
{lat:7.22404385, lng:9.17387962},
{lat:7.23505497, lng:9.19177437},
{lat:7.24421883, lng:9.20248795},
{lat:7.25214815, lng:9.2136507},
{lat:7.26130819, lng:9.22829533},
{lat:7.27181292, lng:9.24456787},
{lat:7.27600622, lng:9.25246239},
{lat:7.28409719, lng:9.25877571},
{lat:7.2944541, lng:9.2762022},
{lat:7.29864502, lng:9.28409672},
{lat:7.30395985, lng:9.29338932},
{lat:7.30883694, lng:9.29736137},
{lat:7.31085396, lng:9.29749584},
{lat:7.31294203, lng:9.29763317},
{lat:7.32206106, lng:9.29725742},
{lat:7.32526493, lng:9.30005836},
{lat:7.3387351, lng:9.30434513},
{lat:7.36335707, lng:9.30342197},
{lat:7.3788681, lng:9.30495262},
{lat:7.39461279, lng:9.30810261},
{lat:7.40965986, lng:9.30755138},
{lat:7.43268299, lng:9.30545902},
{lat:7.45160484, lng:9.30448055},
{lat:7.46140003, lng:9.30249405},
{lat:7.47527122, lng:9.291996},
{lat:7.48597622, lng:9.28886032},
{lat:7.49556684, lng:9.29241562},
{lat:7.50426912, lng:9.30243492},
{lat:7.51206589, lng:9.31382847},
{lat:7.51597023, lng:9.32126045},
{lat:7.52583599, lng:9.33729362},
{lat:7.53341389, lng:9.35122871},
{lat:7.54164696, lng:9.35685062},
{lat:7.55055094, lng:9.35993958},
{lat:7.55715799, lng:9.35861778},
{lat:7.56785202, lng:9.35293961},
{lat:7.57442522, lng:9.34260464},
{lat:7.57712793, lng:9.33361816},
{lat:7.58118677, lng:9.32210445},
{lat:7.58320713, lng:9.31334305},
{lat:7.58979607, lng:9.30693436},
{lat:7.5916028, lng:9.30302334},
{lat:7.60486794, lng:9.29872894},
{lat:7.60572386, lng:9.29845142},
{lat:7.60686207, lng:9.29808426},
{lat:7.61690998, lng:9.30256939},
{lat:7.62142801, lng:9.30766106},
{lat:7.62240505, lng:9.30839729},
{lat:7.6258359, lng:9.31074047},
{lat:7.62646914, lng:9.29734325},
{lat:7.62800121, lng:9.29264832},
{lat:7.62849808, lng:9.29112339},
{lat:7.62477303, lng:9.27168179},
{lat:7.61906385, lng:9.26338196},
{lat:7.61789513, lng:9.26168156},
{lat:7.60666084, lng:9.260952},
{lat:7.60124397, lng:9.26060104},
{lat:7.60034084, lng:9.25955677},
{lat:7.59277201, lng:9.25081539},
{lat:7.58999205, lng:9.24243736},
{lat:7.58469677, lng:9.22647762},
{lat:7.57617283, lng:9.20398521},
{lat:7.57207108, lng:9.18593216},
{lat:7.57107019, lng:9.18152714},
{lat:7.56439877, lng:9.16621494},
{lat:7.55862188, lng:9.14605904},
{lat:7.55898905, lng:9.13870907},
{lat:7.55946493, lng:9.12918186},
{lat:7.55989313, lng:9.12065315},
{lat:7.55908394, lng:9.11564445},
{lat:7.55753183, lng:9.10603333},
{lat:7.55615616, lng:9.0975132},
{lat:7.55674982, lng:9.09182739},
{lat:7.55695581, lng:9.08985138},
{lat:7.55813408, lng:9.07858467},
{lat:7.55744982, lng:9.05847168},
{lat:7.55736303, lng:9.05593491},
{lat:7.55961514, lng:9.04537582},
{lat:7.56139517, lng:9.03702545},
{lat:7.56247616, lng:9.03288078},
{lat:7.5634079, lng:9.02930832},
{lat:7.56566381, lng:9.02066135},
{lat:7.56515789, lng:9.00748539},
{lat:7.5639658, lng:9.00404358},
{lat:7.56356478, lng:9.00404358},
{lat:7.56289005, lng:9.00404358},
{lat:7.56242323, lng:9.00015068},
{lat:7.56232119, lng:8.99929619},
{lat:7.56194496, lng:8.99821568},
{lat:7.56198788, lng:8.99778271},
{lat:7.56215, lng:8.99696159},
{lat:7.56281996, lng:8.96886539},
{lat:7.55899286, lng:8.95738316},
{lat:7.55724001, lng:8.95211983},
{lat:7.55969477, lng:8.93246746},
{lat:7.55676603, lng:8.90829468},
{lat:7.55125523, lng:8.89593029},
{lat:7.54641199, lng:8.88194084},
{lat:7.54488802, lng:8.87319756},
{lat:7.54288197, lng:8.86331367},
{lat:7.53791094, lng:8.85578632},
{lat:7.53442907, lng:8.84015846},
{lat:7.52946901, lng:8.83331966},
{lat:7.5268302, lng:8.82713699},
{lat:7.52469683, lng:8.8237114},
{lat:7.52377796, lng:8.80965614},
{lat:7.522964, lng:8.80752277},
{lat:7.51968002, lng:8.79888344},
{lat:7.51792288, lng:8.79014683},
{lat:7.51585579, lng:8.77657032},
{lat:7.5152092, lng:8.76504707},
{lat:7.51339722, lng:8.75284863},
{lat:7.50989103, lng:8.73583889},
{lat:7.50696516, lng:8.72619915},
{lat:7.50269794, lng:8.71934986},
{lat:7.50024414, lng:8.69586086},
{lat:7.48745108, lng:8.69007874},
{lat:7.48527384, lng:8.68388939},
{lat:7.48022795, lng:8.67174816},
{lat:7.475317, lng:8.65337563},
{lat:7.47107077, lng:8.63921547}];
=== End of Coordinates ===
// Construct the polygon.
const polygong= new google.maps.Polygon({
paths: polyCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: "#FF0000",
fillOpacity: 0.35,
});
var bounds = new google.maps.LatLngBounds();
polyCoords.forEach(function(coord, index)
{
bounds.extend(coord);
});
//Note: "map" object already set and initialized elsewhere but not shown in code snippet to reduce verbosity
map.setCenter(bounds.getCenter());
Upvotes: 1
Reputation: 3404
kotlin version of getting center of polygon. mPoints
is array of latitude
and longitude
.
val bounds = LatLngBounds.Builder()
for(i in 0 until mPoints.size) {
val point = LatLng(mPoints[i].latitude, mPoints[i].longitude)
bounds.include(point)
}
mMap.moveCamera(CameraUpdateFactory.newLatLng(bounds.build().center))
Upvotes: 0
Reputation: 1139
For somone seaching for an answer in dart/flutter you can achieve the same by using the code below.
calculateCenter(List<LatLng> points) {
var longitudes = points.map((i) => i.longitude).toList();
var latitudes = points.map((i) => i.latitude).toList();
latitudes.sort();
longitudes.sort();
var lowX = latitudes.first;
var highX = latitudes.last;
var lowy = longitudes.first;
var highy = longitudes.last;
var centerX = lowX + ((highX - lowX) / 2);
var centerY = lowy + ((highy - lowy) / 2);
return LatLng(centerX, centerY);
}
Upvotes: 6
Reputation: 3133
Here is a custom function I wrote. Feel free to use it.
function polygonCenter(poly) {
const vertices = poly.getPath();
// put all latitudes and longitudes in arrays
const longitudes = new Array(vertices.length).map((_, i) => vertices.getAt(i).lng());
const latitudes = new Array(vertices.length).map((_, i) => vertices.getAt(i).lat());
// sort the arrays low to high
latitudes.sort();
longitudes.sort();
// get the min and max of each
const lowX = latitudes[0];
const highX = latitudes[latitudes.length - 1];
const lowy = longitudes[0];
const highy = longitudes[latitudes.length - 1];
// center of the polygon is the starting point plus the midpoint
const centerX = lowX + ((highX - lowX) / 2);
const centerY = lowy + ((highy - lowy) / 2);
return (new google.maps.LatLng(centerX, centerY));
}
Upvotes: 8
Reputation: 2375
Note that in the case of a concave polygon the center of the bounding rectangle might be completely outside the polygon. If your polygons might be concaved, I'd recommend using the center of the biggest inscribed circle as the "center" of the polygon. You can see a simple enough algorithm here (p. 4). If your task is to place a label on the polygon, this will also give the most aesthetically pleasing results (in which case I'd recommend using this method even if your polygons might not be concave).
Upvotes: 4
Reputation: 591
you can extend the Polygon class with your own version of the missing function, let's call it my_getBounds() :
google.maps.Polygon.prototype.my_getBounds=function(){
var bounds = new google.maps.LatLngBounds()
this.getPath().forEach(function(element,index){bounds.extend(element)})
return bounds
}
and than use it in code like this :
myPolygon.my_getBounds().getCenter()
... etc, it should be equivalent to the v2 behavior
Upvotes: 59
Reputation: 344301
Matthew's answer is a good solution. However, when using the Google Maps API v3, you might want to pass each point of the polygon to a LatLngBounds
object through the extend()
method, and then finally call the getCenter()
method on the LatLngBounds
object. Consider the following example:
var bounds = new google.maps.LatLngBounds();
var i;
// The Bermuda Triangle
var polygonCoords = [
new google.maps.LatLng(25.774252, -80.190262),
new google.maps.LatLng(18.466465, -66.118292),
new google.maps.LatLng(32.321384, -64.757370),
new google.maps.LatLng(25.774252, -80.190262)
];
for (i = 0; i < polygonCoords.length; i++) {
bounds.extend(polygonCoords[i]);
}
// The Center of the Bermuda Triangle - (25.3939245, -72.473816)
console.log(bounds.getCenter());
Upvotes: 235
Reputation: 132254
Algorithm:
Run through all the points in the polygon. For all the points find;
x1
, the lowest x
coordinatey1
, the lowest y
coordinatex2
, the highest x
coordinatey2
, the highest y
coordinateYou now have the bounding rectangle, and can work out the center using:
center.x = x1 + ((x2 - x1) / 2);
center.y = y1 + ((y2 - y1) / 2);
Upvotes: 82