Cómo convertir desde (x, y) coordenadas de pantalla a LatLng (Google Maps)

Estoy implementando una aplicación usando Google Maps y Leap Motion, y lo que quiero ahora mismo, y estoy un poco atascado, es una forma de convertir (x, y) coordenadas de pantalla en un objeto LatLng de Google Maps.

Quiero lograr esto para comenzar, por ejemplo, un outlook (Street View) en el punto donde el usuario está apuntando con Leap Motion.

Sé acerca de la presencia de la función FromPointToLatLng, pero no tengo idea de cuál es el enfoque correcto para usarla y cómo puedo traducir mis coordenadas xey en variables lat lng.

¿Puedes ayudarme con esto?

function latLng2Point(latLng, map) { var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast()); var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest()); var scale = Math.pow(2, map.getZoom()); var worldPoint = map.getProjection().fromLatLngToPoint(latLng); return new google.maps.Point((worldPoint.x - bottomLeft.x) * scale, (worldPoint.y - topRight.y) * scale); } function point2LatLng(point, map) { var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast()); var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest()); var scale = Math.pow(2, map.getZoom()); var worldPoint = new google.maps.Point(point.x / scale + bottomLeft.x, point.y / scale + topRight.y); return map.getProjection().fromPointToLatLng(worldPoint); } 

Después de algunas investigaciones y algunas fallas, se me ocurrió una solución. Siguiendo la documentación de este enlace , descubrí que los puntos de Google se calculan en el rango de x: [0-256], y: [0-256] (un mosaico es 256×256 píxeles) y el punto (0,0) es el punto más a la izquierda del mapa (verifique el enlace para más información).

Sin embargo, mi enfoque es el siguiente:

  • teniendo las coordenadas xey (que son coordenadas en la pantalla – en el mapa) Calculé el porcentaje donde las coordenadas xey se colocaron en respuesta al div que contiene el mapa (en mi caso, la ventana del agujero)

  • calculó los límites NortEast y SouthWest LatLng del mapa (visible)

  • convirtió los límites en Google Points

  • calculó el nuevo lat y lng, en google points, con la ayuda de los límites y el porcentaje de xey

  • convertido de nuevo a lat lng

      // retrieve the lat lng for the far extremities of the (visible) map var latLngBounds = map.getBounds(); var neBound = latLngBounds.getNorthEast(); var swBound = latLngBounds.getSouthWest(); // convert the bounds in pixels var neBoundInPx = map.getProjection().fromLatLngToPoint(neBound); var swBoundInPx = map.getProjection().fromLatLngToPoint(swBound); // compute the percent of x and y coordinates related to the div containing the map; in my case the screen var procX = x/window.innerWidth; var procY = y/window.innerHeight; // compute new coordinates in pixels for lat and lng; // for lng : subtract from the right edge of the container the left edge, // multiply it by the percentage where the x coordinate was on the screen // related to the container in which the map is placed and add back the left boundary // you should now have the Lng coordinate in pixels // do the same for lat var newLngInPx = (neBoundInPx.x - swBoundInPx.x) * procX + swBoundInPx.x; var newLatInPx = (swBoundInPx.y - neBoundInPx.y) * procY + neBoundInPx.y; // convert from google point in lat lng and have fun :) var newLatLng = map.getProjection().fromPointToLatLng(new google.maps.Point(newLngInPx, newLatInPx)); 

Espero que esta solución ayude a alguien también! 🙂

Vea la solución fácil (v3):

 map.getProjection().fromLatLngToPoint(marker.position); 

https://developers.google.com/maps/documentation/javascript/3.exp/reference#Projection

Agregar una solución alternativa basada en un código de pregunta SO existente, a pesar de que el cartel original encontró una solución.

En función de esta respuesta , podemos encontrar la parte necesaria para que Google Maps API v3 realice la conversión. Se enfoca en reposicionar el centro del mapa. Modificarlo para leer la posición desde la pantalla requiere calcular la diferencia de las coordenadas de la pantalla desde el centro de la pantalla.

Cambié el nombre de la función para este ejemplo a pixelOffsetToLatLng y lo cambié para devolver la posición (aparte de eso, no muy diferente del código en la respuesta anterior):

 function pixelOffsetToLatLng(offsetx,offsety) { var latlng = map.getCenter(); var scale = Math.pow(2, map.getZoom()); var nw = new google.maps.LatLng( map.getBounds().getNorthEast().lat(), map.getBounds().getSouthWest().lng() ); var worldCoordinateCenter = map.getProjection().fromLatLngToPoint(latlng); var pixelOffset = new google.maps.Point((offsetx/scale) || 0,(offsety/scale) ||0); var worldCoordinateNewCenter = new google.maps.Point( worldCoordinateCenter.x - pixelOffset.x, worldCoordinateCenter.y + pixelOffset.y ); var latLngPosition = map.getProjection().fromPointToLatLng(worldCoordinateNewCenter); return latLngPosition; } 

Para llamarlo, debe pasar las coordenadas X e Y que tiene en el elemento de la página web:

  var x = mapElement.offsetWidth / 2 - screenPositionX; var y = screenPositionY - mapElement.offsetHeight / 2; pixelOffsetToLatLng(x,y); 

Para el lado de leap.js, solo necesita asignar las coordenadas leap.js a la página web, ya sea mediante la experimentación o mediante el uso del complemento de posición de pantalla que funciona así:

 var $handCursor = $('#hand-cursor'); // using jQuery here, not mandatory though Leap.loop(function(frame) { if (frame.hands.length > 0) { var hand = frame.hands[0]; $handCursor.css({ left: hand.screenPosition()[0] + 'px', top: hand.screenPosition()[1] + 'px' }); if ((hand.grabStrength >= 0.6 && lastGrabStrength < 0.6)) { var x = mapElement.offsetWidth / 2 - hand.screenPosition()[0]; var y = hand.screenPosition()[1] - mapElement.offsetHeight / 2; map.setCenter(pixelOffsetToLatLng(x, y)); } } }).use('screenPosition', { scale: 0.5 }); 

Aquí hay un ejemplo de Codepen sobre cómo leer las coordenadas usando Leap.js en entorno 2D: http://codepen.io/raimo/pen/pKIko

Puede centrar la vista de Google Maps con el mouse o agarrando su mano sobre el Leap Motion Controller (vea el "cursor" rojo para la señal visual).

Necesita saber (x0,y0) del centro de su elemento de mapa, (lat0,lng0) del centro del mapa, y la relación r de grados por píxel, correspondiente al nivel de Zoom del mapa. Entonces

 lat(y) = lat0 + r(y-y0) lng(x) = lng0 + r(x-x0) 

Tenga en cuenta que este es un modelo lineal simplificado, que funciona para mapas que muestran áreas pequeñas.