123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- (function ( $ ) {
- /**
- * Holds google map object and related utility entities.
- * @constructor
- */
- function GMapContext(domElement, options) {
- var _map = new google.maps.Map(domElement, options);
- var _marker = new google.maps.Marker({
- position: new google.maps.LatLng(54.19335, -3.92695),
- map: _map,
- title: "Drag Me",
- draggable: options.draggable
- });
- return {
- map: _map,
- marker: _marker,
- circle: null,
- location: _marker.position,
- radius: options.radius,
- locationName: options.locationName,
- settings: options.settings,
- domContainer: domElement,
- geodecoder: new google.maps.Geocoder()
- }
- }
- // Utility functions for Google Map Manipulations
- var GmUtility = {
- /**
- * Draw a circle over the the map. Returns circle object.
- * Also writes new circle object in gmapContext.
- *
- * @param center - LatLng of the center of the circle
- * @param radius - radius in meters
- * @param gmapContext - context
- * @param options
- */
- drawCircle: function(gmapContext, center, radius, options) {
- if (gmapContext.circle != null) {
- gmapContext.circle.setMap(null);
- }
- if (radius > 0) {
- radius *= 1;
- options = $.extend({
- strokeColor: "#0000FF",
- strokeOpacity: 0.35,
- strokeWeight: 2,
- fillColor: "#0000FF",
- fillOpacity: 0.20
- }, options);
- options.map = gmapContext.map;
- options.radius = radius;
- options.center = center;
- gmapContext.circle = new google.maps.Circle(options);
- return gmapContext.circle;
- }
- return null;
- },
- /**
- *
- * @param gMapContext
- * @param location
- * @param callback
- */
- setPosition: function(gMapContext, location, callback) {
- gMapContext.location = location;
- gMapContext.marker.setPosition(location);
- gMapContext.map.panTo(location);
- this.drawCircle(gMapContext, location, gMapContext.radius, {});
- if (gMapContext.settings.enableReverseGeocode) {
- gMapContext.geodecoder.geocode({latLng: gMapContext.location}, function(results, status){
- if (status == google.maps.GeocoderStatus.OK && results.length > 0){
- gMapContext.locationName = results[0].formatted_address;
- }
- if (callback) {
- callback.call(this, gMapContext);
- }
- });
- } else {
- if (callback) {
- callback.call(this, gMapContext);
- }
- }
- },
- locationFromLatLng: function(lnlg) {
- return {latitude: lnlg.lat(), longitude: lnlg.lng()}
- }
- }
- function isPluginApplied(domObj) {
- return getContextForElement(domObj) != undefined;
- }
- function getContextForElement(domObj) {
- return $(domObj).data("locationpicker");
- }
- function updateInputValues(inputBinding, gmapContext){
- if (!inputBinding) return;
- var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
- if (inputBinding.latitudeInput) {
- inputBinding.latitudeInput.val(currentLocation.latitude);
- }
- if (inputBinding.longitudeInput) {
- inputBinding.longitudeInput.val(currentLocation.longitude);
- }
- if (inputBinding.radiusInput) {
- inputBinding.radiusInput.val(gmapContext.radius);
- }
- if (inputBinding.locationNameInput) {
- inputBinding.locationNameInput.val(gmapContext.locationName);
- }
- }
-
- function setupInputListenersInput(inputBinding, gmapContext) {
- if (inputBinding) {
- if (inputBinding.radiusInput){
- inputBinding.radiusInput.on("change", function() {
- gmapContext.radius = $(this).val();
- GmUtility.setPosition(gmapContext, gmapContext.location, function(context){
- context.settings.onchanged(GmUtility.locationFromLatLng(context.location), context.radius, false);
- });
- });
- }
- if (inputBinding.locationNameInput && gmapContext.settings.enableAutocomplete) {
- gmapContext.autocomplete = new google.maps.places.Autocomplete(inputBinding.locationNameInput.get(0));
- google.maps.event.addListener(gmapContext.autocomplete, 'place_changed', function() {
- var place = gmapContext.autocomplete.getPlace();
- if (!place.geometry) {
- gmapContext.settings.onlocationnotfound(place.name);
- return;
- }
- GmUtility.setPosition(gmapContext, place.geometry.location, function(context) {
- updateInputValues(inputBinding, context);
- context.settings.onchanged(GmUtility.locationFromLatLng(context.location), context.radius, false);
- });
- });
- }
- if (inputBinding.latitudeInput) {
- inputBinding.latitudeInput.on("change", function() {
- GmUtility.setPosition(gmapContext, new google.maps.LatLng($(this).val(), gmapContext.location.lng()), function(context){
- context.settings.onchanged(GmUtility.locationFromLatLng(context.location), context.radius, false);
- });
- });
- }
- if (inputBinding.longitudeInput) {
- inputBinding.longitudeInput.on("change", function() {
- GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.location.lat(), $(this).val()), function(context){
- context.settings.onchanged(GmUtility.locationFromLatLng(context.location), context.radius, false);
- });
- });
- }
- }
- }
- /**
- * Initialization:
- * $("#myMap").locationpicker(options);
- * @param options
- * @param params
- * @returns {*}
- */
- $.fn.locationpicker = function( options, params ) {
- if (typeof options == 'string') { // Command provided
- var _targetDomElement = this.get(0);
- // Plug-in is not applied - nothing to do.
- if (!isPluginApplied(_targetDomElement)) return;
- var gmapContext = getContextForElement(_targetDomElement);
- switch (options) {
- case "location":
- if (params == undefined) { // Getter
- var location = GmUtility.locationFromLatLng(gmapContext.location);
- location.radius = gmapContext.radius;
- location.name = gmapContext.locationName;
- return location;
- } else { // Setter
- if (params.radius) {
- gmapContext.radius = params.radius;
- }
- GmUtility.setPosition(gmapContext, new google.maps.LatLng(params.latitude, params.longitude), function(gmapContext) {
- updateInputValues(gmapContext.settings.inputBinding, gmapContext);
- });
- }
- break;
- case "subscribe":
- /**
- * Provides interface for subscribing for GoogleMap events.
- * See Google API documentation for details.
- * Parameters:
- * - event: string, name of the event
- * - callback: function, callback function to be invoked
- */
- if (options == undefined) { // Getter is not available
- return null;
- } else {
- var event = params.event;
- var callback = params.callback;
- if (!event || ! callback) {
- console.error("LocationPicker: Invalid arguments for method \"subscribe\"")
- return null;
- }
- google.maps.event.addListener(gmapContext.map, event, callback);
- }
- break;
- }
- return null;
- }
- return this.each(function() {
- var $target = $(this);
- // If plug-in hasn't been applied before - initialize, otherwise - skip
- if (isPluginApplied(this)) return;
- // Plug-in initialization is required
- // Defaults
- var settings = $.extend({}, $.fn.locationpicker.defaults, options );
- // Initialize
- var gmapContext = new GMapContext(this, {
- zoom: settings.zoom,
- center: new google.maps.LatLng(settings.location.latitude, settings.location.longitude),
- mapTypeId: google.maps.MapTypeId.ROADMAP,
- mapTypeControl: false,
- disableDoubleClickZoom: false,
- scrollwheel: settings.scrollwheel,
- streetViewControl: false,
- radius: settings.radius,
- locationName: settings.locationName,
- settings: settings,
- draggable: settings.draggable
- });
- $target.data("locationpicker", gmapContext);
- // Subscribe GMap events
- google.maps.event.addListener(gmapContext.marker, "dragend", function(event) {
- GmUtility.setPosition(gmapContext, gmapContext.marker.position, function(context){
- var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
- context.settings.onchanged(currentLocation, context.radius, true);
- updateInputValues(gmapContext.settings.inputBinding, gmapContext);
- });
- });
- GmUtility.setPosition(gmapContext, new google.maps.LatLng(settings.location.latitude, settings.location.longitude), function(context){
- updateInputValues(settings.inputBinding, gmapContext);
- context.settings.oninitialized($target);
- });
- // Set up input bindings if needed
- setupInputListenersInput(settings.inputBinding, gmapContext);
- });
- };
- $.fn.locationpicker.defaults = {
- location: {latitude: 40.7324319, longitude: -73.82480799999996},
- locationName: "",
- radius: 500,
- zoom: 15,
- scrollwheel: true,
- inputBinding: {
- latitudeInput: null,
- longitudeInput: null,
- radiusInput: null,
- locationNameInput: null
- },
- enableAutocomplete: false,
- enableReverseGeocode: true,
- draggable: true,
- onchanged: function(currentLocation, radius, isMarkerDropped) {},
- onlocationnotfound: function(locationName) {},
- oninitialized: function (component) {}
- }
- }( jQuery ));
|