I am hoping someone can point me in the right direction.
I have a Google Map that loads markers from an XML file, along with various other map elements, works great. However I now need to overlay a PNG image onto the map.
I have tried for hours to correctly align the PNG over the top of the site but just cannot find the exact two co-ordinates I need (south-west and north-east). Is there a tool for doing this? Ideally upload the image and drag the corners to fit, and it outputs the two co-ordinates (lat/lng) you need?
I have tried using this tool: http://overlay-tiler.googlecode.com/svn/trunk/upload.html - but it has three contact points.
I have also tried using this tool: http://www.birdtheme.org/useful/customoverlay.html - but you cannot resize the image once uploaded to the map and you get one chance at clicking the south-west marker!
I can also use Google Earth to align the PNG perfectly, but I can't see a way of outputting the lat/lng points.
Any advice would be much appreciated.
Use map images to create extra information without embedding it into your original map. To see how an overlay image corresponds to the map image underneath it: Select the overlay in the viewer. Then, change the transparency so that it's fully opaque.
In your phone's settings navigate to Apps and notifications (or App Info) - Maps, and under "Advanced", disable "Picture-in-Picture". "In your phone's settings navigate to Apps and notifications (or App Info) - Maps, and under "Advanced", disable "Picture-in-Picture"."
Overlays are objects on the map that are tied to latitude/longitude coordinates, so they move when you drag or zoom the map. For information on predefined overlay types, see Drawing on the map. The Maps JavaScript API provides an OverlayView class for creating your own custom overlays.
Heres a working example of André Dion's explanation.
http://jsfiddle.net/4cWCW/3/
var overlay; DebugOverlay.prototype = new google.maps.OverlayView(); function initialize() { var mapOptions = { zoom: 15, center: new google.maps.LatLng(40.743388,-74.007592) }; var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); var swBound = new google.maps.LatLng(40.73660837340877, -74.01852328); var neBound = new google.maps.LatLng(40.75214181, -73.99661518216243); var bounds = new google.maps.LatLngBounds(swBound, neBound); console.log(map); var srcImage = 'http://robincwillis.com/top/splash/04.jpg'; overlay = new DebugOverlay(bounds, srcImage, map); var markerA = new google.maps.Marker({ position: swBound, map: map, draggable:true }); var markerB = new google.maps.Marker({ position: neBound, map: map, draggable:true }); google.maps.event.addListener(markerA,'drag',function(){ var newPointA = markerA.getPosition(); var newPointB = markerB.getPosition(); var newBounds = new google.maps.LatLngBounds(newPointA, newPointB); overlay.updateBounds(newBounds); }); google.maps.event.addListener(markerB,'drag',function(){ var newPointA = markerA.getPosition(); var newPointB = markerB.getPosition(); var newBounds = new google.maps.LatLngBounds(newPointA, newPointB); overlay.updateBounds(newBounds); }); google.maps.event.addListener(markerA, 'dragend', function () { var newPointA = markerA.getPosition(); var newPointB = markerB.getPosition(); console.log("point1"+ newPointA); console.log("point2"+ newPointB); }); google.maps.event.addListener(markerB, 'dragend', function () { var newPointA = markerA.getPosition(); var newPointB = markerB.getPosition(); console.log("point1"+ newPointA); console.log("point2"+ newPointB); }); } function DebugOverlay(bounds, image, map) { this.bounds_ = bounds; this.image_ = image; this.map_ = map; this.div_ = null; this.setMap(map); } DebugOverlay.prototype.onAdd = function() { var div = document.createElement('div'); div.style.borderStyle = 'none'; div.style.borderWidth = '0px'; div.style.position = 'absolute'; var img = document.createElement('img'); img.src = this.image_; img.style.width = '100%'; img.style.height = '100%'; img.style.opacity = '0.5'; img.style.position = 'absolute'; div.appendChild(img); this.div_ = div; var panes = this.getPanes(); panes.overlayLayer.appendChild(div); }; DebugOverlay.prototype.draw = function() { var overlayProjection = this.getProjection(); var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest()); var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast()); var div = this.div_; div.style.left = sw.x + 'px'; div.style.top = ne.y + 'px'; div.style.width = (ne.x - sw.x) + 'px'; div.style.height = (sw.y - ne.y) + 'px'; }; DebugOverlay.prototype.updateBounds = function(bounds){ this.bounds_ = bounds; this.draw(); }; DebugOverlay.prototype.onRemove = function() { this.div_.parentNode.removeChild(this.div_); this.div_ = null; }; initialize();
I had to solve this exact problem for a client not long ago. My solution was to simply create two markers; one at each LatLng
for the overlay's LatLngBounds
that, when moved, would update the overlay and log the LatLndBounds
to the console
for me to reference. I also added reticules (vertical and horizontal lines) that are shown when dragging a marker so it was easier to visually position the overlay.
I cannot share the code from the solution with you, but it involves working with an OverlayView
in order to convert LatLng
coordinates to and from pixels via MapCanvasProjection
.
Like you, we didn't need this functionality for end-users so I added a "authoring mode" that's toggled by providing a debug
parameter to the solution's query string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With