The idea is to calculate the barycenter of a polygon and use it as a map coordinate.
The baricentro of a polygon is given by the arithmetic mean of the coordinates (cartesians!, important detail for later) of the points of the polygon. Roughly, the following algorithm calculates 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 turn these coordinates into radians (180
degrees valley pi
radians). The general formula is this:
theta_rad = theta_graus * pi / 180
The opposite conversion is:
theta_graus = theta_rad *180/pi
Okay, now we have the conversion to radians. Now, we need to convert radians to a point in Cartesian space. I used the contained formulas in that question from the international SO.
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 it (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)
From there, just turn to degrees and be happy. The code below is kind of dirty and polluted, but 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>
<body onload="initialize()">
<div id="map_canvas" style="height: 100vh; width:100vw"></div>
</body>
The @Viana later discovered the function of the Googlemaps API itself that makes the baricentro calculation.
That function is bounds.getCenter()
, being var bounds = new google.maps.LatLngBounds()
. Note that it is necessary to add the desired points on this edge to pick up 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>
<body onload="initialize()">
<div id="map_canvas2" style="height: 100vh; width:100vw"></div>
</body>
Have you tried calculating the center of the polygon? In the case of a triangle (3-edge polygon), there is already a formula for this (maybe you need to adapt to the spherical geometry); formula for flat geometry
– Jefferson Quesado
@Jeffersonquesado but ai would have to return me in latitude and longitude format. = D understand this ?
– viana
That would be one of the adaptations to spherical geometry... Have you tried taking the arithmetic mean of all points? (delete the first/last because it is repeated) Type,
centro = (sum(p[i].lat)/size(p), sum(p[i].lon)/size(p))
– Jefferson Quesado