The idea is to calculate the barycentre of a polygon and use this as a map coordinate.
The barycentre of a polygon is given by the arithmetic mean of the coordinates (Cartesian !, important detail for later) of the polygon points. In general, the following algorithm computes this:
x_baricentro = somatório (x dos pontos) / tamanho(pontos)
y_baricentro = somatório (y dos pontos) / tamanho(pontos)
The problem, however, is that the coordinates are given by spherical coordinates in degrees! To solve this, we need to transform these coordinates into radians ( 180
degrees is pi
radians). The general formula is this:
theta_rad = theta_graus * pi / 180
The opposite conversion is:
theta_graus = theta_rad *180/pi
Ok, now we have the conversion to radians. Now, we need to convert from radians to a point in Cartesian space. I used the formulas contained in that international OS question .
x = cos(lat) * cos(lon)
y = cos(lat) * sin(lon)
z = sin(lat)
With this, I get the average of (x,y,z)
, I'll call (x_c,y_c,z_c)
here in the explanation. From these values, I need to convert back to radians:
lon_rad = atan2(y, x)
hyp_rad = sqrt(x * x + y * y)
lat_rad = atan2(z, hyp)
Hence, just turn to degrees and be happy. The code below is a bit dirty and polluted, but it does these calculations the way it was shown.
function initialize() {
// Define the LatLng coordinates for the polygon's path.
var triangleCoords = [{
lat: 25.774,
lng: -80.190
},
{
lat: 18.466,
lng: -66.118
},
{
lat: 32.321,
lng: -64.757
},
{
lat: 25.774,
lng: -80.190
}
];
var x_cart = 0;
var y_cart = 0;
var z_cart = 0;
var i;
// ignorando primeiro elemento
for (i = 1; i < triangleCoords.length; i++) {
var x, y, z;
var lat, lon;
lat = triangleCoords[i].lat * Math.PI / 180; // transforma para radianos
lon = triangleCoords[i].lng * Math.PI / 180; // transforma para radianos
// obtém as coordenadas cartesianas
x = Math.cos(lat) * Math.cos(lon);
y = Math.cos(lat) * Math.sin(lon);
z = Math.sin(lat);
x_cart += x;
y_cart += y;
z_cart += z;
}
// média das coordenadas cartesianas
x_cart = x_cart/(triangleCoords.length - 1.0);
y_cart = y_cart/(triangleCoords.length - 1.0);
z_cart = z_cart/(triangleCoords.length - 1.0);
// processo para voltar a coordenadas esféricas
var lng_c, hyp, lat_c;
lng_c = Math.atan2(y_cart, x_cart);
hyp = Math.sqrt(x_cart * x_cart + y_cart * y_cart);
lat_c = Math.atan2(z_cart, hyp);
// de volta para graus, saindo dos radianos
lng_c = lng_c * 180.0/Math.PI;
lat_c = lat_c * 180.0/Math.PI;
var center = {
lat: lat_c,
lng: lng_c
};
console.log('lat lng' + lat_c + ',' + lng_c);
var map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 4,
center: new google.maps.LatLng(center.lat, center.lng),
mapTypeId: "roadmap"
});
// Construct the polygon.
var bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script><bodyonload="initialize()">
<div id="map_canvas" style="height: 100vh; width:100vw"></div>
</body>
UPDATE
The @acklay later discovered the function of the GoogleMaps API itself that calculates the barycentre.
This function is bounds.getCenter()
, being var bounds = new google.maps.LatLngBounds()
. Note that it is necessary to add the desired points on this border to get the center.
function initialize() {
// Define the LatLng coordinates for the polygon's path.
var bounds = new google.maps.LatLngBounds();
var i;
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)
];
// ignorando o primeiro elemento
for (i = 1; i < polygonCoords.length; i++) {
bounds.extend(polygonCoords[i]);
}
// Aqui imprime a coordenada central em relação ao poligono - (25.3939245, -72.473816)
console.log(bounds.getCenter());
var map = new google.maps.Map(document.getElementById("map_canvas2"), {
zoom: 4,
center: bounds.getCenter(),
mapTypeId: "roadmap"
});
// Construct the polygon.
var bermudaTriangle = new google.maps.Polygon({
paths: polygonCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script><bodyonload="initialize()">
<div id="map_canvas2" style="height: 100vh; width:100vw"></div>
</body>