I'm trying to implement https://github.com/jawj/OverlappingMarkerSpiderfier to handle multiple map markers that can occur in the exact same location. I'm using the below javascript to grab the map data from divs of class .marker and create the map. It's functioning and works great.
function initialize() {
function render_map( $el ) {
// var
var $markers = $el.find('.marker');
// vars
var args = {
zoom : 8,
center : new google.maps.LatLng(42.7086815, -84.559032),
scrollwheel : false,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
// create map
var map = new google.maps.Map( $el[0], args);
// add a markers reference
map.markers = [];
// add markers
$markers.each(function(){
add_marker( $(this), map );
});
var padder = document.createElement('div');
padder.style.height = '100px';
padder.style.width = '100%';
map.controls[google.maps.ControlPosition.TOP_CENTER].push(padder);
// center map
center_map( map );
}
function add_marker( $marker, map ) {
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map
});
// add to array
map.markers.push( marker );
// if marker contains HTML, add it to an infoWindow
if( $marker.html() )
{
// create info window
var infowindow = new google.maps.InfoWindow({
content : $marker.html()
});
// show info window when marker is clicked
google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
map.setCenter(marker.getPosition());
});
}
}
function center_map( map ) {
// vars
var bounds = new google.maps.LatLngBounds();
// loop through all markers and create bounds
$.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
// only 1 marker?
if( map.markers.length == 1 )
{
// set center of map
map.setCenter( bounds.getCenter() );
}
else if( map.markers.length == 0 )
{
// set center of map
map.setCenter( 42.7086815, -84.559032 );
}
else
{
// fit to bounds
map.fitBounds( bounds );
}
google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
if (this.getZoom() > 8) {
this.setZoom(8);
}
});
}
$(document).ready(function(){
$('#acf-map').each(function(){
render_map( $(this) );
});
});
}
However, when I try to integrate what I have with Spiderfier js, the map markers are not showing up. This is my sorry attempt at merging the js. Any idea of how I can use Spiderfier but still grab the content from the .marker divs?
function initialize() {
function render_map( $el ) {
// var
var $markers = $el.find('.marker');
// vars
var args = {
zoom : 8,
center : new google.maps.LatLng(42.7086815, -84.559032),
scrollwheel : false,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
// create map
var map = new google.maps.Map( $el[0], args);
var oms = new OverlappingMarkerSpiderfier(map);
var iw = new google.maps.InfoWindow();
oms.addListener('click', function(marker, event) {
iw.setContent(marker.desc);
iw.open(map, marker);
});
oms.addListener('spiderfy', function(markers) {
iw.close();
});
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map
});
marker.desc = $marker.html();
oms.addMarker(marker);
var padder = document.createElement('div');
padder.style.height = '100px';
padder.style.width = '100%';
map.controls[google.maps.ControlPosition.TOP_CENTER].push(padder);
// center map
center_map( map );
}
function center_map( map ) {
// vars
var bounds = new google.maps.LatLngBounds();
// loop through all markers and create bounds
$.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
// only 1 marker?
if( map.markers.length == 1 )
{
// set center of map
map.setCenter( bounds.getCenter() );
}
else if( map.markers.length == 0 )
{
// set center of map
map.setCenter( 42.7086815, -84.559032 );
}
else
{
// fit to bounds
map.fitBounds( bounds );
}
google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
if (this.getZoom() > 8) {
this.setZoom(8);
}
});
}
$(document).ready(function(){
$('#acf-map').each(function(){
render_map( $(this) );
});
});
}
Below is the correctly integrated javascript in case it's helpful to anyone else.
function initialize() {
/*
* render_map
*
* This function will render a Google Map onto the selected jQuery element
*
* #type function
* #date 8/11/2013
* #since 4.3.0
*
* #param $el (jQuery element)
* #return n/a
*/
function render_map( $el ) {
// var
var $markers = $el.find('.marker');
// vars
var args = {
zoom : 8,
center : new google.maps.LatLng(42.7086815, -84.559032),
scrollwheel : false,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
// create map
var map = new google.maps.Map( $el[0], args);
var oms = new OverlappingMarkerSpiderfier(map);
var iw = new google.maps.InfoWindow();
oms.addListener('click', function(marker, event) {
iw.setContent(marker.desc);
iw.open(map, marker);
});
oms.addListener('spiderfy', function(markers) {
iw.close();
});
$markers.each(function(index, item) {
// create latlng
var latlng = new google.maps.LatLng( $(item).attr('data-lat'), $(item).attr('data-lng') );
// create marker
var iconBase = '/images/';
var marker = new google.maps.Marker({
position : latlng,
map : map,
icon: iconBase + 'marker.png'
});
marker.desc = $(item).html();
oms.addMarker(marker);
});
var padder = document.createElement('div');
padder.style.height = '100px';
padder.style.width = '100%';
map.controls[google.maps.ControlPosition.TOP_CENTER].push(padder);
// center map
center_map(map);
}
/*
* center_map
*
* This function will center the map, showing all markers attached to this map
*
* #type function
* #date 8/11/2013
* #since 4.3.0
*
* #param map (Google Map object)
* #return n/a
*/
function center_map(map) {
// vars
var bounds = new google.maps.LatLngBounds();
// loop through all markers and create bounds
$.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
// only 1 marker?
if( map.markers.length == 1 )
{
// set center of map
map.setCenter( bounds.getCenter() );
}
else if( map.markers.length == 0 )
{
// set center of map
map.setCenter( 42.7086815, -84.559032 );
}
else
{
// fit to bounds
map.fitBounds( bounds );
}
google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
if (this.getZoom() > 8) {
this.setZoom(8);
}
});
}
/*
* document ready
*
* This function will render each map when the document is ready (page has loaded)
*
* #type function
* #date 8/11/2013
* #since 5.0.0
*
* #param n/a
* #return n/a
*/
$(document).ready(function(){
$('#acf-map').each(function(){
render_map( $(this) );
});
});
}
Related
Hello fellow Stackoverflow members.
I have offered to help out our local communities emergency volunteer group with an improved alert map for notifying members of incidents close by to our town.
I have been using the google maps api, along with the google places api.
I have managed to bring in their news alert JSON data, match it with their custom icons, and display it on the map successfully. However I am now struggling to get the places searchBox to update the map based on the address users are entering into the search.
NB: The search is auto-completing fine, but the map is not updating. Current error is "map.fitBounds is not a function"
My reference link which I have been using to try and get the places search integrated: https://github.com/googlemaps/js-samples/blob/737eb41e78f9cad28e2664b68450676e91424219/dist/samples/places-searchbox/inline.html
I have attached my code below. With a comment where I have added the latest edits to the code for the search function. A fresh perspective would be greatly appreciated.
UPDATE: I have compiled a JSFiddle for easier handling:
https://jsfiddle.net/mcmacca002/zvghd0nu/
Thank you and appreciated.
// BUILD GOOGLE MAPS:
var GoogleMap = {
map: null,
markers: {},
init: function(lat, lng, places) {
var self = this;
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(lat, lng)
};
this.map = new google.maps.Map(document.getElementById('map'), mapOptions);
this.infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(50, 50)
});
// SEARCH STARTS HERE (ALONG WITH ISSUES):
var searchBox = new google.maps.places.SearchBox(document.getElementById('pac-input'));
google.maps.event.addListener(searchBox, 'places_changed', function() {
searchBox.set('map', null);
var places = searchBox.getPlaces();
var bounds = new google.maps.LatLngBounds();
var i, place;
for (i = 0; place = places[i]; i++) {
(function(place) {
var marker = new google.maps.Marker({
position: place.geometry.location
});
marker.bindTo('map', searchBox, 'map');
google.maps.event.addListener(marker, 'map_changed', function() {
if (!this.getMap()) {
this.unbindAll();
}
});
bounds.extend(place.geometry.location);
}(place));
}
map.fitBounds(bounds);
searchBox.set('map', map);
map.setZoom(Math.min(map.getZoom(),12));
});
// END OF SEARCH HERE.
$.each(places, function() {
self.addMarker(this);
});
this.setCenterPoint();
},
// Create map markers
addMarker: function(place) {
var self = this;
var marker = new google.maps.Marker({
position: new google.maps.LatLng(place.coordinate.latitude, place.coordinate.longitude),
map: self.map,
title: place.name,
icon: place.image
});
console.log(place);
// Create information event for each marker
marker.info_window_content = 'TEST'
self.markers[place.id] = marker
google.maps.event.addListener(marker, 'click', function() {
self.infowindow.setContent(marker.info_window_content)
self.infowindow.open(self.map, marker);
});
},
// Update map markers
updateMarkers: function(records) {
var self = this;
$.each(self.markers, function() {
this.setMap(null);
})
$.each(records, function() {
self.markers[this.id].setMap(self.map);
});
//Set map center
if (records.length) self.setCenterPoint();
},
// Set centre point for map
setCenterPoint: function() {
var lat = 0,
lng = 0;
count = 0;
//Calculate approximate center point based on number of JSON entries
for (id in this.markers) {
var m = this.markers[id];
if (m.map) {
lat += m.getPosition().lat();
lng += m.getPosition().lng();
count++;
}
}
if (count > 0) {
this.map.setCenter(new google.maps.LatLng(lat / count, lng / count));
}
}
};
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<div class="container" id="map" style="height:900px;"></div>
You have an error, because you have a wrong reference to this. I updated your Jsfiddle here: https://jsfiddle.net/k23auboq/ but I will also show you what went wrong down below.
init: function(lat, lng, places) {
// ...
var searchBox = new google.maps.places.SearchBox(document.getElementById('pac-input'));
google.maps.event.addListener(searchBox, 'places_changed', () => { // if you pass an arrow function here instead, 'this' will be taken from the outer context
searchBox.set('map', null);
var places = searchBox.getPlaces();
var bounds = new google.maps.LatLngBounds();
var i, place;
for (i = 0; place = places[i]; i++) {
var marker = new google.maps.Marker({
position: place.geometry.location
});
marker.bindTo('map', searchBox, 'map');
google.maps.event.addListener(marker, 'map_changed', function() {
if (!this.getMap()) {
this.unbindAll();
}
});
bounds.extend(place.geometry.location);
}
this.map.fitBounds(bounds); // this.map.fitBounds(...) now exists and works
searchBox.set('map', map);
this.map.setZoom(Math.min(map.getZoom(), 12));
});
// ...
},
To simplify it a bit take a look at the following examples:
function Test() {
this.map = 'test map';
this.callbackAction = function (callback) {
callback();
}
this.action = function () {
this.callbackAction(function () { // callback passed as 'function'
console.log(this.map);
});
}
return this;
}
const instance = new Test();
instance.action();
vs
function Test() {
this.map = 'test map';
this.callbackAction = function (callback) {
callback();
}
this.action = function () {
this.callbackAction(() => { // callback passed as 'ARROW function'
console.log(this.map);
});
}
return this;
}
const instance = new Test();
instance.action();
I have updated the answer which was provided above. The answer was technically correct, however using the bounds method will zoom the map down to level 1.
Here is a solution which should work for you. I have not been able to add a pin to the searched location. Hopefully somebody else may be able to help you there as I have only applied what I have learned using leaflet.js which is slightly different to Google maps, and am only still learning Javascript.
var GoogleMap = {
map: null,
markers: {},
init: function(lat, lng, places) {
var self = this;
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(lat, lng),
draggable: true
};
this.map = new google.maps.Map(document.getElementById('map'), mapOptions);
this.infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(10, 10)
});
// SEARCH STARTS HERE:
var searchBox = new google.maps.places.SearchBox(document.getElementById('pac-input'));
google.maps.event.addListener(searchBox, 'places_changed', () => {
searchBox.set('map', null);
var places = searchBox.getPlaces();
var bounds = new google.maps.LatLngBounds();
var i, place;
for (i = 0; place = places[i]; i++) {
var marker = new google.maps.Marker({
title: places.name,
zoom: 4,
position: place.geometry.location
});
marker.bindTo('map', searchBox, 'map');
google.maps.event.addListener(marker, 'map_changed', function() {
if (!this.getMap()) {
this.unbindAll();
}
bounds.extend(place.geometry.location);
});
marker.setPosition(place.geometry.location);
}
// ADDING PANTO FOR RETAINING THE MAP ZOOM LEVEL - INSTEAD OF SETZOOM :D
this.map.panTo(marker.getPosition());
});
// WHICH THEN ENABLES YOU TO REMOVE THIS:
// this.map.fitBounds(bounds);
// searchBox.set('map', map);
// this.map.setZoom(Math.min(map.getZoom(), 12));
// END OF SEARCH HERE.
i have problem.. i have canvas gmaps and i added some input-text for searching mark on gmaps canvas. The problem is this "input-text for searching" located outside the gmaps canvas, how to move "input-text for searching" inside the gmaps canvas?
here is the HTML and maps.JS
HTML :
<div class="form-group ">
<input id="map-search" class="controls" type="text" placeholder="Search Box" size="50%" >
<div id="map-canvas"></div>
</div>
JavaScript :
function initialize() {
var mapOptions, map, marker, searchBox, city,
infoWindow = '',
addressEl = document.querySelector( '#map-search' ),
latEl = document.querySelector( '.latitude' ),
longEl = document.querySelector( '.longitude' ),
element = document.getElementById( 'map-canvas' );
city = document.querySelector( '.reg-input-city' );
if($('#latspan' ).val() == null){
var latCar = -6.175350;
} else {
var latCar = $('#latspan').val();
}
if($('#lngspan').val() == null){
var longCar = 106.827164;
} else {
var longCar = $('#lngspan').val();
}
mapOptions = {
// How far the maps zooms in.
zoom: 800,
// Current Lat and Long position of the pin/
center: new google.maps.LatLng( latCar, longCar ),
// center : {
// lat: -34.397,
// lng: 150.644
// },
disableDefaultUI: false, // Disables the controls like zoom control on the map if set to true
scrollWheel: true, // If set to false disables the scrolling on the map.
draggable: true, // If set to false , you cannot move the map around.
// mapTypeId: google.maps.MapTypeId.HYBRID, // If set to HYBRID its between sat and ROADMAP, Can be set to SATELLITE as well.
// maxZoom: 11, // Wont allow you to zoom more than this
// minZoom: 9 // Wont allow you to go more up.
};
/**
* Creates the map using google function google.maps.Map() by passing the id of canvas and
* mapOptions object that we just created above as its parameters.
*
*/
// Create an object map with the constructor function Map()
map = new google.maps.Map( element, mapOptions ); // Till this like of code it loads up the map.
/**
* Creates the marker on the map
*
*/
marker = new google.maps.Marker({
position: mapOptions.center,
map: map,
// icon: 'http://pngimages.net/sites/default/files/google-maps-png-image-70164.png',
draggable: true,
animation: google.maps.Animation.DROP
});
/**
* Creates a search box
*/
searchBox = new google.maps.places.SearchBox( addressEl );
/**
* When the place is changed on search box, it takes the marker to the searched location.
*/
google.maps.event.addListener( searchBox, 'places_changed', function () {
var places = searchBox.getPlaces(),
bounds = new google.maps.LatLngBounds(),
i, place, lat, long, resultArray,
addresss = places[0].formatted_address;
for( i = 0; place = places[i]; i++ ) {
bounds.extend( place.geometry.location );
marker.setPosition( place.geometry.location ); // Set marker position new.
}
map.fitBounds( bounds ); // Fit to the bound
map.setZoom( 15 ); // This function sets the zoom to 15, meaning zooms to level 15.
// console.log( map.getZoom() );
lat = marker.getPosition().lat();
long = marker.getPosition().lng();
latEl.value = lat;
longEl.value = long;
resultArray = places[0].address_components;
// Get the city and set the city input value to the one selected
for( var i = 0; i < resultArray.length; i++ ) {
if ( resultArray[ i ].types[0] && 'administrative_area_level_2' === resultArray[ i ].types[0] ) {
citi = resultArray[ i ].long_name;
city.value = citi;
}
}
// Closes the previous info window if it already exists
if ( infoWindow ) {
infoWindow.close();
}
/**
* Creates the info Window at the top of the marker
*/
infoWindow = new google.maps.InfoWindow({
content: addresss
});
infoWindow.open( map, marker );
} );
/**
* Finds the new position of the marker when the marker is dragged.
*/
google.maps.event.addListener( marker, "dragend", function ( event ) {
var lat, long, address, resultArray, citi;
console.log( 'i am dragged' );
lat = marker.getPosition().lat();
long = marker.getPosition().lng();
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { latLng: marker.getPosition() }, function ( result, status ) {
if ( 'OK' === status ) { // This line can also be written like if ( status == google.maps.GeocoderStatus.OK ) {
address = result[0].formatted_address;
resultArray = result[0].address_components;
// Get the city and set the city input value to the one selected
// for( var i = 0; i < resultArray.length; i++ ) {
// if ( resultArray[ i ].types[0] && 'administrative_area_level_2' === resultArray[ i ].types[0] ) {
// citi = resultArray[ i ].long_name;
// console.log( citi );
// city.value = citi;
// }
// }
//addressEl.value = address;
latEl.value = lat;
longEl.value = long;
} else {
console.log( 'Geocode was not successful for the following reason: ' + status );
}
// Closes the previous info window if it already exists
if ( infoWindow ) {
infoWindow.close();
}
/**
* Creates the info Window at the top of the marker
*/
infoWindow = new google.maps.InfoWindow({
content: address
});
infoWindow.open( map, marker );
} );
});
}
Here is the picture on my gmaps canvas pict
thank you for being willing to read this thread, please help
Use map.controls with correct position values
var searchBox = new google.maps.places.SearchBox(document.getElementById('map-search'));
map.controls[google.maps.ControlPosition.TOP_CENTER].push(document.getElementById('map-search'));
I am taking an Advanced Custom Fields (ACF) Google Map Address and creating a Google Map with multiple markers and a singular InfoWindow. The contents of that InfoWindow are then swapped depending on which marker is active.
A PHP $location array is setup through ACF, and the javascript loops through and runs to the Google Maps API.
I want to open the InfoWindow by default when there is only one marker.
I have figured out how to determine if there is only one marker at the end of the new_map function…
if($markers.length == 1) {
console.log('yes');
}
But I am unsure of what to call/how to access the Google Maps API once the map has already been rendered.
I think my issue is scope related, as I've tried every combination of google.maps.event.trigger() and google.maps.Map.event.trigger(marker, 'click'); style functions I can think of.
Array
(
[address] => 123 Hamaker Rd, Manheim, PA, United States
[lat] => 40.1789636
[lng] => -76.3852963
)
<script type="text/javascript">
(function($) {
/*
* new_map
*
* This function will render a Google Map onto the selected jQuery element
*
* #type function
* #date 8/11/2013
* #since 4.3.0
*
* #param $el (jQuery element)
* #return n/a
*/
/*
* Modified from ACF Documentation, here are some links
* http://support.advancedcustomfields.com/forums/topic/multiple-post-points-on-google-maps/
* http://fancysquares.com/google-maps-infowindow-advanced-custom-fields-acf/
*/
function new_map( $el ) {
// var
var $markers = $el.find('.marker');
// vars
var args = {
zoom : 16,
center : new google.maps.LatLng(0, 0),
mapTypeId : google.maps.MapTypeId.ROADMAP,
scrollwheel : false,
mapTypeControl: false,
streetViewControl: false,
};
// create map
var map = new google.maps.Map( $el[0], args);
// add a markers reference
map.markers = [];
// add markers
$markers.each(function(){
add_marker( $(this), map );
});
// center map
center_map( map );
/* Conditional works to find if it only has one marker, but I can't figure out what to trigger */
//console.log($markers);
if($markers.length == 1) {
console.log('yes');
}
}
var infowindow = new google.maps.InfoWindow({
content : ''
});
/*
* add_marker
*
* This function will add a marker to the selected Google Map
*
* #type function
* #date 8/11/2013
* #since 4.3.0
*
* #param $marker (jQuery element)
* #param map (Google Map object)
* #return n/a
*/
function add_marker( $marker, map ) {
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map,
open : true
});
// add to array
map.markers.push( marker );
// if marker contains HTML, add it to an infoWindow
if( $marker.html() ) {
// show info window when marker is clicked & close other markers
google.maps.event.addListener(marker, 'click', function() {
//swap content of that singular infowindow
infowindow.setContent($marker.html());
infowindow.open(map, marker);
});
// close info window when map is clicked
google.maps.event.addListener(map, 'click', function(event) {
if (infowindow) {
infowindow.close();
}
});
}
}
/*
* center_map
*
* This function will center the map, showing all markers attached to this map
*
* #type function
* #date 8/11/2013
* #since 4.3.0
*
* #param map (Google Map object)
* #return n/a
*/
function center_map( map ) {
// vars
var bounds = new google.maps.LatLngBounds();
// loop through all markers and create bounds
$.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
// only 1 marker?
if( map.markers.length == 1 ) {
// set center of map
map.setCenter( bounds.getCenter() );
map.setZoom( 10 );
}
else {
// fit to bounds
map.fitBounds( bounds );
}
}
/* This function will render each map when the document is ready (page has loaded)
*
* #type function
* #date 8/11/2013
* #since 5.0.0
*
* #param n/a
* #return n/a
*/
// global var
var map = null;
$(document).ready(function(){
$('.acf-map').each(function(){
// create map
map = new_map( $(this) );
});
});
})(jQuery);
</script>
In the new_map function you can check the length of the array before adding the markers. if the length is 1 then pass a parameter indicating that showInfoWindow is true, else false.
var showInfoWindow = false;
if($markers.length == 1) {
showInfoWindow = true
}
// add markers
$markers.each(function(){
add_marker( $(this), map , showInfoWindow);
});
And then modify the add_marker code as follows
function add_marker( $marker, map, showInfoWindow ) {
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map,
open : true
});
// add to array
map.markers.push( marker );
// if marker contains HTML, add it to an infoWindow
if( $marker.html() ) {
// show info window when marker is clicked & close other markers
google.maps.event.addListener(marker, 'click', function() {
//swap content of that singular infowindow
infowindow.setContent($marker.html());
infowindow.open(map, marker);
});
// close info window when map is clicked
google.maps.event.addListener(map, 'click', function(event) {
if (infowindow) {
infowindow.close();
}
});
if(showInfoWindow)
{
infowindow.setContent($marker.html());
infowindow.open(map, marker);
}
}
}
I currently have a map that displays a marker on the users geolocation. I have a text input field set to Places Auto-complete. When a user searches a city name, a new marker is placed on the location. However, the old gelocation marker remains. I want to delete the old marker or move it so only 1 marker is on the map. How can I do this?
Here is my code:
<html>
<head>
<script>
var map;
function initialize() {
var mapOptions = {
zoom: 12
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Get GEOLOCATION
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
map.setCenter(pos);
var marker = new google.maps.Marker({
position: pos,
map: map,
draggable:true
});
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
map.setCenter(options.position);
}
// get places auto-complete when user type in location-text-box
var input = /** #type {HTMLInputElement} */(
document.getElementById('location-text-box'));
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
map: map,
anchorPoint: new google.maps.Point(0, -29),
draggable:true
});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17); // Why 17? Because it looks good.
}
marker.setIcon(/** #type {google.maps.Icon} */({
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(35, 35)
}));
marker.setPosition(place.geometry.location);
marker.setVisible(true);
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div>
<input type="text" id="location-text-box">
<div id="map-canvas"></div>
</div>
</body>
</html>
Make your marker global, and either hide it or move it to the new location
working code snippet:
var map;
var marker;
function initialize() {
var mapOptions = {
zoom: 12
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Get GEOLOCATION
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
map.setCenter(pos);
marker = new google.maps.Marker({
position: pos,
map: map,
draggable: true
});
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
map.setCenter(options.position);
marker = new google.maps.Marker({
position: options.position,
map: map,
draggable: true
});
}
// get places auto-complete when user type in location-text-box
var input = /** #type {HTMLInputElement} */
(
document.getElementById('location-text-box'));
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
marker = new google.maps.Marker({
map: map,
anchorPoint: new google.maps.Point(0, -29),
draggable: true
});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17); // Why 17? Because it looks good.
}
marker.setIcon( /** #type {google.maps.Icon} */ ({
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(35, 35)
}));
marker.setPosition(place.geometry.location);
marker.setVisible(true);
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places"></script>
<div style="height:100%; width:100%">
<input type="text" id="location-text-box" />
<div id="map-canvas"></div>
</div>
File javascript.js
function initialize() {
var mapOptions, map, marker, searchBox, city,
infoWindow = '',
addressEl = document.querySelector( '#map-search' ),
latEl = document.querySelector( '.latitude' ),
longEl = document.querySelector( '.longitude' ),
element = document.getElementById( 'map-canvas' );
city = document.querySelector( '.reg-input-city' );
mapOptions = {
// How far the maps zooms in.
zoom: 8,
// Current Lat and Long position of the pin/
center: new google.maps.LatLng( 23.0224, 72.5751 ),
// center : {
// lat: -34.397,
// lng: 150.644
// },
disableDefaultUI: false, // Disables the controls like zoom control on the map if set to true
scrollWheel: true, // If set to false disables the scrolling on the map.
draggable: true, // If set to false , you cannot move the map around.
// mapTypeId: google.maps.MapTypeId.HYBRID, // If set to HYBRID its between sat and ROADMAP, Can be set to SATELLITE as well.
// maxZoom: 11, // Wont allow you to zoom more than this
// minZoom: 9 // Wont allow you to go more up.
};
/**
* Creates the map using google function google.maps.Map() by passing the id of canvas and
* mapOptions object that we just created above as its parameters.
*
*/
// Create an object map with the constructor function Map()
map = new google.maps.Map( element, mapOptions ); // Till this like of code it loads up the map.
/**
* Creates the marker on the map
*
*/
marker = new google.maps.Marker({
position: mapOptions.center,
map: map,
draggable: true
});
/**
* Creates a search box
*/
searchBox = new google.maps.places.SearchBox( addressEl );
/**
* When the place is changed on search box, it takes the marker to the searched location.
*/
google.maps.event.addListener( searchBox, 'places_changed', function () {
var places = searchBox.getPlaces(),
bounds = new google.maps.LatLngBounds(),
i, place, lat, long, resultArray,
addresss = places[0].formatted_address;
for( i = 0; place = places[i]; i++ ) {
bounds.extend( place.geometry.location );
marker.setPosition( place.geometry.location ); // Set marker position new.
}
map.fitBounds( bounds ); // Fit to the bound
map.setZoom( 15 ); // This function sets the zoom to 15, meaning zooms to level 15.
// console.log( map.getZoom() );
lat = marker.getPosition().lat();
long = marker.getPosition().lng();
latEl.value = lat;
longEl.value = long;
resultArray = places[0].address_components;
// Get the city and set the city input value to the one selected
for( var i = 0; i < resultArray.length; i++ ) {
if ( resultArray[ i ].types[0] && 'administrative_area_level_2' === resultArray[ i ].types[0] ) {
citi = resultArray[ i ].long_name;
city.value = citi;
}
}
// Closes the previous info window if it already exists
if ( infoWindow ) {
infoWindow.close();
}
/**
* Creates the info Window at the top of the marker
*/
infoWindow = new google.maps.InfoWindow({
content: addresss
});
infoWindow.open( map, marker );
} );
/**
* Finds the new position of the marker when the marker is dragged.
*/
google.maps.event.addListener( marker, "dragend", function ( event ) {
var lat, long, address, resultArray, citi;
console.log( 'i am dragged' );
lat = marker.getPosition().lat();
long = marker.getPosition().lng();
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { latLng: marker.getPosition() }, function ( result, status ) {
if ( 'OK' === status ) { // This line can also be written like if ( status == google.maps.GeocoderStatus.OK ) {
address = result[0].formatted_address;
resultArray = result[0].address_components;
// Get the city and set the city input value to the one selected
for( var i = 0; i < resultArray.length; i++ ) {
if ( resultArray[ i ].types[0] && 'administrative_area_level_2' === resultArray[ i ].types[0] ) {
citi = resultArray[ i ].long_name;
console.log( citi );
city.value = citi;
}
}
addressEl.value = address;
latEl.value = lat;
longEl.value = long;
} else {
console.log( 'Geocode was not successful for the following reason: ' + status );
}
// Closes the previous info window if it already exists
if ( infoWindow ) {
infoWindow.close();
}
/**
* Creates the info Window at the top of the marker
*/
infoWindow = new google.maps.InfoWindow({
content: address
});
infoWindow.open( map, marker );
} );
});}
This map is to track multiple markers in a single view. The markers have to be updated every 5 seconds from the server.
My infowindow disappears after each refresh. There is a json request every 5 seconds. when i click on the marker, the infowindow appears and is cleared as soon as during next json call. Can i devise a method/any solution to make it appear(dynamic) even after refreshing.
var map1;
function map1_initialize( )
{
setInterval(function() {
var lat=new Array();var lng=new Array();var latlng = [];
$.getJSON('web_services/latlong.php?option=4&user_id=<?php echo $user_id;?>', function(json) {
$.each(json.Result.Data,function(i,gmap){
lat[i]=gmap.latitude;
lng[i]= gmap.longitude;
latlng[i] = new google.maps.LatLng(lat[i], lng[i]);
/*google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(json.Result.Data[i].alias);
console.log(json.Result.Data[i]);
infowindow.open(map, marker);
}
})(marker, i)); */
if ( google.maps.BrowserIsCompatible( ) )
{
map1 = new google.maps.Map2( document.getElementById( 'map' ) );
map1.addControl( new google.maps.LargeMapControl3D( ) );
map1.addControl( new google.maps.MenuMapTypeControl( ) );
map1.setCenter( new google.maps.LatLng( 0, 0 ), 0 );
for ( var i = 0; i < latlng.length; i++ )
{
var marker = new google.maps.Marker( latlng[ i ] );
map1.addOverlay( marker );
}
var latlngbounds = new google.maps.LatLngBounds( );
for ( var i = 0; i < latlng.length; i++ )
{
latlngbounds.extend( latlng[ i ] );
}
map1.setCenter( latlngbounds.getCenter( ), map1.getBoundsZoomLevel( latlngbounds ) );
GEvent.addListener(marker, 'click', function() {
// When clicked, open an Info Window
//alert(gmap.alias);
marker.openInfoWindowHtml(gmap.alias);
});
//gmap.alias is the alias name for the marker-loading it via json response
}
});
});
}, 5000);
}
With lot of R&D, i found out the answer!!!Hope this might help somebody...
var json=[];
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_canvas"), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
});
/*jQuery.extend({
getValues: function(url) {
var result = null;
$.getJSON('web_services/latlong.php?option=4&user_id=21', function(json) {
result = json;
});
return result;
}
});*/
jQuery.extend({
getValues: function(url) {
//setInterval(function() {
var result = null;
$.ajax({
url: url,
type: 'get',
dataType: 'json',
async: false,
success: function(data) {
result = data.Result.Data;
}
});
return result;
//},5000);
}
});
setInterval(function() {
var markers=$.getValues("web_services/latlong.php? option=4&user_id=21");console.log(markers);
// Define the list of markers.
// This could be generated server-side with a script creating the array.
/*var markers = [
{ lat: -33.85, lng: 151.05, name: "marker 1" },
{ lat: -33.90, lng: 151.10, name: "marker 2" },
{ lat: -33.95, lng: 151.15, name: "marker 3" },
{ lat: -33.85, lng: 151.15, name: "marker 4" }
];*/
// 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.latitude, data.longitude),
map: map,
title: data.alias
});
// 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.alias;
content.appendChild(title);
var infowindow = new google.maps.InfoWindow({
content: content
});
// Open the infowindow on marker click
google.maps.event.addListener(marker, "click", function() {
infowindow.open(map, marker);
});
// Handle the DOM ready event to create the StreetView panorama
// as it can only be created once the DIV inside the infowindow is loaded in the DOM.
/* google.maps.event.addListenerOnce(infowindow, "domready", function() {
var panorama = new google.maps.StreetViewPanorama(streetview, {
navigationControl: false,
enableCloseButton: false,
addressControl: false,
linksControl: false,
visible: true,
position: marker.getPosition()
});
});*/
}
// 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.latitude, data.longitude));
}
map.fitBounds(bounds);
},5000);//call every of 5 secs.
}