javascript - una - Mapa de centro automático con múltiples marcadores en Google Maps API v3
multiples puntos en google maps (6)
Aquí está mi opinión sobre esto en caso de que alguien se encuentre con este hilo:
Esto ayuda a proteger contra datos no numéricos que destruyen cualquiera de sus variables finales que determinan lat
y lng
.
Funciona al tomar todas sus coordenadas, analizarlas en elementos separados lat
y lng
de una matriz, y luego determinar el promedio de cada una. Ese promedio debe ser el centro (y ha demostrado ser cierto en mis casos de prueba).
var coords = "50.0160001,3.2840073|50.014458,3.2778274|50.0169713,3.2750587|50.0180745,3.276742|50.0204038,3.2733474|50.0217796,3.2781737|50.0293064,3.2712542|50.0319918,3.2580816|50.0243287,3.2582281|50.0281447,3.2451177|50.0307925,3.2443178|50.0278165,3.2343882|50.0326574,3.2289809|50.0288569,3.2237612|50.0260081,3.2230589|50.0269495,3.2210104|50.0212645,3.2133541|50.0165868,3.1977592|50.0150515,3.1977341|50.0147901,3.1965286|50.0171915,3.1961636|50.0130074,3.1845098|50.0113267,3.1729483|50.0177206,3.1705726|50.0210692,3.1670394|50.0182166,3.158297|50.0207314,3.150927|50.0179787,3.1485753|50.0184944,3.1470782|50.0273077,3.149845|50.024227,3.1340514|50.0244172,3.1236235|50.0270676,3.1244474|50.0260853,3.1184879|50.0344525,3.113806";
var filteredtextCoordinatesArray = coords.split(''|'');
centerLatArray = [];
centerLngArray = [];
for (i=0 ; i < filteredtextCoordinatesArray.length ; i++) {
var centerCoords = filteredtextCoordinatesArray[i];
var centerCoordsArray = centerCoords.split('','');
if (isNaN(Number(centerCoordsArray[0]))) {
} else {
centerLatArray.push(Number(centerCoordsArray[0]));
}
if (isNaN(Number(centerCoordsArray[1]))) {
} else {
centerLngArray.push(Number(centerCoordsArray[1]));
}
}
var centerLatSum = centerLatArray.reduce(function(a, b) { return a + b; });
var centerLngSum = centerLngArray.reduce(function(a, b) { return a + b; });
var centerLat = centerLatSum / filteredtextCoordinatesArray.length ;
var centerLng = centerLngSum / filteredtextCoordinatesArray.length ;
console.log(centerLat);
console.log(centerLng);
var mapOpt = {
zoom:8,
center: {lat: centerLat, lng: centerLng}
};
Esto es lo que uso para mostrar un mapa con 3 pines / marcadores:
<script>
function initialize() {
var locations = [
[''DESCRIPTION'', 41.926979, 12.517385, 3],
[''DESCRIPTION'', 41.914873, 12.506486, 2],
[''DESCRIPTION'', 41.918574, 12.507201, 1]
];
var map = new google.maps.Map(document.getElementById(''map''), {
zoom: 15,
center: new google.maps.LatLng(41.923, 12.513),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, ''click'', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
function loadScript() {
var script = document.createElement(''script'');
script.type = ''text/javascript'';
script.src = ''https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&'' + ''callback=initialize'';
document.body.appendChild(script);
}
window.onload = loadScript;
</script>
<div id="map" style="width: 900px; height: 700px;"></div>
Lo que estoy buscando es una forma de evitar tener que buscar "manualmente" el centro del mapa con el center: new google.maps.LatLng(41.923, 12.513)
. ¿Hay alguna forma de tener automáticamente el mapa centrado en las tres coordenadas?
Creo que debes calcular latitudine min y longitude min: aquí tienes un ejemplo con la función que debes usar para centrar tu punto:
//Example values of min & max latlng values
var lat_min = 1.3049337;
var lat_max = 1.3053515;
var lng_min = 103.2103116;
var lng_max = 103.8400188;
map.setCenter(new google.maps.LatLng(
((lat_max + lat_min) / 2.0),
((lng_max + lng_min) / 2.0)
));
map.fitBounds(new google.maps.LatLngBounds(
//bottom left
new google.maps.LatLng(lat_min, lng_min),
//top right
new google.maps.LatLng(lat_max, lng_max)
));
Hay una forma más fácil, al extender un LatLngBounds
vacío en lugar de crear uno explícitamente desde dos puntos. (Vea esta pregunta para más detalles)
Debería verse algo así, agregado a su código:
//create empty LatLngBounds object
var bounds = new google.maps.LatLngBounds();
var infowindow = new google.maps.InfoWindow();
for (i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
//extend the bounds to include each marker''s position
bounds.extend(marker.position);
google.maps.event.addListener(marker, ''click'', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
//now fit the map to the newly inclusive bounds
map.fitBounds(bounds);
//(optional) restore the zoom level after the map is done scaling
var listener = google.maps.event.addListener(map, "idle", function () {
map.setZoom(3);
google.maps.event.removeListener(listener);
});
De esta manera, puede usar una cantidad arbitraria de puntos y no necesita conocer el orden de antemano.
Demo jsFiddle aquí: http://jsfiddle.net/x5R63/
Para encontrar el centro exacto del mapa, deberá traducir las coordenadas lat / lon en coordenadas de píxeles y luego buscar el centro de píxeles y convertirlo de nuevo en coordenadas lat / lon.
Es probable que no notes o te des cuenta de la deriva, dependiendo de qué tan al norte o al sur del ecuador estés. Puede ver la deriva haciendo map.setCenter (map.getBounds (). GetCenter ()) dentro de un setInterval, la deriva desaparecerá lentamente a medida que se acerca al ecuador.
Puede usar lo siguiente para traducir entre lat / lon y las coordenadas de píxeles. Las coordenadas de píxeles se basan en un plano del mundo entero con zoom completo, pero luego puedes encontrar el centro de eso y volver a ponerlo en lat / lon.
var HALF_WORLD_CIRCUMFERENCE = 268435456; // in pixels at zoom level 21
var WORLD_RADIUS = HALF_WORLD_CIRCUMFERENCE / Math.PI;
function _latToY ( lat ) {
var sinLat = Math.sin( _toRadians( lat ) );
return HALF_WORLD_CIRCUMFERENCE - WORLD_RADIUS * Math.log( ( 1 + sinLat ) / ( 1 - sinLat ) ) / 2;
}
function _lonToX ( lon ) {
return HALF_WORLD_CIRCUMFERENCE + WORLD_RADIUS * _toRadians( lon );
}
function _xToLon ( x ) {
return _toDegrees( ( x - HALF_WORLD_CIRCUMFERENCE ) / WORLD_RADIUS );
}
function _yToLat ( y ) {
return _toDegrees( Math.PI / 2 - 2 * Math.atan( Math.exp( ( y - HALF_WORLD_CIRCUMFERENCE ) / WORLD_RADIUS ) ) );
}
function _toRadians ( degrees ) {
return degrees * Math.PI / 180;
}
function _toDegrees ( radians ) {
return radians * 180 / Math.PI;
}
Tuve una situación en la que no puedo cambiar el código anterior, así que agregué esta función de JavaScript para calcular el punto central y el nivel de zoom:
//input
var tempdata = ["18.9400|72.8200-19.1717|72.9560-28.6139|77.2090"];
function getCenterPosition(tempdata){
var tempLat = tempdata[0].split("-");
var latitudearray = [];
var longitudearray = [];
var i;
for(i=0; i<tempLat.length;i++){
var coordinates = tempLat[i].split("|");
latitudearray.push(coordinates[0]);
longitudearray.push(coordinates[1]);
}
latitudearray.sort(function (a, b) { return a-b; });
longitudearray.sort(function (a, b) { return a-b; });
var latdifferenece = latitudearray[latitudearray.length-1] - latitudearray[0];
var temp = (latdifferenece / 2).toFixed(4) ;
var latitudeMid = parseFloat(latitudearray[0]) + parseFloat(temp);
var longidifferenece = longitudearray[longitudearray.length-1] - longitudearray[0];
temp = (longidifferenece / 2).toFixed(4) ;
var longitudeMid = parseFloat(longitudearray[0]) + parseFloat(temp);
var maxdifference = (latdifferenece > longidifferenece)? latdifferenece : longidifferenece;
var zoomvalue;
if(maxdifference >= 0 && maxdifference <= 0.0037) //zoom 17
zoomvalue=''17'';
else if(maxdifference > 0.0037 && maxdifference <= 0.0070) //zoom 16
zoomvalue=''16'';
else if(maxdifference > 0.0070 && maxdifference <= 0.0130) //zoom 15
zoomvalue=''15'';
else if(maxdifference > 0.0130 && maxdifference <= 0.0290) //zoom 14
zoomvalue=''14'';
else if(maxdifference > 0.0290 && maxdifference <= 0.0550) //zoom 13
zoomvalue=''13'';
else if(maxdifference > 0.0550 && maxdifference <= 0.1200) //zoom 12
zoomvalue=''12'';
else if(maxdifference > 0.1200 && maxdifference <= 0.4640) //zoom 10
zoomvalue=''10'';
else if(maxdifference > 0.4640 && maxdifference <= 1.8580) //zoom 8
zoomvalue=''8'';
else if(maxdifference > 1.8580 && maxdifference <= 3.5310) //zoom 7
zoomvalue=''7'';
else if(maxdifference > 3.5310 && maxdifference <= 7.3367) //zoom 6
zoomvalue=''6'';
else if(maxdifference > 7.3367 && maxdifference <= 14.222) //zoom 5
zoomvalue=''5'';
else if(maxdifference > 14.222 && maxdifference <= 28.000) //zoom 4
zoomvalue=''4'';
else if(maxdifference > 28.000 && maxdifference <= 58.000) //zoom 3
zoomvalue=''3'';
else
zoomvalue=''1'';
return latitudeMid+''|''+longitudeMid+''|''+zoomvalue;
}
Utilizo el método anterior para establecer los límites del mapa, luego, en lugar de restablecer el nivel de zoom, solo calculo el LAT promedio y el LON promedio y establezco el punto central en esa ubicación. Agregué todos los valores lat en latTotal y todos los valores lon en lontotal y luego los dividí por el número de marcadores. Luego establezco el punto central del mapa en esos valores promedio.
latCenter = latTotal / markercount; lonCenter = lontotal / markercount;