How to fitBounds groundOverlay google maps api more closely - google-maps

I created a groundOverlay that uses the Google Maps API. I'd like to make the ground fit much as possible. I also tried to use padding option or zoom++ but it not work as I expected.
Current:
Expected:
Re-production: https://jsfiddle.net/abinhho/5kvtfpeo/10/

The problem is quite easy to understand. fitBounds() will fit the map to the given bounds and make sure the entire bounds are visible within the map viewport. So it will choose the best zoom level (and center point) to achieve that.
It might display with a good margin around, but would not fit anymore if you zoom in one more level. Try it with the below example.
var historicalOverlay;
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 40.740, lng: -74.18},
zoomControl: true
});
var imageBounds = {
north: 40.773941,
south: 40.712216,
east: -74.12544,
west: -74.22655
};
historicalOverlay = new google.maps.GroundOverlay(
'https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
imageBounds);
historicalOverlay.setMap(map);
map.fitBounds(historicalOverlay.getBounds());
}
#map {
height: 220px;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>
The only thing you could do about that, is to use the padding interface, maybe with a negative value. But then you might have the opposite result; the image might not be shown entirely.
var historicalOverlay;
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 40.740, lng: -74.18},
zoomControl: true
});
var imageBounds = {
north: 40.773941,
south: 40.712216,
east: -74.12544,
west: -74.22655
};
historicalOverlay = new google.maps.GroundOverlay(
'https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
imageBounds);
historicalOverlay.setMap(map);
map.fitBounds(historicalOverlay.getBounds(), {'bottom': -50, 'left': -50, 'top': -50, 'right': -50});
}
#map {
height: 180px;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>

Related

Center map to my location

I have the following code:
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 13,
center: new google.maps.LatLng(53.529773,-113.509387),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
How can I replace:
center: new google.maps.LatLng(53.529773,-113.509387)
with my current location, programatically
Your code looks correct, I suspect that your issue is that your device does not have location services enabled, if it does you may not have accept the security prompt when it runs the first time.
This following demo I modified from the google maps API reference
https://developers.google.com/maps/documentation/javascript/
HTML Demo
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
CSS
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
JS
function initMap() {
// Pick a start point, I live in Australia, so just picked the middle of OZ
var myLatLng = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
// Mark it on the map, this is the original center
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
// If location services is enabled, the following should center the map on your location.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(location);
});
}
}

Collaborative Realtime Mapping with Firebase Heatmap not working

I tried the tutorial from this place.
When I get at the heatmap part it doesn't draw the map anymore.
I guess I must be doing something wrong but I have no clue...
The moment I remove the comments from icon: image part I'll get a map drawn,
but the heatmap part isn't working.
I hope that somebody can help me
Kind Regards
Guy
// Reference to the Firebase database.
var firebase = new Firebase("https://adopt-a-portal.firebaseio.com/");
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 0, lng: 0},
zoom: 3
});
// Add marker on user click
map.addListener('click', function(e) {
firebase.push({lat: e.latLng.lat(), lng: e.latLng.lng()});
});
// Create a heatmap.
var heatmap = new google.maps.visualization.HeatmapLayer({
data: [],
map: map,
radius: 8
});
firebase.on("child_added", function(snapshot, prevChildKey) {
// Get latitude and longitude from Firebase.
var newPosition = snapshot.val();
// Create a google.maps.LatLng object for the position of the marker.
// A LatLng object literal (as above) could be used, but the heatmap
// in the next step requires a google.maps.LatLng object.
var latLng = new google.maps.LatLng(newPosition.lat, newPosition.lng);
// Place a marker at that location.
var image = 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png';
var marker = new google.maps.Marker({
position: latLng,
map: map
// icon: image
});
heatmap.getData().push(latLng);
});
}
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html, body { height: 100%; margin: 0; padding: 0; }
#map { height: 100%; }
</style>
<script src="https://cdn.firebase.com/js/client/2.2.1/firebase.js"></script>
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyABc8Rw-DxVzajwPZ8C90cfFT69LfAec6o&region=BE&callback=initMap"
async defer></script>
<script src="map.js"> </script>
</body>
</html>
I get a javascript error with your code: Uncaught TypeError: Cannot read property 'HeatmapLayer' of undefined
You aren't including the visualization library.
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyABc8Rw-DxVzajwPZ8C90cfFT69LfAec6o&region=BE&callback=initMap"
async defer></script>
Should be (note the added "libraries=visualization"):
<script src="https://maps.googleapis.com/maps/api/js?libraries=visualization&key=AIzaSyABc8Rw-DxVzajwPZ8C90cfFT69LfAec6o&region=BE&callback=initMap"
async defer></script>
proof of concept fiddle

multiple rectangles in Google Maps from SQL database

