How to position selected location pin in the center of google map [closed] - google-maps

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 days ago.
Improve this question
Each location should be at the center of the map when selected from a dropdown of locations. The following code is what I used to implement what I currently have.
For more context, this map was built in webflow ( a low code platform) and I get each location from a collection (cms) list I created. I've called collection: "location" and each location contains a latitude and longitude (that's how the markers are plotted on the map)
How do I center each selected location? What code do I add and where should I add it in my existing code?
<script>
var MAPS = {
zoom: 7,
map: '',
markers: {},
infoWindow: null,
init: function (defaultCoordinates = {}) {
MAPS.create(defaultCoordinates);
MAPS.plotMarkers()
},
create: function (defaultCoordinates = {}) {
var mapDom = document.getElementById('map');
if (!defaultCoordinates['lat']) {
defaultCoordinates.lat = 55.03222;
defaultCoordinates.lng = -2.62529;
}
MAPS.map = new google.maps.Map(mapDom, {
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: true,
mapTypeControl: true,
fullscreenControl: true,
scrollwheel: true,
zoom: MAPS.zoom,
center: defaultCoordinates,
plotMarkers: function () {
var locations = MAPS.locations();
gmarkers = {};
for (var i = 0; i < locations.length; i++) {
gmarkers[locations[i][0]] = MAPS.createMarkers(new google.maps.LatLng(locations[i][2], locations[i][3]), // passing lat and long
locations[i][1]); // passing Info-window information
}
MAPS.markers = gmarkers;
},
initAutoComplete: function () {
var input = document.getElementById('search')
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.addListener('place_changed', () => {
const place = autocomplete.getPlace();
if (place.geometry) {
var lat = place.geometry.location.lat();
var lng = place.geometry.location.lng();
MAPS.init({
lat: lat,
lng: lng
});
var marker = new google.maps.Marker({
position: place.geometry.location,
map: MAPS.map,
});
}
});
},
openMarkerOnClick: function () {
var viewInMap = document.querySelectorAll('[data-marker-open]').addEventListener('click', function () {
console.log('clicked');
})
},
createMarkers: function (latlng, html) {
var marker = new google.maps.Marker({
position: latlng,
map: MAPS.map,
icon: 'https://uploads-ssl.webflow.com/63c7cbc99a05611a1bd1ae5a/63ce964d18ff37a39c305bcd_image%2011.png'
});
// Define info window for each marker
google.maps.event.addListener(marker, 'click', function () {
if (MAPS.infoWindow) {
MAPS.infoWindow.close();
}
console.log(MAPS.infoWindow)
MAPS.infoWindow = new google.maps.InfoWindow();
MAPS.infoWindow.setContent(html);
MAPS.infoWindow.open(MAPS.map, marker);
});
return marker;
},
locations: function () {
// Create a locations array
var locations = []
// Add .location-wrapper class to the location Collection Item
var dynPlaces = document.querySelectorAll('.w-dyn-item.location-item');
// Define variables for the map info window
dynPlaces.forEach(function (elem) {
// Create places array
var place = [];
// Define variables for each place
var dataTitle = elem.querySelector('.data---slug').innerText; // Define slug for targeting the information window
var dataLat = Number(elem.querySelector('.data---latitude').innerText); // Define latitude point for pin
var dataLong = Number(elem.querySelector('.data---longitude').innerText); // Define longitude point for pin
var infoWindowContent = elem.querySelector('.data---info-window').innerHTML; // Define content wrapper for the information window
place.push(dataTitle, infoWindowContent, dataLat, dataLong); // Add variables to each place
locations.push(place); // Add each place to the locations array
});
return locations;
},
build: function (defaultCoordinates = {}) {
MAPS.init(defaultCoordinates);
// MAPS.openMarkerOnClick();
}
}
function initMap() {
MAPS.build();
}
window.onload = (event) => {
MAPS.build();
MAPS.initAutoComplete();
};
</script>

Related

Algolia and google filter results based on user position

Hi I am using Google maps alongside algolia where I have an index 'locations' with 'lat' and 'lng'.
I am getting user location and watching position, I am also displaying markers from database based on lng and lat however I want to add a bit to it:
So I have followed that link:
https://www.algolia.com/doc/guides/geo-search/geo-search-overview/
And came up with:
#extends('master') #section('title', 'Live Oldham')
#section('extrafiles')
<script type="text/javascript" src="https://maps.google.com/maps/api/js?v=3&key=AIzaSyAirYgs4Xnt9QabG9v56jsIcCNfNZazq50&language=en"></script>
<script type="text/javascript" src="{!! asset('js/homesearch.js') !!}"></script>
#endsection
#section('content')
<div id="map_canvas" style="height:600px;"></div>
#endsection
and js:
$(document).ready(function() {
var map;
function initializeMap(){
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 19,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
function locError(error) {
// the current position could not be located
alert("The current position could not be found!");
}
function setCurrentPosition(position) {
currentPositionMarker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude
),
title: "Current Position"
});
map.panTo(new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude
));
}
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
console.log(latitude);
console.log(longitude);
function displayAndWatch(position) {
// set current position
setCurrentPosition(position);
// watch position
watchCurrentPosition(position);
console.log(position);
}
function watchCurrentPosition(position) {
var positionTimer = navigator.geolocation.watchPosition(
function (position) {
setMarkerPosition(
currentPositionMarker,
position,
)
});
}
function setMarkerPosition(marker, position) {
marker.setPosition(
new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude)
);
}
function initLocationProcedure() {
initializeMap();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(displayAndWatch, locError);
}else{
alert("Your browser does not support the Geolocation API");
}
}
$(document).ready(function() {
initLocationProcedure();
});
var APPLICATION_ID = '75RQSC1OHE';
var SEARCH_ONLY_API_KEY = 'f2f1e9bba4d7390fc61523a04685cf12';
var INDEX_NAME = 'locations';
var PARAMS = { hitsPerPage: 100 };
// Client + Helper initialization
var algolia = algoliasearch(APPLICATION_ID, SEARCH_ONLY_API_KEY);
var algoliaHelper = algoliasearchHelper(algolia, INDEX_NAME, PARAMS);
// Map initialization
var markers = [];
//alert("heelo");
var fitMapToMarkersAutomatically = true;
algoliaHelper.on('result', function(content) {
renderHits(content);
var i;
// Add the markers to the map
for (i = 0; i < content.hits.length; ++i) {
var hit = content.hits[i];
console.log(hit)
var marker = new google.maps.Marker({
position: {lat: hit.longitude, lng: hit.latitude},
map: map,
title: hit.slug
});
markers.push(marker);
}
// Automatically fit the map zoom and position to see the markers
if (fitMapToMarkersAutomatically) {
var mapBounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
mapBounds.extend(markers[i].getPosition());
}
map.fitBounds(mapBounds);
}
});
function renderHits(content) {
$('#container').html(JSON.stringify(content, null, 2));
}
algoliaHelper.setQueryParameter('aroundRadius', 5000).search(); // 5km Radius
});
However there are few problems with this that I don't know how to tackle:
When user is moving, it doesn't center the map on the marker.
At this moment marker jumps between location when user moves, I would like for the marker to dynamically move on the map when user moves.
I want to use algolia to dynamically set markers, so I want to show markers with 5km radius from user location, and dynamically add or remove markers that are outside it.
I can't help you much with those questions since it's mostly about how to use GMap JS lib and I'm not experienced with it. However, something else catched my eyes:
var marker = new google.maps.Marker({
position: {lat: hit.longitude, lng: hit.latitude},
map: map,
title: hit.slug
});
You should put your coordinates in the _geoloc field in order to be able to use the geo-search features. It looks like this:
_geoloc: {
lat: 40.639751,
lng: -73.778925
}

