Google Maps fitBounds is not working properly - javascript

I have a problem with googlemaps fitBounds functions.
for (var i = 0; i < countries.length; i++) {
var country = countries[i];
var latlng = new google.maps.LatLng(parseFloat(country.lat), parseFloat(country.lng));
mapBounds.extend(latlng);
}
map.fitBounds(mapBounds);
Some icons will be displayed outside the viewport / Visible area.
And idea?
Thanks in advance.

Consider the following example, which will generate 10 random points on the North East USA, and applies the fitBounds() method.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps LatLngBounds.extend() Demo</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 400px; height: 300px;"></div>
<script type="text/javascript">
var map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.TERRAIN
});
var markerBounds = new google.maps.LatLngBounds();
var randomPoint, i;
for (i = 0; i < 10; i++) {
// Generate 10 random points within North East USA
randomPoint = new google.maps.LatLng( 39.00 + (Math.random() - 0.5) * 20,
-77.00 + (Math.random() - 0.5) * 20);
// Draw a marker for each random point
new google.maps.Marker({
position: randomPoint,
map: map
});
// Extend markerBounds with each random point.
markerBounds.extend(randomPoint);
}
// At the end markerBounds will be the smallest bounding box to contain
// our 10 random points
// Finally we can call the Map.fitBounds() method to set the map to fit
// our markerBounds
map.fitBounds(markerBounds);
</script>
</body>
</html>
Refreshing this example many times, no marker ever goes outside the viewport. At most, sometimes a marker is slightly clipped from the top when hidden behind the controls:
It is also worth nothing that the fitBounds() always leaves a small margin between the LatLngBounds object and the viewport. This is clearly shown in the screenshots below, where the red bounding box represents the LatLngBounds which is passed to the fitBounds() method:
You may also be interested in checking out the following Stack Overflow posts on the topic:
fitbounds() in Google maps api V3 does not fit bounds
Google Maps v3 - Automating Zoom Level?

Show us a link to the patient. How many countries do you have in the countries array? The entire world? Are your bounds crossing the anti-meridian?
country.lat and country.lng are one point per country, and that's not enough to define the bounding box of the country. Is that some sort of "country centroid"?
If that's the case, and if you have markers east of the centroid of the easternmost country, or to the west of the centroid of the westermost country, those markers will, of course, fall outside the bounds that you're defining.
The map.fitBounds() method works fine. :-)
Marcelo.

Check if your google map object is shown properly in the area you have given.
it is possible that some part of your google map object is overflowed outside it's container and the markers are in that area, which they exists by you can't see them.

It seems that the result of fitBounds() is depending on the minZoom value.
For my use-case I managed to recenter the view to cover all the markers by using: map.setCenter(bounds.getCenter());
`
zoomToAllMarkers() {
if (!this.mapMarkers.length) {
return;
}
let bounds = new google.maps.LatLngBounds();
for (let i = 0; i < this.mapMarkers.length; i++) {
bounds.extend(this.mapMarkers[i].getPosition());
}
this.map.setCenter(bounds.getCenter());
}
`

Related

Leaflet markers aggregating when dezooming the map

I am new to Leaflet and I am trying to show a map with markers.
The problem I have is that the markers disappear when I zoom out, and are replaced with a number:
I used CircleMarkers to be able to set the color of each marker, and so that the markers keep their size no matter the zoom level. I add the markers using markercluster because I want to be able to delete them all easily.
<script src="https://unpkg.com/leaflet.markercluster#1.3.0/dist/leaflet.markercluster.js"></script>
function addMarkers(data){
// setup a marker group
markerList = L.markerClusterGroup();
for (var i = 0; i < data.length; i++){
var circleColor = getcolor(data[i].roundScore);
var circle = L.circleMarker([data[i].solutionLat, data[i].solutionLng], {
color: circleColor,
fillColor: circleColor,
fillOpacity: 0.5,
radius: 5
});
circle.bindPopup("Score : " + data[i].roundScore + "\n Address :" + data[i].address);
markerList.addLayer(circle);
}
window.mapMark.addLayer(markerList);
}
function deleteMarkers(){
if(markerList) {
markerList.clearLayers();
}
}
I have no idea how to change this behavior, and whether it is linked to the markers themselves or to the tile I use, which is openstreetmap:
const attribution =
'© OpenStreetMap contributors';
const tileUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
const tiles = L.tileLayer(tileUrl, { attribution });
tiles.addTo(mapMark);
}
Any help or hint would be greatly appreciated.
Thank you very much :)
The disappearance of your Circle Markers and replacement by numbers is the expected effect of Leaflet.markercluster. should you have included the plugin CSS files as well, these numbers would appear in green/yellow/orange bubbles.
To avoid this clustering, but still be able to remove all your Markers at once, simply use a basic Layer Group instead of a MarkerClusterGroup:
https://leafletjs.com/reference-1.7.1.html#layergroup
Used to group several layers and handle them as one.
markerList = L.layerGroup();
// you can also clear layers of a basic Layer Group
markerList.clearLayers();

