How to center map in the middle of polygon?

Asked

Viewed 802 times

4

I have a polygon formed, at first, with 3 edges, basically created using 3 locations: Maiami, Puerto Rico and Bermuda. I took the example in the documentation that shows how to create a simple polygon. However, by the required standard of the API, the map must be centralized somewhere (if not open the map), in which I centralized in Rio de Janeiro, through the coordinates. See below and zoom in:

function initialize() {
  var map = new google.maps.Map(document.getElementById("map_canvas"), {
    zoom: 10,
    center: new google.maps.LatLng(-22.91711261458102, -43.16944599151611),
    mapTypeId: "roadmap"
  });

  // 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
    }
  ];

  // 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>

One way that I found was to point the center of the map to any point of the polygon, but it will not be totally centralized (baita perfectionism). The point is, I’d like to center the map in the middle of the polygon, which I’m dynamically creating.

What would be a better way to do this? How to center map in the middle of the polygon?

  • 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

  • @Jeffersonquesado but ai would have to return me in latitude and longitude format. = D understand this ?

  • 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))

1 answer

7


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>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.