I'm using mosne map (www.mosne.it/playground/mosne_map)
What I'm trying to do is, whenever user change zoom level < 10 the image will be changed. Here's what I got now:
currently the marker doesn't change whenever user changes zoom level
$.fn.mosne_map = function (options) {
var baseconf = {
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var s_infobox = {
content: "",
disableAutoPan: false,
maxWidth: 0,
pixelOffset: new google.maps.Size(-110, 5),
zIndex: null,
boxStyle: {
background: "url('images/infobox_top.png') top center no-repeat",
opacity: 1,
color: '#fff',
padding: '0',
width: "300px"
},
closeBoxMargin: "16px 4px",
closeBoxURL: "images/infobox_close_hd2.png",
infoBoxClearance: new google.maps.Size(1, 1),
isHidden: false,
pane: "floatPane",
enableEventPropagation: false
};
defaults = {
elements: '#list .maplocation', //links selector
map_opt: baseconf, // custom map options object
clat: -9.460181, // set the lat default map center
clng: 100.988281, // set the lng default map center
mapstyle_name: '', // custom map style label and id
mapstyle: '', // mapstyle object
cluster_styles: {}, // custom cluster icons object
marker_icon: {}, // custom marker icon url,width,height
infowindows: true, // shows infoWindows grabing html from the .infobox element
infobox: false, // enable custom infoWindows using infobox class
infobox_s: s_infobox, // default color scheme for custom infobox container
trigger: 'map_open', // you can set a event trigger for each link/marker
clickedzoom: 15, // set the zoom level when you click the single marker
timeout: 100, // delay between click and zoom on the single marker
mode: 'latlng', // switch mode
wait: 500, // timeout between geocode requests
maxtry: 10, // limit of time to bypass query overlimit
cat_style: {}, // costum icons and click zoom level
fitbounds: false, // on|off fit bounds
defzoom: 3, // default zoom level if fitbounds is off
showzoom: false, // bind current map zoom level event
before: function () {}, // before create map callback
after: function () {}, // after create map callback
afterUpdate: function () {} // after update map callback
};
var settings = $.extend({}, defaults, options);
this.each(function () {
var map_el = $(this);
var the_map_el = $(this).get(0);
//on before
settings.before.apply(map_el);
//init map
var center = new google.maps.LatLng(settings.clat, settings.clng);
var map = new google.maps.Map(the_map_el, settings.map_opt);
var bounds = new google.maps.LatLngBounds();
var markerCluster = new MarkerClusterer(map, null, settings.cluster_styles);
map.setCenter(center);
bounds.extend(center);
map.setZoom(settings.defzoom);
map.setCenter(center);
//apply map style
if (settings.mapstyle_name != '') {
var styledMapOptions = {
name: settings.mapstyle_name
};
var m_MapType = new google.maps.StyledMapType(settings.mapstyle, styledMapOptions);
map.mapTypes.set(settings.mapstyle_name, m_MapType);
map.setMapTypeId(settings.mapstyle_name);
}
// set markers icons
var markerIcon = new google.maps.MarkerImage("http://googlemaps.googlermania.com/img/google-marker-big.png");
// init infowindow
if (settings.infowindows) {
var infowindow = new google.maps.InfoWindow({
maxWidth: 200
});
}
// init infobox
if (settings.infobox) {
var boxText = document.createElement("div");
boxText.style.cssText = settings.infobox_s_txt
boxText.innerHTML = "hello world";
var m_box = new InfoBox(settings.infobox_s);
}
// function create marker
var _createMarker = function (el, latLng, markerIcon, m_name, cat) {
if (cat) {
var c_icon = settings.cat_style[cat]['icon'];
var c_icon_w = settings.cat_style[cat]['width'];
var c_icon_h = settings.cat_style[cat]['height'];
if (c_icon) { //var markerIcon = c_icon;
var markerIcon = new google.maps.MarkerImage(c_icon, null, null, null, new google.maps.Size(c_icon_w, c_icon_h));
}
}
var marker = new google.maps.Marker({
position: latLng,
icon: markerIcon,
flat: true,
title: m_name
});
//extend bounds
bounds.extend(latLng);
// bind click on map trigger event fill infowindow / infobox content on demand
if (settings.infowindows || settings.infobox) {
var content = el.find('.infobox').html();
}
google.maps.event.addListener(marker, 'click', function () {
if (settings.infowindows) {
infowindow.close();
infowindow.setContent(content);
infowindow.open(map, marker);
map.setCentexxxr(marker.getPosition());
}
if (settings.infobox) {
m_box.close();
$(boxText).hide();
m_box.setContent(content);
m_box.open(map, marker);
$(boxText).show("slow");
map.setCentesr(marker.getPosition());
}
el.trigger(settings.trigger);
$(el).parent().find('.active').removeClass('active');
$(el).addClass('active');
setTimeout(function () {
map.setZoom(settings.clickedzoom);
map.panTo(latLng);
marker.setAnimation(google.maps.Animation.DROP);
}, settings.timeout);
});
// trigger click on list
$(el).find('.maplink').unbind("click").bind("click", function (e) {
e.preventDefault();
google.maps.event.trigger(marker, "click");
return false;
});
markerCluster.addMarker(marker);
};
var _m_geocode = function (el, geocoder, address, name, cat, j) {
geocoder.geocode({
'address': address
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
latLng = results[0].geometry.location;
_createMarker(el, latLng, markerIcon, name, cat);
if (settings.fitbounds === true) {
map.fitBounds(bounds);
}
} else {
if (status === "OVER_QUERY_LIMIT") {
setTimeout(function () {
//console.log("trying again "+g_address);
j++;
if (j <= settings.maxtry) {
_m_geocode(el, geocoder, address, name, cat, j);
} else {
$(el).css({
opacity: .35
});
}
}, settings.wait);
} else if (status === "ZERO_RESULTS") {
$(el).css({
opacity: .35
});
}
}
});
}
//
$(map_el).bind('update', function () {
//reset cluster and bounds
markerCluster.clearMarkers();
bounds = null;
bounds = new google.maps.LatLngBounds();
// markers loop
var markers = [];
var w_delay = 0;
if (settings.mode === 'address') {
var geocoder = new google.maps.Geocoder();
}
var totel = $(settings.elements).length;
$(settings.elements).each(function (i) {
// create marker
var el = $(this);
//mode geocoding
if (settings.mode === 'address') {
var mkr = el.data();
var name = $(this).find(".name").text();
var address = $(this).find(".address").text();
setTimeout(function () {
_m_geocode(el, geocoder, address, name, mkr.cat, 0);
}, settings.wait * i);
} else {
// mode latlng
var mkr = el.data();
var latLng = new google.maps.LatLng(mkr.lat, mkr.lng);
_createMarker(el, latLng, markerIcon, mkr.name, mkr.cat);
}
//end of the elements loop
});
if (settings.fitbounds === true) {
// log(bounds);
map.fitBounds(bounds);
if (totel == 1) {
map.setZoom(settings.clickedzoom);
}
if (totel == 0) {
map.setZoom(settings.defzoom);
map.setCenter(center);
}
// map.setCenter(center);
} else {
//map.setZoom(settings.defzoom);
//map.setCenter(center);
};
//callbak afterUpdate
settings.afterUpdate.apply(map_el);
}).trigger('update');
$(map_el).bind('bounds', function () {
map.fitBounds(bounds);
});
// nice zoom status
if (settings.showzoom) {
google.maps.event.addListener(map, 'zoom_changed', function () {
$(map_el).trigger("showzoom", [map.getZoom()]);
});
};
//on after
settings.after.apply(map_el);
return true;
//change markerIcon
google.maps.event.addListener(map, 'zoom_changed', function() {
var zoom = map.getZoom();
if (zoom <= 10) {
var markerIcon = new google.maps.MarkerImage("http://i.stack.imgur.com/B2Vg5.png");
}
else {
var markerIcon = new google.maps.MarkerImage ("http://googlemaps.googlermania.com/img/google-marker-big.png")
}
});
});
};
A simple solution for a single icon(not a single marker, this method will change the icon of all markers, but there is also an option to define category-markers)
This is the code that currently defines the default-icon:
// set markers icons
var markerIcon = new google.maps.MarkerImage("http://googlemaps.googlermania.com/img/google-marker-big.png");
Replace it with this code:
// set markers icons
var markerIcon = new google.maps.MVCObject();
google.maps.event.addListener(map,'zoom_changed',function(){
markerIcon.set('icon',(this.getZoom()<10)
? 'http://www.google.com/mapfiles/marker.png'//url for zoom<10
: 'http://googlemaps.googlermania.com/img/google-marker-big.png'//url for zoom>=10
);
});
google.maps.event.trigger(map,'zoom_changed',{});
The url of markerIcon now will be updated when the zoom changes
To apply the changes to the markers replace this code:
var marker = new google.maps.Marker({
position: latLng,
icon: markerIcon,
flat: true,
title: m_name
});
with.....
var marker = new google.maps.Marker({
position: latLng,
icon: markerIcon.icon,
flat: true,
title: m_name
});
marker.bindTo('icon',markerIcon,'icon') ;
Related
This is my first experience with GoogleMaps/JS.
My map is working as expected with individual markers. But when i add marker cluster function its not working and the best part is no errors on the console.
Below is my code. Any help would be greatly appreciated.
function CreateMap(rootElement,data,startPin,endPin){
//console.log("startPin : " + startPin);
var google = window.google;
var map;
var marker;
var posInfoWindow;
var markers = [];
var markersArray = [];
var mapElement = rootElement.querySelector('.my-map');
currPos = localStorage.currentPosition;
var currentPosition = JSON.parse(localStorage.currentPosition);
var results = JSON.parse(data);
var defaultIcon, selectedIcon, mainIcon;
function centerOnMyLocation() {
closeAllInfoWindows();
map.panTo(marker.getPosition());
posInfoWindow.open(map, marker);
}
function closeAllInfoWindows() {
if(posInfoWindow !== void 0) {
posInfoWindow.close();
}
markers.forEach(function(it) {
it.infoWindow.close();
it.marker.setIcon(defaultIcon);
});
}
function showInfoWindow(idx) {
closeAllInfoWindows();
if(map !== void 0) {
markers[idx].infoWindow.open(map, markers[idx].marker);
markers[idx].marker.setIcon(selectedIcon);
}
}
function highlightListItem(idx) {
var items = rootElement.querySelectorAll('.my-result-list-item');
[].forEach.call(items, function(it) {
it.className = it.className.replace('my-result-list-item-highlight', '');
});
items[idx].className += ' my-result-list-item-highlight';
}
function selectMarker(idx) {
showInfoWindow(idx);
highlightListItem(idx);
}
defaultIcon = {
url: "/maps/Locator_Green_Pin.png",
anchor: new google.maps.Point(0, 0),
labelOrigin: new google.maps.Point(34, 35)
};
selectedIcon = {
url: "/maps/Locator_Yellow_Pin.png",
anchor: new google.maps.Point(0, 0),
labelOrigin: new google.maps.Point(34, 35)
};
mainIcon = {
url: "/maps/Locator_Blue_Pin.png",
anchor: new google.maps.Point(0, 0)
};
var myLatlng = new google.maps.LatLng(currentPosition.latitude, currentPosition.longitude);
map = new google.maps.Map(mapElement, {
center: myLatlng,
zoom: 3,
styles: [
{
featureType: 'poi',
stylers: [{ visibility: 'off' }] // Turn off points of interest.
}, {
featureType: 'transit.station',
stylers: [{ visibility: 'off' }] // Turn off bus stations, train stations, etc.
}
],
'mapTypeId': google.maps.MapTypeId.ROADMAP,
disableDoubleClickZoom: false,
scaleControl: true
});
map.addListener('click', function() {
closeAllInfoWindows();
});
bounds = new google.maps.LatLngBounds(); // MapAutoZoom : to fit the markers on the map
//alert("working on map");
//results.forEach(function(it, idx) {
$.each(results, function(idx, it) {
//console.log("it : " + it + " , idx : "+idx);
var labelXoffset = -30;
var labelYOffset = -28; //reduce x offset to center longer labels
if (idx >= 9 && idx <= 98) {
labelXoffset = -27;
}
else if ( idx >= 99 && idx <= 998 ) {
labelXoffset = -24;
}
if(startPin<= idx && idx<= endPin){
var m = new MarkerWithLabel({
position: new google.maps.LatLng(it.Latitude, it.Longitude),
title: it.MerchantName,
animation: google.maps.Animation.DROP,
draggable: false,
map: map,
labelContent: (idx+1).toString(),
labelAnchor: new google.maps.Point(labelXoffset, labelYOffset),
icon: defaultIcon
});
m.addListener('click', function() {
if (idx !== -1) {
showInfoWindow(idx);
highlightListItem(idx);
}
});
var iw = new google.maps.InfoWindow({
content: "<div class='my-info-window'>View details</div>"
});
var obj = {
marker: m,
infoWindow: iw
};
markers.push(obj);
var latlongVal = new google.maps.LatLng(data[i].latitude, data[i].longitude);
var markerVal = new google.maps.Marker({
position: latlongVal
});
markersArray.push(markerVal);
bounds.extend(m.position);//MapAutoZoom
}
if(idx== endPin)
return false;
});
console.log(markersArray);
map.fitBounds(bounds); // MapAutoZoom : auto-zoom
map.panToBounds(bounds); // MapAutoZoom : auto-center
marker = new google.maps.Marker({
position: myLatlng,
title: "Me",
animation: google.maps.Animation.DROP,
icon: mainIcon
});
marker.setMap(map);
posInfoWindow = new google.maps.InfoWindow({
content: "My current location"
});
marker.addListener('click', function() {
showInfoWindow(posInfoWindow, marker, map);
});
//
// Custom Current Position Control
//
var centerControlDiv = document.createElement('div');
var div = document.createElement('div');
div.id = 'goToMeUI';
div.className = 'my-map-current-position-control-container';
div.title = 'Click to show your current position';
centerControlDiv.appendChild(div);
centerControlDiv.index = 1;
var img = document.createElement('img');
img.src = '/maps/Locator_Blue_Pin.svg';
div.appendChild(img);
div.addEventListener('click', centerOnMyLocation);
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(centerControlDiv);
//
// List item click event handling
//
$( '.my-result-list-item', rootElement ).on('click', function(event) {
//alert("map result clicked");
selectMarker(event.currentTarget.getAttribute('data-map-list-index'));
});
function initialize(){
var markerCluster = new MarkerClusterer(map, markersArray, {imagePath: '/maps/cluster/m'});
}
google.maps.event.addDomListener(window, 'load', initialize);
}
i am using ionic framework. i created map and multiple markers and value came from server side.all data came properly but i don't know why i getting this error-
ionic.bundle.js:25642 TypeError: Cannot read property 'fitBounds' of null
at autoCenter (app.js:147)
at app.js:135
at processQueue (ionic.bundle.js:27879)
at ionic.bundle.js:27895
at Scope.$eval (ionic.bundle.js:29158)
at Scope.$digest (ionic.bundle.js:28969)
at Scope.$apply (ionic.bundle.js:29263)
at done (ionic.bundle.js:23676)
at completeRequest (ionic.bundle.js:23848)
at XMLHttpRequest.requestLoaded (ionic.bundle.js:23789)
code :
angular.module('starter', ['ionic', 'ngCordova'])
.run(function ($ionicPlatform, GoogleMaps) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
// Don't remove this line unless you know what you are doing. It stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
GoogleMaps.init();
});
})
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('map', {
url: '/',
templateUrl: 'templates/map.html',
controller: 'MapCtrl'
});
$urlRouterProvider.otherwise("/");
})
.factory('Markers', function ($http) {
var markers = [];
return {
getMarkers: function () {
return $http.get("http://localhost:8080/LocationServices/markers.php").then(function (response) {
markers = response;
return markers;
});
}
}
})
.factory('GoogleMaps', function ($cordovaGeolocation, Markers) {
var apiKey = false;
var map = null;
var zoomVal = 15
function initMap() {
var options = { timeout: 10000, enableHighAccuracy: true };
$cordovaGeolocation.getCurrentPosition(options).then(function (position) {
var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
console.log("Latitude current: ", position.coords.latitude);
console.log("Longitude current: ", position.coords.longitude);
var mapOptions = {
center: latLng,
zoom: zoomVal,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), mapOptions);
//Wait until the map is loaded
google.maps.event.addListenerOnce(map, 'idle', function () {
var marker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: latLng
});
//Load the markers
loadMarkers(map);
//map.setCenter(new google.maps.LatLng(-37.92, 151.25));
});
}, function (error) {
console.log("Could not get location");
//Load the markers
loadMarkers(map);
//map.setCenter(new google.maps.LatLng(-37.92, 151.25));
});
}
function loadMarkers(map) {
//Get all of the markers from our Markers factory
Markers.getMarkers().then(function (markers) {
console.log("Markers: ", markers);
var markersss = new Array();
var records = markers.data.markers;
for (var i = 0; i < records.length; i++) {
var record = records[i];
console.log("Latitude: ", record.lat);
console.log("Longitude: ", record.lng);
var markerPos = new google.maps.LatLng(record.lat, record.lng);
console.log("marker position", "" + markerPos);
// Add the markerto the map
var marker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: markerPos
});
markersss.push(marker);
var infoWindowContent = "<h4>" + record.name + "</h4>";
addInfoWindow(marker, infoWindowContent, record);
}
autoCenter(map, markersss);
});
}
function autoCenter(map1, markersss) {
//Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds();
//Go through each...
for (var i = 0; i < markersss.length; i++) {
bounds.extend(markersss[i].position);
console.log("bounds position", "" + markersss[i].position);
}
//Fit these bounds to the map
map1.fitBounds(bounds);
map1.setCenter(bounds.getCenter());
//remove one zoom level to ensure no marker is on the edge.
map1.setZoom(vm.googleMap.getZoom() - 1);
// set a minimum zoom
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if (map1.getZoom() > zoomVal) {
map1.setZoom(zoomVal);
}
}
function addInfoWindow(marker, message, record) {
var infoWindow = new google.maps.InfoWindow({
content: message
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open(map, marker);
});
}
return {
init: function () {
initMap();
}
}
})
.controller('MapCtrl', function ($scope, $state, $cordovaGeolocation) {
});
The map will only be created when $cordovaGeolocation.getCurrentPosition was successfull, but you also call loadMarkers when it wasn't successfull(map is null in this case)
Solution: create the map outside of the getCurrentPosition-callbacks (with a default-value for center).
In the success-callback create the marker and set the center of the map
function initMap() {
var options = { timeout: 10000, enableHighAccuracy: true },
mapOptions = {
center: new google.maps.LatLng(-37.92,151.25),
zoom: zoomVal,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
map = new google.maps.Map(document.getElementById("map"), mapOptions);
google.maps.event.addListenerOnce(map, 'idle', function () {
$cordovaGeolocation.getCurrentPosition(options).then(function (position) {
var center = new google.maps.LatLng( position.coords.latitude,
position.coords.longitude);
map.setCenter(center);
new google.maps.Marker({
map : map,
animation : google.maps.Animation.DROP,
position : center
});
loadMarkers(map);
}, function (error) {
loadMarkers(map);
});
});
}
I would like to add streetview to each infowindow but I can't figure out how to integrate the code. I tried putting the code where the comments are set and that works half. Still have to learn a lot about programming.
html += '<div id="content" style="width:200px;height:200px;"></div>';
var pano = null;
google.maps.event.addListener(infoWindow, 'domready', function () {
if (pano != null) {
pano.unbind("position");
pano.setVisible(false);
}
pano = new google.maps.StreetViewPanorama(document.getElementById("content"), {
navigationControl: true,
navigationControlOptions: { style: google.maps.NavigationControlStyle.ANDROID },
enableCloseButton: false,
addressControl: false,
linksControl: false
});
pano.bindTo("point", marker);
pano.setVisible(true);
});
I'm using this code:
function load() {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
center: new google.maps.LatLng(41.640078, -102.669433),
zoom: 3,
mapTypeId: 'roadmap'
});
var infoWindow = new google.maps.InfoWindow;
downloadUrl("mymap.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + point;
// comment *** streetview here ****
var marker = new google.maps.Marker({
map: map,
position: point
});
bindInfoWindow(marker, map, infoWindow, html);
}
});}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
Working example using DOM elements (rather than using string content):
// this variable will collect the html which will eventually be placed in the side_bar
var side_bar_html = "";
// arrays to hold copies of the markers used by the side_bar
var gmarkers = [];
// global "map" variable
var map = null;
var sv = new google.maps.StreetViewService();
var clickedMarker = null;
var panorama = null;
// Create the shared infowindow with three DIV placeholders
// One for a text string, oned for the html content from the xml, one for the StreetView panorama.
var content = document.createElement("DIV");
var title = document.createElement("DIV");
content.appendChild(title);
var streetview = document.createElement("DIV");
streetview.style.width = "200px";
streetview.style.height = "200px";
content.appendChild(streetview);
var htmlContent = document.createElement("DIV");
content.appendChild(htmlContent);
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150, 50),
content: content
});
// A function to create the marker and set up the event window function
function createMarker(latlng, name, html) {
var contentString = html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: name,
zIndex: Math.round(latlng.lat() * -100000) << 5
});
marker.myHtml = html;
google.maps.event.addListener(marker, "click", function() {
clickedMarker = marker;
sv.getPanoramaByLocation(marker.getPosition(), 50, processSVData);
// openInfoWindow(marker);
});
// save the info we need to use later for the side_bar
gmarkers.push(marker);
// add a line to the side_bar html
side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length - 1) + ')">' + name + '<\/a><br>';
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
google.maps.event.trigger(gmarkers[i], "click");
}
function processSVData(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
var marker = clickedMarker;
openInfoWindow(clickedMarker);
if (!!panorama && !!panorama.setPano) {
panorama.setPano(data.location.pano);
panorama.setPov({
heading: 270,
pitch: 0,
zoom: 1
});
panorama.setVisible(true);
google.maps.event.addListener(marker, 'click', function() {
var markerPanoID = data.location.pano;
// Set the Pano to use the passed panoID
panorama.setPano(markerPanoID);
panorama.setPov({
heading: 270,
pitch: 0,
zoom: 1
});
panorama.setVisible(true);
});
}
} else {
openInfoWindow(clickedMarker);
title.innerHTML = clickedMarker.getTitle() + "<br>Street View data not found for this location";
htmlContent.innerHTML = clickedMarker.myHtml;
panorama.setVisible(false);
// alert("Street View data not found for this location.");
}
}
function initialize() {
// Create the map
// No need to specify zoom and center as we fit the map further down.
map = new google.maps.Map(document.getElementById("map_canvas"), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
});
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// Read the data from example.xml
// downloadUrl("example.xml", function(doc) {
var xmlDoc = xmlParse(xmlData);
var markers = xmlDoc.documentElement.getElementsByTagName("marker");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].getAttribute("lat"));
var lng = parseFloat(markers[i].getAttribute("lng"));
var point = new google.maps.LatLng(lat, lng);
var html = markers[i].getAttribute("html");
var label = markers[i].getAttribute("label");
// create the marker
var marker = createMarker(point, label, html);
bounds.extend(point);
}
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;
// Zoom and center the map to fit the markers
map.fitBounds(bounds);
// });
}
// 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.
var pin = new google.maps.MVCObject();
google.maps.event.addListenerOnce(infowindow, "domready", function() {
panorama = new google.maps.StreetViewPanorama(streetview, {
navigationControl: false,
enableCloseButton: false,
addressControl: false,
linksControl: false,
visible: true
});
panorama.bindTo("position", pin);
});
// Set the infowindow content and display it on marker click.
// Use a 'pin' MVCObject as the order of the domready and marker click events is not garanteed.
function openInfoWindow(marker) {
title.innerHTML = marker.getTitle();
htmlContent.innerHTML = marker.myHtml;
pin.set("position", marker.getPosition());
infowindow.open(map, marker);
}
// This Javascript is based on code provided by the
// Community Church Javascript Team
// http://www.bisphamchurch.org.uk/
// http://econym.org.uk/gmap/
// from the v2 tutorial page at:
// http://econym.org.uk/gmap/basic3.htm
google.maps.event.addDomListener(window, 'load', initialize);
var xmlData = '<markers> <marker lat="43.65654" lng="-79.90138" html="Some stuff to display in the<br>First Info Window" label="Marker One" /> <marker lat="43.91892" lng="-78.89231" html="Some stuff to display in the<br>Second Info Window" label="Marker Two" /> <marker lat="43.82589" lng="-79.10040" html="Some stuff to display in the<br>Third Info Window" label="Marker Three" /></markers> ';
/**
* Parses the given XML string and returns the parsed document in a
* DOM data structure. This function will return an empty DOM node if
* XML parsing is not supported in this browser.
* #param {string} str XML string.
* #return {Element|Document} DOM.
*/
function xmlParse(str) {
if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
}
if (typeof DOMParser != 'undefined') {
return (new DOMParser()).parseFromString(str, 'text/xml');
}
return createElement('div', null);
}
html,
body {
height: 100%;
}
<script src="https://maps.google.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<!-- you can use tables or divs for the overall layout -->
<table border="1">
<tr>
<td>
<div id="map_canvas" style="width: 550px; height: 450px"></div>
</td>
<td valign="top" style="width:150px; text-decoration: underline; color: #4444ff;">
<div id="side_bar"></div>
</td>
</tr>
</table>
I'm running into an issue with the position of my infowindows. I am generating the markers in a for-loop, but when I click on an infowindow, the position is always set to the marker that was generated last. The content is correct, however. It's definitely a scoping issue, and there is also a Drupal Ajax call that fetches the content (which doesn't contain any location info). Can anyone help? Here is the for-loop:
for ( markerItem in data ) {
var icon = icons[data[markerItem][3]].mouseOutIcon;
var image = icons[data[markerItem][3]].mouseOverImage;
var latlng = new google.maps.LatLng( data[markerItem][0], data[markerItem][1] );
var marker = new google.maps.Marker({
icon:icon,
clickable:true,
position: latlng,
map: map,
draggable:false,
title: data[markerItem][2]
});
marker.mapid = mapid;
marker.mid = data[markerItem][4];
google.maps.event.addListener(marker,'click',function(latlng) {
$.get('/map-info/'+this.mapid+'/'+this.mid, null, function(response) {
console.log('first' + marker.getPosition());
var result = Drupal.parseJson(response);
if ( result.status == 0 ) {
if(infowindow != null) {
infowindow.close();
}
infowindow = new google.maps.InfoWindow({
content: result.html
//position: marker.getPosition()
});
infowindow.open(map,marker);
}
});
google.maps.event.addListener(marker, 'mouseover', function(latlng) {
this.setImage( this.mouseOverImage );
});
google.maps.event.addListener(marker, 'mouseout', function(latlng) {
this.setImage( this.mouseOutImage );
});
});
marker.mouseOverImage = image;
marker.mouseOutImage = icon.image;
gmap.overlays.push( marker );
marker.setMap(map);
if ( checkboxState[data[markerItem][3]] ) {
marker.setMap(map);
}
else {
marker.setMap(null);
}
}
});
}
else {
console.log('inside else');
var lat3 = gmap.oldBounds.getSouthWest().lat();
var lng3 = gmap.oldBounds.getSouthWest().lng();
var lat4 = gmap.oldBounds.getNorthEast().lat();
var lng4 = gmap.oldBounds.getNorthEast().lng();
$.get('/map-markers/'+mapid+'/'+lat1+'/'+lng1+'/'+lat2+'/'+lng2+'/'+lat3+'/'+lng3+'/'+lat4+'/'+lng4, null, function(response) {
var result = Drupal.parseJson(response);
var data = result.markers;
for ( var i = 0; i < 4; i++ ) {
icons.push( { mouseOutIcon: Drupal.gmap.getIcon('boilers', i), mouseOverImage: mouseOverImage(Drupal.gmap.getIcon('boilers', i).image)});
}
var gmap = Drupal.gmap.getMap(mapid);
for ( markerItem in data ) {
var icon = icons[data[markerItem][3]].mouseOutIcon;
var image = icons[data[markerItem][3]].mouseOverImage;
var latlng = new GLatLng( data[markerItem][0], data[markerItem][1] );
var marker = createMarker(latlng, {icon: icon, title:data[markerItem][2], clickable:true, draggable:false }, data[markerItem][4] );
marker.mouseOverImage = image;
marker.mouseOutImage = icon.image;
gmap.overlays.push( marker );
map.addOverlay( marker );
if ( checkboxState[data[markerItem][3]] ) {
//marker.show();
}
else {
//marker.hide();
}
}
You have to use closures to solve this problem.
The below in a working sample
Use the JS method AddInfoWidnow from below code to add InfoWindow to a marker.
function AddInfoWidnow(marker,message)
{
var infowindow = new google.maps.InfoWindow({ content: message });
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(marker.get('map'), marker);
});
}
call the AddInfoWidnow method inside the for loop
function ShowOnMap(ContainerId, mapItems) {
var DefaultLatLng= new google.maps.LatLng('12.967461', '79.941824');
var mapOptions = {
center: DefaultLatLng,
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP,
marker: true
};
var mapCust = new google.maps.Map(document.getElementById(ContainerId), mapOptions);
var arrJsonObject = JSON.parse(mapItems);
for (var y = 1; y <= arrJsonObject.length; y++)
{
var myLatLng1 = new google.maps.LatLng(arrJsonObject[y - 1].Latitude, arrJsonObject[y - 1].Lonngitude);
var marker = new google.maps.Marker({
position: myLatLng1,
map: mapCust,
title: 'Marked at '+ arrJsonObject[y - 1].markedDate
});
addInfoWindows(marker,y-1,arrJsonObject);
marker.setMap(mapCust);
}
}
Using the below snnipet I called it.
var mapItems='[
{
"Latitude": "22.575897",
"Lonngitude": "88.431754",
"CustomerCode": "*$$$*",
"CustomerName": "*###*",
"markedDate": "2/20/2014 12:04:41 PM"
},
{
"Latitude": "22.615067",
"Lonngitude": "88.431759",
"CustomerCode": "*$$$*",
"CustomerName": "*###*",
"markedDate": "2/20/2014 3:02:19 PM"
}
]';
ShowOnMap(containerId2, mapItems);
The thing is you have to add the info window using closure and This works for me.
Reference
I have a custom map with an information bubble and custom markers. When I zoom into points of interest such as parks and universities appear and when I click an information window opens. How do I disable the info window?
My code is as follows:
var geocoder;
var map;
var infoBubble;
var dropdown = "";
var gmarkers = [];
var hostel_icon = new google.maps.MarkerImage('/resources/hostel_blue_icon.png',
new google.maps.Size(28,32),
new google.maps.Point(0,0),
new google.maps.Point(14,32));
var bar_icon = new google.maps.MarkerImage('/resources/bar_red_icon.png',
new google.maps.Size(28,32),
new google.maps.Point(0,0),
new google.maps.Point(14,32));
var icon_shadow = new google.maps.MarkerImage('/resources/myicon_shadow.png',
new google.maps.Size(45,32),
new google.maps.Point(0,0),
new google.maps.Point(12,32));
var customIcons = {
hostel: {
icon: hostel_icon,
shadow: icon_shadow
},
bar: {
icon: bar_icon,
shadow: icon_shadow
}
};
function initialize() {
var latlng = new google.maps.LatLng(12.82364, 26.29987);
var myMapOptions = {
zoom: 2,
center: latlng,
panControl: false,
scaleControl: true,
mapTypeId: google.maps.MapTypeId.TERRAIN,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR},
navigationControlOptions: {style: google.maps.NavigationControlStyle.DEFAULT}
}
map = new google.maps.Map(document.getElementById("map_canvas"), myMapOptions);
infoBubble = new InfoBubble({
shadowStyle: 0,
padding: 0,
backgroundColor: 'rgb(57,57,57)',
borderRadius: 5,
arrowSize: 10,
borderWidth: 1,
maxWidth: 400,
borderColor: '#2c2c2c',
disableAutoPan: false,
hideCloseButton: true,
arrowPosition: 50,
backgroundClassName: 'phoney',
arrowStyle: 0
});
// Change this depending on the name of your PHP file
downloadUrl("phpsqlajax_genxml_2.php", function(data) {
var xml = parseXml(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var bar_name = markers[i].getAttribute("bar_name");
var hostel_name = markers[i].getAttribute("hostel_name");
var street = markers[i].getAttribute("street");
var city = markers[i].getAttribute("city");
var postcode = markers[i].getAttribute("postcode");
var country = markers[i].getAttribute("country");
var page = markers[i].getAttribute("page");
var map_photo = markers[i].getAttribute("map_photo");
var type = markers[i].getAttribute("type");
var category = markers[i].getAttribute("category");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = '<div class="infowindow"><div class="iwPhoto" style="width: 105px; height: 65px;">' + "' + "<a href='" + page + "'>" + hostel_name + "" + '</div><div class="iwCategory" style="height: 15px;">' + category + '</div><div class="iwCity" style="height: 29px;">' + "' + "<a href='" + page + "'><img src='/resources/arrow.png'/>" + '</div></div></div>';
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow,
title: bar_name
});
marker.bar_name = bar_name;
marker.category = category;
bindInfoBubble(marker, map, infoBubble, html, bar_name);
gmarkers.push(marker);
str = '<option selected> - Select a club - </option>';
for (j=0; j < gmarkers.length; j++){
str += '<option value="'+gmarkers[j].bar_name+'">'+gmarkers[j].bar_name+', '+gmarkers[j].category+'</option>';
}
var str1 ='<form name="form_city" action=""><select style="width:150px;" id="select_city" name="select_cityUrl" onchange="handleSelected(this);">';
var str2 ='</select></form>';
dropdown = str1 + str + str2;
}
document.getElementById("dd").innerHTML = dropdown;
});
}
function handleSelected(opt) {
var indexNo = opt[opt.selectedIndex].index;
google.maps.event.trigger(gmarkers[indexNo-1], "click");
}
function bindInfoBubble(marker, map, infoBubble, html) {
google.maps.event.addListener(marker, 'click', function() {
infoBubble.setContent(html);
infoBubble.open(map, marker);
google.maps.event.addListener(map, "click", function () {
infoBubble.close();
});
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function parseXml(str) {
if (window.ActiveXObject) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
} else if (window.DOMParser) {
return (new DOMParser).parseFromString(str, 'text/xml');
}
}
function doNothing() {}
UPDATE Google Maps JavaScript API V3
You can set clickableIcons to false in MapOptions. This will keep the POI icons but disable the infowindows just as you want.
function initialize() {
var myMapOptions = { clickableIcons: false }
}
Further details here...
https://developers.google.com/maps/documentation/javascript/3.exp/reference#MapOptions
See the other answers for the clickable: false answer.
However, if you want it clickable, but no infowindow, call stop() on the event to prevent the infowindow from showing, but still get the location info:
map.addListener('click', function (event) {
// If the event is a POI
if (event.placeId) {
// Call event.stop() on the event to prevent the default info window from showing.
event.stop();
// do any other stuff you want to do
console.log('You clicked on place:' + event.placeId + ', location: ' + event.latLng);
}
}
For more info, see the docs.
Other option: completely remove the POI-icons, and not only the infoWindow:
var mapOptions = {
styles: [{ featureType: "poi", elementType: "labels", stylers: [{ visibility: "off" }]}]
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
You can do this by creating a styled map without labels for the points of interest.
This maintains the topography and other nice pieces of information on the map, but removes the markers.
var remove_poi = [
{
"featureType": "poi",
"elementType": "labels",
"stylers": [
{ "visibility": "off" }
]
}
]
map.setOptions({styles: remove_poi})
You could consider the following approach to disable POI Info Window:
function disablePOIInfoWindow(){
var fnSet = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function () {
};
}
Example
function initMap() {
var latlng = new google.maps.LatLng(40.713638, -74.005529);
var myOptions = {
zoom: 17,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
disablePOIInfoWindow();
}
function disablePOIInfoWindow(){
var fnSet = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function () {
alert('Ok');
};
}
google.maps.event.addDomListener(window, 'load', initMap);
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map_canvas {
height: 100%;
}
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<div id="map_canvas"></div>
The above example affects all the info windows, so if you need to disable only POI Info Window, then we could introduce flag to determine whether it is POI Info Window or not:
function disablePOIInfoWindow(){
var fnSet = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function () {
if(this.get('isCustomInfoWindow'))
fnSet.apply(this, arguments);
};
}
Example
function initMap() {
var latlng = new google.maps.LatLng(40.713638, -74.005529);
var myOptions = {
zoom: 17,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var infowindow = new google.maps.InfoWindow({
content: ''
});
infowindow.set('isCustomInfoWindow',true);
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
disablePOIInfoWindow();
google.maps.event.addListener(map, 'click', function (event) {
infowindow.setContent(event.latLng.lat() + "," + event.latLng.lng());
infowindow.setPosition(event.latLng);
infowindow.open(map, this);
});
}
function disablePOIInfoWindow(){
var fnSet = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function () {
if(this.get('isCustomInfoWindow'))
fnSet.apply(this, arguments);
};
}
//google.maps.event.addDomListener(window, 'load', initMap);
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map_canvas {
height: 100%;
}
<div id="map_canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap"
async defer></script>
Simply style the map to not show Points of Interest. This is simple and does not breach Google's terms of service.
eg
mapOpts = {
styles: [
{
featureType: "poi",
stylers: [
visibility: "off"
]
}
]
};
$("#my-map").gmap(mapOpts).on("init", function(evt, map){
// do stuff with the initialised map
});
If you want the data without getting the InfoWindow HTML showing at all, you simply have to re-work the prototype of google.maps.InfoWindow:
google.maps.InfoWindow.prototype.open = function () {
return this; //prevent InfoWindow to appear
}
google.maps.InfoWindow.prototype.setContent = function (content) {
if (content.querySelector) {
var addressHTML = content.querySelector('.address');
var address = addressHTML.innerHTML.replace(/<[^>]*>/g, ' ').trim();
var link = content.querySelector('a').getAttribute('href');
var payload = {
header: 'event',
eventName: 'place_picked',
data: {
name: content.querySelector('.title').innerHTML.trim(),
address: address,
link: link
}
};
console.log('emit your event/call your function', payload);
}
};
We can do it by handling clicks on poi, Google api has provided a way to detect clicks on POI as per this article
Based on article above Here is a simpler version of code that can be used to stop the clicks on POI
function initMap() {
map = new google.maps.Map(document.getElementById('map'), myOptions);
var clickHandler = new ClickEventHandler(map, origin);
}
var ClickEventHandler = function (map, origin) {
this.origin = origin;
this.map = map;
this.map.addListener('click', this.handleClick.bind(this));
};
ClickEventHandler.prototype.handleClick = function (event) {
//console.log('You clicked on: ' + event.latLng);
if (event.placeId) {
//console.log('You clicked on place:' + event.placeId);
// Calling e.stop() on the event prevents the default info window from
// showing.
// If you call stop here when there is no placeId you will prevent some
// other map click event handlers from receiving the event.
event.stop();
}
}