/** * jQuery goMap * * @url http://www.pittss.lv/jquery/gomap/ * @author Jevgenijs Shtrauss * @version 1.3.3 2014.11.27 * This software is released under the MIT License */ (function($) { var geocoder = new google.maps.Geocoder(); function MyOverlay(map) { this.setMap(map); }; MyOverlay.prototype = new google.maps.OverlayView(); MyOverlay.prototype.onAdd = function() { }; MyOverlay.prototype.onRemove = function() { }; MyOverlay.prototype.draw = function() { }; $.goMap = {}; $.fn.goMap = function(options) { return this.each(function() { var goMap = $(this).data('goMap'); if(!goMap) { var goMapBase = $.extend(true, {}, $.goMapBase); $(this).data('goMap', goMapBase.init(this, options)); $.goMap = goMapBase; } else { $.goMap = goMap; } }); }; $.goMapBase = { defaults: { address: '', // Street, City, Country latitude: 56.9, longitude: 24.1, zoom: 4, delay: 200, hideByClick: true, oneInfoWindow: true, prefixId: 'gomarker', polyId: 'gopoly', groupId: 'gogroup', navigationControl: true, // Show or hide navigation control navigationControlOptions: { position: 'TOP_LEFT', // TOP, TOP_LEFT, TOP_RIGHT, BOTTOM, BOTTOM_LEFT, BOTTOM_RIGHT, LEFT, RIGHT style: 'DEFAULT' // DEFAULT, SMALL, LARGE }, mapTypeControl: true, // Show or hide map control mapTypeControlOptions: { position: 'TOP_RIGHT', // TOP, TOP_LEFT, TOP_RIGHT, BOTTOM, BOTTOM_LEFT, BOTTOM_RIGHT, LEFT, RIGHT style: 'DEFAULT'// DEFAULT, DROPDOWN_MENU, HORIZONTAL_BAR }, scaleControl: false, // Show or hide scale scrollwheel: true, // Mouse scroll whell directions: false, directionsResult: null, disableDoubleClickZoom: false, streetViewControl: false, markers: [], overlays: [], polyline: { color: '#FF0000', opacity: 1.0, weight: 2 }, polygon: { color: '#FF0000', opacity: 1.0, weight: 2, fillColor: '#FF0000', fillOpacity: 0.2 }, circle: { color: '#FF0000', opacity: 1.0, weight: 2, fillColor: '#FF0000', fillOpacity: 0.2 }, rectangle: { color: '#FF0000', opacity: 1.0, weight: 2, fillColor: '#FF0000', fillOpacity: 0.2 }, maptype: 'HYBRID', // Map type - HYBRID, ROADMAP, SATELLITE, TERRAIN html_prepend: '
', html_append: '
', addMarker: false }, map: null, count: 0, markers: [], polylines: [], polygons: [], circles: [], rectangles: [], tmpMarkers: [], geoMarkers: [], lockGeocode: false, bounds: null, overlays: null, overlay: null, mapId: null, plId: null, pgId: null, cId: null, rId: null, opts: null, centerLatLng: null, init: function(el, options) { var opts = $.extend(true, {}, $.goMapBase.defaults, options); this.mapId = $(el); this.opts = opts; if (opts.address) this.geocode({address: opts.address, center: true}); // else if (opts.latitude != $.goMapBase.defaults.latitude && opts.longitude != $.goMapBase.defaults.longitude) // this.centerLatLng = new google.maps.LatLng(opts.latitude, opts.longitude); else if ($.isArray(opts.markers) && opts.markers.length > 0) { if (opts.markers[0].address) this.geocode({address: opts.markers[0].address, center: true}); else this.centerLatLng = new google.maps.LatLng(opts.markers[0].latitude, opts.markers[0].longitude); } else this.centerLatLng = new google.maps.LatLng(opts.latitude, opts.longitude); var myOptions = { center: this.centerLatLng, disableDoubleClickZoom: opts.disableDoubleClickZoom, mapTypeControl: opts.mapTypeControl, streetViewControl: opts.streetViewControl, mapTypeControlOptions: { position: google.maps.ControlPosition[opts.mapTypeControlOptions.position.toUpperCase()], style: google.maps.MapTypeControlStyle[opts.mapTypeControlOptions.style.toUpperCase()] }, mapTypeId: google.maps.MapTypeId[opts.maptype.toUpperCase()], panControl: opts.navigationControl, zoomControl: opts.navigationControl, panControlOptions: { position: google.maps.ControlPosition[opts.navigationControlOptions.position.toUpperCase()] }, zoomControlOptions: { position: google.maps.ControlPosition[opts.navigationControlOptions.position.toUpperCase()], style: google.maps.ZoomControlStyle[opts.navigationControlOptions.style.toUpperCase()] }, scaleControl: opts.scaleControl, scrollwheel: opts.scrollwheel, zoom: opts.zoom }; this.map = new google.maps.Map(el, myOptions); this.overlay = new MyOverlay(this.map); this.overlays = { polyline: { id: 'plId', array: 'polylines', create: 'createPolyline' }, polygon: { id: 'pgId', array: 'polygons', create: 'createPolygon' }, circle: { id: 'cId', array: 'circles', create: 'createCircle' }, rectangle: { id: 'rId', array: 'rectangles', create: 'createRectangle' } }; this.plId = $('
').appendTo(this.mapId); this.pgId = $('
').appendTo(this.mapId); this.cId = $('
').appendTo(this.mapId); this.rId = $('
').appendTo(this.mapId); for (var j = 0, l = opts.markers.length; j < l; j++) this.createMarker(opts.markers[j]); for (var j = 0, l = opts.overlays.length; j < l; j++) this[this.overlays[opts.overlays[j].type].create](opts.overlays[j]); var goMap = this; if (opts.addMarker == true || opts.addMarker == 'multi') { google.maps.event.addListener(goMap.map, 'click', function(event) { var options = { position: event.latLng, draggable: true }; var marker = goMap.createMarker(options); google.maps.event.addListener(marker, 'dblclick', function(event) { marker.setMap(null); goMap.removeMarker(marker.id); }); }); } else if (opts.addMarker == 'single') { google.maps.event.addListener(goMap.map, 'click', function(event) { if(!goMap.singleMarker) { var options = { position: event.latLng, draggable: true }; var marker = goMap.createMarker(options); goMap.singleMarker = true; google.maps.event.addListener(marker, 'dblclick', function(event) { marker.setMap(null); goMap.removeMarker(marker.id); goMap.singleMarker = false; }); } }); } delete opts.markers; delete opts.overlays; return this; }, ready: function(f) { google.maps.event.addListenerOnce(this.map, 'bounds_changed', function() { return f(); }); }, geocode: function(address, options) { var goMap = this; setTimeout(function() { geocoder.geocode({'address': address.address}, function(results, status) { if (status == google.maps.GeocoderStatus.OK && address.center) goMap.map.setCenter(results[0].geometry.location); if (status == google.maps.GeocoderStatus.OK && options && options.markerId) options.markerId.setPosition(results[0].geometry.location); else if (status == google.maps.GeocoderStatus.OK && options) { if(goMap.lockGeocode) { goMap.lockGeocode = false; options.position = results[0].geometry.location; options.geocode = true; goMap.createMarker(options); } } else if(status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) { goMap.geocode(address, options); } }); }, this.opts.delay); }, geoMarker: function() { if(this.geoMarkers.length > 0 && !this.lockGeocode) { this.lockGeocode = true; var current = this.geoMarkers.splice(0, 1); this.geocode({address:current[0].address}, current[0]); } else if(this.lockGeocode) { var goMap = this; setTimeout(function() { goMap.geoMarker(); }, this.opts.delay); } }, setMap: function(options) { delete options.mapTypeId; if (options.address) { this.geocode({address: options.address, center: true}); delete options.address; } else if (options.latitude && options.longitude) { options.center = new google.maps.LatLng(options.latitude, options.longitude); delete options.longitude; delete options.latitude; } if(options.mapTypeControlOptions && options.mapTypeControlOptions.position) options.mapTypeControlOptions.position = google.maps.ControlPosition[options.mapTypeControlOptions.position.toUpperCase()]; if(options.mapTypeControlOptions && options.mapTypeControlOptions.style) options.mapTypeControlOptions.style = google.maps.MapTypeControlStyle[options.mapTypeControlOptions.style.toUpperCase()]; if(typeof options.navigationControl !== 'undefined') { options.panControl = options.navigationControl; options.zoomControl = options.navigationControl; } if(options.navigationControlOptions && options.navigationControlOptions.position) { options.panControlOptions = {position: google.maps.ControlPosition[options.navigationControlOptions.position.toUpperCase()]}; options.zoomControlOptions = {position: google.maps.ControlPosition[options.navigationControlOptions.position.toUpperCase()]}; } if(options.navigationControlOptions && options.navigationControlOptions.style) { if(typeof options.zoomControlOptions === 'undefined') options.zoomControlOptions = {style: google.maps.ZoomControlStyle[options.navigationControlOptions.style.toUpperCase()]}; else options.zoomControlOptions.style = google.maps.ZoomControlStyle[options.navigationControlOptions.style.toUpperCase()]; } this.map.setOptions(options); }, getMap: function() { return this.map; }, createListener: function(type, event, data) { var target; if(typeof type != 'object') type = {type:type}; if(type.type == 'map') target = this.map; else if(type.type == 'marker' && type.marker) target = $(this.mapId).data(type.marker); else if(type.type == 'info' && type.marker) target = $(this.mapId).data(type.marker + 'info'); if(target) return google.maps.event.addListener(target, event, data); else if((type.type == 'marker' || type.type == 'info') && this.getMarkerCount() != this.getTmpMarkerCount()) var goMap = this; setTimeout(function() { goMap.createListener(type, event, data); }, this.opts.delay); }, removeListener: function(listener) { google.maps.event.removeListener(listener); }, setInfoWindow: function(marker, html) { var goMap = this; html.content = goMap.opts.html_prepend + html.content + goMap.opts.html_append; var infowindow = new google.maps.InfoWindow(html); infowindow.show = false; $(goMap.mapId).data(marker.id + 'info',infowindow); if (html.popup) { goMap.openWindow(infowindow, marker, html); infowindow.show = true; } google.maps.event.addListener(marker, 'click', function() { if (infowindow.show && goMap.opts.hideByClick) { infowindow.close(); infowindow.show = false; } else { goMap.openWindow(infowindow, marker, html); infowindow.show = true; } }); }, openWindow: function(infowindow, marker, html) { var goMap = this; if(this.opts.oneInfoWindow) this.clearInfo(); if (html.ajax) { infowindow.open(this.map, marker); $.ajax({ url: html.ajax, success: function(html) { infowindow.setContent(goMap.opts.html_prepend + html + goMap.opts.html_append); } }); } else if (html.id) { infowindow.setContent(goMap.opts.html_prepend + $(html.id).html() + goMap.opts.html_append); infowindow.open(this.map, marker); } else infowindow.open(this.map, marker); }, setInfo: function(id, text) { var info = $(this.mapId).data(id + 'info'); if(typeof text == 'object') info.setOptions(goMap.opts.html_prepend + text + goMap.opts.html_append); else info.setContent(goMap.opts.html_prepend + text + goMap.opts.html_append); }, getInfo: function(id, hideDiv) { var info = $(this.mapId).data(id + 'info').getContent(); if(hideDiv) return $(info).html(); else return info; }, clearInfo: function() { for (var i = 0, l = this.markers.length; i < l; i++) { var info = $(this.mapId).data(this.markers[i] + 'info'); if(info) { info.close(); info.show = false; } } }, fitBounds: function(type, markers) { var goMap = this; if(this.getMarkerCount() != this.getTmpMarkerCount()) setTimeout(function() { goMap.fitBounds(type, markers); }, this.opts.delay); else { this.bounds = new google.maps.LatLngBounds(); if(!type || (type && type == 'all')) { for (var i = 0, l = this.markers.length; i < l; i++) { this.bounds.extend($(this.mapId).data(this.markers[i]).position); } } else if (type && type == 'visible') { for (var i = 0, l = this.markers.length; i < l; i++) { if(this.getVisibleMarker(this.markers[i])) this.bounds.extend($(this.mapId).data(this.markers[i]).position); } } else if (type && type == 'markers' && $.isArray(markers)) { for (var i = 0, l = markers.length; i < l; i++) { this.bounds.extend($(this.mapId).data(markers[i]).position); } } this.map.fitBounds(this.bounds); } }, getBounds: function() { return this.map.getBounds(); }, createPolyline: function(poly) { poly.type = 'polyline'; return this.createOverlay(poly); }, createPolygon: function(poly) { poly.type = 'polygon'; return this.createOverlay(poly); }, createCircle: function(poly) { poly.type = 'circle'; return this.createOverlay(poly); }, createRectangle: function(poly) { poly.type = 'rectangle'; return this.createOverlay(poly); }, createOverlay: function(poly) { var overlay = []; if (!poly.id) { this.count++; poly.id = this.opts.polyId + this.count; } switch(poly.type) { case 'polyline': if (poly.coords.length > 0) { for (var j = 0, l = poly.coords.length; j < l; j++) overlay.push(new google.maps.LatLng(poly.coords[j].latitude, poly.coords[j].longitude)); overlay = new google.maps.Polyline({ map: this.map, path: overlay, strokeColor: poly.color ? poly.color : this.opts.polyline.color, strokeOpacity: poly.opacity ? poly.opacity : this.opts.polyline.opacity, strokeWeight: poly.weight ? poly.weight : this.opts.polyline.weight }); } else return false; break; case 'polygon': if (poly.coords.length > 0) { for (var j = 0, l = poly.coords.length; j < l; j++) overlay.push(new google.maps.LatLng(poly.coords[j].latitude, poly.coords[j].longitude)); overlay = new google.maps.Polygon({ map: this.map, path: overlay, strokeColor: poly.color ? poly.color : this.opts.polygon.color, strokeOpacity: poly.opacity ? poly.opacity : this.opts.polygon.opacity, strokeWeight: poly.weight ? poly.weight : this.opts.polygon.weight, fillColor: poly.fillColor ? poly.fillColor : this.opts.polygon.fillColor, fillOpacity: poly.fillOpacity ? poly.fillOpacity : this.opts.polygon.fillOpacity }); } else return false; break; case 'circle': overlay = new google.maps.Circle({ map: this.map, center: new google.maps.LatLng(poly.latitude, poly.longitude), radius: poly.radius, strokeColor: poly.color ? poly.color : this.opts.circle.color, strokeOpacity: poly.opacity ? poly.opacity : this.opts.circle.opacity, strokeWeight: poly.weight ? poly.weight : this.opts.circle.weight, fillColor: poly.fillColor ? poly.fillColor : this.opts.circle.fillColor, fillOpacity: poly.fillOpacity ? poly.fillOpacity : this.opts.circle.fillOpacity }); break; case 'rectangle': overlay = new google.maps.Rectangle({ map: this.map, bounds: new google.maps.LatLngBounds(new google.maps.LatLng(poly.sw.latitude, poly.sw.longitude), new google.maps.LatLng(poly.ne.latitude, poly.ne.longitude)), strokeColor: poly.color ? poly.color : this.opts.circle.color, strokeOpacity: poly.opacity ? poly.opacity : this.opts.circle.opacity, strokeWeight: poly.weight ? poly.weight : this.opts.circle.weight, fillColor: poly.fillColor ? poly.fillColor : this.opts.circle.fillColor, fillOpacity: poly.fillOpacity ? poly.fillOpacity : this.opts.circle.fillOpacity }); break; default: return false; break; } this.addOverlay(poly, overlay); return overlay; }, addOverlay: function(poly, overlay) { $(this[this.overlays[poly.type].id]).data(poly.id, overlay); this[this.overlays[poly.type].array].push(poly.id); }, setOverlay: function(type, overlay, options) { overlay = $(this[this.overlays[type].id]).data(overlay); if (options.coords && options.coords.length > 0) { var array = []; for (var j = 0, l = options.coords.length; j < l; j++) array.push(new google.maps.LatLng(options.coords[j].latitude, options.coords[j].longitude)); options.path = array; delete options.coords; } else if (options.ne && options.sw) { options.bounds = new google.maps.LatLngBounds(new google.maps.LatLng(options.sw.latitude, options.sw.longitude), new google.maps.LatLng(options.ne.latitude, options.ne.longitude)); delete options.ne; delete options.sw; } else if (options.latitude && options.longitude) { options.center = new google.maps.LatLng(options.latitude, options.longitude); delete options.latitude; delete options.longitude; } overlay.setOptions(options); }, showHideOverlay: function(type, overlay, display) { if(typeof display === 'undefined') { if(this.getVisibleOverlay(type, overlay)) display = false; else display = true; } if(display) $(this[this.overlays[type].id]).data(overlay).setMap(this.map); else $(this[this.overlays[type].id]).data(overlay).setMap(null); }, getVisibleOverlay: function(type, overlay) { if($(this[this.overlays[type].id]).data(overlay).getMap()) return true; else return false; }, getOverlaysCount: function(type) { return this[this.overlays[type].array].length; }, removeOverlay: function(type, overlay) { var index = $.inArray(overlay, this[this.overlays[type].array]), current; if (index > -1) { current = this[this.overlays[type].array].splice(index, 1); var markerId = current[0]; $(this[this.overlays[type].id]).data(markerId).setMap(null); $(this[this.overlays[type].id]).removeData(markerId); return true; } return false; }, clearOverlays: function(type) { for (var i = 0, l = this[this.overlays[type].array].length; i < l; i++) { var markerId = this[this.overlays[type].array][i]; $(this[this.overlays[type].id]).data(markerId).setMap(null); $(this[this.overlays[type].id]).removeData(markerId); } this[this.overlays[type].array] = []; }, showHideMarker: function(marker, display) { if(typeof display === 'undefined') { if(this.getVisibleMarker(marker)) { $(this.mapId).data(marker).setVisible(false); var info = $(this.mapId).data(marker + 'info'); if(info && info.show) { info.close(); info.show = false; } } else $(this.mapId).data(marker).setVisible(true); } else $(this.mapId).data(marker).setVisible(display); }, showHideMarkerByGroup: function(group, display) { for (var i = 0, l = this.markers.length; i < l; i++) { var markerId = this.markers[i]; var marker = $(this.mapId).data(markerId); if(marker.group == group) { if(typeof display === 'undefined') { if(this.getVisibleMarker(markerId)) { marker.setVisible(false); var info = $(this.mapId).data(markerId + 'info'); if(info && info.show) { info.close(); info.show = false; } } else marker.setVisible(true); } else marker.setVisible(display); } } }, getVisibleMarker: function(marker) { return $(this.mapId).data(marker).getVisible(); }, getMarkerCount: function() { return this.markers.length; }, getTmpMarkerCount: function() { return this.tmpMarkers.length; }, getVisibleMarkerCount: function() { return this.getMarkers('visiblesInMap').length; }, getMarkerByGroupCount: function(group) { return this.getMarkers('group', group).length; }, getMarkers: function(type, name) { var array = []; switch(type) { case "json": for (var i = 0, l = this.markers.length; i < l; i++) { var temp = "'" + i + "': '" + $(this.mapId).data(this.markers[i]).getPosition().toUrlValue() + "'"; array.push(temp); } array = "{'markers':{" + array.join(",") + "}}"; break; case "data": for (var i = 0, l = this.markers.length; i < l; i++) { var temp = "marker[" + i + "]=" + $(this.mapId).data(this.markers[i]).getPosition().toUrlValue(); array.push(temp); } array = array.join("&"); break; case "visiblesInBounds": for (var i = 0, l = this.markers.length; i < l; i++) { if (this.isVisible($(this.mapId).data(this.markers[i]).getPosition())) array.push(this.markers[i]); } break; case "visiblesInMap": for (var i = 0, l = this.markers.length; i < l; i++) { if(this.getVisibleMarker(this.markers[i])) array.push(this.markers[i]); } break; case "group": if(name) for (var i = 0, l = this.markers.length; i < l; i++) { if($(this.mapId).data(this.markers[i]).group == name) array.push(this.markers[i]); } break; case "markers": for (var i = 0, l = this.markers.length; i < l; i++) { var temp = $(this.mapId).data(this.markers[i]); array.push(temp); } break; default: for (var i = 0, l = this.markers.length; i < l; i++) { var temp = $(this.mapId).data(this.markers[i]).getPosition().toUrlValue(); array.push(temp); } break; } return array; }, getVisibleMarkers: function() { return this.getMarkers('visiblesInBounds'); }, createMarker: function(marker) { if (!marker.geocode) { this.count++; if (!marker.id) marker.id = this.opts.prefixId + this.count; this.tmpMarkers.push(marker.id); } if (marker.address && !marker.geocode) { this.geoMarkers.push(marker); this.geoMarker(); } else if (marker.latitude && marker.longitude || marker.position) { var options = { map:this.map }; options.id = marker.id; options.group = marker.group ? marker.group : this.opts.groupId; options.zIndex = marker.zIndex ? marker.zIndex : 0; options.zIndexOrg = marker.zIndexOrg ? marker.zIndexOrg : 0; if (marker.visible == false) options.visible = marker.visible; if (marker.title) options.title = marker.title; if (marker.draggable) options.draggable = marker.draggable; if (marker.icon && marker.icon.image) { options.icon = marker.icon.image; if (marker.icon.shadow) options.shadow = marker.icon.shadow; } else if (marker.icon) options.icon = marker.icon; else if (this.opts.icon && this.opts.icon.image) { options.icon = this.opts.icon.image; if (this.opts.icon.shadow) options.shadow = this.opts.icon.shadow; } else if (this.opts.icon) options.icon = this.opts.icon; options.position = marker.position ? marker.position : new google.maps.LatLng(marker.latitude, marker.longitude); var cmarker = new google.maps.Marker(options); if (marker.html) { if (!marker.html.content && !marker.html.ajax && !marker.html.id) marker.html = { content:marker.html }; else if (!marker.html.content) marker.html.content = null; this.setInfoWindow(cmarker, marker.html); } this.addMarker(cmarker); return cmarker; } }, addMarker: function(marker) { $(this.mapId).data(marker.id, marker); this.markers.push(marker.id); }, setMarker: function(marker, options) { var tmarker = $(this.mapId).data(marker); delete options.id; delete options.visible; if(options.icon) { var toption = options.icon; delete options.icon; if(toption && toption == 'default') { if (this.opts.icon && this.opts.icon.image) { options.icon = this.opts.icon.image; if (this.opts.icon.shadow) options.shadow = this.opts.icon.shadow; } else if (this.opts.icon) options.icon = this.opts.icon; } else if(toption && toption.image) { options.icon = toption.image; if (toption.shadow) options.shadow = toption.shadow; } else if (toption) options.icon = toption; } if (options.address) { this.geocode({address: options.address}, {markerId:tmarker}); delete options.address; delete options.latitude; delete options.longitude; delete options.position; } else if (options.latitude && options.longitude || options.position) { if (!options.position) options.position = new google.maps.LatLng(options.latitude, options.longitude); } tmarker.setOptions(options); }, removeMarker: function(marker) { var index = $.inArray(marker, this.markers), current; if (index > -1) { this.tmpMarkers.splice(index,1); current = this.markers.splice(index,1); var markerId = current[0]; var marker = $(this.mapId).data(markerId); var info = $(this.mapId).data(markerId + 'info'); marker.setVisible(false); marker.setMap(null); $(this.mapId).removeData(markerId); if(info) { info.close(); info.show = false; $(this.mapId).removeData(markerId + 'info'); } return true; } return false; }, clearMarkers: function() { for (var i = 0, l = this.markers.length; i < l; i++) { var markerId = this.markers[i]; var marker = $(this.mapId).data(markerId); var info = $(this.mapId).data(markerId + 'info'); marker.setVisible(false); marker.setMap(null); $(this.mapId).removeData(markerId); if(info) { info.close(); info.show = false; $(this.mapId).removeData(markerId + 'info'); } } this.singleMarker = false; this.lockGeocode = false; this.markers = []; this.tmpMarkers = []; this.geoMarkers = []; }, isVisible: function(latlng) { return this.map.getBounds().contains(latlng); } } })(jQuery);