I wonder whether someone may be able to help me please.
I'm using this page to allow users to view markers saved in a MySQL database and to geocode/reverse geocode new marker positions.
I'm able to correctly center the map on the marker which is being loaded from the database, but the problem I'm having is that the map zooms in to it's maximum setting, whereas I would like to be able to set this manually.
I've tried adding another zoom control into my script here:
// add marker
var bounds = new google.maps.LatLngBounds();
var loc = new google.maps.LatLng(las[i],lgs[i]);
var marker = new google.maps.Marker({
position: loc,
map: window.map,
zoom: 8,
title: nms[i]
});
bounds.extend(loc);
map.fitBounds(bounds);
Unfortunately this has no affect. I appreciate that to some this may be a very minor fix, but I've been looking at this for sometime and I just can't seem to find a solution.
I just wondered whether someone may be able to look at this please and let me know where I've gone wrong?
POST UPDATE
I have worked out a solution using exisitng code and that suggested by #Andrew Leach. The working solution is:
// add marker
var bounds = new google.maps.LatLngBounds();
var loc = new google.maps.LatLng(las[i],lgs[i]);
var marker = new google.maps.Marker({
position: loc,
map: window.map,
title: nms[i]
});
bounds.extend(loc);
map.fitBounds(bounds);
map.setZoom(16);
Remove the references to the bounds.
You add a marker to the map, and create a LatLngBounds object which contains only that single point. You then ask the map to zoom in to fit the bounds into the map's viewport. Fitting a single location into the viewport will always zoom in as far as it can, and even then a single point can never fill the entire viewport.
However, adding zoom to the marker options won't work either, because zoom is not a valid option. Documentation
Instead, set the map's zoom explicitly, either with map.setZoom(8) or by including the zoom option in the map's options when you set it up.
Related
Let's say I have the following objects:
var map = new google.maps.Map(...)
var marker = new google.maps.Marker(...);
I can add marker to map with:
marker.setMap(map);
If the marker already exists on the map, and I call marker.setMap(map) again, does the API actually redraw the marker? Or does it know the marker already exists on the map, so it doesn't take any further actions?
I am listening for events and need to either add or remove markers from the map when those events occur. I'm wondering if I can simply keep calling setMap(map) even if the marker already exists without performance suffering significantly, or do I need to be smarter and not call setMap in the first place if the marker is already on the map.
If you don't know the answer, do you have any idea how I could figure this out?
If the marker already exists on the map, and I call marker.setMap(map)
again, does the API actually redraw the marker? Or does it know the
marker already exists on the map, so it doesn't take any further
actions?
The setMap function work on the visibility of the marker... assing to the marker in which map object this marker must be place/visibile..
If you set marker.setMap(null) you don't destroy the marker simply is not more showed in the "map".
when you manage event on marker you can use setMap(null) for make the marker invisible.. if you have previuosly stored the marker object in some var..eg
var store_marker = marker;
you can simply turn it on again doing
store_marke.setMap(map);
You can use array for manage collection of markers
I am using google maps api v3, and i need to move many(hundreds) of markers at the same time. From server, i get array of objects, representing a marker with it´s coordinates as it moved over time(few months), ordered by time when it moved. Above my map, i have a progress bar representing time with "month:year" text. What my code does, is move the marker(and draw polyline) at the exact time so it fits the time currently displayed on the "time progress bar". At every position where the marker stops, i leave a new marker to show the history of the movement. The whole process repeats over and over(setInterval() function). My code is working, the problem is performance, so i am asking: is there any way i could improve the performance ? some better way than i am doing it? there must be something. Here is my code:
if (mapOverTime != null) {
trackables.forEach(function (trackable) {
var marker = new google.maps.Marker({
map: mapOverTime,
draggable: false,
clickable: false,
icon: geoIcon,
animation: google.maps.Animation.none,
zIndex: 2
});
var polyline = new google.maps.Polyline(polyOptions);
polyline.setMap(mapOverTime);
// adding these to arrays so i can access and remove them from the map later
markersArray.push(marker);
polylineArray.push(polyline);
trackable.years.forEach(function(year) {
$.each(year.months, function(index, month) {
setTimeout(function() {
if (month.coordinates.length > 0) {
var moveCounter = month.coordinates.length;
var timeToMove = Math.floor(pause_interval / moveCounter);
$.each(month.coordinates, function(i, position) {
var latTo = position.latitude;
var lngTo = position.longitude;
var destination = new google.maps.LatLng(latTo, lngTo);
setTimeout(function() {
moveToPosition(marker, destination, polyline);
}, (i) * timeToMove);
});
}
}, pause_interval * index);
});
});
});
}
This is the function making the moves happen:
function moveToPosition(marker, destination, polyline) {
// current path of the polyline
var path = polyline.getPath();
// add new coordinate
path.push(destination);
// rendering whole line would make the map even more chaotic, this makes the line dissapear after 8 moves of the marker
if (path.getLength() > 8) // comment out to render whole
th.removeAt(0); // path of polyline
// set marker position to the new one
marker.setPosition(destination);
// render new marker on this position so that it is well visible where the coins were
var historyPoint = new google.maps.Marker({
map: mapOverTime,
draggable: false,
icon: historyIcon,
animation: google.maps.Animation.none,
zIndex: 0
});
historyPoint.setPosition(destination);
// again add to global array so i can set access and remove this marker from the map later
historyPoints.push(historyPoint);
}
The only thing i do, is iterate through all the markers and it´s coordinates, move marker at given time, draw line behind it, create new marker at the new position, and go for another coordinates. When 1 iteration end, all the objects are removed from the map and the process starts again. Any idea how to improve performance? or the only solution is to decrease the number of markers i want to render? Thank you for your opinions!
Suggestions:
Why bother specifying animation: google.maps.Animation.none,? If you're not using it, just remove it. And according to the docs, there are two values, BOUNCE and DROP, so there isn't a none value anyway.
Use standard javascript array looping, instead of jquery's $.each() if you can; it's faster
You create two variables just for the benefit of specifying your destination coordinates. You use them once, and never again, so why not just use the original values? i.e.
var latTo = position.latitude;
var lngTo = position.longitude;
var destination = new google.maps.LatLng(latTo, lngTo);
just becomes
var destination = new google.maps.LatLng(position.latitude, position.longitude);
Another improvement you could make here. Use the shorthand inline struct notation for specifying your destination coordinates. It should reduce some overhead in creating hundreds of LatLng objects. i.e.
var destination = new google.maps.LatLng(position.latitude, position.longitude);
then becomes:
var destination = {lat: position.latitude, lng: position.longitude};
You create a polyline, then you set the map:
var polyline = new google.maps.Polyline(polyOptions);
polyline.setMap(mapOverTime);
I see this all the time and never understand it... just add map: mapOverTime to the polyOptions, saves having to do an additional function call.
Similarly with historyPoint... don't call setPosition() on it, just specify position: destination in the options you pass when you create the marker
All these are minor things which will likely make little different to trying to move hundreds of markers at once, but I'd still recommend you try them anyway.
I have to show only one location at a time in the Google map with a marker.
I tried to use auto zoom & auto center using the following code:
var bounds = new google.maps.LatLngBounds();
bounds.extend(latlng);
map.fitBounds(bounds); // auto zoom
map.panToBounds(bounds); // auto center
Also tried with the following:
var bounds = new google.maps.LatLngBounds();
bounds.extend(latlng);
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
Both the above solutions are giving the maximum zoom, since I am showing only one location in the map. With this maximum zoom I was not able to see the surrounding locations in the map.
Is there any solution to set zoom which gives a better view of map.
Giving the best zoom size (like 8, 9, 10....) which fits for all the locations also considerable one.
Thanks,
Gopal.
Please Refer link: http://jsfiddle.net/ZqhPM/3
var mapOptions = {
center: new google.maps.LatLng(39.8634242, -97.28818149999998),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
If you want to increase zoom level. please change zoom option in mapOptions.
I need a specific zoom size which is optimistic for most of the location types like - Street, State, Country
If you know the street, state or city, the geocoder will return a google.maps.LatLngBounds object for that geocoded result (and sometimes 2, a viewport and a bounds, see the documentation).
State (Massachusetts)
Country (France)
Street (Broadway, Arlington, MA)
I have a problem with google.maps.geometry.poly.isLocationOnEdge() method. In fiddle, try to click on horizontal line, returns true like expected, but clicking on vertical line returns false. Why?
Thanks!
Here is fiddle and here is code:
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(0.5, 0.5),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var poly = new google.maps.Polyline({
path: [
new google.maps.LatLng(0, 0),
new google.maps.LatLng(0, 1),
new google.maps.LatLng(1, 1)
],
map: map
});
google.maps.event.addListener(poly, 'click', function(event){
alert(google.maps.geometry.poly.isLocationOnEdge(event.latLng, this), 0.00001);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
I think you are better off using containsLocation()
From the docs :
To find whether a given point falls within a polygon, pass the point
and the polygon to google.maps.geometry.poly.containsLocation(). The
functions returns true if the point is within the polygon or on its
edge.
vs
To determine whether a point falls on or near a polyline, or on or
near the edge of a polygon, pass the point, the polyline/polygon, and
optionally a tolerance value in degrees to
google.maps.geometry.poly.isLocationOnEdge().
If you use containsLocation it works
alert(google.maps.geometry.poly.containsLocation(event.latLng, poly));
forked fiddle http://jsfiddle.net/VL7Rx/
I really cant explain exactly why it does not working with isLocationOnEdge. It seems to be an issue on 100% vertical polylines only, and with your 0,0,0,1 etc the Lng always is zero (0) (clicking vertical) - as if the line does not have any "width" at all, "mapwise".
containsLocation works only in the fiddle by davidkonrad if your listener is for clicks on the polyline. If your listener is on the map instead you will get 'true' anywhere in the triangle formed by the 3 LatLngs. If the user can't click the map itself then this is fine, but it may not work for your specific requirement.
Sadly, I can't see why the vertical line isn't working either (but it isn't just vertical lines, it doesn't seem to be working on any line that isn't horizontal).
I have a script that adds markers one by one to a map
var marker = new google.maps.Marker({
position: new google.maps.LatLng(51,-117)
});
marker.setIcon(getIconFile(initialIconId));
markers.push(new Array(id,marker)); // id, marker
marker.setMap(map);
later on in the script when I press a custom button I want to be able to change the markers icons. So I grab the marker by the id from the markers array and call:
markers[markerIndex].setIcon(getIconFile(newIconId)); // which returns a string url of the icon
However I receive: TypeError: markers[markerId].setIcon is not a function
I print the markerId and it is valid, I also print the result of indexing the marker markers[markerId] and it returns a marker object. I have no other way to debug this I am lost!
Thanks
It seems like you're pushing an Array into the markers, instead of just one element.
Why not:
markers = []
markers.push(marker)
markers[markerIndex].setIcon(getIconFile(newIconId));
or if you insist inserting an array:
markers.push(new Array(id,marker));
markers[markerIndex][1].setIcon(getIconFile(newIconId));