I have a google map with hundreds of markers. I would like the map to center on the users location - preferably with a button click. Currently, I have it centering on page load but with one problem - it clears out all of the markers when it centers on location. I assume this is because of how I'm calling the script. The map container's id is 'map4'.
How can I make this script work without clearing the existing markers? Any help would be greatly appreciated.
<script>
var map; // Google map object
// Initialize and display a google map
function Init()
{
// HTML5/W3C Geolocation
if ( navigator.geolocation )
navigator.geolocation.getCurrentPosition( UserLocation );
// Default to Sherman Oaks
else
ShowLocation( 38.8951, -77.0367, "Sherman Oaks, CA" );
}
// Callback function for asynchronous call to HTML5 geolocation
function UserLocation( position )
{
ShowLocation( position.coords.latitude, position.coords.longitude, "This is your Location" );
}
// Display a map centered at the specified coordinate with a marker and InfoWindow.
function ShowLocation( lat, lng, title )
{
// Create a Google coordinate object for where to center the map
var latlng = new google.maps.LatLng( lat, lng );
// Map options for how to display the Google map
var mapOptions = { zoom: 12, center: latlng };
// Show the Google map in the div with the attribute id 'map-canvas'.
map = new google.maps.Map(document.getElementById('map4'), mapOptions);
// Place a Google Marker at the same location as the map center
// When you hover over the marker, it will display the title
var marker = new google.maps.Marker( {
position: latlng,
map: map,
title: title
});
// Create an InfoWindow for the marker
var contentString = "<b>" + title + "</b>"; // HTML text to display in the InfoWindow
var infowindow = new google.maps.InfoWindow( { content: contentString } );
// Set event to display the InfoWindow anchored to the marker when the marker is clicked.
google.maps.event.addListener( marker, 'click', function() { infowindow.open( map, marker ); });
}
// Call the method 'Init()' to display the google map when the web page is displayed ( load event )
google.maps.event.addDomListener( window, 'load', Init );
</script>
If I understand you correctly, it seems you already have created a map, populated with markers AND THEN you want to center the VERY SAME map. If that's the case, your ShowLocation() function needs to be modified. The reason is that this line
map = new google.maps.Map(document.getElementById('map4'), mapOptions);
creates a fresh new instance of map (replacing any existing map in that container, if the provided map container is the same).
So your problem is that you are creating and centering a new map, instead of just centering the old one.
Just modify the centering function to work with an existing map:
function ShowLocation( lat, lng, title , map)
{
// Create a Google coordinate object for where to center the map
var latlng = new google.maps.LatLng( lat, lng);
//Working with existing map instead of creating a new one
map.setCenter(latlng);
map.setZoom(12);
// Place a Google Marker at the same location as the map center
// When you hover over the marker, it will display the title
var marker = new google.maps.Marker( {
position: latlng,
map: map,
title: title
});
// Create an InfoWindow for the marker
var contentString = "<b>" + title + "</b>"; // HTML text to display in the InfoWindow
var infowindow = new google.maps.InfoWindow( { content: contentString } );
// Set event to display the InfoWindow anchored to the marker when the marker is clicked.
google.maps.event.addListener( marker, 'click', function() { infowindow.open( map, marker ); });
}
And when calling the ShowLocation function, it's 4th parameter would be the google.maps.Map object you created when adding the markers. You cannot reference map only by knowing it's containing element's id, you need the reference for it.
Related
I have a problem with google maps api, when I change the marker position constantly, this leave a trace on map and I need move the marker without leaving a trace.
I actually get the latitude and the longitude from a database in firebase and need represent the route of a car.
var mapOptions = {
center: new google.maps.LatLng(20.615977, -103.339358),
zoom: 12
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
firebase.database().ref('route').on('value', function(data) {
var start = new google.maps.Marker({
position: {lat: latitud, lng: longitud},
map: map,
icon: '../icon/car.png'
});
var myLatlng = new google.maps.LatLng(data.val().latitude, data.val().longitude);
start.setPosition(myLatlng);
start.setMap(map);
});
You're creating a new marker in every event. Instead, create the marker before the event handler (and call setMap there), and in your handler, just do setPosition() to the data's new lat/lng.
I'm using Google Maps Javascript v3 API and MarkerClusterer JS in my Ruby on Rails application.
I want following functionality in my map. I've some markers on my map, in that map markers forms a cluster when I zoom out the map, and again gets separated when I zoom in. When I click on the particular marker it displays the info-window of that marker, and when I click on the cluster it displays the info-window related to that cluster. this is the current behavior of my map.
Now when I click on the particular marker on the map, it displays the info-window of that marker, now I zoom out that and when the marker becomes the part of cluster then the info-window of that marker is hidden, I want that info-window to remain displayed on cluster also.
I'm using global info-window for markers and clusters.
here is the some code that handles map in my application.
function createMarker(latlng, name, html) {
// create new google marker using the latitude and longitude that is passed into this function as "latlng"
var marker = new google.maps.Marker({
position: latlng,
draggable: true ,
map: map,
zIndex: Math.round(latlng.lat()*-100000)<<5,
icon: '/assets/pin.png',
});
// add click event listner to the created marker
google.maps.event.addListener(marker, 'click', function() {
// clear the previous content of infowindow
infowindow.setContent('');;
// close the infowindow
infowindow.close();
// set the content of infowindow that is passed into this function as "html"
infowindow.setContent(html);
// open the new infowindow with the created marker
infowindow.open(map,marker);
clearUpMenus();
});
// add closeclick event listner when user clicks on the close button on the infowindow
google.maps.event.addListener(infowindow,'closeclick',function(){
// set the map of the marker to null
marker.setMap(null);
check = null;
});
// add drag event listner when user drags the created marker
google.maps.event.addListener(marker,'dragend',function(event) {
// update latitude and longitude of the marker with the dragged ones.
var lat = event.latLng.lat();
var lng = event.latLng.lng();
// set latitude and longitude to the input fields for further uses.
form_latitude = lat;
form_longitude = lng;
$("input[id=location_latitude]").val(lat);
$("input[id=location_longitude]").val(lng);
});
// trigger the click event manually
google.maps.event.trigger(marker, 'click');
// return the created marker
return marker;
}
Above is the code to create the new marker on my map.
var markerCluster = new MarkerClusterer(map,markersArray, clusterOptions);
google.maps.event.addListener(markerCluster, 'click', function(cluster) {
// this function displays the info-window on cluster
displayClusterInfo(cluster);
});
function displayClusterInfo(cluster) {
var markers = cluster.getMarkers();
$('.map-title').css('z-index',-1);
map.setOptions({zoomControl:false, streetViewControl:false});
var info = new google.maps.MVCObject;
info.set('position', cluster.getCenter());
//getTopThreeMarkers() - It makes the ajax call to get top markers based on some criteria
getTopThreeMarkers(info,markers);
}
Any help would be appreciated.
Thanks.
Wonder if anyone can help me, I have setup a google map all works nicely. The only thing I cant work out how to do is to open an info window based on ID from an external html link that's not in the JS.
function initialize() {
// Create the map
// No need to specify zoom and center as we fit the map further down.
var map = new google.maps.Map(document.getElementById("map"), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
});
infowindow = new google.maps.InfoWindow();
// Custom markers
var icon = "img/marker.png";
// Define the list of markers.
// This could be generated server-side with a script creating the array.
var markers = [
{ val:0, lat: -40.149049, lng: 172.033095, title: "Title", html: "<div style='text-align:left'><h4 style='color:#0068a6;font-size:16px;margin:0px 0px 10px 0px;'>Title</h4><strong>Telephone</strong><br /><br />Address</div>" },
{ val:1, lat: -41.185765, lng: 174.827516, title: "Title", html: "<div style='text-align:left'><h4 style='color:#0068a6;font-size:16px;margin:0px 0px 10px 0px;'>Title</h4><strong>Telephone</strong><br /><br />Address</div>" },
];
// Create the markers ad infowindows.
for (index in markers) addMarker(markers[index]);
function addMarker(data) {
// Create the marker
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.lat, data.lng),
map: map,
title: data.title,
icon: icon,
id: data.val
});
// Create the infowindow with two DIV placeholders
// One for a text string, the other for the StreetView panorama.
var content = document.createElement("DIV");
var title = document.createElement("DIV");
title.innerHTML = data.html;
content.appendChild(title);
// Open the infowindow on marker click
google.maps.event.addListener(marker, "click", function() {
infowindow.setContent(content);
infowindow.open(map, this);
map.setCenter(this.position);
console.log(this.id);
});
}
// Zoom and center the map to fit the markers
// This logic could be conbined with the marker creation.
// Just keeping it separate for code clarity.
var bounds = new google.maps.LatLngBounds();
for (index in markers) {
var data = markers[index];
bounds.extend(new google.maps.LatLng(data.lat, data.lng));
}
map.fitBounds(bounds);
}
<p id="1">link to open marker</p>
Any help would be gratefully appreciated
Richard :)
The Golden Goose
Then in your js have a function to open the infowindow (such as show()) which takes the properties from that link (opening id 7).
function show(id){
myid = id;
if(markers[myid]){
map.panTo(markers[myid].getPoint());
setTimeout('GEvent.trigger(markers[myid], "click")',500);
map.hideControls();
}
}
That's the function I used previously with one of the marker managers from v2. You have to make sure you set an id for each marker as you set it and then you can call it.
The one thing I made sure of (to simplify matters) was to make sure the map marker set/array was exactly the same as the sql result I used on the page. That way, using id's was a piece of cake.
I am creating a google map in a script with the following code -
var mapElement,
parent,
mapOptions,
map,
marker,
latLong,
openMarker;
parent = document.getElementsByClassName('parent')[0];
mapElement = document.createElement('div');
latLong = new google.maps.LatLng(some_lat_from_db, some_long_from_db);
mapOptions = {
center: latLong,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(mapElement, mapOptions);
marker = new google.maps.Marker({
position: latLong,
map: map,
title: 'some title'
});
openMarker = function () {
var infowindow = new google.maps.InfoWindow();
infowindow.setContent('Some Content');
infowindow.open(map, marker);
};
google.maps.event.addListener(marker, 'click', openMarker);
parent.appendChild(mapElement);
openMarker();
When using this code, the infowindow that opens up by default goes outside the map viewport, so it's not visible. I first tried to reduce the size of the info window but that didn't work out. So I thought to move the center of the map a bit so that the info window remains in the viewport.
So, how can I move the center by some pixels so that the info window remains in the viewport?
You can use .setCenter() to move the center of the map
map.setCenter(marker.getPosition());
Update
Convert the LatLng with .fromLatLngToDivPixel() into a Point add an offset and convert it back into a LatLng with .fromDivPixelToLatLng()
forget all that crap this is what works if you want to reuse a google map marker or move a google map marker, or recenter a google map marker.
var lo = <yourval>;
var la = <yourval>;
var midpoint = {lat:la, lng:lo };
marker.setPosition(midpoint);
if you want to destroy a google maps marker or delete a google maps marker
marker.setMap(null);
The following sample code provided by google maps api
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(40.77627, -73.910965);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
the following only shows google map of the location without a marker.
I was wondering how I can place a marker by giving latitude/longitude parameters?
And how is it possible to store my own information pulled from a database on that marker?
Here is a JSFiddle Demo that shows you how to set a google map marker by Lat Lng and also when click would give you an information window (bubble):
Here is our basic HTML with 3 hyperlinks when clicked adds a marker onto the map:
<div id="map_canvas"></div>
<a href='javascript:addMarker("usa")'>Click to Add U.S.A</a><br/>
<a href='javascript:addMarker("brasil")'>Click to Add Brasil</a><br/>
<a href='javascript:addMarker("argentina")'>Click to Add Argentina</a><br/>
First we set 2 global variables. one for map and another an array to hold our markers:
var map;
var markers = [];
This is our initialize to create a google map:
function initialize() {
var latlng = new google.maps.LatLng(40.77627, -73.910965);
var myOptions = {
zoom: 1,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
We then create 3 lat lng locations where we would like to place our markers:
var usa = new google.maps.LatLng(37.09024, -95.712891);
var brasil = new google.maps.LatLng(-14.235004, -51.92528);
var argentina = new google.maps.LatLng(-38.416097, -63.616672);
Here we create a function to add our markers based on whatever is passed onto it. myloc will be either usa, brasil or argentina and we then create the marker based on the passed param. With in the addMarker function we check and make sure we don't create duplicate marker on the map by calling the for loop and if we the passed param has already been created then we return out of the function and do nothing, else we create the marker and push it onto the global markers array. After the marker is created we then attach an info window with it's associated marker by doing markers[markers.length-1]['infowin'] markers.length-1 is just basically getting the newly pushed marker on the array. Within the info window we set the content using html. This is basically the information you put into the bubble or info window (it can be weather information which you can populate using a weather API and etc). After info window is attached we then attach an onclick event listener using the Google Map API's addListener and when the marker is clicked we want to open the info window that is associated with it by calling this['infowin'].open(map, this) where the map is our global map and this is the marker we are currently associating the onclick event with.
function addMarker(myloc) {
var current;
if (myloc == 'usa') current = usa;
else if (myloc == 'brasil') current = brasil;
else if (myloc == 'argentina') current = argentina;
for (var i = 0; i < markers.length; i++)
if (current.lat() === markers[i].position.lat() && current.lng() === markers[i].position.lng()) return;
markers.push(new google.maps.Marker({
map: map,
position: current,
title: myloc
}));
markers[markers.length - 1]['infowin'] = new google.maps.InfoWindow({
content: '<div>This is a marker in ' + myloc + '</div>'
});
google.maps.event.addListener(markers[markers.length - 1], 'click', function() {
this['infowin'].open(map, this);
});
}
When all is done we basically attach window.onload event and call the initialize function:
window.onload = initialize;