var absoluteURL = '//www.epcdeskundigen.be/'; /** * @seee http://studiowhiz.com/2010/10/02/google-maps-v3-distancefrom/ * @param {google.maps.LatLng} newLatLng * @returns {number} */ google.maps.LatLng.prototype.distanceFrom = function(newLatLng) { // setup our variables var lat1 = this.lat(); var radianLat1 = lat1 * ( Math.PI / 180 ); var lng1 = this.lng(); var radianLng1 = lng1 * ( Math.PI / 180 ); var lat2 = newLatLng.lat(); var radianLat2 = lat2 * ( Math.PI / 180 ); var lng2 = newLatLng.lng(); var radianLng2 = lng2 * ( Math.PI / 180 ); // sort out the radius, MILES or KM? var earth_radius = 6378.1; // (km = 6378.1) OR (miles = 3959) - radius of the earth // sort our the differences var diffLat = ( radianLat1 - radianLat2 ); var diffLng = ( radianLng1 - radianLng2 ); // put on a wave (hey the earth is round after all) var sinLat = Math.sin( diffLat / 2 ); var sinLng = Math.sin( diffLng / 2 ); // maths - borrowed from http://www.opensourceconnections.com/wp-content/uploads/2009/02/clientsidehaversinecalculation.html var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLng, 2.0); // work out the distance var distance = earth_radius * 2 * Math.asin(Math.min(1, Math.sqrt(a))); // return the distance return distance; } var translate = {"browser_not_compatible":"Uw browser ondersteunt geen Google Maps","supplier_already_selected":"U heeft deze deskundige al geselecteerd.","three_suppliers_overwrite":"U heeft reeds drie deskundigen geselecteerd, wilt u de derde deskundigen overschrijven?","loading":"Bezig met laden...","no_suppliers_selection":"U heeft geen deskundigen geselecteerd.","less_three_suppliers":"U heeft minder dan 3 deskundigen geselecteerd. Weet u zeker dat u door wilt gaan?","not_found":" is niet gevonden.","loading_error":"Fout tijdens laden...","click_to_delete":"Klik om te verwijderen","delete":"Verwijder","select_for_manager":"Selecteer voor offerte-aanvraag<\/span>","goto_marker":"Ga naar locatie op de kaart"} var country = {"id":"2","active":"1","name":"Belgie","code":"be","language":"1","siteName":"EPC Deskundigen","domain":"epcdeskundigen.be","coord_lat":"50.805935","coord_lng":"4.432983","zoom_level":"8","cluster_gridSize":"80","cluster_maxZoom":"12","gmaps":"maps.google.be\/maps","gkey":"ABQIAAAAQEVFdvZPE6sLB0y05PKJVBSkRzPXn5XGRrxZoUH-hHt3bSxNoRRy8QZHNJQBwdVShNZSq5pK1oHRHQ","gcode":"be","gtracker":"UA-9547875-1","gverify":"eMgFPWZ7NmLMEcx\/e8Y4Wg3\/UbAVUBWTLfB09sVRaOg="} /** * Google Maps Application - Basics * Author: Maikel Leemans */ dojo.provide('GMap.basic'); dojo.declare('GMap.basic', null, { container: null, // (id | domnode) of container div for GMap searchMap: null, // (id | domnode) of container div for address search form searchAddress: null, // (id | domnode) of input element for address search field map: null, // google.maps.Map object mapProjection: null, // google.maps.Map active projection object country: null, // country center location countryBound: null, // country bound box /** * We have two map modi: top level cluster markers and zoomed-in ajax markers. * See also reEvalMapState() */ markerClusterBatch: null, // batch of all processed markers (in markerCluster) markerCluster: null, // marker manager, cluster version markerClusterActive: false, // flag - marker cluster manager is active or inactive markerClusterPBatch: null, // batch of all processed Premioum markers (seperate display, not in markerCluster) markerAjaxBatch: null, // batch of all dynamic markers (obtained via ajax request) markerManager: null, // marker manager (doubles for markerClusterPBatch and markerAjaxBatch) markerManagerActive: false, // flag - marker (ajax) manager is active or inactive activeMarker: null, // current active marker infoWindow: null, // shared info window (at most one open at any time) activeStep: 0, // (int) active step in the process labelerManager: null, // manager object for labeler selection progressBar: null, // ProgressBarControl statics: { geocoder: null, // geocode client object preloadIcons: [ './gfx/gmap/markerNormal.png', //0 normal './gfx/gmap/markerActive.png', //1 active './gfx/gmap/markerVisited.png', //2 visited './gfx/gmap/markerNormalShadow.png', //3 shadow './gfx/gmap/markerBigNormal.png', //4 big normal './gfx/gmap/markerBigActive.png', //5 big active './gfx/gmap/markerBigVisited.png', //6 big visited './gfx/gmap/markerBigTransparent.png', //7 big shadow './gfx/gmap/ajax-loader.gif' //Loading gif ], preloadImages: new Array(), // Loaded preload icons defaultIcon: null, defaultBigIcon: null, clusterSettings: { calculator: function(markers, numStyles) { var result = MarkerClusterer.CALCULATOR(markers, numStyles); return dojo.mixin({}, result, { text: "" }); }, styles: [ { url: './gfx/gmap/cluster1.png', height: 38, width: 29, opt_anchor: [0, 0], opt_textColor: '#000000' }, { url: './gfx/gmap/cluster2.png', height: 46, width: 41, opt_anchor: [0, 0], opt_textColor: '#ffffff' }, { url: './gfx/gmap/cluster3.png', height: 64, width: 65, opt_anchor: [0, 0], opt_textColor: '#ffffff' } ] }, zoomTriggerLoading: 12, // starting from this zoom level, we will request markers and disable the clustermanager (set to country.cluster_maxZoom) managerSettings: { borderPadding: 25 // padding for manager (markers partly vissible -> map bound + padding) }, progressBarSettings: { loadstring: ' '+translate.loading // text for progress bar }, markerDeactivatePadding: 80 // the distance from the map-border at which markers will automatically be disabled // fix for auto-move of mapview after ajaxload }, /** * Constructor */ constructor: function(container, searchMap, searchAddress, extraContainer, interactionContainer) { this.container = container; // container element for the google.maps.Map this.searchMap = searchMap; // container element for address search form this.searchAddress = searchAddress; // input element for address search field dojo.addOnLoad( dojo.hitch(this, 'initialize', extraContainer, interactionContainer) ); }, /** * Initialize the Google Maps */ initialize: function(extraContainer, interactionContainer) { // prepare elements this.container = dojo.byId(this.container); this.searchMap = dojo.byId(this.searchMap); this.searchAddress = dojo.byId(this.searchAddress); this.labelerManager = new GMap.labelerManager(this, extraContainer, interactionContainer); // v3 has no GBrowserIsCompatible(), so replace by warning text // on init of v3 maps, this warning text will disappear if the maps work var property = (document.createElement('div').textContent == null) ? 'innerText': 'textContent'; this.container[property] = translate.browser_not_compatible; // boot map this.bootMap(); // init after map booted google.maps.event.addListener(this.map, 'projection_changed', dojo.hitch(this, function() { // initialize basic stuff if (!(this.initStatics() && this.initMap() && this.initProgressBar() && this.initMarkers())) { this.container[property] = translate.browser_not_compatible; //alert(this.browser_not_compatible); return; } // link address search dojo.query('form', this.searchMap) .connect('onsubmit', this, 'showAddress'); // initial center if (this.searchAddress != null && this.searchAddress.value != ''){ this.showAddress(); } else{ this.centerCountry(); } // set active step this.setActiveStep(); })); }, /** * Bootstrap map */ bootMap: function() { // Initialize map object this.country = new google.maps.LatLng(country.coord_lat, country.coord_lng); var myOptions = { zoom: parseInt(country.zoom_level), center: this.country, mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControl: false, streetViewControl: false, panControlOptions: { position: google.maps.ControlPosition.RIGHT_CENTER }, zoomControlOptions: { position: google.maps.ControlPosition.RIGHT_CENTER } }; this.map = new google.maps.Map(this.container, myOptions); if (this.map == null || this.map == false || this.map == undefined) return false; return true; }, /** * Initialize statics */ initStatics: function() { // Geocoder if (this.statics.geocoder == null) { this.statics.geocoder = new google.maps.Geocoder(); if (this.statics.geocoder == null || this.statics.geocoder == false || this.statics.geocoder == undefined) return false; } // preload static icon images if (this.statics.preloadImages.length == 0) { for (var index = 0; index < this.statics.preloadIcons.length; index++) { this.statics.preloadImages.push(new Image); this.statics.preloadImages[index].src = this.statics.preloadIcons[index]; } // Set defaults this.statics.defaultIcon = { url: this.statics.preloadImages[0].src, shape: { type: 'rect', coords: [0, 0, , 20, 34] }, _iconIndexOffset: 0, }; this.statics.defaultBigIcon = { url: this.statics.preloadImages[4].src, size: new google.maps.Size(40, 68), origin: new google.maps.Point(0,0), anchor: new google.maps.Point(20, 68), shape: { type: 'rect', coords: [0, 0, , 40, 68] }, _iconIndexOffset: 4 }; } // clusterSettings if (this.statics.clusterSettings.gridSize == undefined || this.statics.clusterSettings.gridSize == null) { this.statics.clusterSettings = dojo.mixin(this.statics.clusterSettings, { gridSize: parseInt(country.cluster_gridSize), // clustering grid size maxZoom: parseInt(country.cluster_maxZoom), // starting at this zoomLevel, no clusters are made loaderDiv: this.loaderDiv // loader overlay }); //console.dir(this.statics.clusterSettings); // other settings // starting from this zoom level, we will request markers and disable the clustermanager this.statics.zoomTriggerLoading = parseInt(country.cluster_maxZoom); } return true; }, /** * Initialize Google Maps Basics */ initMap: function() { this.mapProjection = this.map.getProjection(); this.infoWindow = new google.maps.InfoWindow(); // zoom debug //GEvent.addListener(this.map, "zoomend", function(oldLevel, newLevel) { console.info('oldLevel: ' + oldLevel + ' - newLevel: ' + newLevel); }); // toggle between cluster and ajax markers on each new map state (eg. zoomend for new zoom level or moveend for new coord box) // note: zoomend als triggers moveend google.maps.event.addListener(this.map, "idle", dojo.hitch(this, 'reEvalMapState')); return true; }, /** * Initialize Progressbar control */ initProgressBar: function() { this.progressBar = new progressBar(this.statics.progressBarSettings); this.map.controls[google.maps.ControlPosition.RIGHT].push(this.progressBar.getDiv()); return true; }, /** * Initialize Markers for Map */ initMarkers: function() { // bound NL prep this.countryBound = new google.maps.LatLngBounds(this.country, this.country); // data is declared in the html body // Iterate data list, create country bound and add all markers if (typeof(data) == 'undefined') return false; this.progressBar.start(data.length); this.markerClusterBatch = new Array(); this.markerClusterPBatch = new Array(); for (var index = 0; index < data.length; index++) { //Get location data[index]['coord'] = new google.maps.LatLng(data[index]['coordinate'][0], data[index]['coordinate'][1], data[index]['coordinate'][2]); //Extent bound this.countryBound.extend(data[index]['coord']); //Add marker var marker = this.createMarker(data[index]['coord'], data[index]['id'], index, data[index]['active'], false); if (data[index]['isPremium']) { marker.isPremium = data[index]['isPremium']; this.markerClusterPBatch.push(marker); //this.map.addOverlay(marker); } else this.markerClusterBatch.push(marker); this.progressBar.setCurrent(index); } //console.log('markerClusterBatch: ' + this.markerClusterBatch.length); // add normal marks to the cluster manager this.enableClusterManager(); this.progressBar.hide(); return true; }, /** * Create a marker object * onclick - db data details */ createMarker: function(point, id, index, activeState, isPremium) { if (isPremium) { var marker = new google.maps.Marker({ position: point, map: this.map, icon: dojo.mixin({}, this.statics.defaultBigIcon), shadow: dojo.mixin({}, this.statics.defaultBigIcon, { url: this.statics.preloadImages[ 3 + this.statics.defaultBigIcon._iconIndexOffset ].src }) }); } else { var marker = new google.maps.Marker({ position: point, map: this.map, icon: dojo.mixin({}, this.statics.defaultIcon), shadow: dojo.mixin({}, this.statics.defaultIcon, { url: this.statics.preloadImages[ 3 + this.statics.defaultIcon._iconIndexOffset ].src }) }); } // click and visited marker.visited = false; marker.isPremium = isPremium; google.maps.event.addDomListener(marker, 'click', dojo.hitch(this, function() { // tracker ga('send', 'pageview', '/clicks/mapMarker/' + id); // get database data this.infotabLoad(marker); dojo.xhrGet({ url: './public/zoeken_getmapdata.php?id=' + id, handleAs: 'json', timeout: 5000, // in miliseconds load: dojo.hitch(this, 'infotabComplete', marker, index), error: dojo.hitch(this, 'infotabError', marker) }); // set previous to visited if (this.activeMarker != null) this.setMarkerVisited(this.activeMarker); // set icon to active this.setMarkerActive(marker); this.activeMarker = marker; marker.visited = true; })); return marker; }, /** * Change icon of marker to active */ setMarkerActive: function(marker) { var icon = marker.getIcon(); icon.url = this.statics.preloadImages[1 + icon._iconIndexOffset].src; marker.setIcon(icon); }, /** * Change icon of marker to visited */ setMarkerVisited: function(marker) { var icon = marker.getIcon(); icon.url = this.statics.preloadImages[2 + icon._iconIndexOffset].src; marker.setIcon(icon); this.infoWindow.close(); }, /** * Make the current active marker inactive */ setActiveMarkerVisited: function() { if (this.activeMarker != null) { //console.info('setActiveMarkerVisited'); this.setMarkerVisited(this.activeMarker); this.activeMarker = null; } }, /** * info tab xhr event handlers (createMarker -> click -> zoeken_getmapdata.php?id=) */ infotabLoad: function(marker) { this.markerSetInfoWindow(marker, translate.loading); }, infotabError: function(marker) { this.markerSetInfoWindow(marker, translate.loading_error); }, infotabComplete: function(marker, markerIndex, response) { if (response._error) this.markerSetInfoWindow(marker, response._msg); else this.markerSetInfoWindow(marker, this.formatData(dojo.mixin(response, {markerIndex: markerIndex}))); }, /** * Open an info window balloon for a marker */ markerSetInfoWindow: function(marker, content) { this.infoWindow.setContent(content); this.infoWindow.open(this.map, marker); }, /** * trigger onclick for marker, displaying its info box, etc. */ activateMarkerByIndex: function(index, event) { if (event) event.preventDefault(); console.warn('activateMarkerByIndex() - code disabled'); //GEvent.trigger(this.markerClusterBatch[index], 'click'); }, /** * Activate given marker */ activateMarkerByRef: function(marker) { google.maps.event.trigger(marker, 'click'); }, /** * Center on country */ centerCountry: function() { // zoom accoarding to the bound var zoom = this.getZoomByBounds(this.countryBound); if (zoom < 8) zoom = 7; else if (zoom > 11) zoom = 11; //this.map.setCenter(this.countryBound.getCenter(), zoom); this.map.setCenter(this.countryBound.getCenter()); this.map.setZoom(zoom); /** * debug bound * / var newBound = this.boundApplyPixelPadding(this.map.getBounds(), this.map.getZoom(), this.statics.managerSettings.borderPadding); var southWest = newBound.getSouthWest(); var northEast = newBound.getNorthEast(); var polygonData = [ new GLatLng(northEast.lat(), northEast.lng()), new GLatLng(southWest.lat(), northEast.lng()), new GLatLng(southWest.lat(), southWest.lng()), new GLatLng(northEast.lat(), southWest.lng()), new GLatLng(northEast.lat(), northEast.lng()) ]; this.map.addOverlay(new GPolygon(polygonData, "#ff0000", 5, 0.5, "#00ff00", 0.5, [])); //*/ }, /** * Returns the zoom level at which the given rectangular region fits in the map view. * The zoom level is computed for the currently selected map type. * @see http://stackoverflow.com/questions/9837017/equivalent-of-getboundszoomlevel-in-gmaps-api-3 * * @param {google.maps.Map} map * @param {google.maps.LatLngBounds} bounds * @return {Number} zoom level **/ getZoomByBounds: function(bounds) { var MAX_ZOOM = this.map.mapTypes.get( this.map.getMapTypeId() ).maxZoom || 21 ; var MIN_ZOOM = this.map.mapTypes.get( this.map.getMapTypeId() ).minZoom || 0 ; var ne= this.mapProjection.fromLatLngToPoint( bounds.getNorthEast() ); var sw= this.mapProjection.fromLatLngToPoint( bounds.getSouthWest() ); var worldCoordWidth = Math.abs(ne.x-sw.x); var worldCoordHeight = Math.abs(ne.y-sw.y); //Fit padding in pixels var FIT_PAD = 40; for( var zoom = MAX_ZOOM; zoom >= MIN_ZOOM; --zoom ){ var posinfo = dojo.position(this.map.getDiv()); if( worldCoordWidth*(1< 0) content.addContent(dojo.create('img', {src: 'files/image/' + data.logo, 'class': 'supp_logo', alt: ''})); // add title / name if (data.name == '') content.addContent(dojo.create('b', {innerHTML: data.contact})); else content.addContent(dojo.create('b', {innerHTML: data.name})); // add optional contact if (data.name != '' && data.contact != '') content.addContent(dojo.create('br')).addContent(dojo.create('span', {innerHTML: data.contact})); // add info content .addContent(dojo.create('br')).addContent(dojo.create('span', {innerHTML: data.address})) .addContent(dojo.create('br')).addContent(dojo.create('span', {innerHTML: data.postalcode + ' ' + data.city})) .addContent(dojo.create('br')).addContent(dojo.create('br')); // add additional text (for premium-accounts) if (data.isPremium && data.ad_text != '') content.addContent(dojo.create('div', {innerHTML: data.ad_text, 'class': 'supp_ad_text'})); // select for labelManager link dojo.query(dojo.create('a', {'class': 'selectMgrLink map__button', innerHTML: '« ' + translate.select_for_manager}, content[0])) .onclick(dojo.hitch(this.labelerManager, 'addLabeler', data)); // return result return content[0]; }, /** * Perform geocoding search for address */ showAddress: function(event) { if (event) event.preventDefault(); //console.log('begin search'); // var start = new Date(); var geoQuery = { 'address': this.searchAddress.value, 'region': country.gcode }; // search address by means of the geocoder client this.statics.geocoder.geocode(geoQuery, dojo.hitch(this, function(results, status) { // check point if (status != google.maps.GeocoderStatus.OK) { alert(this.searchAddress.value + ' ' + translate.not_found); return; } var point = results[0].geometry.location; // update active step to 2 this.setActiveStep(2); // we want a result in which markers are shown // to this end, we first find out the closest point to the address var coord = null; var distance = null; for (var index = 0; index < data.length; ++index) { if (distance === null) { coord = data[index]["coord"]; distance = point.distanceFrom(coord); } else if (distance > point.distanceFrom(data[index]["coord"])) { coord = data[index]["coord"]; distance = point.distanceFrom(coord); } } // next we create a point mirrored from coord over point var latlng = {lat: 0, lng: 0}; var coord_mirror = null; latlng["lat"] = coord.lat() - point.lat(); latlng["lng"] = coord.lng() - point.lng(); latlng["lat"] = point.lat() - latlng["lat"]; latlng["lng"] = point.lng() - latlng["lng"]; coord_mirror = new google.maps.LatLng(latlng["lat"], latlng["lng"]); // then we create a bound from these points // first determine the northeast and southwest points latlng = [{lat: 0, lng: 0}, {lat: 0, lng: 0}]; if (coord.lat() > coord_mirror.lat()) { latlng[0]["lat"] = coord.lat(); latlng[1]["lat"] = coord_mirror.lat(); } else { latlng[1]["lat"] = coord.lat(); latlng[0]["lat"] = coord_mirror.lat(); } if (coord.lng() > coord_mirror.lng()) { latlng[0]["lng"] = coord.lng(); latlng[1]["lng"] = coord_mirror.lng(); } else { latlng[1]["lng"] = coord.lng(); latlng[0]["lng"] = coord_mirror.lng(); } // finally, create bound ... var northeast = new google.maps.LatLng(latlng[0]["lat"], latlng[0]["lng"]); var southwest = new google.maps.LatLng(latlng[1]["lat"], latlng[1]["lng"]); var bound = new google.maps.LatLngBounds(southwest, northeast); // ... and zoom accoarding to the bound var zoom = this.getZoomByBounds(bound); this.centerCountry(); if (zoom >= 8) { if (zoom > 12) zoom = 12; //var end = new Date(); //console.log('timing begin search: ' + (end - start)); //console.log('set search'); setTimeout(dojo.hitch(this, function() { //var start = new Date(); this.map.setCenter(bound.getCenter()); this.map.setZoom(zoom); //var end = new Date(); //console.log('timing set search: ' + (end - start)); }), 1); } })); }, /** * Determines if the given marker may still be active in the new view-bound */ evaluateMarkerActiveValidity: function(marker, bound, zoom) { var paddedBound = this.boundApplyPixelPadding(bound, zoom, this.statics.markerDeactivatePadding); return paddedBound.contains( marker.getPosition() ); }, /** * toggle between cluster and ajax markers on each new map state (eg. zoomend for new zoom level or moveend for new coord box) */ reEvalMapState: function() { //console.info('currentZoom: ' + this.map.getZoom() + ' currentCoord: ' + this.map.getBounds()); var zoom = this.map.getZoom(); var bound = this.map.getBounds(); // if active marker is not within new result, set it to null if (this.activeMarker != null) { if (!this.evaluateMarkerActiveValidity(this.activeMarker, bound, zoom)) this.setActiveMarkerVisited(); } if (zoom < 9 && this.markerClusterActive) this.markerCluster.setGridSize(50); else if(this.markerClusterActive) this.markerCluster.setGridSize(this.statics.clusterSettings.gridSize); if (zoom >= this.statics.zoomTriggerLoading) { // ajax markers mode //console.info('ajax markers mode'); this.disableClusterManager(); this.queryAjaxMarkers(zoom, bound); } else { // cluster markers mode //console.info('cluster markers mode'); this.disableAjaxMarkers(); this.enableClusterManager(); } }, /** * Disable the influence (event listening) and overlays (markers and clusters) of the markercluster manager */ disableClusterManager: function() { if (!this.markerClusterActive) return; // clear marker cluster batch (MarkerClusterer) this.markerCluster.clearMarkers(); this.markerCluster = null; // clear marker premium batch (MarkerManager) this.markerManager.clearMarkers(); this.markerManager = null; this.activeMarker = null; this.markerClusterActive = false; }, /** * Enable the influence (event listening) and overlays (markers and clusters) of the markercluster manager */ enableClusterManager: function() { if (this.markerClusterActive) return; // set marker cluster batch (MarkerClusterer) this.markerCluster = new MarkerClusterer(this.map, this.markerClusterBatch, this.statics.clusterSettings); // set marker premium batch (MarkerManager) this.markerManager = new MarkerManager(this.map, this.statics.managerSettings); google.maps.event.addListener(this.markerManager, 'loaded', dojo.hitch(this, function() { this.markerManager.addMarkers(this.markerClusterPBatch, 0); this.markerManager.refresh(); })); this.markerClusterActive = true; }, boundApplyPixelPadding: function(bound, zoom, padding) { var southWest = this.fromLatLngToPixel(bound.getSouthWest(), zoom); southWest.x -= padding; southWest.y += padding; southWest = this.fromPixelToLatLng(southWest, zoom); var northEast = this.fromLatLngToPixel(bound.getNorthEast(), zoom); northEast.x += padding; northEast.y -= padding; northEast = this.fromPixelToLatLng(northEast, zoom); return new google.maps.LatLngBounds(southWest, northEast); }, fromLatLngToPixel: function(latlng, zoom) { // @see http://qfox.nl/notes/116 var normalizedPoint = this.mapProjection.fromLatLngToPoint(latlng); // returns x,y normalized to 0~255 var scale = Math.pow(2, zoom); var pixelCoordinate = new google.maps.Point(normalizedPoint.x * scale, normalizedPoint.y * scale); return pixelCoordinate; }, fromPixelToLatLng: function(point, zoom) { // @see http://qfox.nl/notes/116 var scale = Math.pow(2, zoom); var normalizedPoint = new google.maps.Point(point.x / scale, point.y / scale); var latlng = this.mapProjection.fromPointToLatLng(normalizedPoint); return latlng; }, /** * this method actually makes the ajax post request */ queryAjaxMarkers: function (zoom, bound) { // we initialize the marker manager (note: not the cluster version, but the plain version for ajax markers) this.enableAjaxMarkers(); this.progressBar.setLoadText(this.statics.progressBarSettings.loadstring); this.progressBar.start(1); // manager uses bound padding, so we query with bound padding var newBound = this.boundApplyPixelPadding(bound, zoom, this.statics.managerSettings.borderPadding); var southWest = newBound.getSouthWest(); var northEast = newBound.getNorthEast(); bound = [ [southWest.lat(), southWest.lng()], [northEast.lat(), northEast.lng()] ]; // get database data dojo.xhrPost({ url: './public/zoeken_getmarkerdata.php?', content: {"bound": dojo.toJson(bound), "skip": dojo.toJson(this.markerAjaxBatch)}, handleAs: 'json', timeout: 5000, // in miliseconds load: dojo.hitch(this, 'processAjaxMarkers'), error: dojo.hitch(this, 'errorAjaxMarkers') }); }, /** * in case of an ajax loading error */ errorAjaxMarkers: function() { console.error('errorAjaxMarkers'); this.progressBar.setLoadText(translate.loading_error); this.progressBar.start(1); }, /** * in case of a succesful ajax load */ processAjaxMarkers: function(data) { this.progressBar.start(data.length); var batch = new Array(); for (var index = 0; index < data.length; index++) { //Get location data[index]['coord'] = new google.maps.LatLng(data[index]['coordinate'][0], data[index]['coordinate'][1], data[index]['coordinate'][2]); //Add marker var marker = this.createMarker(data[index]['coord'], data[index]['id'], index, data[index]['active'], data[index]['isPremium']); this.markerAjaxBatch.push(data[index]['id']); batch.push(marker); this.progressBar.setCurrent(index); } this.markerManager.addMarkers(batch, this.statics.zoomTriggerLoading); this.markerManager.refresh(); this.progressBar.hide(); try { if (this.activeMarker != null) this.activateMarkerByRef(this.activeMarker); } catch(e) { console.error('activateMarkerByRef'); console.dir(e); } //console.log('markerAjaxBatch: ' + this.markerAjaxBatch.length); //console.log('[batch]: ' + batch.length); }, /** * turn on the marker manager */ enableAjaxMarkers: function() { if (this.markerManagerActive) return; // prepare marker ajax batch (MarkerManager) this.markerManager = new MarkerManager(this.map, this.statics.managerSettings); this.markerAjaxBatch = new Array(); this.markerManagerActive = true; }, /** * turn off the marker manager and free resources */ disableAjaxMarkers: function() { if (!this.markerManagerActive) return; // clear marker ajax batch (MarkerManager) this.markerManager.clearMarkers(); this.markerManager = null; this.markerAjaxBatch = null; this.activeMarker = null; this.markerManagerActive = false; }, /** * set te active step in the process */ setActiveStep: function(step) { var newStep = 0; if (step == undefined) { if (this.searchAddress.value != '') { newStep = 2; } else { newStep = 1; } } else if (step > -1 && step < 4) { newStep = step; } if (newStep != this.activeStep) { // Reset step styling dojo.removeClass("search_map", "route__step--active"); dojo.removeClass("gmap_interaction_step", "route__step--active"); if (newStep == 1) { // set step 1 styling (search block active) dojo.addClass("search_map", "route__step--active"); } else if (newStep == 2) { // set step 2 styling (select block active) dojo.addClass("gmap_interaction_step", "route__step--active"); } this.activeStep = newStep; } } }); /** * Google Maps Application - Labelers selection and managing * Author: Maikel Leemans */ dojo.provide('GMap.labelerManager'); dojo.declare('GMap.labelerManager', null, { mapObject: null, // reference to the parenting GMap.basic instance labelerArray: null, // array with last selected labelers labelerLimit: 3, // limited size of labelerArray extraContainer: null, // div for extra info (labelers list) interactionContainer: null, // div for labelers list interaction labelerList: null, // DOM reference for laberlers list display container /** * Constructor */ constructor: function(mapObject, extraContainer, interactionContainer) { this.labelerArray = new Array(); this.mapObject = mapObject; this.extraContainer = dojo.byId(extraContainer); this.interactionContainer = dojo.byId(interactionContainer); this.labelerList = false; // created when needed in updateLabelerList() // connect interaction dojo.query('a', this.interactionContainer) .connect('onclick', dojo.hitch(this, 'sendLeads')); }, /** * Add a new labeler to the array * Manage duplicates and array size */ addLabeler: function(data, event) { if (event) event.preventDefault(); // is this labeler already selected => return and alert for (var i = 0; i < this.labelerArray.length; ++i) { if (this.labelerArray[i] == null || this.labelerArray[i] == undefined) continue; else if (this.labelerArray[i].id == data.id) { alert(translate.supplier_already_selected); return; } } // check length if ( this.labelerArray.length >= this.labelerLimit && !confirm(translate.three_suppliers_overwrite) ) return; // add to beginning of array this.labelerArray.unshift(data); // manage array length while (this.labelerArray.length > this.labelerLimit) this.labelerArray.pop(); // update page this.updateLabelerList(); }, removeLabelerByIndex: function(index, event) { if (event) event.preventDefault(); // remove labeler this.labelerArray.splice(index, 1); // update page this.updateLabelerList(); }, /** * Update the list on the left (map_extra) * Displaying new labelers selected and request button */ updateLabelerList: function() { // first time => create list if (!this.labelerList) { dojo.query(this.extraContainer).empty(); this.labelerList = dojo.query(dojo.create('ul', null, this.extraContainer)); // dojo.create('br', {'class': 'clear'}, this.interactionContainer); } // first, clear list this.labelerList.empty(); // (de-)activate the button if (this.labelerArray.length > 0) { // activate button dojo.removeClass("route_button", "not-active"); dojo.removeClass("route_button_sec", "not-active"); } else { // deactivate button dojo.addClass("route_button", "not-active"); dojo.addClass("route_button_sec", "not-active"); } // handle empty list if (this.labelerArray.length == 0) { //dojo.create('span', {innerHTML: translate.no_suppliers_selection}, this.labelerList[0]); //dojo.attr(this.interactionContainer, { style: {display: 'none'} }); return; } // redo list creation for (var i = 0; i < this.labelerArray.length; ++i) { if (this.labelerArray[i] == null || this.labelerArray[i] == undefined) continue; // add list item dojo.query(dojo.create('li', null, this.labelerList[0])) .addContent(this.formatData(this.labelerArray[i], i)); } // and, of course, our interaction div is displayed dojo.attr(this.interactionContainer, { style: {display: 'block'} }); }, /** * format content for labeler marker list item */ formatData: function(data, index) { var content = dojo.create('span', {class: 'selected'}); var title = ''; // determine title / name if (data.name == '') title = data.contact; else title = data.name; /* // create link with title dojo.query(dojo.create('a', {href: '#', title: translate.goto_marker, innerHTML: title}, content)) .connect('onclick', dojo.hitch(this.mapObject, 'activateMarkerByIndex', data.markerIndex)); /*/ dojo.create('span', {title: translate.goto_marker, class: 'selected__name', innerHTML: title}, content); //*/ // add delete button dojo.query(dojo.create('a', {'class': 'pointer selected__remove', title: translate.click_to_delete}, content)) .connect('onclick', dojo.hitch(this, 'removeLabelerByIndex', index)) .addContent(dojo.create('img', {src: './public/gfx/theme/cross.svg', 'class': 'icon', alt: translate['delete']})); // add hidden field for labelersform dojo.create('input', {type: 'hidden', name: 'menu_extra' + index, value: data.id}, content); // return result return content; }, sendLeads: function (event) { if (event) event.preventDefault(); if (this.labelerArray.length == 0) { alert(translate.no_suppliers_selection); return; } /* else if ( this.labelerArray.length < this.labelerLimit && !confirm(translate.less_three_suppliers)) return; */ dojo.byId('labelersform').submit(); } }); var gmap = new GMap.basic( 'gmap_main', /* DOM id - div for Gmap (actual map) */ 'search_map', /* DOM id - div with address search form */ 'address_input', /* DOM id - input element for address search field */ 'gmap_extra', /* DOM id - div for extra info (labelers list) */ 'gmap_interaction' /* DOM id - div for labelers list interaction */ );