maybe there is a solution for this:
I'm using the Gmap api to embed a map undernaeth an overlay that I have on top of my map. The overlay has a little arrow on the right side and I want my map marker to be positioned at this point (or a few pixels beside it)
I know it would be possible to use a GMaps Infowindow, but I have it this way.
So I'm able to use $("#arrow").offset()
in order to get its position on the page, but I don't know how to move
or pan
the map center to this pixel-destination.
window.onload = function() {
var myOptions = {
center: new google.maps.LatLng(47.259998, 11.398032),
zoom: 17,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(47.260071, 11.404705),
map: map,
});
console.log( $("#arrow").offset().top );
}
Update:
This is the code I have in my page-template right now. I have on last problem though. If my page has a width of lets say 1440px the position of the marker relative to my little arrow works just fine:
However as soon as I resize the page to a smaller width and load the page again the marker is behind the overlay and not positioned relative to the little arrow.
google.maps.event.addDomListener(window, 'load', initMap);
window.onresize = function() {
positionMap();
}
function initMap() {
var myOptions = {
center: new google.maps.LatLng(47.260071, 11.404705),
zoom: 17,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true,
draggable: false,
mapTypeControl: false,
zoomControl: false,
scaleControl: false,
scrollwheel: false
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(47.260071, 11.404705),
map: map,
title: 'Österreichisches Rotes Kreuz Innsbruck'
});
}
function positionMap() {
var arrowPos = $("#map-center").position();
console.log(arrowPos);
var getPixelOffset = function(map, marker) {
// Calculate marker position in pixels form upper left corner
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(
map.getBounds().getNorthEast().lat(),
map.getBounds().getSouthWest().lng()
);
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(marker.getPosition());
var pixelOffset = new google.maps.Point(
Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
);
return pixelOffset;
};
// Wait until the map is initialized
var listener = google.maps.event.addListener(map, "idle", function() {
var pixelOffset = getPixelOffset(map, marker);
// Do the pan
map.panBy( Math.abs( pixelOffset.x - ( arrowPos.left ) - 150 ),
Math.abs( pixelOffset.y - ( arrowPos.top ) ) - 50 );
google.maps.event.removeListener(listener);
});
}
One approach is to use map.getProjection().fromLatLngToPoint()
to find the pixel position of the marker inside the map, then subtract your $("#arrow").offset()
from the marker position and call map.panBy()
to move the marker by the calculated difference.
Here's the demo in which the marker is moved to the sample position { top: 50, left: 100 }
:
var myOptions = {
center: new google.maps.LatLng(47.259998, 11.398032),
zoom: 17,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(47.260071, 11.404705),
map: map,
title: 'Hello World!'
});
// Replace this with call to $("#arrow").offset()
var arrowPos = { top: 50, left: 100 };
var getPixelOffset = function(map, marker) {
// Calculate marker position in pixels form upper left corner
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(
map.getBounds().getNorthEast().lat(),
map.getBounds().getSouthWest().lng()
);
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(marker.getPosition());
var pixelOffset = new google.maps.Point(
Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
);
return pixelOffset;
};
// Wait until the map is initialized
var listener = google.maps.event.addListener(map, "idle", function() {
var pixelOffset = getPixelOffset(map, marker);
// Do the pan
map.panBy(Math.abs(pixelOffset.x - arrowPos.left),
Math.abs(pixelOffset.y - arrowPos.top));
google.maps.event.removeListener(listener);
});
html,
body,
#map {
display: block;
width: 100%;
height: 100%;
}
#map {
background: #58B;
}
<script src="http://maps.google.com/maps/api/js?sensor=true&.js"></script>
<div id="map"></div>
Also, note that you have to do that when the map is fully loaded, i.e. in the idle event handler. Otherwise (that's what I experienced) the getProjection()
method might be unavailable.
References: