I want to save the current position where to user is watching and restore back after some clicks.
How do I get the current lat longitude bounds so that I could map.fitBounds on it?
Here's the code to capture the current map bounds, on the "bounds_changed" event
google.maps.event.addListener(map, 'bounds_changed', function() {
try {
if( initialBounds == null ) {
initialBounds = map.getBounds();
}
} catch( err ) {
alert( err );
}
});
Then, you can return the map the bound using this code
google.maps.event.addDomListener(controlUI, 'click', function() {
// map.setCenter(home)
if( initialBounds != null ) {
map.fitBounds( initialBounds );
}
});
getBounds() in Google Maps API v3
So to get our latitude and longitude we need to move getBounds() to bounds_changed event listener.
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 10,
center: new google.maps.LatLng(lat, lng),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, 'bounds_changed', function() {
var bounds = map.getBounds();
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
console.log(ne.lat());
console.log(ne.lng());
console.log(sw.lat());
console.log(sw.lng());
});
This event is fired when the viewport bounds have changed. If you have some ajax call in it, every time position of map changes the ajax call will be fired.
So, the better solution in that case is to move getBounds() in idle event listener. This event is fired when the map becomes idle after zooming.
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 10,
center: new google.maps.LatLng(lat, lng),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, 'idle', function() {
var bounds = map.getBounds();
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
console.log(ne.lat());
console.log(ne.lng());
console.log(sw.lat());
console.log(sw.lng());
});
Related
I am trying to work out how to show custom data when a Google Maps markerclusterer marker is clicked but can't find this documented anywhere.
My markerclusterer code looks like this but my attempt at capturing the click event on a marker is not working:
var markerClusterer = null;
var map = null;
var imageUrl = 'http://chart.apis.google.com/chart?cht=mm&chs=24x32&' +
'chco=FFFFFF,008CFF,000000&ext=.png';
google.maps.event.addDomListener(window, 'load', initialize);
function refreshMap() {
if (markerClusterer) {
markerClusterer.clearMarkers();
}
var markers = [];
var markerImage = new google.maps.MarkerImage(imageUrl,
new google.maps.Size(24, 32));
/*
for (var i = 0; i < 1000; ++i) {
var latLng = new google.maps.LatLng(data.photos[i].latitude,
data.photos[i].longitude)
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage
});
markers.push(marker);
}
*/
for (var i = 0; i < numItemsToShow; ++i) {
var latLng = new google.maps.LatLng(itemsToShow[i].lat, itemsToShow[i].long);
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage
});
markers.push(marker);
}
var zoom = parseInt(document.getElementById('zoom').value, 10);
var size = parseInt(document.getElementById('size').value, 10);
var style = parseInt(document.getElementById('style').value, 10);
zoom = zoom == -1 ? null : zoom;
size = size == -1 ? null : size;
style = style == -1 ? null: style;
markerClusterer = new MarkerClusterer(map, markers, {
maxZoom: zoom,
gridSize: size,
styles: styles[style]
});
}
function initialize() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: new google.maps.LatLng(39.91, 116.38),
mapTypeId: google.maps.MapTypeId.ROADMAP,
//styles: [{"featureType":"administrative","elementType":"labels.text.fill","stylers":[{"color":"#444444"}]},{"featureType":"administrative.land_parcel","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2f2f2"}]},{"featureType":"landscape.natural","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"on"},{"color":"#052366"},{"saturation":"-70"},{"lightness":"85"}]},{"featureType":"poi","elementType":"geometry.fill","stylers":[{"saturation":"-100"},{"lightness":"0"}]},{"featureType":"poi","elementType":"labels","stylers":[{"visibility":"simplified"},{"lightness":"-53"},{"weight":"1.00"},{"gamma":"0.98"}]},{"featureType":"poi","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"labels.icon","stylers":[{"visibility":"off"},{"lightness":"0"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"hue":"#3dff00"},{"saturation":"-100"}]},{"featureType":"road","elementType":"all","stylers":[{"saturation":-100},{"lightness":45},{"visibility":"on"}]},{"featureType":"road","elementType":"geometry","stylers":[{"saturation":"-18"}]},{"featureType":"road","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"road.local","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.local","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"all","stylers":[{"color":"#57677a"},{"visibility":"on"}]},{"featureType":"water","elementType":"geometry.fill","stylers":[{"lightness":"40"}]}]
styles: [{"featureType":"water","stylers":[{"visibility":"on"},{"color":"#b5cbe4"}]},
{"featureType":"landscape","stylers":[{"color":"#efefef"}]},
{"featureType":"road.highway","elementType":"geometry","stylers":[{"color":"#83a5b0"}]},
{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#bdcdd3"}]},
{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"}]},
{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#e3eed3"}]},
{"featureType":"administrative","stylers":[{"visibility":"on"},{"lightness":33}]},
{"featureType":"road"},
{"featureType":"poi.park","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":20}]},{},
{"featureType":"road","stylers":[{"lightness":20}]}]
});
var refresh = document.getElementById('refresh');
google.maps.event.addDomListener(refresh, 'click', refreshMap);
var clear = document.getElementById('clear');
google.maps.event.addDomListener(clear, 'click', clearClusters);
google.maps.event.addListener(markerClusterer, 'click', function () {
// do something with this marker ...
this.setTitle('I am clicked');
});
refreshMap();
}
function clearClusters(e) {
e.preventDefault();
e.stopPropagation();
markerClusterer.clearMarkers();
}
This works for me (it opens an infowindow when you mouseover the cluster icon, if you click on the cluster icon, the default behavior is to zoom to the cluster bounds, which makes it hard to see the change of the tooltip/title on the cluster icon):
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(markerClusterer, 'mouseover', function (cluster) {
// do something with this cluster ...
infoWindow.setContent("Mouseover<br>"+cluster.getCenter().toUrlValue());
infoWindow.setPosition(cluster.getCenter());
infoWindow.open(map);
});
I am working on google maps for quite some time, I am familiar with code and how it works, but unable to place the resize event properly that causes my map to render grey tiles on screen.
Please suggest me where exactly need to place the resize event
Here is my code :
bank.atmDetailsSuccess = function(response) {
bank.locate = response;
bank.getAtmStatus();
};
bank.getAtmStatus = function(results, status) {
var status = bank.locate.Status[0].Value0;
locate = bank.locate;
var map;
if (status == bank.constants.STATUS_ERROR) {
var message = locate.Error[0].Value0;
WL.simpledialog.show(message);
} else if (status == bank.constants.STATUS_SESSION_EXPIRED) {
WL.simpledialog.show("Session Expired!!");
} else if (status == bank.constants.STATUS_SUCCESS) {
map = bank.initializeAtm();
google.maps.event.addDomListener(window, 'load', initializeAtm);
google.maps.event.addDomListener(window, "resize", function() {
alert("In");
var center = map.getCenter();
google.maps.event.trigger(map, "resize");
map.setCenter(center);
map.setZoom(10);
});
}
};
bank.initializeAtm = function(){
locate = bank.locate;
var firstlat = locate.Stmt[0].Value5;
var firstlong= locate.Stmt[0].Value6;
// var latlng = new google.maps.LatLng(latitude,longitude);
var image = {
//url: bank.constants.MARKER_PATH,
url: 'images/720x720/pin.png',
// This marker is 20 pixels wide by 32 pixels tall.
size: new google.maps.Size(32, 40),
// The origin for this image is 0,0.
origin: new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
anchor: new google.maps.Point(0, 32)
};
var myOptions = {
zoom: 10,
center:new google.maps.LatLng(firstlat, firstlong),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map($('#map-canvas')[0], myOptions);
geocoder = new google.maps.Geocoder();
bank.currentposition();
$('#mapbranch').hide();
$('#map-canvas').show();
$('#atm').html("ATM near your current location");
$('#results').html("");
var directionsService = new google.maps.DirectionsService();
MVC.local.directService = directionsService;
directionsRenderer = new google.maps.DirectionsRenderer({
suppressMarkers: true} );
MVC.local.renderer = directionsRenderer;
var n;
for(n=0; n<locate.Stmt.length; n++)
{
var value = locate.Stmt[n];
name = value.Value0,value.Value1;
lat = value.Value5;
lon = value.Value6;
bank.getDistanceFromLatLonInKm(12.919336, 77.502291,lat,lon);
var myLatLng = new google.maps.LatLng(lat,lon);
var marker = new google.maps.Marker({
position: myLatLng,
icon:image,
map: map,
title: name,
zIndex: 1
});
bank.buildInfoWindow(marker,map,value[n]);
}
return map;
};
Note:This is completely working code only problem is rendering works when i resize broswer manually but not resizing while loading. Please don't mind variable names.All function calls are good except resize event.
I want to import kml files that contains more than 2000 placemarks into googla map.
I use google api v3.
I can only show 200 placemarks.
I know that I can use more layers, but I want only one because I have to refresh it weekly and I don't want to split every time.
Thanks for your replays
THIS IS THE CODE:
<script>
var map;
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(47.25,19.5),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
loadKmlLayer(map);
}
function loadKmlLayer(map) {
var ctaLayer2 = new google.maps.KmlLayer('https://.../asdf.kml', {
suppressInfoWindows: false,
preserveViewport: false,
map: map
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
If your KML isn't very complex, you could try rendering it with a third-party KML parser (geoxml3 or geoxml-v3), see if that works (or points to the problem you are having with KmlLayer)
(function() {
window.onload = function() {
// Creating a new map
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(47.10,19.5),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Creating the JSON data
var json = [
DATA HERE LIKE:
{"title" :"City ZIP CODE STREET" , "lat" :47.2876 , "lng" :20.4978 ,"description" :"YOUR DESCRIPTION"},
]
// Creating a global infoWindow object that will be reused by all markers
var infoWindow = new google.maps.InfoWindow();
// Looping through the JSON data
for (var i = 0, length = json.length; i < length; i++)
{
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: data.title,
// icon: iconimage
});
// Creating a closure to retain the correct data, notice how I pass the current data in the loop into the closure (marker, data)
(function(marker, data) {
// Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})
//OnClick event
(marker, data);
}
} })();
Ok I spent 2 days working on this time for some help :) Everything works fine with the code now I just need to make the marker draggable and update Lat and Lng values. At present the code captures lat and lng via current position as well as via entering a location on the web page. The value of _Lat and _lng are then submitted the a database. I need the user to be able to drag the marker to fine tune the location and update _lat and _lng prior to the database submit. I have made the marker draggable but I can't figure out how to add the dragend code so that it dynamically updates the value of lat and _lng prior to the database submit. I don't need to update anything on the web page just I need to update the _lat and _lng values that get posted to the database. Here is the existing code:
Thanks
var gmap;
var gmarker;
var geocoder;
function initialize() {
// Get here center of map - by default - San Francisco center
var center = new google.maps.LatLng(37.47, -122.25);
var mapOptions = {
center: center,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
geocoder = new google.maps.Geocoder()
gmap = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
// Set inner position of map to form parameters
$('input[name="_lat"]').val(37.47);
$('input[name="_lng"]').val(-122.25);
gmarker = new google.maps.Marker({
map: gmap,
position: center,
icon: '/static/internal/images/mapicon.png',
draggable: true
});
google.maps.event.addListener(gmap, 'click', function(event) {
gmarker.setPosition(event.latLng);
$('input[name="_lat"]').val(event.latLng.lat());
$('input[name="_lng"]').val(event.latLng.lng());
});
navigator.geolocation.getCurrentPosition(function(position){
var _lng = position.coords.longitude;
var _lat = position.coords.latitude;
$('input[name="_lng"]').val(_lng);
$('input[name="_lat"]').val(_lat);
var new_position = new google.maps.LatLng(_lat, _lng);
gmap.setCenter(new_position);
gmarker.setPosition(new_position);
})
}
function showAddress(address) {
if (geocoder) {
geocoder.geocode(
{'address': address},
function(results, status) {
if (status != google.maps.GeocoderStatus.OK) {
alert(address + " not found");
} else {
gmap.setCenter(results[0].geometry.location);
gmarker.setPosition(results[0].geometry.location);
$('input[name="_lat"]').val(results[0].geometry.location.lat());
$('input[name="_lng"]').val(results[0].geometry.location.lng());
}
}
);
}
}
listen to the position_changed-event of the marker:
google.maps.event.addListener(gmarker, 'position_changed', function() {
$('input[name="_lat"]').val(this.getPosition().lat());
$('input[name="_lng"]').val(this.getPosition().lng());
});
Your click event is on map it should be on marker
Change
google.maps.event.addListener(gmap, 'click', function(event) {
To
google.maps.event.addListener(gmarker, 'click', function(event) {
I've seen several other posts about this, but the answers from those responses don't work for me.
The other responses:
How do I bind a google maps geocoder.geocode() callback function
Backbone.js with Google Maps - problems with this and listeners
My code:
var ns = namespace('camelcase.geomanager.map');
ns.Site = Backbone.Model.extend({
url: '/site'
});
ns.Sites = Backbone.Collection.extend({
model: ns.Site
});
ns.MapView = Backbone.View.extend({
initialize: function() {
this.markers = new Array();
// Create the Google Map
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.googleMap = new google.maps.Map(this.$(".mapCanvas")[0], mapOptions);
// Register events
this.collection.on('add', this.addSite, this);
this.collection.on('remove', this.removeSite, this);
},
addSite: function(model) {
// Get model attributes
var elementId = model.get('elementId');
var latitude = model.get('latitude');
var longitude = model.get('longitude');
var id = model.get('id');
var notes = model.get('notes');
var title = ""+id;
// Create icon and marker
var icon = '/resources/img/elements/' + elementId + '_marker.png';
var latLng = new google.maps.LatLng(latitude, longitude);
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: this.googleMap,
icon: icon
});
// Load info window
var siteBubbleTemplate = _.template($('#siteBubbleTemplate').html());
var siteContent = $(siteBubbleTemplate({
siteId: id,
siteNotes: notes
}))[0];
var infoWindow = new google.maps.InfoWindow({
content: siteContent
});
// Show info window when clicking on marker
_.bindAll(this, this.openSite);
google.maps.event.addListener(marker, 'click', this.openSite(id));
this.markers.push({
id: id,
marker: marker,
infoWindow: infoWindow
});
},
openSite: function(id) {
var marker;
for (var c=0; c<this.markers.length; c++) {
marker = this.markers[c];
// Open the appropriate marker info window
if (marker.id == id) {
marker.infoWindow.open(googleMap, marker.marker);
}
// Close the rest
else {
marker.infoWindow.close();
}
}
}
});
The offending line:
google.maps.event.addListener(marker, 'click', this.openSite(id));
The error being reported in firebug:
TypeError: func is undefined
underscore.js (line 482)
I suspect this.marker is the problem, since you should be able to just refer to it by name.
google.maps.event.addListener(marker, 'click', this.openSite(id));
Looks like it was a scoping issue. I solved my problem with the following code:
// Show info window when clicking on marker
_.bindAll(this);
var _self = this;
var doSomething = function(event) {
_self.openSite({
event: event
});
};
google.maps.event.addListener(marker, 'click', doSomething);
I'll give the answer to whoever can best explain why this works.
In a model/collection event handler, Backbone sets 'this' to the model/collection which raised the event. If you call _.bindAll(this) in your view's initialize(), 'this' will be set to the view in your event handlers. Check out this jsfiddle: http://jsfiddle.net/9cvVv/339/ and see what happens when you uncomment _.bindAll(this);
var MyView = Backbone.View.extend({
initialize: function() {
// TODO: uncomment this line
// _.bindAll(this);
this.collection.bind('myEvent', this.onDoSomething);
},
updateCollection: function() {
this.collection.doSomething();
},
onDoSomething: function() {
if (this.models && typeof this.models.length === 'number') {
alert('"this" is a collection.');
}
else if (this.collection) {
alert('"this" is the view.');
}
else {
alert('"this" is something else.');
}
}
});