I'm writing some code with the Google Maps API, it works fine in all browsers (FF, IE9, Chrome) but IE8 or below, I have assigned the map to a global variable called Map, which gets populated but when the addMarker function gets called the Map global is null in IE8, but the addMarker function does work when I call it from the locator function, I have included all these functions below.
var GoogleMaps = {};
var Map = null;
var init = (function () {
"use strict";
var MapType = null;
var ZoomLevel = null;
var ControlPos = null;
var ControlSize = null;
var myLatLong = null;
var Geocoder;
var result = null;
GoogleMaps.setup = function (options) {
myLatLong = new google.maps.LatLng(24.886436490787712, -70.26855468754);
if (google.loader.ClientLocation) {
myLatLong = new google.maps.LatLng(
google.loader.ClientLocation.latitude,
google.loader.ClientLocation.longitude);
} else if (options.Lat !== null && options.Long !== null) {
options.Location = new google.maps.LatLng(options.Lat, options.Long);
} else {
// Else centre to UK
options.Location = new google.maps.LatLng(52.961875, -1.419433);
}
if (options.MapType.toUpperCase() === 'ROADMAP') {
MapType = google.maps.MapTypeId.ROADMAP;
} else if (options.MapType.toUpperCase() === 'TERRAIN') {
MapType = google.maps.MapTypeId.TERRAIN;
} else if (options.MapType.toUpperCase() === 'HYBRID') {
MapType = google.maps.MapTypeId.HYBRID;
} else {
MapType = google.maps.MapTypeId.SATELLITE;
}
// Check zoom level, if not set then set to zoom level 8.
if (options.ZoomLevel) {
ZoomLevel = options.ZoomLevel;
} else {
ZoomLevel = 8;
}
var mapOptions = {
center: myLatLong,
zoom: ZoomLevel,
mapTypeId: MapType
};
var mapDiv = document.getElementById('canvas');
// Map gets initiated here
window.Map = new google.maps.Map(mapDiv, mapOptions);
delete options.MapType;
delete options.Lat;
delete options.Long;
delete options.ZoomLevel;
};
GoogleMaps.addMarker = function (options) {
var Location = null;
var Animation = null;
var Title = null;
var Draggable = null;
var Content = null;
var InfoWindow = null;
var Flat = null;
var Clickable = null;
if (options.lat !== null && options.long !== null) {
Location = new google.maps.LatLng(options.lat, options.long);
;
} else {
Location = myLatLong;
}
if (typeof(options.position) !== "undefined") {
Location = options.position;
}
if (options.animation.toUpperCase() === 'BOUNCE') {
Animation = google.maps.Animation.BOUNCE;
} else if (options.animation.toUpperCase() === 'DROP') {
Animation = google.maps.Animation.DROP;
} else {
Animation = google.maps.Animation.NONE;
}
if (options.draggable !== null && options.draggable === 'true') {
Draggable = true;
} else {
Draggable = false;
}
if (options.title !== null) {
Title = options.title;
} else {
Title = null;
}
if (options.content !== null) {
Content = options.content;
InfoWindow = new google.maps.InfoWindow({
content: Content
});
}
if (options.flat !== null && options.flat === 'true') {
Flat = true;
} else {
Flat = false;
}
if (options.clickable !== null && options.clickable === 'true') {
Clickable = true;
} else {
Clickable = false;
}
// Gets used in this section
var Marker = new google.maps.Marker({
position: Location,
map: window.Map,
animation: Animation,
draggable: Draggable,
title: Title,
flat: Flat,
clickable: Clickable,
zIndex: 1
});
// and sets map here
Marker.setMap(window.Map);
if (options.content !== null) {
google.maps.event.addListener(Marker, 'click', function (e) {
InfoWindow.open(window.Map, this);
google.maps.event.addListener(window.Map, 'click', function (e) {
InfoWindow.close(window.Map, window.Marker);
});
});
}
google.maps.event.addListener(Marker, 'dragend', function (e) {
});
delete options.lat;
delete options.long;
delete options.animation;
delete options.title;
delete options.content;
delete options.flat;
delete options.draggable;
delete options.clickable;
};
GoogleMaps.Locator = function (result) {
var address = null;
Geocoder = new google.maps.Geocoder();
address = result;
Geocoder.geocode({ 'address': address }, function (response, status) {
if (status === google.maps.GeocoderStatus.OK) {
window.Map.setCenter(response[0].geometry.location);
var Location = new google.maps.LatLng(response[0].geometry.location.Xa, response[0].geometry.location.Ya);
var markerOptions = {
animation: "drop",
draggable: "true",
content: 'Hello World!',
title: "Hello",
position: Location
};
GoogleMaps.addMarker(markerOptions);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
};
Below is how I am calling the functions:
var markerOptions = {
lat: 52.48278,
long: -0.892089,
animation: "drop",
draggable: "true",
content: 'Hello World!',
title: "Click Me"
};
google.maps.event.addDomListener(window, 'load', function () { GoogleMaps.setMarker(markerOptions) });
google.maps.event.addDomListener(window, 'load', function () { GoogleMaps.Locator('London') });
Thanks for any help.
I resolved the problem like this.
<meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE7; IE=EmulateIE9″/>
Try changing this line in your setup
window.Map = new google.maps.Map(mapDiv, mapOptions);
to just
Map = new google.maps.Map(mapDiv, mapOptions);
This way you accessing the global variable declared.
when is GoogleMaps.setup called? Right now it looks like depending on the browser it can be called after functions attached by
google.maps.event.addDomListener(window, 'load', function () { ... });
and that's why map is not set when you call addMarker, but is already initialized when you receive callback from
Geocoder.geocode(...)
To fix this make sure that GoogleMaps.setup is called before addMarker.
IE8 has always meant trouble. :-) Try adding the following meta tag at the beginning of your <head> section:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
Description here:
http://blogs.msdn.com/b/ie/archive/2008/06/10/introducing-ie-emulateie7.aspx
Related
I think I'm doing something wrong in the variables or syntax... i don't know, help me to correct my code. (I'm using Leaflet for the map show)
Desired Behavior
The user should be able to see the BBOX entering the coordinates into the URL, for example:
.com/#013.0,052.0,013.5,052.5
I only care that the BBOX is shown, I don't care that the URL coordinates change when zooming or moving around the map.
My HTML
<!DOCTYPE html>
<html>
<header>
<link rel="stylesheet" href="style.css" />
<link
rel="stylesheet"
href="https://unpkg.com/leaflet#1.9.3/dist/leaflet.css"
integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="
crossorigin=""
/>
<script
src="https://unpkg.com/leaflet#1.9.3/dist/leaflet.js"
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
crossorigin=""
></script>
</header>
<body>
<div id="map"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="https://unpkg.com/leaflet#1.0.1/dist/leaflet.js"></script>
<script src="leaflet-hash.js"></script>
<script>
var map = L.map("map").setView([42, 12], 4);
// var hash = new L.hash(map);
var urlhash = window.location.hash.substring(1).split("/");
var boundingBox = "";
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 22,
minZoom: 1,
continuousWorld: false,
noWrap: false,
attribution:
'Data by OpenStreetMap, under ODbL.',
detectRetina: false,
}).addTo(map);
var bboxField = L.control({
position: "bottomleft",
});
bboxField.onAdd = function (map) {
//create div container for control
var div = L.DomUtil.create("div", "myButtonBar");
//prevent mouse events from propagating through to the map
L.DomEvent.disableClickPropagation(div);
//create custom radio buttons
div.innerHTML =
'BBOX (Left (LON) ,Bottom (LAT), Right (LON), Top (LAT), comma separated, with or without decimal point):<br><input type="text" id="bbox_field"/><button id="setDimensions">Display BBOX</button><button id="remove">Remove</button>';
return div;
};
bboxField.addTo(map);
$(".myButtonBar").css("font-weight", "bold");
if (urlhash[0] !== "") {
$("#bbox_field").val(urlhash[0]);
draw_bbox(urlhash[0]);
}
function draw_bbox(box) {
var myarray = box.split(",");
var bounds = [
[myarray[1], myarray[0]],
[myarray[3], myarray[2]],
];
boundingBox = L.rectangle(bounds, { color: "#ff7800", weight: 1 });
map.removeLayer(boundingBox);
boundingBox.addTo(map);
map.fitBounds(boundingBox.getBounds());
map.setZoom(map.getZoom() - 1);
}
$("#setDimensions").click(function () {
draw_bbox($("#bbox_field").val());
});
$("#bbox_field").keyup(function (event) {
if (event.keyCode === 13) {
$("#setDimensions").click();
}
});
// console.log(bbox)
$("#remove").click(function () {
map.removeLayer(boundingBox);
});
</script>
</body>
</html>
Leaflet Hash Plugin Code
(function(window) {
var HAS_HASHCHANGE = (function() {
var doc_mode = window.documentMode;
return ('onhashchange' in window) &&
(doc_mode === undefined || doc_mode > 7);
})();
L.hash = function(map) {
this.onHashChange = L.Util.bind(this.onHashChange, this);
if (map) {
this.init(map);
}
};
L.hash.parseHash = function(hash) {
if(hash.indexOf('#') === 0) {
hash = hash.substr(1);
}
var args = hash.split("/");
if (args.length == 3) {
var zoom = parseInt(args[0], 10),
lat = parseFloat(args[1]),
lon = parseFloat(args[2]);
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
return false;
} else {
return {
center: new L.LatLng(lat, lon),
zoom: zoom
};
}
} else {
return false;
}
};
L.hash.formatHash = function(map) {
var center = map.getCenter(),
zoom = map.getZoom(),
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
return "#" + [zoom,
center.lat.toFixed(precision),
center.lng.toFixed(precision)
].join("/");
},
L.hash.prototype = {
map: null,
lastHash: null,
parseHash: L.hash.parseHash,
formatHash: L.hash.formatHash,
init: function(map) {
this.map = map;
// reset the hash
this.lastHash = null;
this.onHashChange();
if (!this.isListening) {
this.startListening();
}
},
removeFrom: function(map) {
if (this.changeTimeout) {
clearTimeout(this.changeTimeout);
}
if (this.isListening) {
this.stopListening();
}
this.map = null;
},
onMapMove: function() {
// bail if we're moving the map (updating from a hash),
// or if the map is not yet loaded
if (this.movingMap || !this.map._loaded) {
return false;
}
var hash = this.formatHash(this.map);
if (this.lastHash != hash) {
location.replace(hash);
this.lastHash = hash;
}
},
movingMap: false,
update: function() {
var hash = location.hash;
if (hash === this.lastHash) {
return;
}
var parsed = this.parseHash(hash);
if (parsed) {
this.movingMap = true;
this.map.setView(parsed.center, parsed.zoom);
this.movingMap = false;
} else {
this.onMapMove(this.map);
}
},
// defer hash change updates every 100ms
changeDefer: 100,
changeTimeout: null,
onHashChange: function() {
// throttle calls to update() so that they only happen every
// `changeDefer` ms
if (!this.changeTimeout) {
var that = this;
this.changeTimeout = setTimeout(function() {
that.update();
that.changeTimeout = null;
}, this.changeDefer);
}
},
isListening: false,
hashChangeInterval: null,
startListening: function() {
this.map.on("moveend", this.onMapMove, this);
if (HAS_HASHCHANGE) {
L.DomEvent.addListener(window, "hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
this.hashChangeInterval = setInterval(this.onHashChange, 50);
}
this.isListening = true;
},
stopListening: function() {
this.map.off("moveend", this.onMapMove, this);
if (HAS_HASHCHANGE) {
L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
}
this.isListening = false;
}
};
L.hash = function(map) {
return new L.hash(map);
};
L.map.prototype.addHash = function() {
this._hash = L.hash(this);
};
L.map.prototype.removeHash = function() {
this._hash.removeFrom();
};
})(window);
I am customizing the WordPress Geodirectory plugin's Google Maps API functionality to store the user set/selected map type, marker, and zoom level in local storage.
I have the user set map type and zoom level functionality working, but am struggling with implementing the selected map marker.
How would I go about storing and retrieving the selected map marker from local storage and displaying it on the map when the user clicks/taps back in the browser?
My existing custom code is included below:
const zoomChangeListener = google.maps.event.addListener(jQuery.goMap.map, 'zoom_changed', function (event) {
storeUserZoom();
});
loadUserZoom();
function storeUserZoom() {
let zoom = jQuery.goMap.map.getZoom();
localStorage.setItem( 'zoom', zoom);
// console.log('Storing zoom level: ' + zoom);
}
function loadUserZoom() {
let zoom = localStorage.getItem( 'zoom' );
if (localStorage.getItem( 'zoom' )) {
jQuery.goMap.map.setZoom(parseInt(zoom));
// console.log('Local storage zoom level: ' + zoom);
}
}
const mapTypeChangeListener = google.maps.event.addListener(jQuery.goMap.map, 'maptypeid_changed', function (event) {
storeUserMapType();
});
loadUserMapType();
function storeUserMapType() {
let mapType = jQuery.goMap.map.getMapTypeId();
localStorage.setItem( 'maptype', mapType);
// console.log('Map type changed: ' + mapType);
}
function loadUserMapType() {
let mapType = localStorage.getItem( 'maptype' );
if (localStorage.getItem( 'maptype' )) {
jQuery.goMap.map.setMapTypeId(mapType);
// console.log('Loading map type: ' + mapType);
}
}
function storeUserMarker(item, map_canvas) {
let markerId, markerTitle, markerIcon, markerPosition;
markerId = item.id;
markerTitle = item.title;
markerIcon = item.icon = {
url: item.icon,
// scaledSize: new google.maps.Size(resizeW, resizeH),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(0, 0)
};
// markerIcon = item.icon;
// console.log(markerIcon);
markerPosition = item.position;
localStorage.setItem( 'id', markerId );
localStorage.setItem( 'title', markerTitle );
localStorage.setItem( 'icon', JSON.stringify(markerIcon) );
localStorage.setItem( 'position', JSON.stringify(markerPosition));
}
function loadUserMarker(item, map_canvas) {
let markerId = localStorage.getItem( 'id' );
let markerTitle = localStorage.getItem( 'title' );
let markerIcon = JSON.parse(localStorage.getItem( 'icon' ));
let markerPosition = JSON.parse(localStorage.getItem( 'position' ));
if (localStorage.getItem( 'position' )) {
let marker = {
id: markerId,
title: markerTitle,
icon: markerIcon,
position: markerPosition,
visible: true,
clickable: true
};
gd_infowindow.open(jQuery.goMap.map, marker);
}
}
Geodirectory initMap function simplified with my additions marked as custom code
function initMap(map_options, marker) {
/** Custom code begin **/
google.maps.event.addListener(jQuery.goMap.map, 'tilesloaded', function() {
loadUserMarker(marker);
});
/** Custom code end **/
}
Geodirectory create_marker function with my additions marked as custom code
// create the marker and set up the event window
function create_marker(item, map_canvas) {
if (window.gdMaps == 'osm') {
return create_marker_osm(item, map_canvas);
}
var map_options = eval(map_canvas);
jQuery("#" + map_canvas).goMap();
gd_infowindow = (typeof google !== 'undefined' && typeof google.maps !== 'undefined') ? new google.maps.InfoWindow({
maxWidth: 200
}) : null;
if (item.lt && item.ln) {
var marker_id, title, icon, cs;
marker_id = item['m'];
title = geodir_htmlEscape(item['t']);
cs = item['cs'];
icon = item['icon'] ? item['icon'] : geodir_params.default_marker_icon;
iconW = item['w'] ? parseFloat(item['w']) : 0;
iconH = item['h'] ? parseFloat(item['h']) : 0;
iconMW = geodir_params.marker_max_width ? parseFloat(geodir_params.marker_max_width) : 0;
iconMH = geodir_params.marker_max_height ? parseFloat(geodir_params.marker_max_height) : 0;
/* Some svg files has dimensions with different unit */
if (geodir_params.resize_marker && ( iconW < iconMW || iconH < iconMH ) && icon.substr((icon.lastIndexOf('.')+1)).toLowerCase() == 'svg') {
iconW = iconW * 10;
iconH = iconH * 10;
}
if (geodir_params.resize_marker && iconW > 5 && iconH > 5 && ((iconMW > 5 && iconW > iconMW) || (iconMH > 5 && iconH > iconMH))) {
resizeW = iconW;
resizeH = iconH;
resize = false;
if (iconMH > 5 && resizeH > iconMH) {
_resizeH = iconMH;
_resizeW = Math.round(((_resizeH * resizeW) / resizeH) * 10) / 10;
resizeW = _resizeW;
resizeH = _resizeH;
resize = true;
}
if (iconMW > 5 && resizeW > iconMW) {
_resizeW = iconMW;
_resizeH = Math.round(((_resizeW * resizeH) / resizeW) * 10) / 10;
resizeW = _resizeW;
resizeH = _resizeH;
resize = true;
}
if (resize && resizeW > 5 && resizeH > 5) {
icon = {
url: icon,
scaledSize: new google.maps.Size(resizeW, resizeH),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point((Math.round(resizeW / 2)), resizeH)
};
}
}
var latlng = new google.maps.LatLng(item.lt, item.ln);
var marker = jQuery.goMap.createMarker({
id: marker_id,
title: title,
position: latlng,
visible: true,
clickable: true,
icon: icon,
label: cs,
zIndex: (item.zIndex ? item.zIndex : 0),
zIndexOrg: (item.zIndexOrg ? item.zIndexOrg : 0)
});
bounds.extend(latlng);
// Adding a click event to the marker
google.maps.event.addListener(marker, 'spider_click', function() { // 'click' => normal, 'spider_click' => Overlapping Marker Spiderfier
/** Custom code begin **/
storeUserMarker(marker);
/** Custom code end **/
var marker_url = map_options.map_marker_ajax_url;
is_zooming = true;
jQuery("#" + map_canvas).goMap();
var preview_query_str = '';
if (item.post_preview) {
preview_query_str = '&post_preview=' + item.post_preview;
}
marker_url = marker_url + '' + item.m;
post_data = marker_url.indexOf('?') === -1 ? '?' : '&';
post_data += '_wpnonce=' + map_options._wpnonce;
if (map_options.bubble_size) {
post_data += '&small=1';
}
if (map_options.map_marker_url_params) {
post_data += map_options.map_marker_url_params;
}
var loading = '<div id="map_loading"></div>';
gd_infowindow.open(jQuery.goMap.map, marker);
gd_infowindow.setContent(loading);
jQuery.ajax({
type: "GET",
url: marker_url + post_data,
cache: false,
dataType: "json",
error: function(xhr, error) {
alert(error);
},
success: function(response) {
jQuery("#" + map_canvas).goMap();
html = typeof response == 'object' && response.html ? geodir_htmlEscape(response.html) : '';
gd_infowindow.setContent(html);
gd_infowindow.open(jQuery.goMap.map, marker);
setTimeout(function() {
jQuery(document.body).trigger('geodir_map_infowindow_open', [{
map: 'google',
canvas: map_canvas,
content: html
}]);
}, 100);
// give the map 1 second to reposition before allowing it to reload
setTimeout(function() {
is_zooming = false;
}, 1000);
}
});
return;
});
// Overlapping Marker Spiderfier
jQuery.goMap.oms.addMarker(marker);
// Adding a visible_changed event to the marker
google.maps.event.addListener(marker, 'visible_changed', function() {
gd_infowindow.close(jQuery.goMap.map, marker);
});
return true;
} else {
//no lat & long, return no marker
return false;
}
}
The loadUserMarker(); function returns [object Object] in the console when executed.
The functionality can be tested on the staging site. Try clicking on a map marker, visiting the individual page, then return to the map with the browser back button.
Update
I am receiving the following error when trying to load the previously clicked/tapped map marker: Uncaught (in promise) TypeError: b.anchor.get is not a function. I know it relates to anchoring the info window to the map marker, but I am not sure how to correct it.
My storeUserMarker function has been updated to make item.icon into an object that includes the marker URL, origin, and anchor.
How would I go about getting the marker's anchor data so the info window can be displayed?
Can any one help me out ArcGIS JavaScript API NAVIGATION TOOLS to migrating from 3X to 4X (4.24) version. facing some of the challenges while doing the navigation tool migration.
please suggest me the solution.
var _prevExtent, _preExtent,
_currentvExtent, _extentHistory
require([
"esri/Map",
"esri/views/MapView",
"esri/core/watchUtils",
"dojo/dom-class",
"dojo/dom",
"dojo/on"
], function(Map, MapView, watchUtils, domClass, dom, on) {
_prevExtent = false;
_preExtent = null;
_currentExtent = null;
_extentHistory = [];
_extentHistoryIndx = 0;
_nextExtent = false;
var map = new Map({
basemap: "streets"
});
var view = new MapView({
container: "viewDiv",
map: map,
zoom: 4,
center: [15, 65] // longitude, latitude
});
watchUtils.whenTrue(view, "ready", function(){
initToolbar();
watchUtils.whenOnce(view, "extent", function(){
watchUtils.when(view, 'stationary', function(evt){
if(evt){
extentChangeHandler(view.extent);
}
});
});
});
function extentChangeHandler(evt) {
if(_prevExtent || _nextExtent){
_currentExtent = evt;
}else{
_preExtent = _currentExtent;
_currentExtent = evt;
_extentHistory.push({
preExtent: _preExtent,
currentExtent: _currentExtent
});
_extentHistoryIndx = _extentHistory.length - 1;
}
_prevExtent = _nextExtent = false;
extentHistoryChange();
}
function extentHistoryChange() {
if(_extentHistory.length === 0 || _extentHistoryIndx === 0 ){
domClass.add(dom.byId("zoomprev"), "disabled");
} else {
domClass.remove(dom.byId("zoomprev"), "disabled");
}
if(_extentHistory.length === 0 || _extentHistoryIndx === _extentHistory.length - 1){
domClass.add(dom.byId("zoomnext"), "disabled");
} else {
domClass.remove(dom.byId("zoomnext"), "disabled");
}
}
function initToolbar() {
on(dom.byId("zoomnext"), "click", function() {
_nextExtent = true;
_extentHistoryIndx++;
view.goTo(_extentHistory[_extentHistoryIndx].currentExtent);
});
on(dom.byId("zoomprev"), "click", function() {
if(_extentHistory[_extentHistoryIndx].preExtent){
_prevExtent = true;
view.goTo(_extentHistory[_extentHistoryIndx].preExtent);
_extentHistoryIndx--;
}
});
}
view.ui.add("tools", "top-right");
});
Can anyone tell me why the map does not load centered the first time it loads? It works fine when I do a second search, but never loads up correctly the first time.
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"
var directionsDisplay;
var directionsService;
var geocoder;
var currentAddress = 'placeholder';
var tabCount = 0;
var altRouteCount = 0;
var savedRoutes;
$(document).ready(function(){
$('#message-container').hide (0);
document.getElementById('sidebar').className = 'sidebar-hidden';
// Keeps form pointAB from refreshing the page.
$('#pointAB').on('submit', function (e) {
e.preventDefault();
});
$('#tabs').tab();
$('#tabs a').click( function (e) {
e.preventDefault();
$(this).tab('show');
});
$('#sidebar #togglebtn').click(toggleSidebar);
$('#deletes').click(deleteTabs);
$('#routeChange').click(function () {
var index = $('#routeChange').data('route');
index = (index+1)%altRouteCount;
deleteTabs();
printRoute (savedRoutes, index);
$('#routeChange').data('route', index);
});
// Call Google Direction
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
// Google Autocomplete
var start_input = document.getElementById('start');
var end_input = document.getElementById('end');
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(40.532980, -74.118551),
new google.maps.LatLng(40.895218, -73.735403)
);
// Bounds right now only restrict country
var start_autocomplete = new google.maps.places.Autocomplete((start_input),{
// bounds: {sw:new google.maps.LatLng(40.895218, -73.735403), ne:new google.maps.LatLng(40.532980, -74.118551)},
componentRestrictions: {country: 'us'}
}
);
var end_autocomplete = new google.maps.places.Autocomplete((end_input),{
// bounds: {sw:new google.maps.LatLng(40.895218, -73.735403), ne:new google.maps.LatLng(40.532980, -74.118551)},
componentRestrictions: {country: 'us'}
}
);
start_autocomplete.setBounds(bounds);
end_autocomplete.setBounds(bounds);
// Initial map
function initialize() {
var map;
var pos;
// Default pos for map will be center of Manhattan
if(!pos){
pos = new google.maps.LatLng(40.784148400000000000, -73.966140699999980000);
}
var mapOptions = {
zoom: 13
};
getAddress();
// Draw Map
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
map.setCenter(pos);
// Google Direction text route
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directions-panel'));
//Needed to resize maps
google.maps.event.addDomListener (map, 'idle', function(){
google.maps.event.trigger (map, 'resize');
});
}
// Load Map
google.maps.event.addDomListener(window, 'load', initialize);
});
/************************************************
Site Navigational Elements
************************************************/
function toggleSidebar() {
var state = $('#sidebar').data('toggle');
if (state == 'hidden') {
document.getElementById('sidebar').className = "sidebar-appear";
$('#sidebar').data('toggle', 'shown');
}
else if (state == 'shown') {
document.getElementById('sidebar').className = "sidebar-hidden";
$('#sidebar').data('toggle', 'hidden');
}
};
function nextSlide() {
$('#navCarousel').carousel('next');
};
function prevSlide(){
$('#navCarousel').carousel('prev');
};
/************************************************
UI Messages
************************************************/
function hideMessage(){
$('#init-message').hide(1000);
};
function pushMessage (messageType, message) {
$('#message-container').hide (0);
if (messageType == 'error') {
document.getElementById('message-container').className = "alert alert-danger";
document.getElementById('icon').className = "glyphicon glyphicon-remove-sign";
}
else if (messageType == 'success') {
document.getElementById('message-container').className = "alert alert-success";
document.getElementById('icon').className = "glyphicon glyphicon-ok-sign";
}
else if (messageType == 'warn') {
document.getElementById('message-container').className = "alert alert-warning";
document.getElementById('icon').className = "glyphicon glyphicon-exclaimation-sign";
}
else {
//Congrats. Senpai has noticed your ability to break shit. Rejoice.
console.error ("Please check your messageType.")
}
$('#message').text(message);
$('#message-container').show (1000);
};
/************************************************
Information Retrieval
************************************************/
// Get current location button function
function getAddress(callback){
geocoder = new google.maps.Geocoder();
// If geolocation available, get position
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {timeout:60000,maximumAge:60000});
}
//Else, browser doesn't support geolocaiton
else {
pushMessage ('error', 'Your browser doesn\'t support geolocation.');
console.log("Browser doesn't support geolocaiton");
}
// Optional callback
if (callback){
callback();
}
};
function successCallback(position){
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
//Reverse geocoding for current location
geocoder.geocode({'latLng': pos}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results.length != 0) {
currentAddress = results[0].formatted_address;
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
};
function errorCallback(){
};
fillAddress = function() {
if (currentAddress != 'placeholder') {
$('#start').val (currentAddress);
pushMessage ('success', "Got your current location!");
}
else {
pushMessage ('warn', 'Please share your location to use this feature.');
}
};
// Set route and request direction result
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
if (start == '' && end == '') {
pushMessage ('error', "Please fill in your current location and destination.");
start='';
end='';
return;
}
else if (start == '') {
pushMessage ('error', "Please fill in your current location.");
start='';
end='';
return;
}
else if (end == '') {
pushMessage ('error', "Please fill in your destination.");
start='';
end='';
return;
}
else {
start += ' new york city';
end += ' new york city';
}
var request = {
origin: start,
destination: end,
provideRouteAlternatives: true,
travelMode: google.maps.TravelMode.TRANSIT
};
deleteTabs();
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
altRouteCount = response.routes.length;
savedRoutes = response;
printRoute (savedRoutes, 0);
//Move to next slide when directions have been retrieved.
$('#navCarousel').carousel('next');
//Disable loading icon pseudocode.
//$('#loadingIcon').hide(300);
savedRoutes = response;
}
else {
//If DirectionsStatus.NOT_FOUND
//or DirectionsStatus.ZERO_RESULTS
pushMessage ('error', 'No directions found.');
}
});
};
function printRoute (routeObj, routeNo) {
// Get route object
var thisRoute = routeObj.routes[routeNo].legs[0];
for (var i = 0; i < thisRoute.steps.length; i++) {
// Find all possible transit
if (typeof thisRoute.steps[i].transit != 'undefined'
&& thisRoute.steps[i].transit.line.vehicle.type == "SUBWAY") {
trainTab (thisRoute.steps[i]);
}
}
}
//Get details from Maps API json object
function getTransitDetail(obj, tabNo){
var parent='';
if (tabNo) {
parent='div#tab'+tabNo+' ';
}
$(parent+'#train').text(obj.transit.line.short_name + " Train");
$(parent+'#train-stop-depart').text(obj.transit.departure_stop.name);
$(parent+'#train-stop-end').text(obj.transit.arrival_stop.name);
$(parent+'#num-stop').text(obj.transit.num_stops + " Stops");
$(parent+'#arrival_time').text(obj.transit.arrival_time.text);
$(parent+'#departure_time').text(obj.transit.departure_time.text);
$(parent+'#distance').text(obj.distance.text);
$(parent+'#duration').text(obj.duration.text);
};
// Get current time from device
function getTime(){
var currentdate = new Date();
var datetime = currentdate.getDate() + "/"
+ (currentdate.getMonth()+1) + "/"
+ currentdate.getFullYear() + " # "
+ currentdate.getHours() + ":"
+ currentdate.getMinutes() + ":"
+ currentdate.getSeconds();
return datetime;
};
function makeNewTab() {
var prevTab = 'tab' + tabCount;
tabCount++;
var newTab = 'tab' + tabCount;
console.log ('New Tab.');
//Adds tab to nav bar
$('#routeChange').before('<li>TAG LABEL</li>');
//Adds contents of tab
$('div.tab-content #'+prevTab).after('<div id="'+newTab+'"></div>');
$('#'+newTab).addClass("tab-pane");
};
function deleteTabs() {
var thisTab;
while (tabCount >= 1) {
thisTab = 'tab' + tabCount;
//Remove tab from nav bar
$('ul#tabs li a[href="#'+thisTab+'"]').remove();
//Remove contents of tab
$('#'+thisTab).remove();
tabCount--;
}
tabCount = 1;
$('#tabs a:first').tab('show');
};
function trainTab (obj) {
makeNewTab();
$('ul#tabs li a[href="#tab'+tabCount+'"]').text(obj.transit.line.short_name);
$('#tab'+tabCount).append (
'<div id="station-info" class="col-xs-11 col-xs-height col-sm-12 col-sm-height">\
<p>Station Info:</p>\
<p id="train"></p>\
<p id="train-stop-depart"></p>\
<p id="train-stop-end"></p>\
<p id="num-stop"></p>\
<p id="arrival_time"></p>\
<p id="departure_time"></p>\
<p id="distance"></p>\
<p id="duration"></p>\
<!-- <%= link_to "an article", #station%> -->\
</div>');
getTransitDetail (obj, tabCount);
};
Is it because of the order of my code? I tried playing around with the order and could not find a solution. Any help would be appreciated. Thanks in advance!
I am not a programmer or a developer. I am facing a problem that the google map infobox not display when they are in exact same location, (geocodezip) have a very good solution, however I don't know how to modify my code.
This is my code
(function ($) {
var settings;
var element;
var map;
var markers = new Array();
var markerCluster;
var clustersOnMap = new Array();
var clusterListener;
var methods = {
init: function (options) {
element = $(this);
var defaults = $.extend({
enableGeolocation: false,
pixelOffsetX : -145,
pixelOffsetY : -200
});
settings = $.extend({}, defaults, options);
google.maps.Map.prototype.setCenterWithOffset = function (latlng, offsetX, offsetY) {
var map = this;
var ov = new google.maps.OverlayView();
ov.onAdd = function () {
var proj = this.getProjection();
var aPoint = proj.fromLatLngToContainerPixel(latlng);
aPoint.x = aPoint.x + offsetX;
aPoint.y = aPoint.y + offsetY;
map.setCenter(proj.fromContainerPixelToLatLng(aPoint));
}
ov.draw = function () {
};
ov.setMap(this);
};
google.maps.visualRefresh = true;
google.maps.event.addDomListener(window, 'load', loadMap);
if (settings.filterForm && $(settings.filterForm).length !== 0) {
$(settings.filterForm).submit(function (e) {
var form = $(this);
var action = $(this).attr('action');
$.ajax({
type : 'GET',
url : action,
data : form.serialize(),
success: function (data) {
element.aviators_map('removeMarkers');
element.aviators_map('addMarkers', {
locations: eval(data.locations),
types : eval(data.types),
contents : eval(data.contents)
});
}
});
e.preventDefault();
});
}
if (options.callback) {
options.callback();
}
return $(this);
},
removeMarkers: function () {
for (i = 0; i < markers.length; i++) {
markers[i].infobox.close();
markers[i].marker.close();
markers[i].setMap(null);
}
markerCluster.clearMarkers();
$.each(clustersOnMap, function (index, cluster) {
cluster.cluster.close();
});
clusterListener.remove();
},
addMarkers: function (options) {
markers = new Array();
settings.locations = options.locations;
settings.contents = options.contents;
settings.types = options.types;
renderElements();
}
}
$.fn.aviators_map = function (method) {
// Method calling logic
if (methods[method]) {
return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on Aviators Map');
}
};
function loadMap() {
var mapOptions = {
zoom : settings.zoom,
mapTypeId : google.maps.MapTypeId.ROADMAP,
scrollwheel : false,
draggable : true,
mapTypeControl : false,
panControl : false,
zoomControl : true,
zoomControlOptions: {
style : google.maps.ZoomControlStyle.SMALL,
position: google.maps.ControlPosition.LEFT_BOTTOM
}
};
if (settings.enableGeolocation) {
if (navigator.geolocation) {
browserSupportFlag = true;
navigator.geolocation.getCurrentPosition(function (position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(initialLocation);
}, function () {
mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
});
} else {
browserSupportFlag = false;
mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
}
} else {
mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
}
map = new google.maps.Map($(element)[0], mapOptions);
var dragFlag = false;
var start = 0, end = 0;
function thisTouchStart(e) {
dragFlag = true;
start = e.touches[0].pageY;
}
function thisTouchEnd() {
dragFlag = false;
}
function thisTouchMove(e) {
if (!dragFlag) {
return
}
end = e.touches[0].pageY;
window.scrollBy(0, ( start - end ));
}
var el = $('#map')[0];
if (el.addEventListener) {
el.addEventListener('touchstart', thisTouchStart, true);
el.addEventListener('touchend', thisTouchEnd, true);
el.addEventListener('touchmove', thisTouchMove, true);
} else if (el.attachEvent){
el.attachEvent('touchstart', thisTouchStart);
el.attachEvent('touchend', thisTouchEnd);
el.attachEvent('touchmove', thisTouchMove);
}
google.maps.event.addListener(map, 'zoom_changed', function () {
$.each(markers, function (index, marker) {
marker.infobox.close();
marker.infobox.isOpen = false;
});
});
renderElements();
$('.infobox .close').live('click', function () {
$.each(markers, function (index, marker) {
marker.infobox.close();
marker.infobox.isOpen = false;
});
});
}
function isClusterOnMap(clustersOnMap, cluster) {
if (cluster === undefined) {
return false;
}
if (clustersOnMap.length == 0) {
return false;
}
var val = false;
$.each(clustersOnMap, function (index, cluster_on_map) {
if (cluster_on_map.getCenter() == cluster.getCenter()) {
val = cluster_on_map;
}
});
return val;
}
function addClusterOnMap(cluster) {
// Hide all cluster's markers
$.each(cluster.getMarkers(), (function () {
if (this.marker.isHidden == false) {
this.marker.isHidden = true;
this.marker.close();
}
}));
var newCluster = new InfoBox({
markers : cluster.getMarkers(),
draggable : true,
content : '<div class="clusterer"><div class="clusterer-inner">' + cluster.getMarkers().length + '</div></div>',
disableAutoPan : true,
pixelOffset : new google.maps.Size(-21, -21),
position : cluster.getCenter(),
closeBoxURL : "",
isHidden : false,
enableEventPropagation: true,
pane : "mapPane"
});
cluster.cluster = newCluster;
cluster.markers = cluster.getMarkers();
cluster.cluster.open(map, cluster.marker);
clustersOnMap.push(cluster);
}
function renderElements() {
$.each(settings.locations, function (index, location) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(location[0], location[1]),
map : map,
icon : settings.transparentMarkerImage
});
marker.infobox = new InfoBox({
content : settings.contents[index],
disableAutoPan : false,
maxWidth : 0,
pixelOffset : new google.maps.Size(settings.pixelOffsetX, settings.pixelOffsetY),
zIndex : null,
closeBoxURL : "",
infoBoxClearance : new google.maps.Size(1, 1),
position : new google.maps.LatLng(location[0], location[1]),
isHidden : false,
pane : "floatPane",
enableEventPropagation: false
});
marker.infobox.isOpen = false;
marker.marker = new InfoBox({
draggable : true,
content : '<div class="marker ' + settings.types[index] + '"><div class="marker-inner"></div></div>',
disableAutoPan : true,
pixelOffset : new google.maps.Size(-21, -58),
position : new google.maps.LatLng(location[0], location[1]),
closeBoxURL : "",
isHidden : false,
pane : "floatPane",
enableEventPropagation: true
});
marker.marker.isHidden = false;
marker.marker.open(map, marker);
markers.push(marker);
google.maps.event.addListener(marker, 'click', function (e) {
var curMarker = this;
$.each(markers, function (index, marker) {
// if marker is not the clicked marker, close the marker
if (marker !== curMarker) {
marker.infobox.close();
marker.infobox.isOpen = false;
}
});
if (curMarker.infobox.isOpen === false) {
curMarker.infobox.open(map, this);
curMarker.infobox.isOpen = true;
map.setCenterWithOffset(curMarker.getPosition(), 100, -120);
} else {
curMarker.infobox.close();
curMarker.infobox.isOpen = false;
}
});
});
markerCluster = new MarkerClusterer(map, markers, {
gridSize: 40,
styles: [
{
height : 42,
url : settings.transparentClusterImage,
width : 42,
textColor: 'transparent'
}
]
});
clustersOnMap = new Array();
clusterListener = google.maps.event.addListener(markerCluster, 'clusteringend', function (clusterer) {
var availableClusters = clusterer.getClusters();
var activeClusters = new Array();
$.each(availableClusters, function (index, cluster) {
if (cluster.getMarkers().length > 1) {
activeClusters.push(cluster);
}
});
$.each(availableClusters, function (index, cluster) {
if (cluster.getMarkers().length > 1) {
var val = isClusterOnMap(clustersOnMap, cluster);
if (val !== false) {
val.cluster.setContent('<div class="clusterer"><div class="clusterer-inner">' + cluster.getMarkers().length + '</div></div>');
val.markers = cluster.getMarkers();
$.each(cluster.getMarkers(), (function (index, marker) {
if (marker.marker.isHidden == false) {
marker.marker.isHidden = true;
marker.marker.close();
}
}));
} else {
addClusterOnMap(cluster);
}
} else {
// Show all markers without the cluster
$.each(cluster.getMarkers(), function (index, marker) {
if (marker.marker.isHidden == true) {
marker.marker.open(map, this);
marker.marker.isHidden = false;
}
});
// Remove old cluster
$.each(clustersOnMap, function (index, cluster_on_map) {
if (cluster !== undefined && cluster_on_map !== undefined) {
if (cluster_on_map.getCenter() == cluster.getCenter()) {
// Show all cluster's markers/
cluster_on_map.cluster.close();
clustersOnMap.splice(index, 1);
}
}
});
}
});
var newClustersOnMap = new Array();
$.each(clustersOnMap, function (index, clusterOnMap) {
var remove = true;
$.each(availableClusters, function (index2, availableCluster) {
if (availableCluster.getCenter() == clusterOnMap.getCenter()) {
remove = false;
}
});
if (!remove) {
newClustersOnMap.push(clusterOnMap);
} else {
clusterOnMap.cluster.close();
}
});
clustersOnMap = newClustersOnMap;
});
}
})(jQuery);
and This is geocodezip code
Google Maps Multiple markers with the exact same location Not working
Many Many Thanks
That solution is great, but I'd take a look at using the Overlapping Marker Spiderfier library to handle markers in the same location. You can use this in conjunction with the marker clusterer library, without any issues. This way you also don't lose the ability to see how many markers are actually in that same location - and it gives you a great UI in my opinion.
To use Overlapping Marker Spiderfier, include the script file before your main js file in your html. Then in your js, create an instance of the OverlappingMarkerSpiderfier object:
var oms = new OverlappingMarkerSpiderfier(map);
/*in your case I'd do this after you initialize the `map` object,
*and declare the `oms` globally, like you do with your other global objects
*/
Then when the markers are created, you want to add the marker to the oms object via the addMarker() method. So, in your case add the following line to the renderElements() function after the click event listener you declare for the marker:
oms.addMarker(marker);
Lastly, make sure to also clear the markers from the oms object when the removeMarkers() function in your code is called by adding the following to that function:
oms.clearMarkers();