在谷歌地图's JS API fromPointToLatLng没有'根据事件来看似乎并不准确

In Google Map's JS API fromPointToLatLng doesn't seem accurate based on events

本文关键字:事件 不准确 没有 谷歌地图 JS API fromPointToLatLng      更新时间:2023-09-26

我的目标是,当他们有一个像矩形工具这样的绘图工具时,如果他们在某个地方单击,它会将他们单击的地图居中,这样他们就可以更容易地绘制矩形,而无需切换工具或拖动到窗口边缘并滚动。

我不能使用谷歌地图的事件,因为如果你使用他们的DrawingManager,他们会禁用它们,所以我被迫使用jQuery或香草JS。

我有一张100%宽的地图,大约是窗户高度的50%。以下是我一直在尝试的基本代码:

    $('#myMapWapperElement').on('click', function (event) {
        var position = settings.map.getProjection().fromPointToLatLng(
            new google.maps.Point(
                event.offsetX,
                event.offsetY
            )
        );
        map.setCenter(position);
    });

然而,当我点击时,这会使地图跳得到处都是。它根本不在标记点击的中心。我尝试了offsetX,pageX,还有offsetX的relative-"elementPositionX"。似乎没有什么东西能正确居中。

google.maps.Projection对象的fromPointToLatLngfromLatLngToPoint方法在256x256坐标系中的点和现实世界坐标之间转换。您可以使用以下函数将地图投影上的像素坐标转换为LatLng值:

var fromPixelToLatLng = function (map, x, y) {
    var projection = map.getProjection();
    var topRight = projection.fromLatLngToPoint(map.getBounds().getNorthEast());
    var bottomLeft = projection.fromLatLngToPoint(map.getBounds().getSouthWest());
    var scale = 1 << map.getZoom();
    return projection.fromPointToLatLng(new google.maps.Point(x / scale + bottomLeft.x, y / scale + topRight.y));
};

示例

function initMap() {
   
    var map = new google.maps.Map(document.getElementById('map'), {
        center: { lat: -34.397, lng: 150.644 },
        zoom: 8
    });
  
    var infowindow = new google.maps.InfoWindow({
        content: ''
    });
    $("#map").on('click', function (event) {
        var position = fromPixelToLatLng(map, event.offsetX, event.offsetY);
        infowindow.setContent('Pixel(' + event.offsetX + ',' + event.offsetY + ') -> LatLng:' + position.toString());
        infowindow.setPosition(position);
        infowindow.open(map);
        map.setCenter(position);
    });
  
    //var drawingManager = new google.maps.drawing.DrawingManager({
    //    drawingMode: google.maps.drawing.OverlayType.MARKER,
    //    drawingControl: true,
    //    drawingControlOptions: {
    //        position: google.maps.ControlPosition.TOP_CENTER,
    //        drawingModes: [
    //          google.maps.drawing.OverlayType.MARKER,
    //          google.maps.drawing.OverlayType.CIRCLE,
    //          google.maps.drawing.OverlayType.POLYGON,
    //          google.maps.drawing.OverlayType.POLYLINE,
    //          google.maps.drawing.OverlayType.RECTANGLE
    //        ]
    //    }
    //});
    //drawingManager.setMap(map);  
}
var fromPixelToLatLng = function (map, x, y) {
    var projection = map.getProjection();
    var topRight = projection.fromLatLngToPoint(map.getBounds().getNorthEast());
    var bottomLeft = projection.fromLatLngToPoint(map.getBounds().getSouthWest());
    var scale = 1 << map.getZoom();
    return projection.fromPointToLatLng(new google.maps.Point(x / scale + bottomLeft.x, y / scale + topRight.y));
};
html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}
#map {
    height: 100%;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=drawing&callback=initMap"
            async defer></script>

您需要使用MapCanvasProjection 的.fromContainerPixelToLatLng

该方法在OverlayView类中可用。

概念验证小提琴

代码片段:

var geocoder;
var map;
function initialize() {
  map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 13,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  overlay = new google.maps.OverlayView();
  overlay.draw = function() {
    console.log("draw");
  };
  overlay.setMap(map);
  google.maps.event.addListener(overlay, 'projection_changed', function() {
    var projection = overlay.getProjection();
    $('#map_canvas').on('click', function(event) {
      var position = projection.fromContainerPixelToLatLng(
        new google.maps.Point(
          event.offsetX,
          event.offsetY
        )
      );
      map.setCenter(position);
    });
  })
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>