app/assets/javascripts/onepage/jquery.gmap.js
/**
* jQuery gMap v3
*
* @url http://www.smashinglabs.pl/gmap
* @author Sebastian Poreba <sebastian.poreba@gmail.com>
* @version 3.3.2
* @date 16.03.2011
*/
/*jslint white: false, undef: true, regexp: true, plusplus: true, bitwise: true, newcap: true, strict: true, devel: true, maxerr: 50, indent: 4 */
/*global window, jQuery, $, google, $googlemaps */
(function ($) {
"use strict";
/**
* Internals and experimental section
*/
var Cluster = function () {
this.markers = [];
this.mainMarker = false;
this.icon = "http://www.google.com/mapfiles/marker.png";
};
/**
* For iterating over all clusters to find if any is close enough to be merged with marker
*
* @param marker
* @param currentSize - calculated as viewport percentage (opts.clusterSize)
* @return bool
*/
Cluster.prototype.dist = function (marker) {
return Math.sqrt(Math.pow(this.markers[0].latitude - marker.latitude, 2) +
Math.pow(this.markers[0].longitude - marker.longitude, 2));
};
Cluster.prototype.setIcon = function (icon) {
this.icon = icon;
};
Cluster.prototype.addMarker = function (marker) {
this.markers[this.markers.length] = marker;
};
/**
* returns one marker if there is only one or
* returns special cloister marker if there are more
*/
Cluster.prototype.getMarker = function () {
if (this.mainmarker) {return this.mainmarker; }
var gicon, title;
if (this.markers.length > 1) {
gicon = new $googlemaps.MarkerImage("http://thydzik.com/thydzikGoogleMap/markerlink.php?text=" + this.markers.length + "&color=EF9D3F");
title = "cluster of " + this.markers.length + " markers";
} else {
gicon = new $googlemaps.MarkerImage(this.icon);
title = this.markers[0].title;
}
this.mainmarker = new $googlemaps.Marker({
position: new $googlemaps.LatLng(this.markers[0].latitude, this.markers[0].longitude),
icon: gicon,
title: title,
map: null
});
return this.mainmarker;
};
// global google maps objects
var $googlemaps = google.maps,
$geocoder = new $googlemaps.Geocoder(),
$markersToLoad = 0,
overQueryLimit = 0,
methods = {};
methods = {
/**
* initialisation/internals
*/
init: function (options) {
var k,
// Build main options before element iteration
opts = $.extend({}, $.fn.gMap.defaults, options);
// recover icon array
for (k in $.fn.gMap.defaults.icon) {
if(!opts.icon[k]) {
opts.icon[k] = $.fn.gMap.defaults.icon[k];
}
}
// Iterate through each element
return this.each(function () {
var $this = $(this),
center = methods._getMapCenter.apply($this, [opts]),
i, $data;
if (opts.zoom == "fit") {
opts.zoomFit = true;
opts.zoom = methods._autoZoom.apply($this, [opts]);
}
var mapOptions = {
zoom: opts.zoom,
center: center,
mapTypeControl: opts.mapTypeControl,
mapTypeControlOptions: {},
zoomControl: opts.zoomControl,
zoomControlOptions: {},
panControl : opts.panControl,
panControlOptions: {},
scaleControl : opts.scaleControl,
scaleControlOptions: {},
streetViewControl: opts.streetViewControl,
streetViewControlOptions: {},
mapTypeId: opts.maptype,
scrollwheel: opts.scrollwheel,
maxZoom: opts.maxZoom,
minZoom: opts.minZoom
};
if(opts.controlsPositions.mapType) {mapOptions.mapTypeControlOptions.position = opts.controlsPositions.mapType};
if(opts.controlsPositions.zoom) {mapOptions.zoomControlOptions.position = opts.controlsPositions.zoom};
if(opts.controlsPositions.pan) {mapOptions.panControlOptions.position = opts.controlsPositions.pan};
if(opts.controlsPositions.scale) {mapOptions.scaleControlOptions.position = opts.controlsPositions.scale};
if(opts.controlsPositions.streetView) {mapOptions.streetViewControlOptions.position = opts.controlsPositions.streetView};
mapOptions.mapTypeControlOptions.style = opts.controlsStyle.mapType;
mapOptions.zoomControlOptions.style = opts.controlsStyle.zoom;
// Create map and set initial options
var $gmap = new $googlemaps.Map(this, mapOptions);
if (opts.log) {console.log('map center is:'); }
if (opts.log) {console.log(center); }
// Create map and set initial options
$this.data("$gmap", $gmap);
$this.data('gmap', {
'opts': opts,
'gmap': $gmap,
'markers': [],
'markerKeys' : {},
'infoWindow': null,
'clusters': []
});
// Check for map controls
if (opts.controls.length !== 0) {
// Add custom map controls
for (i = 0; i < opts.controls.length; i += 1) {
$gmap.controls[opts.controls[i].pos].push(opts.controls[i].div);
}
}
if (opts.clustering.enabled) {
$data = $this.data('gmap');
(function(markers) {$data.markers = markers;}(opts.markers));
methods._renderCluster.apply($this, []);
$googlemaps.event.addListener($gmap, 'bounds_changed', function () {
methods._renderCluster.apply($this, []);
});
} else {
if (opts.markers.length !== 0) {
methods.addMarkers.apply($this, [opts.markers]);
}
}
methods._onComplete.apply($this, []);
});
},
_delayedMode: false,
/**
* Check every 100ms if all markers were loaded, then call onComplete
*/
_onComplete: function () {
var $data = this.data('gmap'),
that = this;
if ($markersToLoad !== 0) {
window.setTimeout(function () {methods._onComplete.apply(that, []); }, 100);
return;
}
if(methods._delayedMode) {
var center = methods._getMapCenter.apply(this, [$data.opts, true]);
methods._setMapCenter.apply(this, [center]);
if($data.opts.zoomFit) {
var zoom = methods._autoZoom.apply(this, [$data.opts, true]);
$data.gmap.setZoom(zoom);
}
}
$data.opts.onComplete();
},
/**
* set map center when map is loaded (check every 100ms)
*/
_setMapCenter: function (center) {
var $data = this.data('gmap');
if ($data.opts.log) {console.log('delayed setMapCenter called'); }
if ($data.gmap !== undefined && $markersToLoad == 0) {
$data.gmap.setCenter(center);
} else {
var that = this;
window.setTimeout(function () {methods._setMapCenter.apply(that, [center]); }, 100);
}
},
/**
* calculate boundaries, optimised and independent from Google Maps
*/
_boundaries: null,
_getBoundaries: function (opts) {
// if(methods._boundaries) {return methods._boundaries; }
var markers = opts.markers, i;
var mostN = 1000,
mostE = -1000,
mostW = 1000,
mostS = -1000;
if(markers) {
for (i = 0; i < markers.length; i += 1) {
if(!markers[i].latitude || !markers[i].longitude) continue;
if(mostN > markers[i].latitude) {mostN = markers[i].latitude; }
if(mostE < markers[i].longitude) {mostE = markers[i].longitude; }
if(mostW > markers[i].longitude) {mostW = markers[i].longitude; }
if(mostS < markers[i].latitude) {mostS = markers[i].latitude; }
console.log(markers[i].latitude, markers[i].longitude, mostN, mostE, mostW, mostS);
}
methods._boundaries = {N: mostN, E: mostE, W: mostW, S: mostS};
}
if(mostN == -1000) methods._boundaries = {N: 0, E: 0, W: 0, S: 0};
return methods._boundaries;
},
_getBoundariesFromMarkers: function () {
var markers = this.data('gmap').markers, i;
var mostN = 1000,
mostE = -1000,
mostW = 1000,
mostS = -1000;
if(markers) {
for (i = 0; i < markers.length; i += 1) {
if(mostN > markers[i].getPosition().lat()) {mostN = markers[i].getPosition().lat(); }
if(mostE < markers[i].getPosition().lng()) {mostE = markers[i].getPosition().lng(); }
if(mostW > markers[i].getPosition().lng()) {mostW = markers[i].getPosition().lng(); }
if(mostS < markers[i].getPosition().lat()) {mostS = markers[i].getPosition().lat(); }
}
methods._boundaries = {N: mostN, E: mostE, W: mostW, S: mostS};
}
if(mostN == -1000) methods._boundaries = {N: 0, E: 0, W: 0, S: 0};
return methods._boundaries;
},
/**
* Priorities order:
* - latitude & longitude in options
* - address in options
* - latitude & longitude of first marker having it
* - address of first marker having it
* - failsafe (0,0)
*
* Note: with geocoding returned value is (0,0) and callback sets map center. It's not very nice nor efficient.
* It is quite good idea to use only first option
*/
_getMapCenter: function (opts, fromMarkers) {
// Create new object to geocode addresses
var center,
that = this, // 'that' scope fix in geocoding
i,
selectedToCenter,
most; //hoisting
if (opts.markers.length && (opts.latitude == "fit" || opts.longitude == "fit")) {
if(fromMarkers) most = methods._getBoundariesFromMarkers.apply(this);
else most = methods._getBoundaries(opts);
center = new $googlemaps.LatLng((most.N + most.S)/2, (most.E + most.W)/2);
console.log(fromMarkers, most, center);
return center;
}
if (opts.latitude && opts.longitude) {
// lat & lng available, return
center = new $googlemaps.LatLng(opts.latitude, opts.longitude);
return center;
} else {
center = new $googlemaps.LatLng(0, 0);
}
// Check for address to center on
if (opts.address) {
// Get coordinates for given address and center the map
$geocoder.geocode(
{address: opts.address},
function (result, status) {
if (status === google.maps.GeocoderStatus.OK) {
methods._setMapCenter.apply(that, [result[0].geometry.location]);
} else {
if (opts.log) {console.log("Geocode was not successful for the following reason: " + status); }
}
}
);
return center;
}
// Check for a marker to center on (if no coordinates given)
if (opts.markers.length > 0) {
selectedToCenter = null;
for (i = 0; i < opts.markers.length; i += 1) {
if(opts.markers[i].setCenter) {
selectedToCenter = opts.markers[i];
break;
}
}
if (selectedToCenter === null) {
for (i = 0; i < opts.markers.length; i += 1) {
if (opts.markers[i].latitude && opts.markers[i].longitude) {
selectedToCenter = opts.markers[i];
break;
}
if (opts.markers[i].address) {
selectedToCenter = opts.markers[i];
}
}
}
// failed to find any reasonable marker (it's quite impossible BTW)
if (selectedToCenter === null) {
return center;
}
if (selectedToCenter.latitude && selectedToCenter.longitude) {
return new $googlemaps.LatLng(selectedToCenter.latitude, selectedToCenter.longitude);
}
// Check if the marker has an address
if (selectedToCenter.address) {
// Get the coordinates for given marker address and center
$geocoder.geocode(
{address: selectedToCenter.address},
function (result, status) {
if (status === google.maps.GeocoderStatus.OK) {
methods._setMapCenter.apply(that, [result[0].geometry.location]);
} else {
if (opts.log) {console.log("Geocode was not successful for the following reason: " + status); }
}
}
);
}
}
return center;
},
/**
* clustering
*/
_renderCluster: function () {
var $data = this.data('gmap'),
markers = $data.markers,
clusters = $data.clusters,
opts = $data.opts,
i,
j,
viewport;
for (i = 0; i < clusters.length; i += 1) {
clusters[i].getMarker().setMap(null);
}
clusters.length = 0;
viewport = $data.gmap.getBounds();
if (!viewport) {
var that = this;
window.setTimeout(function () {methods._renderCluster.apply(that); }, 1000);
return;
}
var ne = viewport.getNorthEast(),
sw = viewport.getSouthWest(),
width = ne.lat() - sw.lat(),
// height = ne.lng() - sw.lng(), // unused
clusterable = [],
best,
bestDist,
maxSize = width * opts.clustering.clusterSize / 100,
dist,
newCluster;
for (i = 0; i < markers.length; i += 1) {
if (markers[i].latitude < ne.lat() &&
markers[i].latitude > sw.lat() &&
markers[i].longitude < ne.lng() &&
markers[i].longitude > sw.lng()) {
clusterable[clusterable.length] = markers[i];
}
}
if (opts.log) {console.log("number of markers " + clusterable.length + "/" + markers.length); }
if (opts.log) {console.log('cluster radius: ' + maxSize); }
for (i = 0; i < clusterable.length; i += 1) {
bestDist = 10000;
best = -1;
for (j = 0; j < clusters.length; j += 1) {
dist = clusters[j].dist(clusterable[i]);
if (dist < maxSize) {
bestDist = dist;
best = j;
if (opts.clustering.fastClustering) {break; }
}
}
if (best === -1) {
newCluster = new Cluster();
newCluster.addMarker(clusterable[i]);
clusters[clusters.length] = newCluster;
} else {
clusters[best].addMarker(clusterable[i]);
}
}
if (opts.log) {console.log("Total clusters in viewport: " + clusters.length); }
for (j = 0; j < clusters.length; j += 1) {
clusters[j].getMarker().setMap($data.gmap);
}
},
_processMarker: function (marker, gicon, gshadow, location) {
var $data = this.data('gmap'),
$gmap = $data.gmap,
opts = $data.opts,
gmarker,
markeropts;
if (location === undefined) {
location = new $googlemaps.LatLng(marker.latitude, marker.longitude);
}
if (!gicon) {
// Set icon properties from global options
var _gicon = {
image: opts.icon.image,
iconSize: new $googlemaps.Size(opts.icon.iconsize[0], opts.icon.iconsize[1]),
iconAnchor: new $googlemaps.Point(opts.icon.iconanchor[0], opts.icon.iconanchor[1]),
infoWindowAnchor: new $googlemaps.Size(opts.icon.infowindowanchor[0], opts.icon.infowindowanchor[1])
};
gicon = new $googlemaps.MarkerImage(_gicon.image, _gicon.iconSize, null, _gicon.iconAnchor);
}
if (!gshadow) {
var _gshadow = {
image: opts.icon.shadow,
iconSize: new $googlemaps.Size(opts.icon.shadowsize[0], opts.icon.shadowsize[1]),
anchor: (_gicon && _gicon.iconAnchor)?_gicon.iconAnchor:new $googlemaps.Point(opts.icon.iconanchor[0], opts.icon.iconanchor[1])
};
}
markeropts = {
position: location,
icon: gicon,
title: marker.title,
map: null,
draggable: ((marker.draggable === true) ? true : false)
};
if (!opts.clustering.enabled) {markeropts.map = $gmap; }
gmarker = new $googlemaps.Marker(markeropts);
gmarker.setShadow(gshadow);
$data.markers.push(gmarker);
if(marker.key) {$data.markerKeys[marker.key] = gmarker; }
// Set HTML and check if info window should be opened
var infoWindow;
if (marker.html) {
var infoContent = typeof(marker.html) === "string" ? opts.html_prepend + marker.html + opts.html_append : marker.html;
var infoOpts = {
content: infoContent,
pixelOffset: marker.infoWindowAnchor
};
if (opts.log) {console.log('setup popup with data'); }
if (opts.log) {console.log(infoOpts); }
infoWindow = new $googlemaps.InfoWindow(infoOpts);
$googlemaps.event.addListener(gmarker, 'click', function () {
if (opts.log) {console.log('opening popup ' + marker.html); }
if (opts.singleInfoWindow && $data.infoWindow) {$data.infoWindow.close(); }
infoWindow.open($gmap, gmarker);
$data.infoWindow = infoWindow;
});
}
if (marker.html && marker.popup) {
if (opts.log) {console.log('opening popup ' + marker.html); }
infoWindow.open($gmap, gmarker);
$data.infoWindow = infoWindow;
}
if (marker.onDragEnd){
$googlemaps.event.addListener(gmarker, 'dragend', function(event) {
if (opts.log) {console.log('drag end');}
marker.onDragEnd(event);
});
}
},
_geocodeMarker: function (marker, gicon, gshadow) {
var that = this;
$geocoder.geocode({'address': marker.address}, function (results, status) {
if (status === $googlemaps.GeocoderStatus.OK) {
$markersToLoad -= 1;
if (that.data('gmap').opts.log) {console.log("Geocode was successful with point: ", results[0].geometry.location); }
methods._processMarker.apply(that, [marker, gicon, gshadow, results[0].geometry.location]);
} else {
if(status === $googlemaps.GeocoderStatus.OVER_QUERY_LIMIT) {
if ((!that.data('gmap').opts.noAlerts) && (overQueryLimit === 0)) {alert('Error: too many geocoded addresses! Switching to 1 marker/s mode.'); }
overQueryLimit+=1000;
window.setTimeout(function() {
methods._geocodeMarker.apply(that, [marker, gicon, gshadow]);
}, overQueryLimit);
}
if (that.data('gmap').opts.log) {console.log("Geocode was not successful for the following reason: " + status); }
}
});
},
_autoZoom: function (options, fromMarkers){
var data = $(this).data('gmap'),
opts = $.extend({}, data?data.opts:{}, options),
i, boundaries, resX, resY, baseScale = 39135.758482;
if (opts.log) {console.log("autozooming map");}
if(fromMarkers) boundaries = methods._getBoundariesFromMarkers.apply(this);
else boundaries = methods._getBoundaries(opts);
resX = (boundaries.E - boundaries.W) * 111000 / this.width();
resY = (boundaries.S - boundaries.N) * 111000 / this.height();
for(i = 2; i < 20; i += 1) {
if (resX > baseScale || resY > baseScale) {
break;
}
baseScale = baseScale / 2;
}
return i - 2;
},
/**
* public methods section
*/
/**
* add array of markers
* @param markers
*/
addMarkers: function (markers){
var opts = this.data('gmap').opts;
if (markers.length !== 0) {
if (opts.log) {console.log("adding " + markers.length +" markers");}
// Loop through marker array
for (var i = 0; i < markers.length; i+= 1) {
methods.addMarker.apply(this,[markers[i]]);
}
}
},
/**
* add single marker
* @param marker
*/
addMarker: function (marker) {
var opts = this.data('gmap').opts;
if (opts.log) {console.log("putting marker at " + marker.latitude + ', ' + marker.longitude + " with address " + marker.address + " and html " + marker.html); }
// Create new icon
// Set icon properties from global options
var _gicon = {
image: opts.icon.image,
iconSize: new $googlemaps.Size(opts.icon.iconsize[0], opts.icon.iconsize[1]),
iconAnchor: new $googlemaps.Point(opts.icon.iconanchor[0], opts.icon.iconanchor[1]),
infoWindowAnchor: new $googlemaps.Size(opts.icon.infowindowanchor[0], opts.icon.infowindowanchor[1])
},
_gshadow = {
image: opts.icon.shadow,
iconSize: new $googlemaps.Size(opts.icon.shadowsize[0], opts.icon.shadowsize[1]),
anchor: new $googlemaps.Point(opts.icon.shadowanchor[0], opts.icon.shadowanchor[1])
};
// not very nice, but useful
marker.infoWindowAnchor = _gicon.infoWindowAnchor;
if (marker.icon) {
// Overwrite global options
if (marker.icon.image) { _gicon.image = marker.icon.image; }
if (marker.icon.iconsize) { _gicon.iconSize = new $googlemaps.Size(marker.icon.iconsize[0], marker.icon.iconsize[1]); }
if (marker.icon.iconanchor) { _gicon.iconAnchor = new $googlemaps.Point(marker.icon.iconanchor[0], marker.icon.iconanchor[1]); }
if (marker.icon.infowindowanchor) { _gicon.infoWindowAnchor = new $googlemaps.Size(marker.icon.infowindowanchor[0], marker.icon.infowindowanchor[1]); }
if (marker.icon.shadow) { _gshadow.image = marker.icon.shadow; }
if (marker.icon.shadowsize) { _gshadow.iconSize = new $googlemaps.Size(marker.icon.shadowsize[0], marker.icon.shadowsize[1]); }
if (marker.icon.shadowanchor) { _gshadow.anchor = new $googlemaps.Point(marker.icon.shadowanchor[0], marker.icon.shadowanchor[1]); }
}
var gicon = new $googlemaps.MarkerImage(_gicon.image, _gicon.iconSize, null, _gicon.iconAnchor);
var gshadow = new $googlemaps.MarkerImage( _gshadow.image,_gshadow.iconSize, null, _gshadow.anchor);
// Check if address is available
if (marker.address) {
// Check for reference to the marker's address
if (marker.html === '_address') {
marker.html = marker.address;
}
if (marker.title == '_address') {
marker.title = marker.address;
}
if (opts.log) {console.log('geocoding marker: ' + marker.address); }
// Get the point for given address
$markersToLoad += 1;
methods._delayedMode = true;
methods._geocodeMarker.apply(this, [marker, gicon, gshadow]);
} else {
// Check for reference to the marker's latitude/longitude
if (marker.html === '_latlng') {
marker.html = marker.latitude + ', ' + marker.longitude;
}
if (marker.title == '_latlng') {
marker.title = marker.latitude + ', ' + marker.longitude;
}
// Create marker
var gpoint = new $googlemaps.LatLng(marker.latitude, marker.longitude);
methods._processMarker.apply(this, [marker, gicon, gshadow, gpoint]);
}
},
/**
*
*/
removeAllMarkers: function () {
var markers = this.data('gmap').markers, i;
for (i = 0; i < markers.length; i += 1) {
markers[i].setMap(null);
delete markers[i];
}
markers.length = 0;
},
/**
* get marker by key, if set previously
* @param key
*/
getMarker: function (key) {
return this.data('gmap').markerKeys[key];
},
/**
* should be called if DOM element was resized
* @param nasty
*/
fixAfterResize: function (nasty) {
var data = this.data('gmap');
$googlemaps.event.trigger(data.gmap, 'resize');
if(nasty) {
data.gmap.panTo(new google.maps.LatLng(0,0));
}
data.gmap.panTo(this.gMap('_getMapCenter', data.opts));
},
/**
* change zoom, works with 'fit' option as well
* @param zoom
*/
setZoom: function (zoom, opts, fromMarkers) {
var $map = this.data('gmap').gmap;
if (zoom === "fit"){
zoom = methods._autoZoom.apply(this, [opts, fromMarkers]);
}
$map.setZoom(parseInt(zoom));
},
changeSettings: function (options) {
var data = this.data('gmap'),
markers = [], i;
for (i = 0; i < data.markers.length; i += 1) {
markers[i] = {
latitude: data.markers[i].getPosition().lat(),
longitude: data.markers[i].getPosition().lng()
}
}
options.markers = markers;
if(options.zoom) methods.setZoom.apply(this,[options.zoom, options]);
if(options.latitude || options.longitude) {
data.gmap.panTo(methods._getMapCenter.apply(this,[options]));
}
// add controls and maptype
},
mapclick: function(callback) {
google.maps.event.addListener(this.data('gmap').gmap, 'click', function(event) {
callback(event.latLng);
});
},
geocode: function(address, callback, errorCallback) {
$geocoder.geocode({'address': address}, function (results, status) {
if (status === $googlemaps.GeocoderStatus.OK) {
callback(results[0].geometry.location);
} else if(errorCallback) {
errorCallback(results, status);
}
});
},
getRoute: function (options) {
var $data = this.data('gmap'),
$gmap = $data.gmap,
$directionsDisplay = new $googlemaps.DirectionsRenderer(),
$directionsService = new $googlemaps.DirectionsService(),
$travelModes = { 'BYCAR': $googlemaps.DirectionsTravelMode.DRIVING, 'BYBICYCLE': $googlemaps.DirectionsTravelMode.BICYCLING, 'BYFOOT': $googlemaps.DirectionsTravelMode.WALKING },
$travelUnits = { 'MILES': $googlemaps.DirectionsUnitSystem.IMPERIAL, 'KM': $googlemaps.DirectionsUnitSystem.METRIC },
displayObj = null,
travelMode = null,
travelUnit = null,
unitSystem = null;
// look if there is an individual or otherwise a default object for this call to display route text informations
if(options.routeDisplay !== undefined){
displayObj = (options.routeDisplay instanceof jQuery) ? options.routeDisplay[0] : ((typeof options.routeDisplay == "string") ? $(options.routeDisplay)[0] : null);
} else if($data.opts.routeFinder.routeDisplay !== null){
displayObj = ($data.opts.routeFinder.routeDisplay instanceof jQuery) ? $data.opts.routeFinder.routeDisplay[0] : ((typeof $data.opts.routeFinder.routeDisplay == "string") ? $($data.opts.routeFinder.routeDisplay)[0] : null);
}
// set route renderer to map
$directionsDisplay.setMap($gmap);
if(displayObj !== null){
$directionsDisplay.setPanel(displayObj);
}
// get travel mode and unit
travelMode = ($travelModes[$data.opts.routeFinder.travelMode] !== undefined) ? $travelModes[$data.opts.routeFinder.travelMode] : $travelModes['BYCAR'];
travelUnit = ($travelUnits[$data.opts.routeFinder.travelUnit] !== undefined) ? $travelUnits[$data.opts.routeFinder.travelUnit] : $travelUnits['KM'];
// build request
var request = {
origin: options.from,
destination: options.to,
travelMode: travelMode,
unitSystem: travelUnit
};
// send request
$directionsService.route(request, function(result, status) {
// show the rout or otherwise show an error message in a defined container for route text information
if (status == $googlemaps.DirectionsStatus.OK) {
$directionsDisplay.setDirections(result);
} else if(displayObj !== null){
$(displayObj).html($data.opts.routeFinder.routeErrors[status]);
}
});
return this;
}
};
// Main plugin function
$.fn.gMap = 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 jQuery.gmap');
}
};
// Default settings
$.fn.gMap.defaults = {
log: false,
address: '',
latitude: null,
longitude: null,
zoom: 3,
maxZoom: null,
minZoom: null,
markers: [],
controls: {},
scrollwheel: true,
maptype: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
zoomControl: true,
panControl: false,
scaleControl: false,
streetViewControl: true,
controlsPositions: {
mapType: null,
zoom: null,
pan: null,
scale: null,
streetView: null
},
controlsStyle: {
mapType: google.maps.MapTypeControlStyle.DEFAULT,
zoom: google.maps.ZoomControlStyle.DEFAULT
},
singleInfoWindow: true,
html_prepend: '<div class="gmap_marker">',
html_append: '</div>',
icon: {
image: "http://www.google.com/mapfiles/marker.png",
iconsize: [20, 34],
iconanchor: [9, 34],
infowindowanchor: [9, 2],
shadow: "http://www.google.com/mapfiles/shadow50.png",
shadowsize: [37, 34],
shadowanchor: [9, 34]
},
onComplete: function () {},
routeFinder: {
travelMode: 'BYCAR',
travelUnit: 'KM',
routeDisplay: null,
routeErrors: {
'INVALID_REQUEST': 'The provided request is invalid.',
'NOT_FOUND': 'One or more of the given addresses could not be found.',
'OVER_QUERY_LIMIT': 'A temporary error occured. Please try again in a few minutes.',
'REQUEST_DENIED': 'An error occured. Please contact us.',
'UNKNOWN_ERROR': 'An unknown error occured. Please try again.',
'ZERO_RESULTS': 'No route could be found within the given addresses.'
}
},
clustering: {
enabled: false,
fastClustering: false,
clusterCount: 10,
clusterSize: 40 //radius as % of viewport width
}
};
}(jQuery));