Google Nearby change type on click

I'm working on a project where I'd like to show the choosen event on google maps with some additional information. (ex. all gas stations radius 2km).
Google doesn't allow a nearby search with multiple types.
Restricts the results to places matching the specified type. Only one type may be specified (if more than one type is provided, all types following the first entry are ignored).
So for now I'd like to change the type (ex. gas_station or store) if I click to a custom button I added.
(used the google document example)
Screenshot: http://imgur.com/qYwLuw4
Question:
Which is the best way to change the type and refresh the map with the new information?
I'd like to present you our solution.
We wrote a clear() and a showType() function, which will erase all markers and let the right ones appear on click. By the way we give the button a state class called "selected" for CSS styling.
We didn't find a solution to show both (washstation AND fuelstation).
<script type="text/javascript">
var map;
var infowindow;
var service;
var eventLocation = {lat: <?= $arrCoordinates['latitude']?>, lng: <?= $arrCoordinates['longitude']?>};
var markers = [];
var wash = document.getElementById('wash'); //washbutton
var fuel = document.getElementById('fuel'); //fuelstation button
function initMap() {
map = new google.maps.Map(document.getElementById('eventmap'), {
center: eventLocation,
zoom: 13,
});
infowindow = new google.maps.InfoWindow();
service = new google.maps.places.PlacesService(map);
showType('gas_station');
fuel.classList.add("selected");
typeControl(map);
}
// Type control function
function typeControl ( map ) {
google.maps.event.addDomListener(fuel, 'click', function() {
wash.classList.remove("selected");
fuel.classList.remove("selected");
clear()
showType('gas_station')
this.classList.add("selected");
});
google.maps.event.addDomListener(wash, 'click', function() {
wash.classList.remove("selected");
fuel.classList.remove("selected");
clear()
showType('car_wash')
this.classList.add("selected");
});
}
function showType(type) {
service.nearbySearch({
location: eventLocation,
radius: 10000,
type: [type]
}, callback);
}
function clear() {
markers.forEach(marker => marker.setMap(null));
markers = [];
}
function callback(results, status) {
clear()
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
createTuningEventMarker();
}
}
function createTuningEventMarker(place) {
var eventLocation = {lat: <?= $arrCoordinates['latitude']?>, lng: <?= $arrCoordinates['longitude']?>};
var eventIcon = {
url: 'https://www.foo.lol/img/icons/pin.svg',
// This marker is 20 pixels wide by 32 pixels high.
scaledSize: new google.maps.Size(60, 60),
// The origin for this image is (0, 0).
origin: new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at (0, 32).
anchor: new google.maps.Point(30,60)
};
var marker = new google.maps.Marker({
map: map,
icon:eventIcon,
position: eventLocation
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<?= $event['name']?>');
infowindow.open(map, this);
});
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name + "<br>Adress: " + place.vicinity);
infowindow.open(map, this);
});
}
</script>

