Не знаю в чем может быть проблема ? вот такая фигня, ничего не вписывается на локацию не реагирует. Кто сталкивался помогите решить .. Фото http://www.picshare.ru/view/7900207/ --- Добавлено, 7 фев 2017 --- Нашел косячный фаил , но не могу понять где тут косяк )))) Код: /*! * GMAP3 Plugin for JQuery * Version : 5.0b * Date : 2012-11-17 * Licence : GPL v3 : http://www.gnu.org/licenses/gpl.html * Author : DEMONTE Jean-Baptiste * Contact : [email protected] * Web site : http://gmap3.net * * Copyright (c) 2010-2012 Jean-Baptiste DEMONTE * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * - Neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ (function ($, undef) { /***************************************************************************/ /* GMAP3 DEFAULTS */ /***************************************************************************/ // defaults are defined later in the code to pass the rails asset pipeline and //jasmine while google library is not loaded var defaults, gId = 0; function initDefaults() { if (!defaults) { defaults = { verbose: false, queryLimit: { attempt: 5, delay: 250, // setTimeout(..., delay + random); random: 250 }, classes: { Map : google.maps.Map, Marker : google.maps.Marker, InfoWindow : google.maps.InfoWindow, Circle : google.maps.Circle, Rectangle : google.maps.Rectangle, OverlayView : google.maps.OverlayView, StreetViewPanorama: google.maps.StreetViewPanorama, KmlLayer : google.maps.KmlLayer, TrafficLayer : google.maps.TrafficLayer, BicyclingLayer : google.maps.BicyclingLayer, GroundOverlay : google.maps.GroundOverlay, StyledMapType : google.maps.StyledMapType, ImageMapType : google.maps.ImageMapType }, map: { mapTypeId : google.maps.MapTypeId.ROADMAP, center: [46.578498, 2.457275], zoom: 2 }, overlay: { pane: "floatPane", content: "", offset: { x: 0, y: 0 } }, geoloc: { getCurrentPosition: { maximumAge: 60000, timeout: 5000 } } } } } function globalId(id, simulate){ return id !== undef ? id : "gmap3_" + (simulate ? gId + 1 : ++gId); } /** * Return true if current version of Google Maps is equal or above to these in parameter * @param version {string} Minimal version required * @return {Boolean} */ function googleVersionMin(version) { var toInt = function(v){return parseInt(v, 10);}, // extract the google map version gmVersion = google.maps.version.split(".").map(toInt), i; version = version.split(".").map(toInt); for(i = 0; i < version.length; i++) { if (gmVersion.hasOwnProperty(i)) { if (gmVersion[i] < version[i]) { return false; } } else { return false; } } return true; } /** * attach events from a container to a sender * todo[ * events => { eventName => function, } * onces => { eventName => function, } * data => mixed data * ] **/ function attachEvents($container, args, sender, id, senders){ if (args.todo.events || args.todo.onces) { var context = { id: id, data: args.todo.data, tag: args.todo.tag }; if (args.todo.events){ $.each(args.todo.events, function(name, f){ var that = $container, fn = f; if ($.isArray(f)) { that = f[0]; fn = f[1] } google.maps.event.addListener(sender, name, function(event) { fn.apply(that, [senders ? senders : sender, event, context]); }); }); } if (args.todo.onces){ $.each(args.todo.onces, function(name, f){ var that = $container, fn = f; if ($.isArray(f)) { that = f[0]; fn = f[1] } google.maps.event.addListenerOnce(sender, name, function(event) { fn.apply(that, [senders ? senders : sender, event, context]); }); }); } } } /***************************************************************************/ /* STACK */ /***************************************************************************/ function Stack (){ var st = []; this.empty = function (){ return !st.length; }; this.add = function(v){ st.push(v); }; this.get = function (){ return st.length ? st[0] : false; }; this.ack = function (){ st.shift(); }; } /***************************************************************************/ /* TASK */ /***************************************************************************/ function Task(ctx, onEnd, todo){ var session = {}, that = this, current, resolve = { latLng:{ // function => bool (=> address = latLng) map:false, marker:false, infowindow:false, circle:false, overlay: false, getlatlng: false, getmaxzoom: false, getelevation: false, streetviewpanorama: false, getaddress: true }, geoloc:{ getgeoloc: true } }; if (typeof todo === "string"){ todo = unify(todo); } function unify(todo){ var result = {}; result[todo] = {}; return result; } function next(){ var k; for(k in todo){ if (k in session){ // already run continue; } return k; } } this.run = function (){ var k, opts; while(k = next()){ if (typeof ctx[k] === "function"){ current = k; opts = $.extend(true, {}, defaults[k] || {}, todo[k].options || {}); if (k in resolve.latLng){ if (todo[k].values){ resolveAllLatLng(todo[k].values, ctx, ctx[k], {todo:todo[k], opts:opts, session:session}); } else { resolveLatLng(ctx, ctx[k], resolve.latLng[k], {todo:todo[k], opts:opts, session:session}); } } else if (k in resolve.geoloc){ geoloc(ctx, ctx[k], {todo:todo[k], opts:opts, session:session}); } else { ctx[k].apply(ctx, [{todo:todo[k], opts:opts, session:session}]); } return; // wait until ack } else { session[k] = null; } } onEnd.apply(ctx, [todo, session]); }; this.ack = function(result){ session[current] = result; that.run.apply(that, []); }; } function getKeys(obj){ var k, keys = []; for(k in obj){ keys.push(k); } return keys; } function tuple(args, value){ var todo = {}; // "copy" the common data if (args.todo){ for(var k in args.todo){ if ((k !== "options") && (k !== "values")){ todo[k] = args.todo[k]; } } } // "copy" some specific keys from value first else args.todo var i, keys = ["data", "tag", "id", "events", "onces"]; for(i=0; i<keys.length; i++){ copyKey(todo, keys[i], value, args.todo); } // create an extended options todo.options = $.extend({}, args.opts || {}, value.options || {}); return todo; } /** * copy a key content **/ function copyKey(target, key){ for(var i=2; i<arguments.length; i++){ if (key in arguments[i]){ target[key] = arguments[i][key]; return; } } } /***************************************************************************/ /* GEOCODERCACHE */ /***************************************************************************/ function GeocoderCache(){ var cache = []; this.get = function(request){ if (cache.length){ var i, j, k, item, eq, keys = getKeys(request); for(i=0; i<cache.length; i++){ item = cache[i]; eq = keys.length == item.keys.length; for(j=0; (j<keys.length) && eq; j++){ k = keys[j]; eq = k in item.request; if (eq){ if ((typeof request[k] === "object") && ("equals" in request[k]) && (typeof request[k] === "function")){ eq = request[k].equals(item.request[k]); } else{ eq = request[k] === item.request[k]; } } } if (eq){ return item.results; } } } }; this.store = function(request, results){ cache.push({request:request, keys:getKeys(request), results:results}); }; } /***************************************************************************/ /* OVERLAYVIEW */ /***************************************************************************/ function OverlayView(map, opts, latLng, $div) { var that = this, listeners = []; defaults.classes.OverlayView.call(this); this.setMap(map); this.onAdd = function() { var panes = this.getPanes(); if (opts.pane in panes) { $(panes[opts.pane]).append($div); } $.each("dblclick click mouseover mousemove mouseout mouseup mousedown".split(" "), function(i, name){ listeners.push( google.maps.event.addDomListener($div[0], name, function(e) { $.Event(e).stopPropagation(); google.maps.event.trigger(that, name, [e]); that.draw(); }) ); }); listeners.push( google.maps.event.addDomListener($div[0], "contextmenu", function(e) { $.Event(e).stopPropagation(); google.maps.event.trigger(that, "rightclick", [e]); that.draw(); }) ); }; this.getPosition = function(){ return latLng; }; this.draw = function() { var ps = this.getProjection().fromLatLngToDivPixel(latLng); $div .css("left", (ps.x+opts.offset.x) + "px") .css("top" , (ps.y+opts.offset.y) + "px"); }; this.onRemove = function() { for (var i = 0; i < listeners.length; i++) { google.maps.event.removeListener(listeners[i]); } $div.remove(); }; this.hide = function() { $div.hide(); }; this.show = function() { $div.show(); }; this.toggle = function() { if ($div) { if ($div.is(":visible")){ this.show(); } else { this.hide(); } } }; this.toggleDOM = function() { if (this.getMap()) { this.setMap(null); } else { this.setMap(map); } }; this.getDOMElement = function() { return $div[0]; }; } /***************************************************************************/ /* CLUSTERING */ /***************************************************************************/ /** * Usefull to get a projection * => done in a function, to let dead-code analyser works without google library loaded **/ function newEmptyOverlay(map, radius){ function Overlay(){ this.onAdd = function(){}; this.onRemove = function(){}; this.draw = function(){}; return defaults.classes.OverlayView.apply(this, []); } Overlay.prototype = defaults.classes.OverlayView.prototype; var obj = new Overlay(); obj.setMap(map); return obj; } /** * Class InternalClusterer * This class manage clusters thanks to "todo" objects * * Note: * Individuals marker are created on the fly thanks to the todo objects, they are * first set to null to keep the indexes synchronised with the todo list * This is the "display" function, set by the gmap3 object, which uses theses data * to create markers when clusters are not required * To remove a marker, the objects are deleted and set not null in arrays * markers[key] * = null : marker exist but has not been displayed yet * = false : marker has been removed **/ function InternalClusterer($container, map, raw){ var updating = false, updated = false, redrawing = false, ready = false, enabled = true, that = this, events = [], store = {}, // combin of index (id1-id2-...) => object ids = {}, // unique id => index idxs = {}, // index => unique id markers = [], // index => marker todos = [], // index => todo or null if removed values = [], // index => value overlay = newEmptyOverlay(map, raw.radius), timer, projection, ffilter, fdisplay, ferror; // callback function main(); function prepareMarker(index) { if (!markers[index]) { delete todos[index].options.map; markers[index] = new defaults.classes.Marker(todos[index].options); attachEvents($container, {todo: todos[index]}, markers[index], todos[index].id); } } /** * return a marker by its id, null if not yet displayed and false if no exist or removed **/ this.getById = function(id){ if (id in ids) { prepareMarker(ids[id]); return markers[ids[id]]; } return false; }; /** * remove one object from the store **/ this.rm = function (id) { var index = ids[id]; if (markers[index]){ // can be null markers[index].setMap(null); } delete markers[index]; markers[index] = false; delete todos[index]; todos[index] = false; delete values[index]; values[index] = false; delete ids[id]; delete idxs[index]; updated = true; }; /** * remove a marker by its id **/ this.clearById = function(id){ if (id in ids){ this.rm(id); return true; } }; /** * remove objects from the store **/ this.clear = function(last, first, tag){ var start, stop, step, index, i, list = [], check = ftag(tag); if (last) { start = todos.length - 1; stop = -1; step = -1; } else { start = 0; stop = todos.length; step = 1; } for (index = start; index != stop; index += step) { if (todos[index]) { if (!check || check(todos[index].tag)){ list.push(idxs[index]); if (first || last) { break; } } } } for (i = 0; i < list.length; i++) { this.rm(list[i]); } }; // add a "marker todo" to the cluster this.add = function(todo, value){ todo.id = globalId(todo.id); this.clearById(todo.id); ids[todo.id] = markers.length; idxs[markers.length] = todo.id; markers.push(null); // null = marker not yet created / displayed todos.push(todo); values.push(value); updated = true; }; // add a real marker to the cluster this.addMarker = function(marker, todo){ todo = todo || {}; todo.id = globalId(todo.id); this.clearById(todo.id); if (!todo.options){ todo.options = {}; } todo.options.position = marker.getPosition(); attachEvents($container, {todo:todo}, marker, todo.id); ids[todo.id] = markers.length; idxs[markers.length] = todo.id; markers.push(marker); todos.push(todo); values.push(todo.data || {}); updated = true; }; // return a "marker todo" by its index this.todo = function(index){ return todos[index]; }; // return a "marker value" by its index this.value = function(index){ return values[index]; }; // return a marker by its index this.marker = function(index){ if (index in markers) { prepareMarker(index); return markers[index]; } return false; }; // return a marker by its index this.markerIsSet = function(index){ return Boolean(markers[index]); }; // store a new marker instead if the default "false" this.setMarker = function(index, marker){ markers[index] = marker; }; // link the visible overlay to the logical data (to hide overlays later) this.store = function(cluster, obj, shadow){ store[cluster.ref] = {obj:obj, shadow:shadow}; }; // free all objects this.free = function(){ for(var i = 0; i < events.length; i++){ google.maps.event.removeListener(events[i]); } events = []; $.each(store, function(key){ flush(key); }); store = {}; $.each(todos, function(i){ todos[i] = null; }); todos = []; $.each(markers, function(i){ if (markers[i]){ // false = removed markers[i].setMap(null); delete markers[i]; } }); markers = []; $.each(values, function(i){ delete values[i]; }); values = []; ids = {}; idxs = {}; }; // link the display function this.filter = function(f){ ffilter = f; redraw(); }; // enable/disable the clustering feature this.enable = function(value){ if (enabled != value){ enabled = value; redraw(); } }; // link the display function this.display = function(f){ fdisplay = f; }; // link the errorfunction this.error = function(f){ ferror = f; }; // lock the redraw this.beginUpdate = function(){ updating = true; }; // unlock the redraw this.endUpdate = function(){ updating = false; if (updated){ redraw(); } }; // extends current bounds with internal markers this.autofit = function(bounds){ for(var i=0; i<todos.length; i++){ if (todos[i]){ bounds.extend(todos[i].options.position); } } }; // bind events function main(){ projection = overlay.getProjection(); if (!projection){ setTimeout(function(){ main.apply(that, []); }, 25); return; } ready = true; events.push(google.maps.event.addListener(map, "zoom_changed", function(){delayRedraw();})); events.push(google.maps.event.addListener(map, "bounds_changed", function(){delayRedraw();})); redraw(); } // flush overlays function flush(key){ if (typeof store[key] === "object"){ // is overlay if (typeof(store[key].obj.setMap) === "function") { store[key].obj.setMap(null); } if (typeof(store[key].obj.remove) === "function") { store[key].obj.remove(); } if (typeof(store[key].shadow.remove) === "function") { store[key].obj.remove(); } if (typeof(store[key].shadow.setMap) === "function") { store[key].shadow.setMap(null); } delete store[key].obj; delete store[key].shadow; } else if (markers[key]){ // marker not removed markers[key].setMap(null); // don't remove the marker object, it may be displayed later } delete store[key]; } /** * return the distance between 2 latLng couple into meters * Params : * Lat1, Lng1, Lat2, Lng2 * LatLng1, Lat2, Lng2 * Lat1, Lng1, LatLng2 * LatLng1, LatLng2 **/ function distanceInMeter(){ var lat1, lat2, lng1, lng2, e, f, g, h; if (arguments[0] instanceof google.maps.LatLng){ lat1 = arguments[0].lat(); lng1 = arguments[0].lng(); if (arguments[1] instanceof google.maps.LatLng){ lat2 = arguments[1].lat(); lng2 = arguments[1].lng(); } else { lat2 = arguments[1]; lng2 = arguments[2]; } } else { lat1 = arguments[0]; lng1 = arguments[1]; if (arguments[2] instanceof google.maps.LatLng){ lat2 = arguments[2].lat(); lng2 = arguments[2].lng(); } else { lat2 = arguments[2]; lng2 = arguments[3]; } } e = Math.PI*lat1/180; f = Math.PI*lng1/180; g = Math.PI*lat2/180; h = Math.PI*lng2/180; return 1000*6371 * Math.acos(Math.min(Math.cos(e)*Math.cos(g)*Math.cos(f)*Math.cos(h)+Math.cos(e)*Math.sin(f)*Math.cos(g)*Math.sin(h)+Math.sin(e)*Math.sin(g),1)); } // extend the visible bounds function extendsMapBounds(){ var radius = distanceInMeter(map.getCenter(), map.getBounds().getNorthEast()), circle = new google.maps.Circle({ center: map.getCenter(), radius: 1.25 * radius // + 25% }); return circle.getBounds(); } // return an object where keys are store keys function getStoreKeys(){ var keys = {}, k; for(k in store){ keys[k] = true; } return keys; } // async the delay function function delayRedraw(){ clearTimeout(timer); timer = setTimeout(function(){ redraw(); }, 25); } // generate bounds extended by radius function extendsBounds(latLng) { var p = projection.fromLatLngToDivPixel(latLng), ne = projection.fromDivPixelToLatLng(new google.maps.Point(p.x+raw.radius, p.y-raw.radius)), sw = projection.fromDivPixelToLatLng(new google.maps.Point(p.x-raw.radius, p.y+raw.radius)); return new google.maps.LatLngBounds(sw, ne); } // run the clustering process and call the display function function redraw(){ if (updating || redrawing || !ready){ return; } var keys = [], used = {}, zoom = map.getZoom(), forceDisabled = ("maxZoom" in raw) && (zoom > raw.maxZoom), previousKeys = getStoreKeys(), i, j, k, indexes, check = false, bounds, cluster, position; // reset flag updated = false; if (zoom > 3){ // extend the bounds of the visible map to manage clusters near the boundaries bounds = extendsMapBounds(); // check contain only if boundaries are valid check = bounds.getSouthWest().lng() < bounds.getNorthEast().lng(); } // calculate positions of "visibles" markers (in extended bounds) for(i=0; i<todos.length; i++){ if (todos[i] && (!check || bounds.contains(todos[i].options.position)) && (!ffilter || ffilter(values[i]))){ keys.push(i); } } // for each "visible" marker, search its neighbors to create a cluster // we can't do a classical "for" loop, because, analysis can bypass a marker while focusing on cluster while(1){ i=0; while(used[i] && (i<keys.length)){ // look for the next marker not used i++; } if (i == keys.length){ break; } indexes = []; if (enabled && !forceDisabled){ position = todos[ keys[i] ].options.position; bounds = extendsBounds(position); for(j=i; j<keys.length; j++){ if (used[j]){ continue; } if (bounds.contains(todos[ keys[j] ].options.position)){ indexes.push(j); } } } else { // create a marker of one element (the first not used) for(j=i; j<keys.length; j++){ if (used[j]){ continue; } indexes.push(j); break; } } cluster = {indexes:[], ref:[]}; for(k=0; k<indexes.length; k++){ used[ indexes[k] ] = true; cluster.indexes.push(keys[indexes[k]]); cluster.ref.push(keys[indexes[k]]); } cluster.latLng = position; cluster.ref = cluster.ref.join("-"); if (cluster.ref in previousKeys){ // cluster doesn't change delete previousKeys[cluster.ref]; // remove this entry, these still in this array will be removed } else { // cluster is new if (indexes.length === 1){ // alone markers are not stored, so need to keep the key (else, will be displayed every time and marker will blink) store[cluster.ref] = true; } // use a closure to async the display call make faster the process of cle clustering (function(cl){ setTimeout(function(){ fdisplay(cl); // while displaying, will use store to link object }, 1); })(cluster); } } // flush the previous overlays which are not still used $.each(previousKeys, function(key){ flush(key); }); redrawing = false; } } /** * Class Clusterer * a facade with limited method for external use **/ function Clusterer(id, internalClusterer){ this.id = function(){ return id; }; this.filter = function(f){ internalClusterer.filter(f); }; this.enable = function(){ internalClusterer.enable(true); }; this.disable = function(){ internalClusterer.enable(false); }; this.add = function(marker, todo, lock){ if (!lock) { internalClusterer.beginUpdate(); } internalClusterer.addMarker(marker, todo); if (!lock) { internalClusterer.endUpdate(); } }; this.getById = function(id){ return internalClusterer.getById(id); }; this.clearById = function(id, lock){ var result; if (!lock) { internalClusterer.beginUpdate(); } result = internalClusterer.clearById(id); if (!lock) { internalClusterer.endUpdate(); } return result; }; this.clear = function(last, first, tag, lock){ if (!lock) { internalClusterer.beginUpdate(); } internalClusterer.clear(last, first, tag); if (!lock) { internalClusterer.endUpdate(); } }; } /***************************************************************************/ /* STORE */ /***************************************************************************/ function Store(){ var store = {}, // name => [id, ...] objects = {}; // id => object function normalize(res) { return { id: res.id, name: res.name, object:res.obj, tag:res.tag, data:res.data }; } /** * add a mixed to the store **/ this.add = function(args, name, obj, sub){ var todo = args.todo || {}, id = globalId(todo.id); if (!store[name]){ store[name] = []; } if (id in objects){ // object already exists: remove it this.clearById(id); } objects[id] = {obj:obj, sub:sub, name:name, id:id, tag:todo.tag, data:todo.data}; store[name].push(id); return id; }; /** * return a stored object by its id **/ this.getById = function(id, sub, full){ if (id in objects){ if (sub) { return objects[id].sub } else if (full) { return normalize(objects[id]); } return objects[id].obj; } return false; }; /** * return a stored value **/ this.get = function(name, last, tag, full){ var n, id, check = ftag(tag); if (!store[name] || !store[name].length){ return null; } n = store[name].length; while(n){ n--; id = store[name][last ? n : store[name].length - n - 1]; if (id && objects[id]){ if (check && !check(objects[id].tag)){ continue; } return full ? normalize(objects[id]) : objects[id].obj; } } return null; }; /** * return all stored values **/ this.all = function(name, tag, full){ var result = [], check = ftag(tag), find = function(n){ var i, id; for(i=0; i<store[n].length; i++){ id = store[n][i]; if (id && objects[id]){ if (check && !check(objects[id].tag)){ continue; } result.push(full ? normalize(objects[id]) : objects[id].obj); } } }; if (name in store){ find(name); } else if (name === undef){ // internal use only for(name in store){ find(name); } } return result; }; /** * hide and remove an object **/ function rm(obj){ // Google maps element if (typeof(obj.setMap) === "function") { obj.setMap(null); } // jQuery if (typeof(obj.remove) === "function") { obj.remove(); } // internal (cluster) if (typeof(obj.free) === "function") { obj.free(); } obj = null; } /** * remove one object from the store **/ this.rm = function(name, check, pop){ var idx, id; if (!store[name]) { return false; } if (check){ if (pop){ for(idx = store[name].length - 1; idx >= 0; idx--){ id = store[name][idx]; if ( check(objects[id].tag) ){ break; } } } else { for(idx = 0; idx < store[name].length; idx++){ id = store[name][idx]; if (check(objects[id].tag)){ break; } } } } else { idx = pop ? store[name].length - 1 : 0; } if ( !(idx in store[name]) ) { return false; } return this.clearById(store[name][idx], idx); }; /** * remove object from the store by its id **/ this.clearById = function(id, idx){ if (id in objects){ var i, name = objects[id].name; for(i=0; idx === undef && i<store[name].length; i++){ if (id === store[name][i]){ idx = i; } } rm(objects[id].obj); if(objects[id].sub){ rm(objects[id].sub); } delete objects[id]; store[name].splice(idx, 1); return true; } return false; }; /** * return an object from a container object in the store by its id * ! for now, only cluster manage this feature **/ this.objGetById = function(id){ var result; if (store["clusterer"]) { for(var idx in store["clusterer"]){ if ((result = objects[store["clusterer"][idx]].obj.getById(id)) !== false){ return result; } } } return false; }; /** * remove object from a container object in the store by its id * ! for now, only cluster manage this feature **/ this.objClearById = function(id){ if (store["clusterer"]) { for(var idx in store["clusterer"]){ if (objects[store["clusterer"][idx]].obj.clearById(id)){ return true; } } } return null; }; /** * remove objects from the store **/ this.clear = function(list, last, first, tag){ var k, i, name, check = ftag(tag); if (!list || !list.length){ list = []; for(k in store){ list.push(k); } } else { list = array(list); } for(i=0; i<list.length; i++){ name = list[i]; if (last){ this.rm(name, check, true); } else if (first){ this.rm(name, check, false); } else { // all while(this.rm(name, check, false)); } } }; /** * remove object from a container object in the store by its tags * ! for now, only cluster manage this feature **/ this.objClear = function(list, last, first, tag){ if (store["clusterer"] && ($.inArray("marker", list) >= 0 || !list.length)) { for(var idx in store["clusterer"]){ objects[store["clusterer"][idx]].obj.clear(last, first, tag); } } }; } /***************************************************************************/ /* GMAP3 GLOBALS */ /***************************************************************************/ var services = {}, geocoderCache = new GeocoderCache(); //-----------------------------------------------------------------------// // Service tools //-----------------------------------------------------------------------// function geocoder(){ if (!services.geocoder) { services.geocoder = new google.maps.Geocoder(); } return services.geocoder; } function directionsService(){ if (!services.directionsService) { services.directionsService = new google.maps.DirectionsService(); } return services.directionsService; } function elevationService(){ if (!services.elevationService) { services.elevationService = new google.maps.ElevationService(); } return services.elevationService; } function maxZoomService(){ if (!services.maxZoomService) { services.maxZoomService = new google.maps.MaxZoomService(); } return services.maxZoomService; } function distanceMatrixService(){ if (!services.distanceMatrixService) { services.distanceMatrixService = new google.maps.DistanceMatrixService(); } return services.distanceMatrixService; } //-----------------------------------------------------------------------// // Unit tools //-----------------------------------------------------------------------// function error(){ if (defaults.verbose){ var i, err = []; if (window.console && (typeof console.error === "function") ){ for(i=0; i<arguments.length; i++){ err.push(arguments[i]); } console.error.apply(console, err); } else { err = ""; for(i=0; i<arguments.length; i++){ err += arguments[i].toString() + " " ; } alert(err); } } } /** * return true if mixed is usable as number **/ function numeric(mixed){ return (typeof(mixed) === "number" || typeof(mixed) === "string") && mixed !== "" && !isNaN(mixed); } /** * convert data to array **/ function array(mixed){ var k, a = []; if (mixed !== undef){ if (typeof(mixed) === "object"){ if (typeof(mixed.length) === "number") { a = mixed; } else { for(k in mixed) { a.push(mixed[k]); } } } else{ a.push(mixed); } } return a; } /** * create a function to check a tag */ function ftag(tag){ if (tag){ if (typeof tag === "function"){ return tag; } tag = array(tag); return function(val){ if (val === undef){ return false; } if (typeof val === "object"){ for(var i=0; i<val.length; i++){ if($.inArray(val[i], tag) >= 0){ return true; } } return false; } return $.inArray(val, tag) >= 0; } } } /** * convert mixed [ lat, lng ] objet to google.maps.LatLng **/ function toLatLng (mixed, emptyReturnMixed, noFlat){ var empty = emptyReturnMixed ? mixed : null; if (!mixed || (typeof mixed === "string")){ return empty; } // defined latLng if (mixed.latLng) { return toLatLng(mixed.latLng); } // google.maps.LatLng object if (mixed instanceof google.maps.LatLng) { return mixed; } // {lat:X, lng:Y} object else if ( numeric(mixed.lat) ) { return new google.maps.LatLng(mixed.lat, mixed.lng); } // [X, Y] object else if ( !noFlat && $.isArray(mixed)){ if ( !numeric(mixed[0]) || !numeric(mixed[1]) ) { return empty; } return new google.maps.LatLng(mixed[0], mixed[1]); } return empty; } /** * convert mixed [ sw, ne ] object by google.maps.LatLngBounds **/ function toLatLngBounds(mixed){ var ne, sw; if (!mixed || mixed instanceof google.maps.LatLngBounds) { return mixed || null; } if ($.isArray(mixed)){ if (mixed.length == 2){ ne = toLatLng(mixed[0]); sw = toLatLng(mixed[1]); } else if (mixed.length == 4){ ne = toLatLng([mixed[0], mixed[1]]); sw = toLatLng([mixed[2], mixed[3]]); } } else { if ( ("ne" in mixed) && ("sw" in mixed) ){ ne = toLatLng(mixed.ne); sw = toLatLng(mixed.sw); } else if ( ("n" in mixed) && ("e" in mixed) && ("s" in mixed) && ("w" in mixed) ){ ne = toLatLng([mixed.n, mixed.e]); sw = toLatLng([mixed.s, mixed.w]); } } if (ne && sw){ return new google.maps.LatLngBounds(sw, ne); } return null; } /** * resolveLatLng **/ function resolveLatLng(ctx, method, runLatLng, args, attempt){ var latLng = runLatLng ? toLatLng(args.todo, false, true) : false, conf = latLng ? {latLng:latLng} : (args.todo.address ? (typeof(args.todo.address) === "string" ? {address:args.todo.address} : args.todo.address) : false), cache = conf ? geocoderCache.get(conf) : false, that = this; if (conf){ attempt = attempt || 0; // convert undefined to int if (cache){ args.latLng = cache.results[0].geometry.location; args.results = cache.results; args.status = cache.status; method.apply(ctx, [args]); } else { if (conf.location){ conf.location = toLatLng(conf.location); } if (conf.bounds){ conf.bounds = toLatLngBounds(conf.bounds); } geocoder().geocode( conf, function(results, status) { if (status === google.maps.GeocoderStatus.OK){ geocoderCache.store(conf, {results:results, status:status}); args.latLng = results[0].geometry.location; args.results = results; args.status = status; method.apply(ctx, [args]); } else if ( (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) && (attempt < defaults.queryLimit.attempt) ){ setTimeout( function(){ resolveLatLng.apply(that, [ctx, method, runLatLng, args, attempt+1]); }, defaults.queryLimit.delay + Math.floor(Math.random() * defaults.queryLimit.random) ); } else { error("geocode failed", status, conf); args.latLng = args.results = false; args.status = status; method.apply(ctx, [args]); } } ); } } else { args.latLng = toLatLng(args.todo, false, true); method.apply(ctx, [args]); } } function resolveAllLatLng(list, ctx, method, args){ var that = this, i = -1; function resolve(){ // look for next address to resolve do{ i++; }while( (i < list.length) && !("address" in list[i]) ); // no address found, so run method if (i >= list.length){ method.apply(ctx, [args]); return; } resolveLatLng( that, function(args){ delete args.todo; $.extend(list[i], args); resolve.apply(that, []); // resolve next (using apply avoid too much recursion) }, true, {todo:list[i]} ); } resolve(); } /** * geolocalise the user and return a LatLng **/ function geoloc(ctx, method, args){ var is_echo = false; // sometime, a kind of echo appear, this trick will notice once the first call is run to ignore the next one if (navigator && navigator.geolocation){ navigator.geolocation.getCurrentPosition( function(pos) { if (is_echo){ return; } is_echo = true; args.latLng = new google.maps.LatLng(pos.coords.latitude,pos.coords.longitude); method.apply(ctx, [args]); }, function() { if (is_echo){ return; } is_echo = true; args.latLng = false; method.apply(ctx, [args]); }, args.opts.getCurrentPosition ); } else { args.latLng = false; method.apply(ctx, [args]); } } /***************************************************************************/ /* GMAP3 */ /***************************************************************************/ function Gmap3($this){ var that = this, stack = new Stack(), store = new Store(), map = null, task; //-----------------------------------------------------------------------// // Stack tools //-----------------------------------------------------------------------// /** * store actions to execute in a stack manager **/ this._plan = function(list){ for(var k = 0; k < list.length; k++) { stack.add(new Task(that, end, list[k])); } run(); }; /** * if not running, start next action in stack **/ function run(){ if (!task && (task = stack.get())){ task.run(); } } /** * called when action in finished, to acknoledge the current in stack and start next one **/ function end(){ task = null; stack.ack(); run.call(that); // restart to high level scope } //-----------------------------------------------------------------------// // Tools //-----------------------------------------------------------------------// /** * execute callback functions **/ function callback(args){ if (args.todo.callback) { var params = Array.prototype.slice.call(arguments, 1); if (typeof args.todo.callback === "function") { args.todo.callback.apply($this, params); } else if ($.isArray(args.todo.callback)) { if (typeof args.todo.callback[1] === "function") { args.todo.callback[1].apply(args.todo.callback[0], params); } } } } /** * execute ending functions **/ function manageEnd(args, obj, id){ if (id){ attachEvents($this, args, obj, id); } callback(args, obj); task.ack(obj); } /** * initialize the map if not yet initialized **/ function newMap(latLng, args){ args = args || {}; if (map) { if (args.todo && args.todo.options){ if (args.todo.options.center) { args.todo.options.center = toLatLng(args.todo.options.center); } map.setOptions(args.todo.options); } } else { var opts = args.opts || $.extend(true, {}, defaults.map, args.todo && args.todo.options ? args.todo.options : {}); opts.center = latLng || toLatLng(opts.center); map = new defaults.classes.Map($this.get(0), opts); } } /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = => function with latLng resolution = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /** * Initialize google.maps.Map object **/ this.map = function(args){ newMap(args.latLng, args); attachEvents($this, args, map); manageEnd(args, map); }; /** * destroy an existing instance **/ this.destroy = function(args){ store.clear(); $this.empty(); if (map){ map = null; } manageEnd(args, true); }; /** * add an infowindow **/ this.infowindow = function(args){ var objs = [], multiple = "values" in args.todo; if (!multiple){ if (args.latLng) { args.opts.position = args.latLng; } args.todo.values = [{options:args.opts}]; } $.each(args.todo.values, function(i, value){ var id, obj, todo = tuple(args, value); todo.options.position = todo.options.position ? toLatLng(todo.options.position) : toLatLng(value.latLng); if (!map){ newMap(todo.options.position); } obj = new defaults.classes.InfoWindow(todo.options); if (obj && ((todo.open === undef) || todo.open)){ if (multiple){ obj.open(map, todo.anchor ? todo.anchor : undef); } else { obj.open(map, todo.anchor ? todo.anchor : (args.latLng ? undef : (args.session.marker ? args.session.marker : undef))); } } objs.push(obj); id = store.add({todo:todo}, "infowindow", obj); attachEvents($this, {todo:todo}, obj, id); }); manageEnd(args, multiple ? objs : objs[0]); }; /** * add a circle **/ this.circle = function(args){ var objs = [], multiple = "values" in args.todo; if (!multiple){ args.opts.center = args.latLng || toLatLng(args.opts.center); args.todo.values = [{options:args.opts}]; } if (!args.todo.values.length){ manageEnd(args, false); return; } $.each(args.todo.values, function(i, value){ var id, obj, todo = tuple(args, value); todo.options.center = todo.options.center ? toLatLng(todo.options.center) : toLatLng(value); if (!map){ newMap(todo.options.center); } todo.options.map = map; obj = new defaults.classes.Circle(todo.options); objs.push(obj); id = store.add({todo:todo}, "circle", obj); attachEvents($this, {todo:todo}, obj, id); }); manageEnd(args, multiple ? objs : objs[0]); }; /** * add an overlay **/ this.overlay = function(args, internal){ var objs = [], multiple = "values" in args.todo; if (!multiple){ args.todo.values = [{latLng: args.latLng, options: args.opts}]; } if (!args.todo.values.length){ manageEnd(args, false); return; } if (!OverlayView.__initialised) { OverlayView.prototype = new defaults.classes.OverlayView(); OverlayView.__initialised = true; } $.each(args.todo.values, function(i, value){ var id, obj, todo = tuple(args, value), $div = $(document.createElement("div")).css({ border: "none", borderWidth: "0px", position: "absolute" }); $div.append(todo.options.content); obj = new OverlayView(map, todo.options, toLatLng(todo) || toLatLng(value), $div); objs.push(obj); $div = null; // memory leak if (!internal){ id = store.add(args, "overlay", obj); attachEvents($this, {todo:todo}, obj, id); } }); if (internal){ return objs[0]; } manageEnd(args, multiple ? objs : objs[0]); }; /** * returns address structure from latlng **/ this.getaddress = function(args){ callback(args, args.results, args.status); task.ack(); }; /** * returns latlng from an address **/ this.getlatlng = function(args){ callback(args, args.results, args.status); task.ack(); }; /** * return the max zoom of a location **/ this.getmaxzoom = function(args){ maxZoomService().getMaxZoomAtLatLng( args.latLng, function(result) { callback(args, result.status === google.maps.MaxZoomStatus.OK ? result.zoom : false, status); task.ack(); } ); }; /** * return the elevation of a location **/ this.getelevation = function(args){ var i, locations = [], f = function(results, status){ callback(args, status === google.maps.ElevationStatus.OK ? results : false, status); task.ack(); }; if (args.latLng){ locations.push(args.latLng); } else { locations = array(args.todo.locations || []); for(i=0; i<locations.length; i++){ locations[i] = toLatLng(locations[i]); } } if (locations.length){ elevationService().getElevationForLocations({locations:locations}, f); } else { if (args.todo.path && args.todo.path.length){ for(i=0; i<args.todo.path.length; i++){ locations.push(toLatLng(args.todo.path[i])); } } if (locations.length){ elevationService().getElevationAlongPath({path:locations, samples:args.todo.samples}, f); } else { task.ack(); } } }; /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = => function without latLng resolution = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /** * define defaults values **/ this.defaults = function(args){ $.each(args.todo, function(name, value){ if (typeof defaults[name] === "object"){ defaults[name] = $.extend({}, defaults[name], value); } else { defaults[name] = value; } }); task.ack(true); }; /** * add a rectangle **/ this.rectangle = function(args){ var objs = [], multiple = "values" in args.todo; if (!multiple){ args.todo.values = [{options:args.opts}]; } if (!args.todo.values.length){ manageEnd(args, false); return; } $.each(args.todo.values, function(i, value){ var id, obj, todo = tuple(args, value); todo.options.bounds = todo.options.bounds ? toLatLngBounds(todo.options.bounds) : toLatLngBounds(value); if (!map){ newMap(todo.options.bounds.getCenter()); } todo.options.map = map; obj = new defaults.classes.Rectangle(todo.options); objs.push(obj); id = store.add({todo:todo}, "rectangle", obj); attachEvents($this, {todo:todo}, obj, id); }); manageEnd(args, multiple ? objs : objs[0]); }; /** * add a polygone / polyline **/ function poly(args, poly, path){ var objs = [], multiple = "values" in args.todo; if (!multiple){ args.todo.values = [{options:args.opts}]; } if (!args.todo.values.length){ manageEnd(args, false); return; } newMap(); $.each(args.todo.values, function(_, value){ var id, i, j, obj, todo = tuple(args, value); if (todo.options[path]){ if (todo.options[path][0][0] && $.isArray(todo.options[path][0][0])){ for(i=0; i<todo.options[path].length; i++){ for(j=0; j<todo.options[path][i].length; j++){ todo.options[path][i][j] = toLatLng(todo.options[path][i][j]); } } } else { for(i=0; i<todo.options[path].length; i++){ todo.options[path][i] = toLatLng(todo.options[path][i]); } } } todo.options.map = map; obj = new google.maps[poly](todo.options); objs.push(obj); id = store.add({todo:todo}, poly.toLowerCase(), obj); attachEvents($this, {todo:todo}, obj, id); }); manageEnd(args, multiple ? objs : objs[0]); } this.polyline = function(args){ poly(args, "Polyline", "path"); }; this.polygon = function(args){ poly(args, "Polygon", "paths"); }; /** * add a traffic layer **/ this.trafficlayer = function(args){ newMap(); var obj = store.get("trafficlayer"); if (!obj){ obj = new defaults.classes.TrafficLayer(); obj.setMap(map); store.add(args, "trafficlayer", obj); } manageEnd(args, obj); }; /** * add a bicycling layer **/ this.bicyclinglayer = function(args){ newMap(); var obj = store.get("bicyclinglayer"); if (!obj){ obj = new defaults.classes.BicyclingLayer(); obj.setMap(map); store.add(args, "bicyclinglayer", obj); } manageEnd(args, obj); }; /** * add a ground overlay **/ this.groundoverlay = function(args){ args.opts.bounds = toLatLngBounds(args.opts.bounds); if (args.opts.bounds){ newMap(args.opts.bounds.getCenter()); } var id, obj = new defaults.classes.GroundOverlay(args.opts.url, args.opts.bounds, args.opts.opts); obj.setMap(map); id = store.add(args, "groundoverlay", obj); manageEnd(args, obj, id); }; /** * set a streetview **/ this.streetviewpanorama = function(args){ if (!args.opts.opts){ args.opts.opts = {}; } if (args.latLng){ args.opts.opts.position = args.latLng; } else if (args.opts.opts.position){ args.opts.opts.position = toLatLng(args.opts.opts.position); } if (args.todo.divId){ args.opts.container = document.getElementById(args.todo.divId) } else if (args.opts.container){ args.opts.container = $(args.opts.container).get(0); } var id, obj = new defaults.classes.StreetViewPanorama(args.opts.container, args.opts.opts); if (obj){ map.setStreetView(obj); } id = store.add(args, "streetviewpanorama", obj); manageEnd(args, obj, id); }; this.kmllayer = function(args){ var objs = [], multiple = "values" in args.todo; if (!multiple){ args.todo.values = [{options:args.opts}]; } if (!args.todo.values.length){ manageEnd(args, false); return; } $.each(args.todo.values, function(i, value){ var id, obj, options, todo = tuple(args, value); if (!map){ newMap(); } options = todo.options; // compatibility 5.0- if (todo.options.opts) { options = todo.options.opts; if (todo.options.url) { options.url = todo.options.url; } } // -- end -- options.map = map; if (googleVersionMin("3.10")) { obj = new defaults.classes.KmlLayer(options); } else { obj = new defaults.classes.KmlLayer(options.url, options); } objs.push(obj); id = store.add({todo:todo}, "kmllayer", obj); attachEvents($this, {todo:todo}, obj, id); }); manageEnd(args, multiple ? objs : objs[0]); }; /** * add a fix panel **/ this.panel = function(args){ newMap(); var id, x= 0, y=0, $content, $div = $(document.createElement("div")); $div.css({ position: "absolute", zIndex: 1000, visibility: "hidden" }); if (args.opts.content){ $content = $(args.opts.content); $div.append($content); $this.first().prepend($div); if (args.opts.left !== undef){ x = args.opts.left; } else if (args.opts.right !== undef){ x = $this.width() - $content.width() - args.opts.right; } else if (args.opts.center){ x = ($this.width() - $content.width()) / 2; } if (args.opts.top !== undef){ y = args.opts.top; } else if (args.opts.bottom !== undef){ y = $this.height() - $content.height() - args.opts.bottom; } else if (args.opts.middle){ y = ($this.height() - $content.height()) / 2 } $div.css({ top: y, left: x, visibility: "visible" }); } id = store.add(args, "panel", $div); manageEnd(args, $div, id); $div = null; // memory leak }; /** * Create an InternalClusterer object **/ function createClusterer(raw){ var internalClusterer = new InternalClusterer($this, map, raw), todo = {}, styles = {}, thresholds = [], isInt = /^[0-9]+$/, calculator, k; for(k in raw){ if (isInt.test(k)){ thresholds.push(1*k); // cast to int styles[k] = raw[k]; styles[k].width = styles[k].width || 0; styles[k].height = styles[k].height || 0; } else { todo[k] = raw[k]; } } thresholds.sort(function (a, b) { return a > b}); // external calculator if (todo.calculator){ calculator = function(indexes){ var data = []; $.each(indexes, function(i, index){ data.push(internalClusterer.value(index)); }); return todo.calculator.apply($this, [data]); }; } else { calculator = function(indexes){ return indexes.length; }; } // set error function internalClusterer.error(function(){ error.apply(that, arguments); }); // set display function internalClusterer.display(function(cluster){ var i, style, atodo, obj, offset, cnt = calculator(cluster.indexes); // look for the style to use if (raw.force || cnt > 1) { for(i = 0; i < thresholds.length; i++) { if (thresholds[i] <= cnt) { style = styles[thresholds[i]]; } } } if (style){ offset = style.offset || [-style.width/2, -style.height/2]; // create a custom overlay command // nb: 2 extends are faster that a deeper extend atodo = $.extend({}, todo); atodo.options = $.extend({ pane: "overlayLayer", content:style.content ? style.content.replace("CLUSTER_COUNT", cnt) : "", offset:{ x: ("x" in offset ? offset.x : offset[0]) || 0, y: ("y" in offset ? offset.y : offset[1]) || 0 } }, todo.options || {}); obj = that.overlay({todo:atodo, opts:atodo.options, latLng:toLatLng(cluster)}, true); atodo.options.pane = "floatShadow"; atodo.options.content = $(document.createElement("div")).width(style.width+"px").height(style.height+"px").css({cursor:"pointer"}); shadow = that.overlay({todo:atodo, opts:atodo.options, latLng:toLatLng(cluster)}, true); // store data to the clusterer todo.data = { latLng: toLatLng(cluster), markers:[] }; $.each(cluster.indexes, function(i, index){ todo.data.markers.push(internalClusterer.value(index)); if (internalClusterer.markerIsSet(index)){ internalClusterer.marker(index).setMap(null); } }); attachEvents($this, {todo:todo}, shadow, undef, {main:obj, shadow:shadow}); internalClusterer.store(cluster, obj, shadow); } else { $.each(cluster.indexes, function(i, index){ internalClusterer.marker(index).setMap(map); }); } }); return internalClusterer; } /** * add a marker **/ this.marker = function(args){ var multiple = "values" in args.todo, init = !map; if (!multiple){ args.opts.position = args.latLng || toLatLng(args.opts.position); args.todo.values = [{options:args.opts}]; } if (!args.todo.values.length){ manageEnd(args, false); return; } if (init){ newMap(); } if (args.todo.cluster && !map.getBounds()){ // map not initialised => bounds not available : wait for map if clustering feature is required google.maps.event.addListenerOnce(map, "bounds_changed", function() { that.marker.apply(that, [args]); }); return; } if (args.todo.cluster){ var clusterer, internalClusterer; if (args.todo.cluster instanceof Clusterer){ clusterer = args.todo.cluster; internalClusterer = store.getById(clusterer.id(), true); } else { internalClusterer = createClusterer(args.todo.cluster); clusterer = new Clusterer(globalId(args.todo.id, true), internalClusterer); store.add(args, "clusterer", clusterer, internalClusterer); } internalClusterer.beginUpdate(); $.each(args.todo.values, function(i, value){ var todo = tuple(args, value); todo.options.position = todo.options.position ? toLatLng(todo.options.position) : toLatLng(value); todo.options.map = map; if (init){ map.setCenter(todo.options.position); init = false; } internalClusterer.add(todo, value); }); internalClusterer.endUpdate(); manageEnd(args, clusterer); } else { var objs = []; $.each(args.todo.values, function(i, value){ var id, obj, todo = tuple(args, value); todo.options.position = todo.options.position ? toLatLng(todo.options.position) : toLatLng(value); todo.options.map = map; if (init){ map.setCenter(todo.options.position); init = false; } obj = new defaults.classes.Marker(todo.options); objs.push(obj); id = store.add({todo:todo}, "marker", obj); attachEvents($this, {todo:todo}, obj, id); }); manageEnd(args, multiple ? objs : objs[0]); } }; /** * return a route **/ this.getroute = function(args){ args.opts.origin = toLatLng(args.opts.origin, true); args.opts.destination = toLatLng(args.opts.destination, true); directionsService().route( args.opts, function(results, status) { callback(args, status == google.maps.DirectionsStatus.OK ? results : false, status); task.ack(); } ); }; /** * add a direction renderer **/ this.directionsrenderer = function(args){ args.opts.map = map; var id, obj = new google.maps.DirectionsRenderer(args.opts); if (args.todo.divId){ obj.setPanel(document.getElementById(args.todo.divId)); } else if (args.todo.container){ obj.setPanel($(args.todo.container).get(0)); } id = store.add(args, "directionrenderer", obj); manageEnd(args, obj, id); }; /** * returns latLng of the user **/ this.getgeoloc = function(args){ manageEnd(args, args.latLng); }; /** * add a style **/ this.styledmaptype = function(args){ newMap(); var obj = new defaults.classes.StyledMapType(args.todo.styles, args.opts); map.mapTypes.set(args.todo.id, obj); manageEnd(args, obj); }; /** * add an imageMapType **/ this.imagemaptype = function(args){ newMap(); var obj = new defaults.classes.ImageMapType(args.opts); map.mapTypes.set(args.todo.id, obj); manageEnd(args, obj); }; /** * autofit a map using its overlays (markers, rectangles ...) **/ this.autofit = function(args){ var bounds = new google.maps.LatLngBounds(); $.each(store.all(), function(i, obj){ if (obj.getPosition){ bounds.extend(obj.getPosition()); } else if (obj.getBounds){ bounds.extend(obj.getBounds().getNorthEast()); bounds.extend(obj.getBounds().getSouthWest()); } else if (obj.getPaths){ obj.getPaths().forEach(function(path){ path.forEach(function(latLng){ bounds.extend(latLng); }); }); } else if (obj.getPath){ obj.getPath().forEach(function(latLng){ bounds.extend(latLng);"" }); } else if (obj.getCenter){ bounds.extend(obj.getCenter()); } else if (obj instanceof Clusterer){ obj = store.getById(obj.id(), true); if (obj){ obj.autofit(bounds); } } }); if (!bounds.isEmpty() && (!map.getBounds() || !map.getBounds().equals(bounds))){ if ("maxZoom" in args.todo){ // fitBouds Callback event => detect zoom level and check maxZoom google.maps.event.addListenerOnce( map, "bounds_changed", function() { if (this.getZoom() > args.todo.maxZoom){ this.setZoom(args.todo.maxZoom); } } ); } map.fitBounds(bounds); } manageEnd(args, true); }; /** * remove objects from a map **/ this.clear = function(args){ if (typeof args.todo === "string"){ if (store.clearById(args.todo) || store.objClearById(args.todo)){ manageEnd(args, true); return; } args.todo = {name:args.todo}; } if (args.todo.id){ $.each(array(args.todo.id), function(i, id){ store.clearById(id) || store.objClearById(id); }); } else { store.clear(array(args.todo.name), args.todo.last, args.todo.first, args.todo.tag); store.objClear(array(args.todo.name), args.todo.last, args.todo.first, args.todo.tag); } manageEnd(args, true); }; /** * run a function on each items selected **/ this.exec = function(args){ var that = this; $.each(array(args.todo.func), function(i, func){ $.each(that.get(args.todo, true, args.todo.hasOwnProperty("full") ? args.todo.full : true), function(j, res){ func.call($this, res); }); }); manageEnd(args, true); }; /** * return objects previously created **/ this.get = function(args, direct, full){ var name, res, todo = direct ? args : args.todo; if (!direct) { full = todo.full; } if (typeof todo === "string"){ res = store.getById(todo, false, full) || store.objGetById(todo); if (res === false){ name = todo; todo = {}; } } else { name = todo.name; } if (name === "map"){ res = map; } if (!res){ res = []; if (todo.id){ $.each(array(todo.id), function(i, id) { res.push(store.getById(id, false, full) || store.objGetById(id)); }); if (!$.isArray(todo.id)) { res = res[0]; } } else { $.each(name ? array(name) : [undef], function(i, aName) { var result; if (todo.first){ result = store.get(aName, false, todo.tag, full); if (result) res.push(result); } else if (todo.all){ $.each(store.all(aName, todo.tag, full), function(i, result){ res.push(result); }); } else { result = store.get(aName, true, todo.tag, full); if (result) res.push(result); } }); if (!todo.all && !$.isArray(name)) { res = res[0]; } } } res = $.isArray(res) || !todo.all ? res : [res]; if (direct){ return res; } else { manageEnd(args, res); } }; /** * return the distance between an origin and a destination * **/ this.getdistance = function(args){ var i; args.opts.origins = array(args.opts.origins); for(i=0; i<args.opts.origins.length; i++){ args.opts.origins[i] = toLatLng(args.opts.origins[i], true); } args.opts.destinations = array(args.opts.destinations); for(i=0; i<args.opts.destinations.length; i++){ args.opts.destinations[i] = toLatLng(args.opts.destinations[i], true); } distanceMatrixService().getDistanceMatrix( args.opts, function(results, status) { callback(args, status === google.maps.DistanceMatrixStatus.OK ? results : false, status); task.ack(); } ); }; /** * trigger events on the map **/ this.trigger = function(args){ if (typeof args.todo === "string"){ google.maps.event.trigger(map, args.todo); } else { var options = [map, args.todo.eventName]; if (args.todo.var_args) { $.each(args.todo.var_args, function(i, v){ options.push(v); }); } google.maps.event.trigger.apply(google.maps.event, options); } callback(args); task.ack(); }; } /** * Return true if get is a direct call * it means : * - get is the only key * - get has no callback * @param obj {Object} The request to check * @return {Boolean} */ function isDirectGet(obj) { var k; if (!typeof obj === "object" || !obj.hasOwnProperty("get")){ return false; } for(k in obj) { if (k !== "get") { return false; } } return !obj.get.hasOwnProperty("callback"); } //-----------------------------------------------------------------------// // jQuery plugin //-----------------------------------------------------------------------// $.fn.gmap3 = function(){ var i, list = [], empty = true, results = []; // init library initDefaults(); // store all arguments in a todo list for(i=0; i<arguments.length; i++){ if (arguments[i]){ list.push(arguments[i]); } } // resolve empty call - run init if (!list.length) { list.push("map"); } // loop on each jQuery object $.each(this, function() { var $this = $(this), gmap3 = $this.data("gmap3"); empty = false; if (!gmap3){ gmap3 = new Gmap3($this); $this.data("gmap3", gmap3); } if (list.length === 1 && (list[0] === "get" || isDirectGet(list[0]))){ results.push(gmap3.get(list[0] === "get" ? "map" : list[0].get, true)); } else { gmap3._plan(list); } }); // return for direct call only if (results.length){ if (results.length === 1){ // 1 css selector return results[0]; } else { return results; } } return this; } })(jQuery);
Решение нашел ) Вот что написали разработчики : Hello, You need to register your domain for getting an API key, then add it into the site to solve Google Map issue. This is solution: https://www.latecnosfera.com/2016/06/google-maps-api-error-missing-keymap-error-solved.html When you have API key, you need to add it in these files: - catalog/view/theme/your_theme/template/information/contact.tpl - admin\view\template\module\themecontrol\tab\pages-setting.tpl В общем нужен API ключ.