I am trying to create multiple rectangles with info windows on a Google Map. I have followed the pattern used for multiple markers found at Generating Google Maps markers From Database
I first used that example and used one of the lat and one of long to display icons on the map. That worked. Then I change the code to rectangles and added bounds. But no rectangles appear on the map. I tried to hard code one of the rectangles on the map and one rectangle appeared.
I also made sure that the description to be used in the infowindow did not have any links in. I found that to be a problem if I was passing a link in the data variable. But I could get the link to work if I add the variable with a link at the point of the creation of the infowindow content.
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var markers = [
<asp:Repeater ID="rptMarkers" runat="server">
<ItemTemplate>
{
"title": '<%# Eval("Quad_Name") %>',
"north": '<%# Eval("poly_north") %>',
"east": '<%# Eval("poly_east") %>',
"south": '<%# Eval("poly_south") %>',
"west": '<%# Eval("poly_west") %>',
"description": '<%# Eval("smqcomment") %>'
}
</ItemTemplate>
<SeparatorTemplate>
,
</SeparatorTemplate>
</asp:Repeater>
];
window.onload = function () {
var mapOptions = {
center: new google.maps.LatLng(41.78768535298007, -99.96481875),
zoom: 7,
mapTypeId: google.maps.MapTypeId.HYBRID
};
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var rectangle = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
map: map,
bounds: {
north: data.north,
south: data.south,
east: data.east,
west: data.west
}
});
(function (rectangle,data) {
google.maps.event.addListener(rectangle, "click", function (e) {
infoWindow.setContent(data.description);
infoWindow.open(map,rectangle);
});
})(rectangle,data);
}
}
</script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<div id="dvMap" style="width: 960px; height: 532px"></div>
Any help would be great thanks.
I get a javasript error on your live page: js:31 InvalidValueError: setBounds: not a LatLngBounds or LatLngBoundsLiteral: in property south: not a number. You need to translate the strings in your JSON into numbers before using them to construct google.maps.Rectangle objects.
To open an infowindow on a rectangle, you need to set the position of the infowindow. The syntax infoWindow.open(map, rectangle) doesn't apply to rectangles, that only applies to markers (at least for API objects), see the documentation for more information.
position contains the LatLng at which this info window is anchored. Note: An InfoWindow may be attached either to a Marker object (in which case its position is based on the marker's location) or on the map itself at a specified LatLng. Opening an info window on a marker will automatically update the position.
(function(rectangle, data) {
google.maps.event.addListener(rectangle, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.setPosition(rectangle.getBounds().getCenter());
infoWindow.open(map);
});
})(rectangle, data);
code snippet:
window.onload = function() {
var mapOptions = {
center: new google.maps.LatLng(41.492537, -99.901813),
zoom: 6,
mapTypeId: google.maps.MapTypeId.HYBRID
};
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var bounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var rectangle = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
map: map,
bounds: {
north: parseFloat(data.north),
south: parseFloat(data.south),
east: parseFloat(data.east),
west: parseFloat(data.west)
}
});
(function(rectangle, data) {
google.maps.event.addListener(rectangle, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.setPosition(rectangle.getBounds().getCenter());
infoWindow.open(map);
});
})(rectangle, data);
}
}
var markers = [
{
"title": 'Andrews',
"north": '42.75001',
"east": '-103.625',
"south": '42.62501',
"west": '-103.75',
"description": 'Andrews description',
}
,
{
"title": 'Arlington',
"north": '41.50001',
"east": '-96.25001',
"south": '41.37501',
"west": '-96.37501',
"description": '<img src="http://snr.unl.edu/csd-esic/download/geologysoils/digitalgeologicmapscleaned/Arlington/Arlington_Quad.jpg" height="400">',
}
,
{
"title": 'Ashland East',
"north": '41.12501',
"east": '-96.25001',
"south": '41.00001',
"west": '-96.37501',
"description": '<img src="http://snr.unl.edu/csd-esic/download/geologysoils/digitalgeologicmapscleaned/Ashland_East/Ashland_East_Quad.jpg" height="400"">',
}
,
{
"title": 'Beaver Wall',
"north": '43.00001',
"east": '-102.625',
"south": '42.87501',
"west": '-102.75',
"description": 'Beaver Wall description',
}
];
html,
body,
#dvMap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="dvMap"></div>
I see that geocodezip updated the code in their original answer to the question. Two things are new
First the defining of the bounds applied the function of parseFloat() to each of the coordinates. I am not sure that was necessary since I have been able to get icons or polygons to draw with the coordinates without this function.
I think what really solved the problem was adding the line of code
var bounds = new google.maps.LatLngBounds();
I am not actually sure what this is doing beside defining the variable "bounds" but it seems to have solved my problem.
Thanks geocodezip!

Google Map not showing up API V3 or showing up very slowly