Javascript : Load markers on a Google map with a loop

I come for help for a javascript problem.
I'm adding a Google map to my website; this map is currently integrated in my page and works fine.
My problem is that i have a lot of markers to place on the map and i want to use a loop to do it.
The coordinates of the markers are stored in a Site[] table.
For now i have this :
// Create markers on the map
for( i = 0; i < Site.length; i++ )
{
var pos = new google.maps.LatLng(Site[i][7], Site[i][8]); //7 and 8 are the latitude and longitude of the markers.
marker = new google.maps.Marker({
position: pos,
map: maCarte, //my map
title: Site[i][1] //1 is the description of the marker
}
});
And, of course, this doesn't work. Does anybody have an idea ?
You messed up with the different parenthesis... If you would indent your code properly, this would be quite obvious.
// Create markers on the map
for (i = 0; i < Site.length; i++) {
var pos = new google.maps.LatLng(Site[i][7], Site[i][8]); //7 and 8 are the latitude and longitude of the markers.
marker = new google.maps.Marker({
position: pos,
map: maCarte, //my map
title: Site[i][1] //1 is the description of the marker
});
}
If it still doesn't work after you corrected this, then problem must be somewhere else. Without knowing the content of the Site array, we can't help any further.
JSFiddle demo

Google Maps API Markerclusterer Plus set icon