Issue to set map in center so multiple marker display

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);
});
});
}

retrieving latitude and longitude from database(db2) and show in map in IBM worklight

I have saved latitude and longitude in database(db2).I want to use them to show their location in map.I am working with IBM Worklight and as database I am using DB2.
My problem is I can retrieve value from database,store it in a variable but could not be able to pass the value in the function of map where it can be used as latitude and longitude.
Any positive help would be appreciated.Thanks in advance.
My approach:
CODE:
var mylat;
var mylon;
var clat;
var clon;
function maplo() {
//database value,I have stored them in a text input type
clat=$("#lati").val();
clon=$("#long").val();
}
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
mylat=position.coords.latitude;
mylon=position.coords.longitude;
}
function success(position) {
//reload();
maplo();
showPosition(position);
var mapcanvas = document.createElement('div');
mapcanvas.id = 'mapcontainer';
mapcanvas.style.height = '460px';
mapcanvas.style.width = '320px';
document.querySelector('article').appendChild(mapcanvas);
var flat=clat;
var flon=clon;
alert("custom latitude is : "+flat);
var coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var coords1 = new google.maps.LatLng(flat, flon);
var options = {
zoom: 16,
center: coords,
mapTypeControl: false,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
},
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("mapcontainer"), options);
var marker = new google.maps.Marker({
position: coords,
map: map,
title:"You are here!"
});
var geolocation = new google.maps.Marker({
position: coords1,
map: map,
title: 'Your car location',
icon: 'http://labs.google.com/ridefinder/images/mm_20_green.png'
});
}
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success);
} else {
error('Geo Location is not supported');
}
function searchcarl()
{
var a=$("#searchcar").val();
var invocationData={
adapter:'park',
procedure :'procedure4',
parameters:[a]
};
var options={
onSuccess:success6,
onFailure:fail6
};
WL.Client.invokeProcedure(invocationData, options);
}
function success6(result){
if((result.invocationResult.resultSet.length)>0)
{
alert("location fetching!");
var I=result.invocationResult.resultSet[0].LAT;
var J=result.invocationResult.resultSet[0].LON;
$("#lati").val(I);
$("#long").val(J);
}
else{
alert("Incorrect Username or Password!");
window.location.assign("#log");
}
}
function fail6()
{
alert("fail6");
}
I will update the code as follows:
// create a map global variable
var map;
function initMap(position) {
var mapcanvas = document.createElement('div');
mapcanvas.id = 'mapcontainer';
mapcanvas.style.height = '460px';
mapcanvas.style.width = '320px';
document.querySelector('body').appendChild(mapcanvas);
var coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var options = {
zoom : 16,
center : coords,
mapTypeControl : false,
navigationControlOptions : {
style : google.maps.NavigationControlStyle.SMALL
},
mapTypeId : google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("mapcontainer"), options);
var marker = new google.maps.Marker({
position : coords,
map : map,
title : "You are here!"
});
}
// adds a marker to the map
function addCarLocationMarker(lat, lng) {
var coords = new google.maps.LatLng(lat, lng);
var geolocation = new google.maps.Marker({
position : cords,
map : map,
title : 'Your car location',
icon : 'http://labs.google.com/ridefinder/images/mm_20_green.png'
});
}
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
// once you know the user location, init the map
initMap(position);
});
} else {
alert('Geo Location is not supported');
}
function searchcarl() {
var a = $("#searchcar").val();
var invocationData = {
adapter : 'park',
procedure : 'procedure4',
parameters : [ a ]
};
var options = {
onSuccess : adapterSuccess,
onFailure : adapterFailed
};
WL.Client.invokeProcedure(invocationData, options);
}
function adapterSuccess(result) {
if ((result.invocationResult.resultSet.length) > 0) {
alert("location fetching!");
var I = result.invocationResult.resultSet[0].LAT;
var J = result.invocationResult.resultSet[0].LON;
// add the marker directly to the map
addCarLocationMarker(I, J);
}
else {
alert("Incorrect Username or Password!");
window.location.assign("#log");
}
}
function adapterFailed() {
alert("adapter invocation failed");
}
Like Idan mentioned, it's not a good idea to store the coordinates in text boxes to then use the text boxes as the source of the coordinates.
You should add the marker directly after you received the coordinates from the adapter. In this case I created a separate function initMap to initialize the map and center it on the current user's location. It is a good idea to make your functions smaller to perform one single task.
I removed some function that I thought you didn't need or were duplicating functionality namely maplo, getLocation and showPosition.

change google maps custom image marker depending on zoom level

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') ;