I'm having a heck of a time trying to get a basic Google Map to show up. I've been on Stack Overflow for hours and haven't had any success so far. The closest I've gotten is the map loads 1/4 of a square, the top left quarter. But then if you try to drag, zoom, etc it just turns grey like the rest of the map. On a few occasions, with the same code, the map will load fully but only after a long time (not sure exactly how long, but > 5 minutes).
In my template I have
<div id="map" style="width: 500px; height: 400px;"></div>
And then in my backbone view
$.getScript('http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback')
window.gMapsCallback = function(){
var myLatlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
}
Any ideas what might be happening? I am also open to any suggestions on a superior way to load a google map into a backbone view.
Ok, turns out there were a number of issues, including embedding a map in a Bootstrap tab, not including a callback, defining the div height and width, setting a small delay to load the map, and setting css attributes for the map. Oi. My final solution turned out to be:
In the template
<script src='http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback'></script>
<div id="map" style="width: 500px; height: 400px;"></div>
In the stylesheet
#map img {
max-width: none;
}
#map label {
width: auto; display:inline;
}
In the Backbone View
setTimeout(function(){
var myLatlng = new google.maps.LatLng(53.1, -2.44);
var mapOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
// Create marker
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(53.1, -2.44),
title: 'The armpit of Cheshire'
});
// Add circle overlay and bind to marker
var circle = new google.maps.Circle({
map: map,
radius: 10000, // metres
fillColor: '#AA0000'
});
circle.bindTo('center', marker, 'position');
google.maps.event.trigger(map, "resize");
map.setZoom( map.getZoom() );
}, 100);
Painful. Notice that when I call the gmaps script I had to include the callback even though I never use it. Without it, it didn't work fully. No clue why.

Google Maps API v3: Gray Box, no map

