(function($, OC) { $(function() { mapController.initMap(); //Photos photosController.initLayer(mapController.map); $('#navigation-photos').click(function() { photosController.toggleLayer(); optionsController.saveOptionValues({photosLayer: mapController.map.hasLayer(photosController.photoLayer)}); }); // once controllers have been set/initialized, we can restore option values from server optionsController.restoreOptions(); // Popup $(document).on('click', '#opening-hours-header', function() { $('#opening-hours-table').toggle(); $('#opening-hours-table-toggle-expand').toggle(); $('#opening-hours-table-toggle-collapse').toggle(); }); // Search $('#search-form').submit(function(e) { e.preventDefault(); submitSearchForm(); }); $('#search-submit').click(function() { submitSearchForm(); }); function submitSearchForm() { var str = $('#search-term').val(); if(str.length < 1) { return; } searchController.search(str).then(function(results) { if (results.length === 0) { return; } else if (results.length === 1) { var result = results[0]; mapController.displaySearchResult(result); } else { console.log('multiple results'); var result = results[0]; mapController.displaySearchResult(result); } }); } }); var helpers = { beautifyUrl: function(url) { return url.replace(/^(?:\w+:|)\/\/(?:www\.|)(.*[^\/])\/*$/, '$1'); } }; var optionsController = { optionValues: {}, saveOptionValues: function (optionValues) { var req = { options: optionValues }; var url = OC.generateUrl('/apps/maps/saveOptionValue'); $.ajax({ type: 'POST', url: url, data: req, async: true }).done(function (response) { }).fail(function() { OC.Notification.showTemporary( t('maps', 'Failed to save option values') ); }); }, restoreOptions: function () { var mom; var url = OC.generateUrl('/apps/maps/getOptionsValues'); var req = {}; var optionsValues = {}; $.ajax({ type: 'POST', url: url, data: req, async: true }).done(function (response) { optionsValues = response.values; // set tilelayer before showing photo layer because it needs a max zoom value if (optionsValues.hasOwnProperty('tileLayer')) { mapController.map.addLayer(mapController.baseLayers[optionsValues.tileLayer]); } else { mapController.map.addLayer(mapController.baseLayers['OpenStreetMap']); } if (optionsValues.hasOwnProperty('photosLayer') && optionsValues.photosLayer === 'true') { photosController.showLayer(); } if (optionsValues.hasOwnProperty('locControlEnabled') && optionsValues.locControlEnabled === 'true') { mapController.locControl.start(); } }).fail(function() { OC.Notification.showTemporary( t('maps', 'Failed to restore options values') ); }); } } var mapController = { searchMarker: {}, map: {}, locControl: undefined, baseLayers: undefined, displaySearchResult: function(result) { if(this.searchMarker) this.map.removeLayer(this.searchMarker); this.searchMarker = L.marker([result.lat, result.lon]); var name = result.display_name; var popupContent = searchController.parseOsmResult(result); this.searchMarker.bindPopup(popupContent); this.searchMarker.addTo(this.map); this.searchMarker.openPopup(); }, initMap: function() { var attribution = '© OpenStreetMap contributors, CC-BY-SA'; var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution : attribution, noWrap: true, detectRetina: false, maxZoom: 19 }); var attributionESRI = 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'; var ESRIAerial = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { attribution : attributionESRI, noWrap: false, detectRetina: true, maxZoom: 19 }); var ESRITopo = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', { attribution : attributionESRI, noWrap: false, detectRetina: false, maxZoom: 19 }); var attributionOpenTopo = 'Map data: © OpenStreetMap, SRTM | Map style: © OpenTopoMap (CC-BY-SA)'; var openTopo = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', { attribution : attributionOpenTopo, noWrap: false, detectRetina: false, maxZoom: 17 }); var attributionDark = '© Map tiles by CartoDB, under CC BY 3.0. Data by OpenStreetMap, under ODbL.'; var dark = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', { attribution : attributionDark, noWrap: false, detectRetina: false, maxZoom: 18 }); var attributionWatercolor = 'Leaflet | © Map tiles by Stamen Design, under CC BY 3.0, Data by OpenStreetMap, under CC BY SA.'; var watercolor = L.tileLayer('http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg', { attribution : attributionWatercolor, noWrap: false, detectRetina: false, maxZoom: 18 }); this.map = L.map('map', { zoom: 2, zoomControl: true, center: new L.LatLng(0, 0), maxBounds: new L.LatLngBounds(new L.LatLng(-90, 180), new L.LatLng(90, -180)), layers: [] }); this.locControl = L.control.locate({ position: 'topright', drawCircle: true, drawMarker: true, showPopup: false, icon: 'fa fa-map-marker-alt', iconLoading: 'fa fa-spinner fa-spin', strings: { title: t('maps', 'Get current location') } }).addTo(this.map); $('.leaflet-control-locate a').click( function(e) { optionsController.saveOptionValues({locControlEnabled: mapController.locControl._active}); }); L.control.scale({metric: true, imperial: true, position: 'topleft'}) .addTo(this.map); // tile layer selector var baseLayers = { 'OpenStreetMap': osm, 'ESRI Aerial': ESRIAerial, 'ESRI Topo': ESRITopo, 'OpenTopoMap': openTopo, 'Dark': dark, 'Watercolor': watercolor } this.baseLayers = baseLayers; L.control.layers(baseLayers, {}, {position: 'bottomright'}).addTo(this.map); // main layers buttons var esriButton = L.easyButton({ position: 'bottomright', states: [{ stateName: 'no-importa', icon: 'fa-image', title: t('maps', 'Aerial map'), onClick: function(btn, map) { for (var tl in baseLayers) { map.removeLayer(baseLayers[tl]); } map.addLayer(ESRIAerial); } }] }); esriButton.addTo(this.map); var osmButton = L.easyButton({ position: 'bottomright', states: [{ stateName: 'no-importa', icon: 'fa-map', title: t('maps', 'Classic map'), onClick: function(btn, map) { for (var tl in baseLayers) { map.removeLayer(baseLayers[tl]); } map.addLayer(osm); } }] }); osmButton.addTo(this.map); // save tile layer when changed this.map.on('baselayerchange ', function(e) { optionsController.saveOptionValues({tileLayer: e.name}); }); } }; //var url = OC.generateUrl('/apps/maps/favorites'); //var type = 'GET'; //$.ajax({ // type: type, // url: url, // data: {}, // async: true, //}).done(function (response) { // console.log(response); //}).always(function() { //}).fail(function() { // OC.Notification.showTemporary(t('maps', 'Failed to get favorites')); //}); //url = OC.generateUrl('/apps/maps/api/1.0/favorites'); //type = 'GET'; //$.ajax({ // type: type, // url: url, // data: {}, // async: true, //}).done(function (response) { // console.log(response); //}).always(function() { //}).fail(function() { // OC.Notification.showTemporary(t('maps', 'Failed to get favorites with API')); //}); var photosController = new PhotosController(); var searchController = { isGeocodeabe: function(str) { var pattern = /^\s*\d+\.?\d*\,\s*\d+\.?\d*\s*$/; return pattern.test(str); }, search: function(str) { var searchTerm = str.replace(' ', '%20'); // encode spaces var apiUrl = 'https://nominatim.openstreetmap.org/search/'+searchTerm+'?format=json&addressdetails=1&extratags=1&namedetails=1&limit=8'; return $.getJSON(apiUrl, {}, function(response) { return response; }); }, geocode: function(latlng) { if(!this.isGeocodeabe(latlng)) return; var splits = latlng.split(','); var lat = splits[0].trim(); var lon = splits[1].trim(); var apiUrl = 'https://nominatim.openstreetmap.org/reverse?format=json&lat=' + lat + '&lon='+ lon + '&addressdetails=1'; return $.getJSON(apiUrl, {}, function(response) { return response; }); }, parseOsmResult: function(result) { var add = result.address; var road, postcode, city, state, name; if(add.road) { road = add.road; if(add.house_number) road += ' ' + add.house_number; } if(add.postcode) postcode = add.postcode; if(add.city || add.town || add.village) { if(add.city) city = add.city; else if(add.town) city = add.town; else if(add.village) city = add.village; if(add.state) { state = add.state; } } var details = result.namedetails; if(details.name) name = details.name; var unformattedHeader; if(name) unformattedHeader = name; else if(road) unformattedHeader = road; else if(city) unformattedHeader = city; var unformattedDesc = ''; var needSeparator = false; // add road to desc if it is not heading and exists (isn't heading, if 'name' is set) if(name && road) { unformattedDesc = road; needSeparator = true; } if(postcode) { if(needSeparator) { unformattedDesc += ', '; needSeparator = false; } unformattedDesc += postcode; } if(city) { if(needSeparator) { unformattedDesc += ', '; needSeparator = false; } else if(unformattedDesc.length > 0) { unformattedDesc += ' '; } unformattedDesc += city; } if(state && add && add.country_code == 'us') { // assume that state is only important for us addresses if(unformattedDesc.length > 0) { unformattedDesc += ' '; } unformattedDesc += '(' + state + ')'; } var header = '

' + unformattedHeader + '

'; if(result.icon) header = '
' + header + '
'; var desc = '' + unformattedDesc + ''; // Add extras to parsed desc var extras = result.extratags; if(extras.opening_hours) { desc += '
'; var oh = new opening_hours(extras.opening_hours, result); var isCurrentlyOpen = oh.getState(); var changeDt = oh.getNextChange(); var currentDt = new Date(); var dtDiff = changeDt.getTime() - currentDt.getTime(); dtDiff = dtDiff / 60000; // get diff in minutes if(oh.getState()) { // is open? desc += 'Open'; if(dtDiff <= 60) { desc += ', closes in ' + dtDiff + ' minutes'; } else { desc += ' until ' + changeDt.toLocaleTimeString() + ''; } } else { desc += 'Closed'; desc += 'opens at ' + changeDt.toLocaleTimeString() + ''; } desc += '
'; var todayStart = currentDt; todayStart.setHours(0); todayStart.setMinutes(0); todayStart.setSeconds(0); var sevDaysEnd = new Date(todayStart); var sevDaysMs = 7 * 24 * 60 * 60 * 1000; sevDaysEnd.setTime(sevDaysEnd.getTime()+sevDaysMs); var intervals = oh.getOpenIntervals(todayStart, sevDaysEnd); desc += ''; // intervals should be 7, if 8, then first entry is interval after 00:00:00 from last day if(intervals.length == 8) { // set end time of last element to end time of first element and remove it intervals[7][1] = intervals[0][1]; intervals.splice(0, 1); } for(var i=0; i'; var startTime = from.toLocaleTimeString(); var endTime =to.toLocaleTimeString(); desc += ''; desc += ''; } desc += '
' + startTime + ' - ' + endTime + '
'; } if(extras.website) { desc += '
' + helpers.beautifyUrl(extras.website) + '
'; } if(extras.phone) { desc += '
' + extras.phone + '
'; } if(extras.email) { desc += '
' + extras.email + '
'; } return header + desc; } }; })(jQuery, OC);