I'm making a google maps where the user can have an unlimited number of different categories on the map. I want to cluster each category in a differently colored cluster.
So far I'm using the google maps symbol for the individual markers, and I want to create a symbol for the marker clusters as well.
From checking the reference of the marker clusterer plus. I see that it asks for image url - is there any way to use symbols instead?
thanks!
A symbol(in the meaning of the maps-API), basically is defined by a SVG-path.
The MarkerClusterer draws the Cluster-Icons via <img/>.
A image-src may also be a data-URI, so it's possible to draw such an symbol(SVG-document) as <img/> .
Simple implementation:
function initialize() {
var Symbol=function(id,width,height,fill){
var s={
heart: {
p:'M340.8,83C307,83,276,98.8,256,124.8c-20-26-51-41.8-84.8-41.8C112.1,83,64,131.3,64,190.7c0,27.9,10.6,54.4,29.9,74.6 L245.1,418l10.9,11l10.9-11l148.3-149.8c21-20.3,32.8-47.9,32.8-77.5C448,131.3,399.9,83,340.8,83L340.8,83z',
v:'0 0 512 512'
},
gear: {
p:'M462,280.72v-49.44l-46.414-16.48c-3.903-15.098-9.922-29.343-17.675-42.447l0.063-0.064l21.168-44.473l-34.96-34.96 l-44.471,21.167l-0.064,0.064c-13.104-7.753-27.352-13.772-42.447-17.673L280.72,50h-49.44L214.8,96.415 c-15.096,3.9-29.343,9.919-42.447,17.675l-0.064-0.066l-44.473-21.167l-34.96,34.96l21.167,44.473l0.066,0.064 c-7.755,13.104-13.774,27.352-17.675,42.447L50,231.28v49.44l46.415,16.48c3.9,15.096,9.921,29.343,17.675,42.447l-0.066,0.064 l-21.167,44.471l34.96,34.96l44.473-21.168l0.064-0.063c13.104,7.753,27.352,13.771,42.447,17.675L231.28,462h49.44l16.48-46.414 c15.096-3.903,29.343-9.922,42.447-17.675l0.064,0.063l44.471,21.168l34.96-34.96l-21.168-44.471l-0.063-0.064 c7.753-13.104,13.771-27.352,17.675-42.447L462,280.72z M256,338.4c-45.509,0-82.4-36.892-82.4-82.4c0-45.509,36.891-82.4,82.4-82.4 c45.509,0,82.4,36.891,82.4,82.4C338.4,301.509,301.509,338.4,256,338.4z',
v:'0 0 512 512'
},
vader: {
p:'M 454.5779,419.82295 328.03631,394.69439 282.01503,515.21933 210.30518,407.97233 92.539234,460.65437 117.66778,334.11278 -2.8571457,288.09151 104.38984,216.38165 51.707798,98.615703 178.2494,123.74425 224.27067,3.2193247 295.98052,110.46631 413.74648,57.784277 388.61793,184.32587 509.14286,230.34714 401.89587,302.057 z',
v:'0 0 512 512'
}
}
return ('data:image/svg+xml;base64,'+window.btoa('<svg xmlns="http://www.w3.org/2000/svg" height="'+height+'" viewBox="0 0 512 512" width="'+width+'" ><g><path fill="'+fill+'" d="'+s[id].p+'" /></g></svg>'));
}
var center = new google.maps.LatLng(37.4419, -122.1419);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 1,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var markers = [];
for (var i = 0; i < 500; i++) {
var dataPhoto = data.photos[i];
var latLng = new google.maps.LatLng(dataPhoto.latitude,
dataPhoto.longitude);
var marker = new google.maps.Marker({
position: latLng
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers,{styles:[
{width:50,height:50,url:Symbol('heart',50,50,'red')},
{width:75,height:75,url:Symbol('gear',75,75,'green')},
{textColor:'tomato',textSize:'18',width:100,height:100,url:Symbol('vader',100,100,'blue')}
]});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,body,#map{height:100%;margin:0;padding:0;}
<div id="map"></div>
<script src="http://maps.googleapis.com/maps/api/js?v=3"></script>
<script src="https://cdn.rawgit.com/mahnunchik/markerclustererplus/master/src/data.json"></script>
<script src="https://cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"></script>
The properties of the symbols are:
p (the path)
v (the viewBox)
Note: window.btoa is not supported by IE<10 , you'll need to implement it on your own when you need to support older IEs
In the past I had to deal with this.
To solve it what I did was to extend the class Cluster to add a new Google Marker as an attribute. This marker, attached at the same position as the cluster object, is the one that will show the symbol.
Remember that to avoid the overlap of your symbol and the cluster image you will have to set the opacity to 0 in the style of the clusters.
Hope it works for you.

How to obtain extreme coordinates visible in map based on current location?

Holla....I have to find the extreme coordinates that are visible in the map currently based on my current location's coordinates.
I have included a google map in my website.
I have set the zoom level to 6 & maximum zoom value to 8 & minimum zoom value to 2 in my map.
I have centered my map based on my current location.
To obtain the coordinates of my current position, I used Maxmind's geoip service.
<script language="JavaScript" src="http://j.maxmind.com/app/geoip.js"></script>
<script language="JavaScript">var laa=geoip_latitude();</script>
<script language="JavaScript">var lonn=geoip_longitude();</script>
After obtaining my current position, I used those values to center my map.
Here's the Javascript code I used to display & center map.
<script>
//map included.
function initialize()
{
var myLatlng=new google.maps.LatLng(laa,lonn);
var mapProp = {
center: new google.maps.LatLng(laa,lonn),
zoom:6,
maxZoom: 8,
minZoom:2,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googleMap"),mapProp);
var image = 'mapmarkers/you-are-here-2.png';
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'I am Here.',
icon: image
});
}
function loadScript()
{
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyDY0kkJiTPVd2U7aTOAwhc9ySH6oHxOIYM&sensor=false&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;
</script>
HTML code used to include map into my web page is:
<div id="googleMap" style="width:900px;height:500px;">
</div>
I have included a screenshot of my map.
I have added a green marker to identify my current location. Now based on that, I wanna find the 4 extreme coordinates that I have marked (circled) in red.
I don't know how to acheive this. Any tips from anyone??
Gracias. :)
I want to find the extreme coordinates whenever user zooms in or zooms out based on mouse over or mouse down function.
Worst thing is, IDK how to achieve that.
Use the getBounds() method. https://developers.google.com/maps/documentation/javascript/reference#Map
Use it in a bounds_changed event listener. That should suit your needs.
google.maps.event.addListener(map, 'bounds_changed', function () {
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
});
Edit: JSFiddle demo
With this, you will be able to calculate the 2 other points. Hope this helps.

How can I get the smallest LatLngBounds that still contains a set of Lat/Long Coordinates in Google Maps JS API?

I need to plot a set of coordinates on the map in response to a user selection, and when it happens, I'd like to pan the map to focus on that set of points. How can I find the smallest bounding box (LatLngBounds) that contains all of the coordinates?
In addition to the Stack Overflow post which #Crescent Fresh pointed to above (which is using the v2 API), the method you'd want to use is the LatLngBounds.extend().
Here's a complete example, using the v3 API:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps LatLngBounds.extend() Demo</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 400px; height: 300px;"></div>
<script type="text/javascript">
var map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.TERRAIN
});
var markerBounds = new google.maps.LatLngBounds();
var randomPoint, i;
for (i = 0; i < 10; i++) {
// Generate 10 random points within North East America
randomPoint = new google.maps.LatLng( 39.00 + (Math.random() - 0.5) * 20,
-77.00 + (Math.random() - 0.5) * 20);
// Draw a marker for each random point
new google.maps.Marker({
position: randomPoint,
map: map
});
// Extend markerBounds with each random point.
markerBounds.extend(randomPoint);
}
// At the end markerBounds will be the smallest bounding box to contain
// our 10 random points
// Finally we can call the Map.fitBounds() method to set the map to fit
// our markerBounds
map.fitBounds(markerBounds);
</script>
</body>
</html>
Screenshot:

Categories