As part of a much bigger project, we're trying to get a Map on a site using Google's Map API v3. I have followed the simplest steps that Google has laid out, I've tried copying code outright from other working maps. But no matter what I do, all we get is a gray box and no map.
Using Firebug, I can see the information trying to populate the map, but it is simply not displaying. I've tried jquery, jquery libraries specifically made for google maps, nothing is working. I have been up and down the internet and all through google's api help files. Plus, the problem is not local as I've uploaded the file to multiple servers and tested it on multiple browsers and computers. Nothing is working.
At this point it's got to be something stupid that I'm overlooking. Here's my code.
<!DOCTYPE html>
<html>
<head>
<title></title>
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?&sensor=true">
</script>
<script type="text/javascript">
function load()
{
var mapDiv = document.getElementById("map");
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions =
{
//zoom: 8,
center:latlng,
//backgroundColor: '#ff0000',
mapTypeId: google.maps.MapTypeId.ROADMAP,
imageDefaultUI: true
};
var map = new google.maps.Map(mapDiv, mapOptions);
function createMarker(point, text, title)
{
var marker =
new GMarker(point,{title:title});
return marker;
}
}
</script>
</head>
<body onload="load()">
<div id="map" style="width: 800px; height: 400px;"></div>
</div>
</body>
</html>
This works for me. You simply have to set zoom parameter:
UPDATE (by #user2652379): You need to set BOTH zoom and center options. Just zoom does not work.
<!DOCTYPE html>
<html>
<head>
<title></title>
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
</script>
<script type="text/javascript">
function load()
{
var mapDiv = document.getElementById("map");
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions =
{
zoom: 8,
center:latlng,
//backgroundColor: '#ff0000',
mapTypeId: google.maps.MapTypeId.ROADMAP,
//imageDefaultUI: true
};
var map = new google.maps.Map(mapDiv, mapOptions);
// map.addControl(new GSmallMapControl());
// map.addControl(new GMapTypeControl());
// map.addMapType(ROADMAP);
// map.setCenter(
// new GLatLng(37.4419, -122.1419), 13);
}
</script>
</head>
<body onload="load()">
<div id="map" style="width: 800px; height: 400px;"> </div>
</body>
</html>
Another case is when map container is hidden at the moment you initialize the map. E.g. you are doing it inside bootstrap show.bs.modal event, instead of shown.bs.modal
I had the same issue and came across a lot of topics on stackoverflow but none of them had the working solution for me. I eventually found out it was caused to a line of css I had added.
All the elements in the map inherited a
overflow:hidden;
By adding the following line to my CSS it was fixed
#map * {
overflow:visible;
}
I would like to add a quick comment to this since I had the same problem with the zoom parameter set.
I found out that the problem was my theme's css. In my base theme I had the following CSS:
img, embed, object, video {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
}
This messed up the rendering of the map and after I removed it, my map renders just fine.
Also beware of having an invalid latitude or longitude value for the map center or your markers. For example, this fiddle shows the Grey Map Of Death because the map center is at latitude 131.044 which is invalid (not from +90:-90).
function initMap() {
var uluru = {lat: 131.044, lng: -25.363};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: uluru
});
var marker = new google.maps.Marker({
position: uluru,
map: map
});
}
In my case, I was working on a map with vue and a modal in the iview library; and during the first render it worked, but any other render displayed the grey screen of death. I fixed the issue by setting a timeout function to display the map after 50 ms to give the modal enough time to render and be visible.
//Time out is crucial for the map to load when opened with vue
setTimeout(() => {
this.showMap(id);
}, 50);
The above example was an earlier fix and a quick hack, i have realized all you need to do is wait for the next tick, on vue you can achieve this by
async mounted(){
await this.$nextTick()
this.showMap(id)
}
or if you are not comfortable with async await you can try the callback option
mounted(){
Vue.nextTick(function () {
this.showMap(id)
})
}
I had the same issue. i was using google maps in Jquery Accordion and when i expand the div the map only consisted a grayed area. I was able to solve this issue by triggering a click event on the specified accordion heading and setting the map container to visible.
Script:
<script type="text/javascript">
var map;
function initMap(lat, lng) {
var myCenter = new google.maps.LatLng(lat, lng);
var mapOptions = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: myCenter
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
}
function ViewMap() {
var latlng = document.getElementById('<%=txt.ClientID%>').value.split(','); // This is where my latlng are placed: 25.12312,55.3212333
$("#showmap").show();
// Sorry for mixing up Jquery and javascript.
initMap(latlng[0], latlng[1]);
}
</script>
ASPX File/Html Markup:
<h3 id="lMap" onclick="ViewMap();"><i class="fa fa-map-o" onclick="ViewMap();"></i>Location Map</h3>
<div style="height:auto" id="showmap">
<div id="map" style="width: 850px; height: 550px; overflow: visible"></div>
</div>
I realise this is an old thread, but this may help someone in the future.
Struggled with this for hours, but after discovering that the Google Map is rendered with a grey box overlay if the map is rendered while not being visible, I used a bit of jQuery to make my application only instantiate and render the map if the map is visible, like such:
if ($("#myHomeMapHolder").is(":visible")) {
if (homemap == null) {
homemap = new google.maps.Map(document.getElementById("myHomeMapHolder"), myOptions);
google.maps.event.addListener(homemap, 'click', function (event) {
placeHomeMarker(event.latLng);
});
} else {
homemap.setCenter(myLatlng);
}
if (homemarker == null) {
homemarker = new google.maps.Marker({
position: myLatlng,
map: homemap,
title: "Home"
});
} else {
homemarker.setPosition(myLatlng);
}
}
And voila, my map is only rendered if the map holder is visible, so it never renders with a grey box.
For anyone wondering, myHomeMapHolder is a div which the map sits inside.
In my case, someone had dropped this little prize in some responsive.css file:
img {
max-width: 100% !important;
}
Removed that and all is fine now.
I had this issue with a site I'm working on too. We're doing some things to all <img> tags for responsiveness. This fix is working for us for the map:
img {max-width: initial !important;}
For those who might be stuck regardless of the nice solutions provided here, try setting the height and width of your container directly in the html markup instead of a stylesheet ie.
<div id="map-container" style="width: 100%; height: 300px;"></div>
happy mapping!
This may not be the case for everyone, but maybe it can help someone.
I was creating markers in my map from data attributes placed on the map element like this: data-1-lat="2" data-1-lon="3" data-text="foo". I was putting them in an array based on the order they were placed in the data attributes.
The problem is that IE and Edge (for some mad reason) invert the order of the data attributes in the HTML tag, therefore I wasn't able to correctly extract them from the data attributes.
None of the existing answers helped me because my problem was that Apollo was adding extra properties ("__typename" fields) to my MapOptions object.
In other words, the JSON looked like this:
mapOptions {"__typename":"MapOptions","center":{"__typename":"GeoCoordinates","lat":33.953056,"lng":-83.9925},"zoom":10}
Once I realized that those extra properties were problematic, this is how I solved it (using TypeScript):
function getCleanedMapOptions(mapOptionsGql: google.maps.MapOptions): google.maps.MapOptions {
const mapOptions = { ...mapOptionsGql };
const lat: number = mapOptions.center.lat as number;
const lng: number = mapOptions.center.lng as number;
const mapOptionsCleaned = {
center: new google.maps.LatLng({ lat, lng }),
zoom: mapOptions.zoom,
};
return mapOptionsCleaned;
}
export function createMap(mapOptions: google.maps.MapOptions): google.maps.Map {
const mapOptionsCleaned = getCleanedMapOptions(mapOptions);
const map = new google.maps.Map(document.getElementById('map') as HTMLElement, mapOptionsCleaned);
return map;
}
In my case (version is 3.30 when submitting this), it was because the div id MUST be "map"
<div id="map"></div>
...
document.getElementById("map")