【问题标题】:Google Maps: Get click or marker (x,y) pixel coordinates inside marker click listenerGoogle Maps:在标记单击侦听器中获取单击或标记(x,y)像素坐标
【发布时间】:2023-03-08 10:29:01
【问题描述】:

我正在尝试在标记点击时在地图标记上显示完全自定义信息窗口。我已成功实现this answer 以使 div 显示在地图画布点击上...但我无法在标记点击上复制它。

是否可以在标记点击函数中获取标记像素位置,并抑制普通信息窗口以显示所需的自定义信息窗口?

我试过这个:

      google.maps.event.addListener(marker, 'click', function(args) {
        var x=args.pixel.x+$('#map').offset().left; //we clicked here
        var y=args.pixel.y;

        info.style.left=x+'px';
        info.style.top=y+'px';
        info.style.display='block';
      });

但在控制台中,我看到了:

Uncaught TypeError: Cannot read property 'x' of undefined

【问题讨论】:

    标签: javascript jquery google-maps google-maps-api-3


    【解决方案1】:

    在 Radio 的帮助下,我能够解决这个问题。给他点个赞。

      <div id="myinfo" class="info"><p>I am a div on top of a google map .. </p></div>
    
      <script>
    
      info = document.getElementById('myinfo');
    
      google.maps.event.addListener(marker, 'click', function() {
    
        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(this.getPosition());
        var markerCoords = new google.maps.Point((worldPoint.x - bottomLeft.x) * scale, (worldPoint.y - topRight.y) * scale);
    
        var x=markerCoords['x']+$('#map').offset().left; //offset needed if map not fullscreen
        var y=markerCoords['y'];
    
        info.style.left=x+'px';
        info.style.top=y+'px';
        info.style.display='block';
    
      });
    
      </script>
    

    【讨论】:

      【解决方案2】:

      marker click event 返回MouseClickEvent

      MouseClickEvent 的唯一记录属性是:

      latLng LatLng 事件发生时光标下方的纬度/经度。

      要将其转换为像素位置,请使用 MapCanvasProjection 的 fromLatLngToContainerPixel 方法:

          google.maps.event.addListener(marker, 'click', function (e) {
             var point = overlay.getProjection().fromLatLngToDivPixel(e.latLng); 
                  info.style.left = point.x + 'px';
                  info.style.top = point.y + 'px';
                  info.style.display = 'block';
          });
      

      working fiddle

      代码sn-p:

      var geocoder;
      var map;
      var overlay;
      
      function initialize() {
          var 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
          });
          var marker = new google.maps.Marker({
              map: map,
              draggable: true,
              position: map.getCenter()
          });
      
          google.maps.event.addListener(map, 'projection_changed', function () {
              overlay = new google.maps.OverlayView();
              overlay.draw = function () {};
              overlay.setMap(map);
      
              var info = document.getElementById('myinfo');
              google.maps.event.addListener(marker, 'click', function (e) {
                 var point = overlay.getProjection().fromLatLngToContainerPixel(e.latLng); 
                      info.style.left = (point.x - 100)+ 'px';
                      info.style.top = (point.y) + 'px';
                      info.style.display = 'block';
              });
              google.maps.event.addListener(map, 'center_changed', function (e) {
                  var point = overlay.getProjection().fromLatLngToContainerPixel(marker.getPosition()); 
                      info.style.left = (point.x - 100)+ 'px';
                      info.style.top = (point.y) + 'px';
                      info.style.display = 'block';
              });
                      google.maps.event.addListener(marker, 'drag', function (e) {
                 var point = overlay.getProjection().fromLatLngToContainerPixel(marker.getPosition()); 
                      info.style.left = (point.x - 100)+ 'px';
                      info.style.top = (point.y) + 'px';
                      info.style.display = 'block';
              });
              
          });
      }
      google.maps.event.addDomListener(window, "load", initialize);
      html,
      body,
      #map_canvas {
        height: 100%;
        width: 100%;
        margin: 0px;
        padding: 0px
      }
      div.info {
        position: absolute;
        z-index: 999;
        width: 200px;
        height: 50px;
        display: none;
        background-color: #fff;
        border: 3px solid #ebebeb;
        padding: 10px;
      }
      <script src="https://maps.googleapis.com/maps/api/js"></script>
      <div id="map_canvas" style="border: 2px solid #3872ac;"></div>
      <div id="myinfo" class="info">
        <p>I am a div on top of a google map ..</p>
      </div>

      【讨论】:

        【解决方案3】:

        另一种选择。使用InfoBox third party library。它继承自 OverlayView,您可以将“完全自定义”的 div 放入其中。

        proof of concept fiddle

        var geocoder;
        var map;
        var overlay;
        
        function initialize() {
          var 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
            });
          var marker = new google.maps.Marker({
            map: map,
            draggable: true,
            position: map.getCenter()
          });
        
          var boxText = document.createElement("div");
          boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: white; padding: 5px;";
          boxText.innerHTML = "I am a div on top of a google map ..";
          var myOptions = {
            content: boxText,
            disableAutoPan: false,
            maxWidth: 0,
            pixelOffset: new google.maps.Size(-75, -10),
            zIndex: null,
            boxStyle: {
              background: "url('tipbox.gif') no-repeat",
              opacity: 0.75,
              width: "150px"
            },
            closeBoxMargin: "0px 0px 0px 0px",
            closeBoxURL: "",
            infoBoxClearance: new google.maps.Size(0, 0),
            isHidden: false,
            pane: "floatPane",
            enableEventPropagation: false
          };
        
          var info = new InfoBox(myOptions);
        
          info.open(map, marker);
        
          google.maps.event.addListener(marker, 'click', function() {
            // info.setContent('<div id="myinfo" class="info"><p>I am a div on top of a google map ..</p></div>');
            info.open(map, marker);
          });
        }
        google.maps.event.addDomListener(window, "load", initialize);
        html,
        body,
        #map_canvas {
          height: 100%;
          width: 100%;
          margin: 0px;
          padding: 0px
        }
        div.info {
          position: absolute;
          z-index: 999;
          width: 200px;
          height: 50px;
          display: none;
          background-color: #fff;
          border: 3px solid #ebebeb;
          padding: 10px;
        }
        <script src="https://maps.googleapis.com/maps/api/js"></script>
        <script src="https://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
        <div id="map_canvas" style="border: 2px solid #3872ac;"></div>

        【讨论】:

          【解决方案4】:

          获取像素位置的方法如下:

          function getPixelLocation(currentLatLng) {
          
                  var scale = Math.pow(2, map.getZoom());
                  // The NorthWest corner of the current viewport corresponds
                  // to the upper left corner of the map.
                  // The script translates the coordinates of the map's center point
                  // to screen coordinates. Then it subtracts the coordinates of the
                  // coordinates of the map's upper left corner to translate the 
                  // currentLatLng location into pixel values in the <div> element that hosts the map.
                  var nw = new google.maps.LatLng(
                      map.getBounds().getNorthEast().lat(),
                      map.getBounds().getSouthWest().lng()
                  );
                  // Convert the nw location from geo-coordinates to screen coordinates
                  var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
                  // Convert the location that was clicked to screen coordinates also
                  var worldCoordinate = map.getProjection().fromLatLngToPoint(currentLatLng);
                  var currentLocation = new google.maps.Point(
                      Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
                      Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
                  );
          
                  console.log(currentLocation);
                  return currentLocation;
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-01-05
            • 1970-01-01
            • 1970-01-01
            • 2016-03-15
            • 2011-01-10
            • 2016-01-01
            • 1970-01-01
            相关资源
            最近更新 更多