I have a custom map I'm working on, and have 2 overlays that show up perfectly, and can be hidden, then shown, by pushing a button. Problem is, I want to have the map load with the overlays hidden, and only have them show when the respective button is pushed. I used this thread Google Maps show/hide multiple overlays plus the example here https://developers.google.com/maps/documentation/javascript/customoverlays to get this far, but simply cannot figure out how to make it function opposite.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" type="text/css" href="maps.css">
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>AAPG Breach</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=drawing"></script>
<script>
function CustomMapType() {
}
CustomMapType.prototype.tileSize = new google.maps.Size(256,256);
CustomMapType.prototype.maxZoom = 7;
CustomMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
var div = ownerDocument.createElement('DIV');
var baseURL = '/maps/bdx_breach/';
baseURL += zoom + '_' + coord.x + '_' + coord.y + '.png';
div.style.width = this.tileSize.width + 'px';
div.style.height = this.tileSize.height + 'px';
div.style.backgroundColor = '#222222';
div.style.backgroundImage = 'url(' + baseURL + ')';
return div;
};
CustomMapType.prototype.name = "Custom";
CustomMapType.prototype.alt = "Tile Coordinate Map Type";
var map;
var CustomMapType = new CustomMapType();
var overlays = [];
var boundsArray = [];
AAPGOverlay.prototype = new google.maps.OverlayView();
function initialize() {
var mapOptions = {
minZoom: 2,
maxZoom: 7,
isPng: true,
mapTypeControl: false,
streetViewControl: false,
center: new google.maps.LatLng(80,-160),
zoom: 3,
mapTypeControlOptions: {
mapTypeIds: ['custom', google.maps.MapTypeId.ROADMAP],
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
}
};
map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
map.mapTypes.set('custom',CustomMapType);
map.setMapTypeId('custom');
var swBound = new google.maps.LatLng(80.03238, -169.90);
var neBound = new google.maps.LatLng(80.70, -163.50);
var swBound2 = new google.maps.LatLng(83.35, -163.35);
var neBound2 = new google.maps.LatLng(84.41, -153.35);
var bounds = new google.maps.LatLngBounds(swBound, neBound);
var bounds2 = new google.maps.LatLngBounds(swBound2, neBound2);
boundsArray.push(bounds);
boundsArray.push(bounds2);
var srcImage = '/maps/bdx_breach/breach_alpha_spawn.png';
var srcImage2 = '/maps/bdx_breach/breach_bravo_spawn.png';
overlays.push(new AAPGOverlay(bounds, srcImage, map));
overlays.push(new AAPGOverlay(bounds2, srcImage2, map));
}
function AAPGOverlay(bounds, image, map) {
// Initialize all properties.
this.bounds_ = bounds;
this.image_ = image;
this.map_ = map;
// Define a property to hold the image's div. We'll
// actually create this div upon receipt of the onAdd()
// method so we'll leave it null for now.
this.div_ = null;
// Explicitly call setMap on this overlay.
this.setMap(map);
}
/**
* onAdd is called when the map's panes are ready and the overlay has been
* added to the map.
*/
AAPGOverlay.prototype.onAdd = function() {
var div = document.createElement('div');
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
// Create the img element and attach it to the div.
var img = document.createElement('img');
img.src = this.image_;
img.style.width = '100%';
img.style.height = '100%';
img.style.position = 'absolute';
div.appendChild(img);
this.div_ = div;
// Add the element to the "overlayLayer" pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
};
// [END region_attachment]
// [START region_drawing]
AAPGOverlay.prototype.draw = function() {
// We use the south-west and north-east
// coordinates of the overlay to peg it to the correct position and size.
// To do this, we need to retrieve the projection from the overlay.
var overlayProjection = this.getProjection();
// Retrieve the south-west and north-east coordinates of this overlay
// in LatLngs and convert them to pixel coordinates.
// We'll use these coordinates to resize the div.
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Resize the image's div to fit the indicated dimensions.
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';
};
AAPGOverlay.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
//this.div_ = null;
};
AAPGOverlay.prototype.hide = function() {
if (this.div_) {
this.div_.style.visibility = "hidden";
}
};
AAPGOverlay.prototype.show = function() {
if (this.div_) {
this.div_.style.visibility = "visible";
}
};
AAPGOverlay.prototype.toggle = function() {
if (this.div_) {
if (this.div_.style.visibility == 'hidden') {
this.show();
} else {
this.hide();
}
}
};
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="toggle">
<input type="button" class="toggle" value="Alpha Spawn" onclick="overlays[0].toggle();"></input></br>
<input type="button" class="toggle" value="Bravo Spawn" onclick="overlays[1].toggle();"></input>
</div>
<div id="map_canvas" style="background: #222222;"></div>
</body>
</html>
You never tell the div to be hidden after you add the image to it like you do in your fucntions.
The way you have it right now is:
// Create the img element and attach it to the div.
var img = document.createElement('img');
img.src = this.image_;
img.style.width = '100%';
img.style.height = '100%';
img.style.position = 'absolute';
div.appendChild(img);
You can add at the end of that:
div.style.visibility = "hidden"
You do this in your calls later, but you don't at the beginning.
Related
I am trying to add custom overlay & Kml layer. The custom layer is working, but the KML layer is not showing at all. What would cause this?
var overlay;
USGSOverlay.prototype = new google.maps.OverlayView();
// Initialize the map and the custom overlay.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: {lat: 31.1917, lng: 27.56553},
mapTypeId: 'satellite'
});
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(31.18954, 27.56144),
new google.maps.LatLng(31.19277, 27.56806));
var srcImage = 'https://travcop.zohosites.com/selc02.png';
overlay = new USGSOverlay(bounds, srcImage, map);
}
/** #constructor */
function USGSOverlay(bounds, image, map) {
// Initialize all properties.
this.bounds_ = bounds;
this.image_ = image;
this.map_ = map;
// Define a property to hold the image's div. We'll
// actually create this div upon receipt of the onAdd()
// method so we'll leave it null for now.
this.div_ = null;
// Explicitly call setMap on this overlay.
this.setMap(map);
}
/**
* onAdd is called when the map's panes are ready and the overlay has been
* added to the map.
*/
USGSOverlay.prototype.onAdd = function() {
var div = document.createElement('div');
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
// Create the img element and attach it to the div.
var img = document.createElement('img');
img.src = this.image_;
img.style.width = '100%';
img.style.height = '100%';
img.style.position = 'absolute';
div.appendChild(img);
this.div_ = div;
// Add the element to the "overlayLayer" pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
};
USGSOverlay.prototype.draw = function() {
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Resize the image's div to fit the indicated dimensions.
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';
};
var kmlLayer = new google.maps.KmlLayer({
url: 'https://travcop.zohosites.com/sel.kml',
suppressInfoWindows: true,
map: map
});
function showInContentWindow(text) {
var sidediv = document.getElementById('content-window');
sidediv.innerHTML = text;
}
// The onRemove() method will be called automatically from the API if
// we ever set the overlay's map property to 'null'.
USGSOverlay.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};
google.maps.event.addDomListener(window, 'load', initMap);
I am not sure why the KML layer is not loading. Could be the two layers loading in the same time?
Trying to create a real estate portal where data is marked in KML and the map is for a future project that is not yet displayed on Google Maps
I get a javascript error with the posted code: Uncaught ReferenceError: map is not defined.
The map variable is local to your initMap function, you need to instantiate the KmlLayer inside your initMap method.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: {lat: 31.1917, lng: 27.56553},
mapTypeId: 'satellite'
});
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(31.18954, 27.56144),
new google.maps.LatLng(31.19277, 27.56806));
var srcImage = 'https://travcop.zohosites.com/selc02.png';
overlay = new USGSOverlay(bounds, srcImage, map);
var kmlLayer = new google.maps.KmlLayer({
url: 'https://travcop.zohosites.com/sel.kml',
suppressInfoWindows: true,
preserveViewport: true,
map: map
});
}
Once I fix that, there is another error: Uncaught ReferenceError: overlayProjection is not defined, because overlayProjection isn't defined. Taking the definition from Google's example fixes that.
proof of concept fiddle
code snippet:
var overlay;
USGSOverlay.prototype = new google.maps.OverlayView();
// Initialize the map and the custom overlay.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: {
lat: 31.1917,
lng: 27.56553
},
mapTypeId: 'satellite'
});
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(31.18954, 27.56144),
new google.maps.LatLng(31.19277, 27.56806));
var srcImage = 'https://travcop.zohosites.com/selc02.png';
overlay = new USGSOverlay(bounds, srcImage, map);
var kmlLayer = new google.maps.KmlLayer({
url: 'https://travcop.zohosites.com/sel.kml',
suppressInfoWindows: true,
preserveViewport: true,
map: map
});
google.maps.event.addListener(kmlLayer, 'status_changed', function() {
console.log(kmlLayer.getStatus());
})
map.fitBounds(bounds);
}
/** #constructor */
function USGSOverlay(bounds, image, map) {
// Initialize all properties.
this.bounds_ = bounds;
this.image_ = image;
this.map_ = map;
// Define a property to hold the image's div. We'll
// actually create this div upon receipt of the onAdd()
// method so we'll leave it null for now.
this.div_ = null;
// Explicitly call setMap on this overlay.
this.setMap(map);
}
/**
* onAdd is called when the map's panes are ready and the overlay has been
* added to the map.
*/
USGSOverlay.prototype.onAdd = function() {
var div = document.createElement('div');
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
// Create the img element and attach it to the div.
var img = document.createElement('img');
img.src = this.image_;
img.style.width = '100%';
img.style.height = '100%';
img.style.position = 'absolute';
div.appendChild(img);
this.div_ = div;
// Add the element to the "overlayLayer" pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
};
USGSOverlay.prototype.draw = function() {
var overlayProjection = this.getProjection();
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Resize the image's div to fit the indicated dimensions.
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';
};
function showInContentWindow(text) {
var sidediv = document.getElementById('content-window');
sidediv.innerHTML = text;
}
// The onRemove() method will be called automatically from the API if
// we ever set the overlay's map property to 'null'.
USGSOverlay.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};
google.maps.event.addDomListener(window, 'load', initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
First of all, I am totally aware that a similar question has been asked here
I used the JSFiddle proposed in the accepted answer - JsFiddle
The code provides me both markers coordinates as expected
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);
});
My problem is that I am using Open Street Map and after positioning my image and using the coordinates in my application, the image is not correctly positioned as in the JSFiddle.
I found that both Google Maps and Open Street Map have a significant difference with their coordinates.
How can I find the correct position for the overlay?
There are tutorials on the web to display OSM tiles on Google Maps, one in the OSM documentation from a quick search: Google Maps Example
Combining that with the Google Maps example yields this fiddle
code snippet:
var overlay;
var map;
DebugOverlay.prototype = new google.maps.OverlayView();
function initialize() {
var mapOptions = {
zoom: 15,
center: new google.maps.LatLng(40.743388, -74.007592),
mapTypeId: "OSM",
mapTypeControl: false,
streetViewControl: false
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// 40.674018,-74.251324,40.788664,-74.116993
var swBound = new google.maps.LatLng(40.674018, -74.251324);
var neBound = new google.maps.LatLng(40.788664, -74.116993);
var bounds = new google.maps.LatLngBounds(swBound, neBound);
map.fitBounds(bounds);
var srcImage = 'https://www.lib.utexas.edu/maps/historical/newark_nj_1922.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();
//google.maps.event.addDomListener(window, 'load', initialize);
//Define OSM map type pointing at the OpenStreetMap tile server
map.mapTypes.set("OSM", new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
// "Wrap" x (logitude) at 180th meridian properly
// NB: Don't touch coord.x because coord param is by reference, and changing its x property breakes something in Google's lib
var tilesPerGlobe = 1 << zoom;
var x = coord.x % tilesPerGlobe;
if (x < 0) {
x = tilesPerGlobe + x;
}
// Wrap y (latitude) in a like manner if you want to enable vertical infinite scroll
return "http://tile.openstreetmap.org/" + zoom + "/" + x + "/" + coord.y + ".png";
},
tileSize: new google.maps.Size(256, 256),
name: "OpenStreetMap",
maxZoom: 18
}));
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map-canvas"></div>
<div id="footer">© OpenStreetMap contributors</div>
I have a script of google map which is using by me,I want to change the zoom controller icon(+,-) or color.is there a any way to do this?
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
var map;
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644)
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
The style options of deafult zoom controls don't offer anything to change the color.
But you can hide the default controls, add custom controls and give them the same functionality.
Here an example javascript code to add a custom zoom in button
function CustomZoomInControl(controlDiv, map) {
// Set CSS for the control border
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#5ff';
controlUI.style.border = '2px solid #5ff';
controlUI.style.borderRadius = '3px';
controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
controlUI.style.cursor = 'pointer';
controlUI.style.marginBottom = '22px';
controlUI.style.textAlign = 'center';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
controlText.style.fontSize = '16px';
controlText.style.fontWeight = 'bold';
controlText.style.paddingLeft = '5px';
controlText.style.paddingRight = '5px';
controlText.innerHTML = '+';
controlUI.appendChild(controlText);
// Setup the click event listeners
google.maps.event.addDomListener(controlUI, 'click', function () {
map.setZoom(map.getZoom() + 1);
});
}
var map;
function initialize() {
var mapOptions = {
zoom: 8,
zoomControl: false,
center: new google.maps.LatLng(-34.397, 150.644)
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Create the DIV to hold the control and
// call the CustomZoomInControl() constructor passing
// in this DIV.
var customZoomInControlDiv = document.createElement('div');
var customZoomInControl = new CustomZoomInControl(customZoomInControlDiv, map);
customZoomInControlDiv.index = 1;
map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(customZoomInControlDiv);
}
google.maps.event.addDomListener(window, 'load', initialize);
If you want both control button change the CustomZoomInControl function into this:
function CustomZoomInControl(controlDiv, map) {
// Set CSS for the control border
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#000';
controlUI.style.border = '2px solid #000';
controlUI.style.cursor = 'pointer';
controlUI.style.marginBottom = '10px';
controlUI.style.textAlign = 'center';
controlUI.style.width = '40px';
controlUI.style.height = '40px';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontSize = '24px';
controlText.style.paddingLeft = '5px';
controlText.style.paddingRight = '5px';
controlText.style.color = '#fff';
controlText.innerHTML = '+';
controlUI.appendChild(controlText);
// Setup the click event listeners
google.maps.event.addDomListener(controlUI, 'click', function () {
map.setZoom(map.getZoom() + 1);
});
// Set CSS for the control border
var controlUILeft = document.createElement('div');
controlUILeft.style.backgroundColor = '#000';
controlUILeft.style.border = '2px solid #000';
controlUILeft.style.cursor = 'pointer';
controlUILeft.style.marginBottom = '20px';
controlUILeft.style.textAlign = 'center';
controlUILeft.style.width = '40px';
controlUILeft.style.height = '40px';
controlDiv.appendChild(controlUILeft);
// Set CSS for the control interior
var controlTextLeft = document.createElement('div');
controlTextLeft.style.fontSize = '24px';
controlTextLeft.style.paddingLeft = '5px';
controlTextLeft.style.paddingRight = '5px';
controlTextLeft.style.color = '#fff';
controlTextLeft.innerHTML = '-';
controlUILeft.appendChild(controlTextLeft);
// Setup the click event listeners
google.maps.event.addDomListener(controlUILeft, 'click', function () {
map.setZoom(map.getZoom() - 1);
});
}
And same code to create the controls:
var customZoomInControlDiv = document.createElement('div');
var customZoomInControl = new CustomZoomInControl(customZoomInControlDiv, map);
customZoomInControlDiv.index = 1;
map.controls[google.maps.ControlPosition.BOTTOM_RIGHT].push(customZoomInControlDiv );
Those + and - are SVG file.
I was able to change position, opacity etc. by targeting img in the css.
My map div id is id="gmap".
My css was targeting #gmap img {...}
Forcing a new img url might work as well.
Building on #92-92's answer. The .svg files have a transparent background, and are children of a div with class = 'gm-controls-active'. Google styles these inline; and so you need to use !important in your css to override.
.css to override
:root {
--gm-button-background-color:white;
}
#media (prefers-color-scheme: dark) {
:root {
--gm-button-background-color:#2c4973;
}
}
.gm-control-active {
background-color:var(--gm-button-background-color) !important;
}
You don't need to get fancy with the prefers-color-scheme.
This solution is a bit of a hack as Google could change their class names at any point. Also unfortunately the .svg image files for the fullscreen button and the zoom buttons are different colors.
Hello fellow StackExchange members,
I am really struggling with adding multiple GroundOverlays and/or CustomOverlays. Google Maps always shows a slight and recurring anomaly in positioning the tiles. The image below shows what I mean:
http://i.stack.imgur.com/ZmPa4.jpg (I don't have enough reputation to show the image inline).
I used Google's example code of how to use the CustomOverlay, as shown below, and a prebuild grid.json file which houses all the tile image keys and their SW and NE bounds:
The Maps file:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
*{ margin:0;padding:0;}
html{ height: 100%;}
body{ height: 100%; margin:0; padding:0;}
#map-canvas{ height: 100%; }
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDOwFuc5S-hRJnfyYI3xL-0TJNcPjbRd2s&sensor=false">
</script>
<script type="text/javascript">
// This example creates a custom overlay called USGSOverlay, containing
// a U.S. Geological Survey (USGS) image of the relevant area on the map.
// Set the custom overlay object's prototype to a new instance
// of OverlayView. In effect, this will subclass the overlay class.
// Note that we set the prototype to an instance, rather than the
// parent class itself, because we do not wish to modify the parent class.
var overlay;
USGSOverlay.prototype = new google.maps.OverlayView();
// Initialize the map and the custom overlay.
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(51.960515285616523328826588112860918045043945312500,
4.026193748674999461911738762864843010902404785156 ),
zoom: 13
};
var map = new google.maps.Map( document.getElementById( 'map-canvas'), mapOptions );
var grid = $.getJSON( 'grid.json', function( json ){
$.each( json, function( index, value )
{
var image = index + '.png';
var swBound = new google.maps.LatLng( value['sw'][0], value['sw'][1] );
var neBound = new google.maps.LatLng( value['ne'][0], value['ne'][1] );
var bounds = new google.maps.LatLngBounds( swBound, neBound )
overlay = new USGSOverlay( bounds, image, map );
overlay.setOpacity( 50 );
});
});
}
/** #constructor */
function USGSOverlay(bounds, image, map) {
// Initialize all properties.
this.bounds_ = bounds;
this.image_ = image;
this.map_ = map;
// Define a property to hold the image's div. We'll
// actually create this div upon receipt of the onAdd()
// method so we'll leave it null for now.
this.div_ = null;
// Explicitly call setMap on this overlay.
this.setMap(map);
}
/**
* onAdd is called when the map's panes are ready and the overlay has been
* added to the map.
*/
USGSOverlay.prototype.onAdd = function() {
var div = document.createElement('div');
div.className = 'reset';
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
div.style.opacity = '0.6';
// Create the img element and attach it to the div.
var img = document.createElement('img');
img.src = this.image_;
img.style.width = '100%';
img.style.height = '100%';
img.style.position = 'absolute';
div.appendChild(img);
this.div_ = div;
// Add the element to the "overlayLayer" pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
};
USGSOverlay.prototype.setOpacity = function( op )
{
$('div.reset').css( 'opacity', op/100 );
}
USGSOverlay.prototype.draw = function() {
// We use the south-west and north-east
// coordinates of the overlay to peg it to the correct position and size.
// To do this, we need to retrieve the projection from the overlay.
var overlayProjection = this.getProjection();
// Retrieve the south-west and north-east coordinates of this overlay
// in LatLngs and convert them to pixel coordinates.
// We'll use these coordinates to resize the div.
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Resize the image's div to fit the indicated dimensions.
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';
};
// The onRemove() method will be called automatically from the API if
// we ever set the overlay's map property to 'null'.
USGSOverlay.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};
google.maps.event.addDomListener( window, 'load', initialize );
</script>
</head>
<body>
<div id="map-canvas">
</div>
</body>
</html>
To give an idea of the contents of grid.json, here's an excerpt:
{
"110-861": {
"ne": [
51.952818013763725,
3.959379207489501
],
"sw": [
51.94812597892079,
3.952079437462081
]
},
"110-862": {
"ne": [
51.95741935496997,
3.9592327762378288
],
"sw": [
51.95272731127462,
3.9519322780340236
]
},
...
}
It consists of many keys ( like "110-862" ) which represent, after a calculation, Rijksdriehoeks Coordinates (a Dutch geospatial representation). These coordinates have been converted to WGS84 with a precision of 0.2mm. Still I get these strange distortions.
Is there anyone who has experience in using this much map tiles together?
With kind regards
I have many (100s) of maps in a databse made for V2. Now migrating to V3 and they're all offeset by quite a long way than they were before.
Have I done something wrong? Or is there a bug or difference that I have to correct? I don't really want to have to re-make all my maps for the new version.
See an example here: http://www.trebrown.com/plant_info_temp.php?species=Bismarckia+nobilis+sp.+silver Scroll down the page to se the map, and then zoom out 1 or 2 stops, you'll then see the Madagascar map out in the middle of the Indian ocean.
Here's my code:
var overlay;
TrebrownOverlay.prototype = new google.maps.OverlayView();
function initialize() {
var marker;
var sp_id = "353";
function createMarker(point,infowindow) {
var marker = new google.maps.Marker({ position: point, map: map, title:"" });
google.maps.event.addListener(marker, "click", function() {
infowindow.open(map,marker);
});
return marker;
}
var localitiy = new google.maps.LatLng(-19.311144, 46.362305);
var mapOptions = {
zoom: 5,
center: localitiy,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var swBound = new google.maps.LatLng(-27.371767300523032, 33.1787109375);
var neBound = new google.maps.LatLng(-10.83330598364249, 59.5458984375);
var bounds = new google.maps.LatLngBounds(swBound, neBound);
var srcImage = 'http://www.trebrown.com/images/maps/bismarckia-nobilis.png';
overlay = new TrebrownOverlay(bounds, srcImage, map);
}
function TrebrownOverlay(bounds, image, map) {
this.bounds_ = bounds;
this.image_ = image;
this.map_ = map;
this.div_ = null;
this.setMap(map);
}
TrebrownOverlay.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.position = 'absolute';
div.appendChild(img);
this.div_ = div;
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
}
TrebrownOverlay.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';
}
TrebrownOverlay.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
google.maps.event.addDomListener(window, 'load', initialize);
It's a CSS-issue, there is a interaction with the style of the parent-element of #map-canvas
remove the format text-align: right; from the parent div.morespace
or override it by applying the style text-align:left for #map-canvas