Google地图:在标记点击侦听器中获取点击或标记(x,y)像素坐标

时间:2015-03-20 22:26:39

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

我正在尝试在标记点击上的地图标记上显示 完全 自定义信息窗口。我已经成功实现了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

4 个答案:

答案 0 :(得分:18)

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

代码段:



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>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

以下是获取像素位置的方法:

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

答案 2 :(得分:0)

另一种选择。使用InfoBox third party library。它继承自OverlayView,你可以把你的&#34;完全自定义&#34; div in。

proof of concept fiddle

&#13;
&#13;
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);
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 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>