2014-08-15 23:46:04 +04:00
|
|
|
(function($, OC) {
|
2017-08-23 14:51:37 +03:00
|
|
|
$(function() {
|
2019-04-19 00:51:25 +03:00
|
|
|
if (window.isSecureContext) {
|
|
|
|
window.navigator.registerProtocolHandler('geo', OC.generateUrl('/apps/maps/openGeoLink/') + '%s', 'Nextcloud Maps');
|
|
|
|
}
|
2017-08-24 13:28:00 +03:00
|
|
|
mapController.initMap();
|
2019-03-28 16:51:24 +03:00
|
|
|
mapController.map.favoritesController = favoritesController;
|
2019-03-27 20:04:04 +03:00
|
|
|
favoritesController.initFavorites(mapController.map);
|
2019-04-03 05:14:10 +03:00
|
|
|
routingController.initRoutingControl(mapController.map);
|
2019-03-26 19:26:29 +03:00
|
|
|
photosController.initLayer(mapController.map);
|
2019-04-09 13:07:06 +03:00
|
|
|
nonLocalizedPhotosController.initLayer(mapController.map);
|
2019-04-08 21:25:40 +03:00
|
|
|
mapController.map.photosController = photosController;
|
2019-04-04 20:47:41 +03:00
|
|
|
contactsController.initLayer(mapController.map);
|
2019-04-09 05:01:11 +03:00
|
|
|
mapController.map.contactsController = contactsController;
|
2019-04-06 22:00:14 +03:00
|
|
|
tracksController.initController(mapController.map);
|
2019-04-26 01:29:12 +03:00
|
|
|
tracksController.map.tracksController = tracksController;
|
2019-04-17 02:06:07 +03:00
|
|
|
devicesController.initController(mapController.map);
|
2019-04-17 19:47:08 +03:00
|
|
|
mapController.map.devicesController = devicesController;
|
2019-04-26 16:12:49 +03:00
|
|
|
searchController.initController(mapController.map);
|
2019-03-26 21:27:58 +03:00
|
|
|
|
|
|
|
// once controllers have been set/initialized, we can restore option values from server
|
2019-03-26 20:59:11 +03:00
|
|
|
optionsController.restoreOptions();
|
2019-04-13 22:42:43 +03:00
|
|
|
geoLinkController.showLinkLocation();
|
2014-08-10 23:33:43 +04:00
|
|
|
|
2017-08-24 19:58:36 +03:00
|
|
|
// Popup
|
|
|
|
$(document).on('click', '#opening-hours-header', function() {
|
|
|
|
$('#opening-hours-table').toggle();
|
|
|
|
$('#opening-hours-table-toggle-expand').toggle();
|
|
|
|
$('#opening-hours-table-toggle-collapse').toggle();
|
|
|
|
});
|
|
|
|
|
2019-03-29 05:54:32 +03:00
|
|
|
document.onkeydown = function (e) {
|
|
|
|
e = e || window.event;
|
2019-04-23 05:50:39 +03:00
|
|
|
if (e.key === 'Escape') {
|
|
|
|
if (favoritesController.movingFavoriteId !== null) {
|
|
|
|
favoritesController.leaveMoveFavoriteMode();
|
|
|
|
}
|
|
|
|
if (contactsController.movingBookid !== null) {
|
|
|
|
contactsController.leaveMoveContactMode();
|
|
|
|
}
|
2019-04-24 17:25:23 +03:00
|
|
|
if (photosController.movingPhotoPath !== null) {
|
|
|
|
photosController.leaveMovePhotoMode();
|
|
|
|
}
|
2019-03-29 05:54:32 +03:00
|
|
|
}
|
|
|
|
};
|
2019-04-21 16:46:42 +03:00
|
|
|
window.onclick = function(event) {
|
2019-05-03 01:42:36 +03:00
|
|
|
if (event.button === 0) {
|
|
|
|
$('.leaflet-control-layers').hide();
|
|
|
|
$('.easy-button-container').show();
|
|
|
|
if (!event.target.matches('.app-navigation-entry-utils-menu-button button')) {
|
|
|
|
$('.app-navigation-entry-menu.open').removeClass('open');
|
|
|
|
}
|
|
|
|
mapController.map.contextmenu.hide();
|
2019-04-21 19:55:42 +03:00
|
|
|
}
|
2019-04-21 16:46:42 +03:00
|
|
|
};
|
2019-04-30 20:37:40 +03:00
|
|
|
|
|
|
|
// click on menu buttons
|
|
|
|
$('body').on('click',
|
|
|
|
'.routingMenuButton, .favoritesMenuButton, .categoryMenuButton, .photosMenuButton, .contactsMenuButton, ' +
|
|
|
|
'.nonLocalizedPhotosMenuButton, .devicesMenuButton, .deviceMenuButton, .tracksMenuButton, .trackMenuButton',
|
|
|
|
function(e) {
|
|
|
|
var menu = $(this).parent().parent().parent().find('> .app-navigation-entry-menu');
|
|
|
|
var wasOpen = menu.hasClass('open');
|
|
|
|
$('.app-navigation-entry-menu.open').removeClass('open');
|
|
|
|
if (!wasOpen) {
|
|
|
|
menu.addClass('open');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// right click on entry line
|
|
|
|
$('body').on('contextmenu',
|
|
|
|
'#navigation-routing > .app-navigation-entry-utils, #navigation-routing > a, ' +
|
|
|
|
'#navigation-favorites > .app-navigation-entry-utils, #navigation-favorites > a, ' +
|
|
|
|
'.category-line > a, .category-line > .app-navigation-entry-utils, ' +
|
|
|
|
'#navigation-devices > .app-navigation-entry-utils, #navigation-devices > a, ' +
|
|
|
|
'.device-line > a, .device-line > .app-navigation-entry-utils, ' +
|
|
|
|
'#navigation-tracks > .app-navigation-entry-utils, #navigation-tracks > a, ' +
|
|
|
|
'.track-line > a, .track-line > .app-navigation-entry-utils, ' +
|
|
|
|
'#navigation-nonLocalizedPhotos > .app-navigation-entry-utils, #navigation-nonLocalizedPhotos > a, ' +
|
|
|
|
'#navigation-contacts > .app-navigation-entry-utils, #navigation-contacts > a, ' +
|
|
|
|
'#navigation-photos > .app-navigation-entry-utils, #navigation-photos > a ',
|
|
|
|
function(e) {
|
|
|
|
var menu = $(this).parent().find('> .app-navigation-entry-menu');
|
|
|
|
var wasOpen = menu.hasClass('open');
|
|
|
|
$('.app-navigation-entry-menu.open').removeClass('open');
|
|
|
|
if (!wasOpen) {
|
|
|
|
menu.addClass('open');
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
// right click on expand icon
|
|
|
|
$('body').on('contextmenu', '#navigation-favorites, #navigation-photos, #navigation-devices, #navigation-tracks', function(e) {
|
|
|
|
var id = $(e.target).attr('id');
|
|
|
|
if (e.target.tagName === 'LI' && (id === 'navigation-favorites' || id === 'navigation-photos' || id === 'navigation-devices' || id === 'navigation-tracks')) {
|
|
|
|
var menu = $(this).find('> .app-navigation-entry-menu');
|
|
|
|
var wasOpen = menu.hasClass('open');
|
|
|
|
$('.app-navigation-entry-menu.open').removeClass('open');
|
|
|
|
if (!wasOpen) {
|
|
|
|
menu.addClass('open');
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
2017-08-23 14:51:37 +03:00
|
|
|
});
|
2017-08-23 16:39:28 +03:00
|
|
|
|
2019-04-13 22:42:43 +03:00
|
|
|
var geoLinkController = {
|
|
|
|
marker: null,
|
|
|
|
lat: null,
|
|
|
|
lng: null,
|
2019-04-15 00:09:21 +03:00
|
|
|
showLinkLocation: function() {
|
2019-04-14 23:59:40 +03:00
|
|
|
var geourlElem = document.getElementById('geourl');
|
|
|
|
if (geourlElem) {
|
|
|
|
var geourl = geourlElem.value;
|
|
|
|
[this.lat, this.lng] = geourl.substring(4).split(',');
|
|
|
|
this.marker = L.marker([this.lat, this.lng]);
|
|
|
|
mapController.map.addLayer(this.marker);
|
|
|
|
mapController.map.setView([this.lat, this.lng], 15);
|
|
|
|
}
|
2019-04-15 00:09:21 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
shareLocation: function(e) {
|
|
|
|
var lat = e.latlng.lat;
|
|
|
|
var lng = e.latlng.lng;
|
|
|
|
var geoLink = 'geo:' + lat.toFixed(6) + ',' + lng.toFixed(6);
|
|
|
|
var dummy = $('<input id="dummycopy">').val(geoLink).appendTo('body').select();
|
|
|
|
document.execCommand('copy');
|
|
|
|
$('#dummycopy').remove();
|
|
|
|
OC.Notification.showTemporary(t('maps', 'Geo link ({geoLink}) copied to clipboard', {geoLink: geoLink}));
|
|
|
|
},
|
2019-04-13 22:42:43 +03:00
|
|
|
};
|
|
|
|
|
2019-03-26 20:09:08 +03:00
|
|
|
var optionsController = {
|
|
|
|
optionValues: {},
|
2019-03-29 21:07:53 +03:00
|
|
|
enabledFavoriteCategories: [],
|
2019-04-07 06:19:47 +03:00
|
|
|
enabledTracks: [],
|
2019-04-17 03:44:08 +03:00
|
|
|
enabledDevices: [],
|
2019-04-18 01:50:40 +03:00
|
|
|
enabledDeviceLines: [],
|
2019-03-26 20:09:08 +03:00
|
|
|
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 () {
|
2019-03-29 21:07:53 +03:00
|
|
|
var that = this;
|
2019-03-26 20:09:08 +03:00
|
|
|
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;
|
2019-03-26 21:27:58 +03:00
|
|
|
// set tilelayer before showing photo layer because it needs a max zoom value
|
2019-03-26 20:59:11 +03:00
|
|
|
if (optionsValues.hasOwnProperty('tileLayer')) {
|
2019-04-19 17:33:17 +03:00
|
|
|
mapController.changeTileLayer(optionsValues.tileLayer);
|
2019-03-26 20:59:11 +03:00
|
|
|
}
|
|
|
|
else {
|
2019-04-19 17:33:17 +03:00
|
|
|
mapController.changeTileLayer('OpenStreetMap');
|
2019-03-26 20:59:11 +03:00
|
|
|
}
|
2019-06-25 12:03:00 +03:00
|
|
|
if (optionsValues.hasOwnProperty('mapBounds')) {
|
|
|
|
var nsew = optionsValues.mapBounds.split(';');
|
|
|
|
if (nsew.length === 4) {
|
|
|
|
var n = parseFloat(nsew[0]);
|
|
|
|
var s = parseFloat(nsew[1]);
|
|
|
|
var e = parseFloat(nsew[2]);
|
|
|
|
var w = parseFloat(nsew[3]);
|
|
|
|
if (n && s && e && w) {
|
|
|
|
mapController.map.fitBounds([
|
|
|
|
[n, e],
|
|
|
|
[s, w]
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-04-01 18:45:23 +03:00
|
|
|
if (!optionsValues.hasOwnProperty('photosLayer') || optionsValues.photosLayer === 'true') {
|
2019-03-26 21:34:58 +03:00
|
|
|
photosController.toggleLayer();
|
2019-03-26 21:27:58 +03:00
|
|
|
}
|
2019-04-04 20:47:41 +03:00
|
|
|
if (!optionsValues.hasOwnProperty('contactLayer') || optionsValues.contactLayer === 'true') {
|
|
|
|
contactsController.toggleLayer();
|
|
|
|
}
|
2019-03-26 21:27:58 +03:00
|
|
|
if (optionsValues.hasOwnProperty('locControlEnabled') && optionsValues.locControlEnabled === 'true') {
|
|
|
|
mapController.locControl.start();
|
|
|
|
}
|
2019-04-01 18:45:23 +03:00
|
|
|
if (!optionsValues.hasOwnProperty('favoriteCategoryListShow') || optionsValues.favoriteCategoryListShow === 'true') {
|
2019-03-29 19:27:53 +03:00
|
|
|
favoritesController.toggleCategoryList();
|
|
|
|
}
|
2019-03-29 21:07:53 +03:00
|
|
|
if (optionsValues.hasOwnProperty('enabledFavoriteCategories')
|
|
|
|
&& optionsValues.enabledFavoriteCategories
|
|
|
|
&& optionsValues.enabledFavoriteCategories !== '')
|
|
|
|
{
|
|
|
|
that.enabledFavoriteCategories = optionsValues.enabledFavoriteCategories.split('|');
|
|
|
|
}
|
2019-04-09 16:55:20 +03:00
|
|
|
if (!optionsValues.hasOwnProperty('favoritesEnabled') || optionsValues.favoritesEnabled === 'true') {
|
|
|
|
favoritesController.toggleFavorites();
|
|
|
|
}
|
2019-04-06 22:00:14 +03:00
|
|
|
if (!optionsValues.hasOwnProperty('trackListShow') || optionsValues.trackListShow === 'true') {
|
|
|
|
tracksController.toggleTrackList();
|
|
|
|
}
|
|
|
|
if (optionsValues.hasOwnProperty('enabledTracks')
|
|
|
|
&& optionsValues.enabledTracks
|
|
|
|
&& optionsValues.enabledTracks !== '')
|
|
|
|
{
|
2019-04-07 18:47:55 +03:00
|
|
|
that.enabledTracks = optionsValues.enabledTracks.split('|').map(function (x) {
|
|
|
|
return parseInt(x);
|
|
|
|
});
|
2019-04-06 22:00:14 +03:00
|
|
|
}
|
2019-04-30 17:31:35 +03:00
|
|
|
if (getUrlParameter('track') || !optionsValues.hasOwnProperty('tracksEnabled') || optionsValues.tracksEnabled === 'true') {
|
2019-04-09 16:55:20 +03:00
|
|
|
tracksController.toggleTracks();
|
|
|
|
}
|
2019-04-17 03:44:08 +03:00
|
|
|
if (!optionsValues.hasOwnProperty('deviceListShow') || optionsValues.deviceListShow === 'true') {
|
|
|
|
devicesController.toggleDeviceList();
|
|
|
|
}
|
|
|
|
if (optionsValues.hasOwnProperty('enabledDevices')
|
|
|
|
&& optionsValues.enabledDevices
|
|
|
|
&& optionsValues.enabledDevices !== '')
|
|
|
|
{
|
|
|
|
that.enabledDevices = optionsValues.enabledDevices.split('|').map(function (x) {
|
|
|
|
return parseInt(x);
|
|
|
|
});
|
|
|
|
}
|
2019-04-18 01:50:40 +03:00
|
|
|
if (optionsValues.hasOwnProperty('enabledDeviceLines')
|
|
|
|
&& optionsValues.enabledDeviceLines
|
|
|
|
&& optionsValues.enabledDeviceLines !== '')
|
|
|
|
{
|
|
|
|
that.enabledDeviceLines = optionsValues.enabledDeviceLines.split('|').map(function (x) {
|
|
|
|
return parseInt(x);
|
|
|
|
});
|
|
|
|
}
|
2019-04-17 03:44:08 +03:00
|
|
|
if (!optionsValues.hasOwnProperty('devicesEnabled') || optionsValues.devicesEnabled === 'true') {
|
|
|
|
devicesController.toggleDevices();
|
|
|
|
}
|
2019-04-18 17:42:09 +03:00
|
|
|
if (optionsValues.hasOwnProperty('trackMe') && optionsValues.trackMe === 'true') {
|
|
|
|
$('#track-me').prop('checked', true);
|
|
|
|
devicesController.launchTrackLoop();
|
|
|
|
}
|
2019-03-29 19:38:24 +03:00
|
|
|
|
|
|
|
// save tile layer when changed
|
|
|
|
// do it after restore, otherwise restoring triggers save
|
|
|
|
mapController.map.on('baselayerchange ', function(e) {
|
|
|
|
optionsController.saveOptionValues({tileLayer: e.name});
|
2019-04-21 03:25:55 +03:00
|
|
|
// make sure map is clean
|
|
|
|
for (var ol in mapController.baseOverlays) {
|
|
|
|
mapController.map.removeLayer(mapController.baseOverlays[ol]);
|
|
|
|
}
|
|
|
|
for (var tl in mapController.baseLayers) {
|
|
|
|
if (tl !== e.name) {
|
|
|
|
mapController.map.removeLayer(mapController.baseLayers[tl]);
|
|
|
|
}
|
|
|
|
}
|
2019-04-21 16:06:50 +03:00
|
|
|
if (e.name === 'Watercolor') {
|
|
|
|
mapController.map.addLayer(mapController.baseOverlays['Roads and labels']);
|
|
|
|
}
|
2019-04-19 17:33:17 +03:00
|
|
|
mapController.layerChanged(e.name);
|
2019-03-29 19:38:24 +03:00
|
|
|
});
|
2019-06-10 15:58:34 +03:00
|
|
|
|
|
|
|
// add router to routing machine
|
2019-06-10 19:06:29 +03:00
|
|
|
if (optionsValues.hasOwnProperty('osrmCarURL') && optionsValues.osrmCarURL !== '') {
|
|
|
|
routingController.addRouter('osrmCar', 'By car (OSRM)', optionsValues.osrmCarURL, null);
|
|
|
|
}
|
|
|
|
if (optionsValues.hasOwnProperty('osrmBikeURL') && optionsValues.osrmBikeURL !== '') {
|
|
|
|
routingController.addRouter('osrmBike', 'By bike (OSRM)', optionsValues.osrmBikeURL, null);
|
|
|
|
}
|
|
|
|
if (optionsValues.hasOwnProperty('osrmFootURL') && optionsValues.osrmFootURL !== '') {
|
|
|
|
routingController.addRouter('osrmFoot', 'By foot (OSRM)', optionsValues.osrmFootURL, null);
|
2019-06-10 15:58:34 +03:00
|
|
|
}
|
|
|
|
if (optionsValues.hasOwnProperty('osrmDEMO') && optionsValues.osrmDEMO === '1') {
|
2019-06-10 19:06:29 +03:00
|
|
|
routingController.addRouter('osrmDEMO', 'By car (OSRM demo)', null, null);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
delete routingController.routers.osrmDEMO;
|
2019-06-10 15:58:34 +03:00
|
|
|
}
|
2019-06-11 02:04:30 +03:00
|
|
|
if (optionsValues.hasOwnProperty('mapboxAPIKEY') && optionsValues.mapboxAPIKEY !== '') {
|
|
|
|
routingController.addRouter('mapbox', 'Mapbox', null, optionsValues.mapboxAPIKEY);
|
|
|
|
}
|
2019-06-11 02:18:34 +03:00
|
|
|
if ((optionsValues.hasOwnProperty('graphhopperURL') && optionsValues.graphhopperURL !== '') ||
|
|
|
|
(optionsValues.hasOwnProperty('graphhopperAPIKEY') && optionsValues.graphhopperAPIKEY !== '') ){
|
2019-06-10 15:58:34 +03:00
|
|
|
var apikey = undefined;
|
|
|
|
if (optionsValues.hasOwnProperty('graphhopperAPIKEY') && optionsValues.graphhopperAPIKEY !== '') {
|
|
|
|
apikey = optionsValues.graphhopperAPIKEY;
|
|
|
|
}
|
2019-06-10 19:06:29 +03:00
|
|
|
routingController.addRouter('graphhopperCar', 'By car (GrahHopper)', optionsValues.graphhopperURL, apikey);
|
|
|
|
routingController.addRouter('graphhopperBike', 'By bike (GrahHopper)', optionsValues.graphhopperURL, apikey);
|
|
|
|
routingController.addRouter('graphhopperFoot', 'By Foot (GrahHopper)', optionsValues.graphhopperURL, apikey);
|
2019-06-10 15:58:34 +03:00
|
|
|
}
|
|
|
|
if (optionsValues.hasOwnProperty('selectedRouter') && optionsValues.selectedRouter !== '') {
|
|
|
|
routingController.selectedRouter = optionsValues.selectedRouter;
|
2019-06-10 16:59:14 +03:00
|
|
|
routingController.setRouter(optionsValues.selectedRouter);
|
|
|
|
}
|
2019-06-25 20:04:42 +03:00
|
|
|
//if (optionsValues.hasOwnProperty('routingEnabled') && optionsValues.routingEnabled === 'true') {
|
|
|
|
// routingController.toggleRouting();
|
|
|
|
//}
|
2019-03-26 20:09:08 +03:00
|
|
|
}).fail(function() {
|
|
|
|
OC.Notification.showTemporary(
|
|
|
|
t('maps', 'Failed to restore options values')
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
2019-04-01 12:23:11 +03:00
|
|
|
};
|
2019-03-26 20:09:08 +03:00
|
|
|
|
2017-08-24 13:28:00 +03:00
|
|
|
var mapController = {
|
2019-04-28 23:44:50 +03:00
|
|
|
searchMarkerLayerGroup: null,
|
2017-08-24 13:28:00 +03:00
|
|
|
map: {},
|
2017-09-24 16:59:22 +03:00
|
|
|
locControl: undefined,
|
2019-03-26 20:59:11 +03:00
|
|
|
baseLayers: undefined,
|
2019-04-28 23:44:50 +03:00
|
|
|
displaySearchResult: function(results) {
|
|
|
|
this.searchMarkerLayerGroup.clearLayers();
|
|
|
|
var result, searchMarker;
|
|
|
|
for (var i=0; i < results.length; i++) {
|
|
|
|
result = results[i];
|
|
|
|
searchMarker = L.marker([result.lat, result.lon], {
|
|
|
|
icon: this.searchIcon
|
|
|
|
});
|
|
|
|
var name = result.display_name;
|
2019-04-29 02:15:47 +03:00
|
|
|
// popup
|
2019-04-28 23:44:50 +03:00
|
|
|
var popupContent = searchController.parseOsmResult(result);
|
|
|
|
searchMarker.bindPopup(popupContent, {className: 'search-result-popup'});
|
2019-04-29 02:15:47 +03:00
|
|
|
// tooltip
|
|
|
|
var name = '';
|
|
|
|
if (result.namedetails && result.namedetails.name) {
|
|
|
|
name = result.namedetails.name;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
name = result.display_name;
|
|
|
|
}
|
|
|
|
var tooltipContent = brify(name, 40);
|
|
|
|
searchMarker.bindTooltip(tooltipContent, {className: 'search-result-tooltip'});
|
2019-04-28 23:44:50 +03:00
|
|
|
searchMarker.addTo(this.searchMarkerLayerGroup);
|
|
|
|
}
|
|
|
|
if (results.length === 1) {
|
|
|
|
this.searchMarkerLayerGroup.getLayers()[0].openPopup();
|
|
|
|
this.map.flyTo([results[0].lat, results[0].lon], 15, {duration: 1});
|
|
|
|
}
|
2017-08-24 13:28:00 +03:00
|
|
|
},
|
|
|
|
initMap: function() {
|
2019-04-19 17:33:17 +03:00
|
|
|
var that = this;
|
2019-04-23 02:19:39 +03:00
|
|
|
this.searchIcon = L.divIcon({
|
|
|
|
iconAnchor: [12, 25],
|
|
|
|
className: 'route-waypoint route-middle-waypoint',
|
|
|
|
html: ''
|
|
|
|
});
|
2017-08-24 13:28:00 +03:00
|
|
|
var attribution = '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>';
|
|
|
|
|
2019-03-19 02:16:32 +03:00
|
|
|
var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
|
|
attribution : attribution,
|
2019-04-19 16:28:41 +03:00
|
|
|
noWrap: false,
|
2019-03-19 20:50:20 +03:00
|
|
|
detectRetina: false,
|
|
|
|
maxZoom: 19
|
2019-03-19 02:16:32 +03:00
|
|
|
});
|
|
|
|
|
2019-04-21 03:25:55 +03:00
|
|
|
var attributionESRI = 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN...';
|
2019-03-19 02:16:32 +03:00
|
|
|
var ESRIAerial = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
|
|
|
|
attribution : attributionESRI,
|
|
|
|
noWrap: false,
|
2019-03-19 20:50:20 +03:00
|
|
|
detectRetina: true,
|
|
|
|
maxZoom: 19
|
|
|
|
});
|
2019-04-20 22:08:36 +03:00
|
|
|
var roadsOverlay = L.tileLayer('https://{s}.tile.openstreetmap.se/hydda/roads_and_labels/{z}/{x}/{y}.png', {
|
|
|
|
maxZoom: 18,
|
|
|
|
opacity: 0.7,
|
2019-04-21 03:25:55 +03:00
|
|
|
attribution: '<a href="http://openstreetmap.se/" target="_blank">OpenStreetMap Sweden</a> — Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
2019-04-20 22:08:36 +03:00
|
|
|
});
|
2019-03-19 20:50:20 +03:00
|
|
|
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: © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://viewfinderpanoramass.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)';
|
|
|
|
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 = '<a href="https://leafletjs.com" title="A JS library for interactive maps">Leaflet</a> | © Map tiles by <a href="https://stamen.com">Stamen Design</a>, under <a href="https://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>, Data by <a href="https://openstreetmap.org">OpenStreetMap</a>, under <a href="https://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>.';
|
2019-04-20 14:55:18 +03:00
|
|
|
var watercolor = L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.{ext}', {
|
2019-03-19 20:50:20 +03:00
|
|
|
attribution : attributionWatercolor,
|
|
|
|
noWrap: false,
|
|
|
|
detectRetina: false,
|
2019-04-20 14:55:18 +03:00
|
|
|
maxZoom: 18,
|
|
|
|
ext: 'jpg',
|
|
|
|
subdomains: 'abcd'
|
2017-08-24 13:28:00 +03:00
|
|
|
});
|
2019-04-08 15:37:47 +03:00
|
|
|
var starImageUrl = OC.generateUrl('/svg/core/actions/star-dark?color=000000');
|
|
|
|
var markerRedImageUrl = OC.generateUrl('/svg/core/actions/address?color=EE3333');
|
|
|
|
var markerBlueImageUrl = OC.generateUrl('/svg/core/actions/address?color=3333EE');
|
|
|
|
var markerGreenImageUrl = OC.generateUrl('/svg/core/actions/address?color=33EE33');
|
|
|
|
var photoImageUrl = OC.generateUrl('/svg/core/places/picture?color=000000');
|
|
|
|
var contactImageUrl = OC.generateUrl('/svg/core/actions/user?color=000000');
|
2019-04-15 00:09:21 +03:00
|
|
|
var shareImageUrl = OC.generateUrl('/svg/core/actions/share?color=000000');
|
2017-08-24 13:28:00 +03:00
|
|
|
this.map = L.map('map', {
|
2019-03-26 19:10:18 +03:00
|
|
|
zoom: 2,
|
2019-04-19 16:46:55 +03:00
|
|
|
zoomControl: false,
|
2019-04-02 03:50:18 +03:00
|
|
|
maxZoom: 19,
|
2019-04-19 16:28:41 +03:00
|
|
|
minZoom: 2,
|
2019-03-26 19:10:18 +03:00
|
|
|
center: new L.LatLng(0, 0),
|
2019-04-20 18:54:19 +03:00
|
|
|
maxBounds: new L.LatLngBounds(new L.LatLng(-90, 720), new L.LatLng(90, -720)),
|
2019-04-08 15:37:47 +03:00
|
|
|
layers: [],
|
|
|
|
// right click menu
|
2019-04-30 14:07:02 +03:00
|
|
|
contextmenu: false,
|
2019-04-08 15:37:47 +03:00
|
|
|
contextmenuWidth: 160,
|
|
|
|
contextmenuItems: [{
|
|
|
|
text: t('maps', 'Add a favorite'),
|
|
|
|
icon: starImageUrl,
|
|
|
|
callback: favoritesController.contextAddFavorite
|
|
|
|
}, {
|
2019-04-09 00:48:25 +03:00
|
|
|
text: t('maps', 'Place photos'),
|
2019-04-08 15:37:47 +03:00
|
|
|
icon: photoImageUrl,
|
|
|
|
callback: photosController.contextPlacePhotos
|
2019-04-08 21:51:07 +03:00
|
|
|
}, {
|
2019-04-09 00:48:25 +03:00
|
|
|
text: t('maps', 'Place photo folder'),
|
2019-04-08 21:51:07 +03:00
|
|
|
icon: photoImageUrl,
|
|
|
|
callback: photosController.contextPlacePhotoFolder
|
2019-04-08 15:37:47 +03:00
|
|
|
}, {
|
2019-04-09 00:48:25 +03:00
|
|
|
text: t('maps', 'Place contact'),
|
2019-04-08 15:37:47 +03:00
|
|
|
icon: contactImageUrl,
|
|
|
|
callback: contactsController.contextPlaceContact
|
2019-04-15 00:09:21 +03:00
|
|
|
}, {
|
|
|
|
text: t('maps', 'Share this location'),
|
|
|
|
icon: shareImageUrl,
|
|
|
|
callback: geoLinkController.shareLocation
|
2019-04-08 15:37:47 +03:00
|
|
|
}, '-', {
|
|
|
|
text: t('maps', 'Route from here'),
|
|
|
|
icon: markerGreenImageUrl,
|
|
|
|
callback: routingController.contextRouteFrom
|
|
|
|
}, {
|
|
|
|
text: t('maps', 'Add route point'),
|
|
|
|
icon: markerBlueImageUrl,
|
|
|
|
callback: routingController.contextRoutePoint
|
|
|
|
}, {
|
|
|
|
text: t('maps', 'Route to here'),
|
|
|
|
icon: markerRedImageUrl,
|
|
|
|
callback: routingController.contextRouteTo
|
|
|
|
}]
|
2017-08-24 13:28:00 +03:00
|
|
|
});
|
2019-04-30 14:07:02 +03:00
|
|
|
this.map.on('contextmenu', function(e) {
|
|
|
|
if ($(e.originalEvent.target).attr('id') === 'map') {
|
|
|
|
that.map.contextmenu.showAt(L.latLng(e.latlng.lat, e.latlng.lng));
|
|
|
|
}
|
|
|
|
});
|
2019-04-28 23:44:50 +03:00
|
|
|
|
2019-06-25 12:03:00 +03:00
|
|
|
this.map.on('moveend', function(e) {
|
|
|
|
var bounds = that.map.getBounds();
|
|
|
|
optionsController.saveOptionValues({
|
|
|
|
mapBounds: bounds.getNorth() + ';' +
|
|
|
|
bounds.getSouth() + ';' +
|
|
|
|
bounds.getEast() + ';' +
|
|
|
|
bounds.getWest()
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2019-04-28 23:44:50 +03:00
|
|
|
this.searchMarkerLayerGroup = L.featureGroup();
|
|
|
|
this.map.addLayer(this.searchMarkerLayerGroup);
|
|
|
|
|
2019-04-21 19:41:00 +03:00
|
|
|
var locale = OC.getLocale();
|
|
|
|
var imperial = (
|
|
|
|
locale === 'en_US' ||
|
|
|
|
locale === 'en_GB' ||
|
|
|
|
locale === 'en_AU' ||
|
|
|
|
locale === 'en_IE' ||
|
|
|
|
locale === 'en_NZ' ||
|
|
|
|
locale === 'en_CA'
|
|
|
|
);
|
|
|
|
var metric = !imperial;
|
|
|
|
L.control.scale({metric: metric, imperial: imperial, position: 'bottomleft'})
|
2019-04-02 18:11:45 +03:00
|
|
|
.addTo(this.map);
|
2019-04-19 17:44:15 +03:00
|
|
|
//L.control.mousePosition().addTo(this.map);
|
2019-04-20 18:57:42 +03:00
|
|
|
|
|
|
|
L.control.zoom({position: 'bottomright'}).addTo(this.map);
|
|
|
|
|
2017-09-24 16:59:22 +03:00
|
|
|
this.locControl = L.control.locate({
|
2019-04-20 18:57:42 +03:00
|
|
|
position: 'bottomright',
|
2019-03-26 20:59:11 +03:00
|
|
|
drawCircle: true,
|
|
|
|
drawMarker: true,
|
2017-09-24 16:59:22 +03:00
|
|
|
showPopup: false,
|
2019-03-26 20:59:11 +03:00
|
|
|
icon: 'fa fa-map-marker-alt',
|
2017-09-24 16:59:22 +03:00
|
|
|
iconLoading: 'fa fa-spinner fa-spin',
|
|
|
|
strings: {
|
2019-04-20 18:57:42 +03:00
|
|
|
title: t('maps', 'See current location')
|
2019-04-15 17:44:47 +03:00
|
|
|
},
|
2019-04-20 19:19:46 +03:00
|
|
|
flyTo: true,
|
|
|
|
returnToPrevBounds: true,
|
|
|
|
setView: 'untilPan',
|
|
|
|
showCompass: true,
|
|
|
|
locateOptions: {enableHighAccuracy: true, maxZoom: 15}
|
2017-09-24 16:59:22 +03:00
|
|
|
}).addTo(this.map);
|
2019-03-26 20:59:11 +03:00
|
|
|
$('.leaflet-control-locate a').click( function(e) {
|
|
|
|
optionsController.saveOptionValues({locControlEnabled: mapController.locControl._active});
|
|
|
|
});
|
2019-03-19 02:16:32 +03:00
|
|
|
|
2019-04-21 16:46:42 +03:00
|
|
|
this.layersButton = L.easyButton({
|
|
|
|
position: 'bottomright',
|
|
|
|
states: [{
|
|
|
|
stateName: 'no-importa',
|
|
|
|
icon: '<a class="icon icon-menu" style="height: 100%"> </a>',
|
|
|
|
title: t('maps', 'Other layers'),
|
|
|
|
onClick: function(btn, map) {
|
|
|
|
$('.leaflet-control-layers').toggle();
|
|
|
|
$('.easy-button-container').toggle();
|
|
|
|
}
|
|
|
|
}]
|
|
|
|
});
|
|
|
|
this.layersButton.addTo(this.map);
|
|
|
|
|
2019-03-19 02:16:32 +03:00
|
|
|
// tile layer selector
|
2019-04-20 22:08:36 +03:00
|
|
|
this.baseLayers = {
|
2019-03-19 02:16:32 +03:00
|
|
|
'OpenStreetMap': osm,
|
2019-03-19 20:50:20 +03:00
|
|
|
'ESRI Aerial': ESRIAerial,
|
|
|
|
'ESRI Topo': ESRITopo,
|
|
|
|
'OpenTopoMap': openTopo,
|
|
|
|
'Dark': dark,
|
|
|
|
'Watercolor': watercolor
|
2019-03-19 02:16:32 +03:00
|
|
|
}
|
2019-04-20 22:08:36 +03:00
|
|
|
this.baseOverlays = {
|
|
|
|
'Roads and labels': roadsOverlay
|
|
|
|
}
|
2019-04-21 16:46:42 +03:00
|
|
|
this.controlLayers = L.control.layers(
|
|
|
|
this.baseLayers,
|
|
|
|
this.baseOverlays,
|
|
|
|
{position: 'bottomright', collapsed: false}
|
|
|
|
).addTo(this.map);
|
2019-04-21 03:25:55 +03:00
|
|
|
// hide openstreetmap, ESRI Aerial and roads/labels because they are dynamically managed
|
2019-04-20 22:08:36 +03:00
|
|
|
this.controlLayers.removeLayer(this.baseLayers['OpenStreetMap']);
|
|
|
|
this.controlLayers.removeLayer(this.baseLayers['ESRI Aerial']);
|
2019-04-21 03:25:55 +03:00
|
|
|
this.controlLayers.removeLayer(this.baseOverlays['Roads and labels']);
|
2019-04-21 16:46:42 +03:00
|
|
|
$('.leaflet-control-layers').toggle();
|
2019-03-19 20:24:00 +03:00
|
|
|
|
|
|
|
// main layers buttons
|
2019-04-26 02:16:04 +03:00
|
|
|
var esriImageUrl = OC.filePath('maps', 'css/images', 'esri.jpg');
|
2019-04-19 17:33:17 +03:00
|
|
|
this.esriButton = L.easyButton({
|
2019-03-19 20:24:00 +03:00
|
|
|
position: 'bottomright',
|
|
|
|
states: [{
|
|
|
|
stateName: 'no-importa',
|
2019-03-27 20:46:17 +03:00
|
|
|
icon: '<img src="'+esriImageUrl+'"/>',
|
2019-03-19 20:50:20 +03:00
|
|
|
title: t('maps', 'Aerial map'),
|
2019-03-19 20:24:00 +03:00
|
|
|
onClick: function(btn, map) {
|
2019-04-19 17:33:17 +03:00
|
|
|
that.changeTileLayer('ESRI Aerial', true);
|
2019-03-19 20:24:00 +03:00
|
|
|
}
|
|
|
|
}]
|
|
|
|
});
|
2019-04-26 02:16:04 +03:00
|
|
|
var osmImageUrl = OC.filePath('maps', 'css/images', 'osm.png');
|
2019-04-19 17:33:17 +03:00
|
|
|
this.osmButton = L.easyButton({
|
2019-03-19 20:24:00 +03:00
|
|
|
position: 'bottomright',
|
|
|
|
states: [{
|
|
|
|
stateName: 'no-importa',
|
2019-03-27 20:46:17 +03:00
|
|
|
icon: '<img src="'+osmImageUrl+'"/>',
|
2019-03-19 20:50:20 +03:00
|
|
|
title: t('maps', 'Classic map'),
|
2019-03-19 20:24:00 +03:00
|
|
|
onClick: function(btn, map) {
|
2019-04-19 17:33:17 +03:00
|
|
|
that.changeTileLayer('OpenStreetMap', true);
|
2019-03-19 20:24:00 +03:00
|
|
|
}
|
|
|
|
}]
|
|
|
|
});
|
2019-04-19 17:33:17 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
changeTileLayer: function(name, save=false) {
|
|
|
|
for (var tl in this.baseLayers) {
|
|
|
|
this.map.removeLayer(this.baseLayers[tl]);
|
|
|
|
}
|
2019-04-20 22:08:36 +03:00
|
|
|
for (var ol in this.baseOverlays) {
|
|
|
|
this.map.removeLayer(this.baseOverlays[ol]);
|
|
|
|
}
|
2019-04-19 17:33:17 +03:00
|
|
|
this.map.addLayer(this.baseLayers[name]);
|
2019-04-21 16:06:50 +03:00
|
|
|
if (name === 'ESRI Aerial' || name === 'Watercolor') {
|
2019-04-20 22:08:36 +03:00
|
|
|
this.map.addLayer(this.baseOverlays['Roads and labels']);
|
|
|
|
}
|
2019-04-19 17:33:17 +03:00
|
|
|
this.layerChanged(name);
|
|
|
|
if (save) {
|
|
|
|
optionsController.saveOptionValues({tileLayer: name});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
layerChanged: function(name) {
|
|
|
|
if (name === 'ESRI Aerial') {
|
|
|
|
this.esriButton.remove();
|
2019-04-19 17:38:26 +03:00
|
|
|
this.osmButton.addTo(this.map);
|
2019-04-19 17:33:17 +03:00
|
|
|
}
|
2019-04-19 17:38:26 +03:00
|
|
|
else {
|
2019-04-19 17:33:17 +03:00
|
|
|
this.osmButton.remove();
|
|
|
|
this.esriButton.addTo(this.map);
|
|
|
|
}
|
2019-04-30 16:04:19 +03:00
|
|
|
// map maxZoom should be dynamic (if not specified at map creation) but something crashes like that
|
|
|
|
// so we set it on map creation and
|
|
|
|
// we change it on tile layer change
|
|
|
|
if (this.baseLayers[name].options.maxZoom) {
|
|
|
|
this.map.setMaxZoom(this.baseLayers[name].options.maxZoom);
|
|
|
|
}
|
2019-04-21 16:46:42 +03:00
|
|
|
$('.leaflet-control-layers').hide();
|
|
|
|
$('.easy-button-container').show();
|
2019-04-19 17:33:17 +03:00
|
|
|
},
|
2019-04-03 05:14:10 +03:00
|
|
|
};
|
2019-04-02 18:11:45 +03:00
|
|
|
|
2019-04-03 05:14:10 +03:00
|
|
|
var routingController = {
|
|
|
|
control: undefined,
|
|
|
|
map: undefined,
|
|
|
|
enabled: false,
|
2019-06-10 15:58:34 +03:00
|
|
|
routers: {},
|
|
|
|
selectedRouter: 'osrmDEMO',
|
2019-04-03 05:14:10 +03:00
|
|
|
initRoutingControl: function(map) {
|
|
|
|
this.map = map;
|
|
|
|
var that = this;
|
|
|
|
|
2019-06-25 20:04:42 +03:00
|
|
|
$('body').on('click', '#routing-close', function(e) {
|
|
|
|
routingController.toggleRouting();
|
|
|
|
});
|
|
|
|
|
2019-04-22 04:55:42 +03:00
|
|
|
this.beginIcon = L.divIcon({
|
|
|
|
iconAnchor: [12, 25],
|
|
|
|
className: 'route-waypoint route-begin-waypoint',
|
|
|
|
html: ''
|
|
|
|
});
|
|
|
|
this.middleIcon = L.divIcon({
|
|
|
|
iconAnchor: [12, 25],
|
|
|
|
className: 'route-waypoint route-middle-waypoint',
|
|
|
|
html: ''
|
|
|
|
});
|
|
|
|
this.endIcon = L.divIcon({
|
|
|
|
iconAnchor: [12, 25],
|
|
|
|
className: 'route-waypoint route-end-waypoint',
|
|
|
|
html: ''
|
|
|
|
});
|
|
|
|
|
2019-04-23 01:15:44 +03:00
|
|
|
var lang = OC.getLocale();
|
|
|
|
// this is for all routing engines except OSRM
|
|
|
|
L.Routing.Localization[lang] = {
|
|
|
|
directions: {
|
|
|
|
N: t('maps', 'north'),
|
|
|
|
NE: t('maps', 'northeast'),
|
|
|
|
E: t('maps', 'east'),
|
|
|
|
SE: t('maps', 'southeast'),
|
|
|
|
S: t('maps', 'south'),
|
|
|
|
SW: t('maps', 'southwest'),
|
|
|
|
W: t('maps', 'west'),
|
|
|
|
NW: t('maps', 'northwest'),
|
|
|
|
SlightRight: t('maps', 'slight right'),
|
|
|
|
Right: t('maps', 'right'),
|
|
|
|
SharpRight: t('maps', 'sharp right'),
|
|
|
|
SlightLeft: t('maps', 'slight left'),
|
|
|
|
Left: t('maps', 'left'),
|
|
|
|
SharpLeft: t('maps', 'sharp left'),
|
|
|
|
Uturn: t('maps', 'Turn around')
|
|
|
|
},
|
|
|
|
instructions: {
|
|
|
|
// instruction, postfix if the road is named
|
|
|
|
'Head':
|
2019-04-23 01:35:14 +03:00
|
|
|
[t('maps', 'Head {dir}'), t('maps', ' on {road}')],
|
2019-04-23 01:15:44 +03:00
|
|
|
'Continue':
|
|
|
|
[t('maps', 'Continue {dir}')],
|
|
|
|
'TurnAround':
|
|
|
|
[t('maps', 'Turn around')],
|
|
|
|
'WaypointReached':
|
|
|
|
[t('maps', 'Waypoint reached')],
|
|
|
|
'Roundabout':
|
|
|
|
[t('maps', 'Take the {exitStr} exit in the roundabout'), t('maps', ' onto {road}')],
|
|
|
|
'DestinationReached':
|
|
|
|
[t('maps', 'Destination reached')],
|
|
|
|
'Fork': [t('maps', 'At the fork, turn {modifier}'), t('maps', ' onto {road}')],
|
|
|
|
'Merge': [t('maps', 'Merge {modifier}'), t('maps', ' onto {road}')],
|
|
|
|
'OnRamp': [t('maps', 'Turn {modifier} on the ramp'), t('maps', ' onto {road}')],
|
|
|
|
'OffRamp': [t('maps', 'Take the ramp on the {modifier}'), t('maps', ' onto {road}')],
|
|
|
|
'EndOfRoad': [t('maps', 'Turn {modifier} at the end of the road'), t('maps', ' onto {road}')],
|
|
|
|
'Onto': t('maps', 'onto {road}')
|
|
|
|
},
|
|
|
|
ui: {
|
|
|
|
startPlaceholder: t('maps', 'Start'),
|
|
|
|
viaPlaceholder: t('maps', 'Via {viaNumber}'),
|
|
|
|
endPlaceholder: t('maps', 'Destination')
|
|
|
|
},
|
|
|
|
formatOrder: function(n) {
|
|
|
|
return n + 'º';
|
|
|
|
},
|
|
|
|
units: {
|
|
|
|
meters: t('maps', 'm'),
|
|
|
|
kilometers: t('maps', 'km'),
|
|
|
|
yards: t('maps', 'yd'),
|
|
|
|
miles: t('maps', 'mi'),
|
|
|
|
hours: t('maps', 'h'),
|
|
|
|
minutes: t('maps', 'min'),
|
|
|
|
seconds: t('maps', 's')
|
|
|
|
}
|
|
|
|
};
|
2019-06-10 15:58:34 +03:00
|
|
|
this.routers.osrmDEMO = {
|
2019-06-10 19:06:29 +03:00
|
|
|
name: 'By car (OSRM demo)',
|
2019-06-10 15:58:34 +03:00
|
|
|
router: L.Routing.osrmv1({
|
|
|
|
serviceUrl: 'https://router.project-osrm.org/route/v1',
|
|
|
|
//profile: 'driving', // works with demo server
|
|
|
|
profile: 'car', // works with demo server
|
|
|
|
//profile: 'bicycle', // does not work with demo server...
|
|
|
|
//profile: 'foot', // does not work with demo server...
|
|
|
|
suppressDemoServerWarning: true,
|
|
|
|
// this makes OSRM use our local translations
|
|
|
|
// otherwise it uses osrm-text-instructions which requires to import another lib
|
|
|
|
stepToText: function(e) {
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
2019-04-03 05:14:10 +03:00
|
|
|
this.control = L.Routing.control({
|
2019-06-10 15:58:34 +03:00
|
|
|
router: this.routers.osrmDEMO.router,
|
2019-04-22 03:52:49 +03:00
|
|
|
position: 'topleft',
|
2019-04-02 18:11:45 +03:00
|
|
|
routeWhileDragging: true,
|
2019-04-08 15:44:59 +03:00
|
|
|
reverseWaypoints: true,
|
2019-04-02 18:11:45 +03:00
|
|
|
geocoder: L.Control.Geocoder.nominatim(),
|
2019-04-23 01:15:44 +03:00
|
|
|
language: lang,
|
2019-04-22 04:55:42 +03:00
|
|
|
lineOptions: {
|
2019-06-10 15:58:34 +03:00
|
|
|
styles: [
|
|
|
|
{color: 'black', opacity: 0.15, weight: 9},
|
|
|
|
{color: 'white', opacity: 0.8, weight: 6},
|
|
|
|
{color: 'blue', opacity: 1, weight: 2}
|
|
|
|
],
|
2019-04-22 04:55:42 +03:00
|
|
|
},
|
|
|
|
pointMarkerStyle: {radius: 5, color: '#03f', fillColor: 'white', opacity: 1, fillOpacity: 0.7},
|
|
|
|
createMarker: this.createMarker
|
2019-04-23 00:30:42 +03:00
|
|
|
})
|
|
|
|
.on('routingerror', this.onRoutingError)
|
|
|
|
.on('routingstart', this.onRoutingStart)
|
|
|
|
.on('routesfound', this.onRoutingEnd);
|
2019-04-22 20:04:57 +03:00
|
|
|
|
2019-06-10 15:58:34 +03:00
|
|
|
|
2019-06-25 20:04:42 +03:00
|
|
|
//// toggle routing control
|
|
|
|
//$('body').on('click', '#navigation-routing > a', function(e) {
|
|
|
|
// that.toggleRouting();
|
|
|
|
// optionsController.saveOptionValues({routingEnabled: that.enabled});
|
|
|
|
//});
|
2019-04-03 05:21:23 +03:00
|
|
|
// export
|
|
|
|
$('body').on('click', '.exportCurrentRoute', function(e) {
|
|
|
|
that.exportRoute();
|
|
|
|
});
|
2019-06-10 15:58:34 +03:00
|
|
|
// select router
|
|
|
|
$('body').on('change', '#router-select', function(e) {
|
|
|
|
var type = $(this).val();
|
|
|
|
that.selectedRouter = type;
|
|
|
|
var router = that.routers[type].router;
|
2019-06-10 16:59:14 +03:00
|
|
|
that.setRouter(type);
|
2019-06-10 15:58:34 +03:00
|
|
|
optionsController.saveOptionValues({selectedRouter: type});
|
|
|
|
that.control.route();
|
|
|
|
});
|
2019-04-03 05:14:10 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
toggleRouting: function() {
|
|
|
|
if (this.enabled) {
|
2019-06-25 20:04:42 +03:00
|
|
|
$('#search-form').show();
|
2019-04-03 05:14:10 +03:00
|
|
|
this.control.remove();
|
2019-04-20 16:07:54 +03:00
|
|
|
$('#navigation-routing').removeClass('active');
|
|
|
|
$('#map').focus();
|
2019-04-03 05:14:10 +03:00
|
|
|
this.enabled = false;
|
|
|
|
}
|
|
|
|
else {
|
2019-06-25 20:04:42 +03:00
|
|
|
$('#search-form').hide();
|
2019-04-03 05:14:10 +03:00
|
|
|
this.control.addTo(this.map);
|
2019-04-20 16:07:54 +03:00
|
|
|
$('#navigation-routing').addClass('active');
|
2019-04-03 05:14:10 +03:00
|
|
|
this.enabled = true;
|
2019-04-22 03:52:49 +03:00
|
|
|
$('.leaflet-routing-geocoder input').first().focus();
|
2019-06-10 15:58:34 +03:00
|
|
|
|
|
|
|
// add router selector
|
|
|
|
var select = '<select id="router-select">';
|
|
|
|
var r, router, selected;
|
|
|
|
for (r in this.routers) {
|
|
|
|
router = this.routers[r];
|
|
|
|
selected = '';
|
|
|
|
if (r === this.selectedRouter) {
|
|
|
|
selected = ' selected';
|
|
|
|
}
|
|
|
|
select += '<option value="'+r+'"'+selected+'>'+router.name+'</option>';
|
|
|
|
}
|
|
|
|
select += '</select>';
|
2019-06-10 16:59:14 +03:00
|
|
|
|
2019-06-25 20:04:42 +03:00
|
|
|
var close = '<button class="icon-close" id="routing-close"></button>';
|
|
|
|
|
|
|
|
$('.leaflet-routing-container').prepend(close);
|
|
|
|
$('.leaflet-routing-geocoders').append(select);
|
2019-04-03 05:14:10 +03:00
|
|
|
}
|
2019-04-03 05:21:23 +03:00
|
|
|
},
|
|
|
|
|
2019-06-10 16:59:14 +03:00
|
|
|
setRouter: function(routerType) {
|
2019-06-10 19:06:29 +03:00
|
|
|
if (this.routers.hasOwnProperty(routerType)) {
|
|
|
|
var router = this.routers[routerType].router;
|
|
|
|
this.control._router = router;
|
|
|
|
this.control.options.router = router;
|
|
|
|
}
|
2019-04-22 20:04:57 +03:00
|
|
|
},
|
|
|
|
|
2019-06-10 15:58:34 +03:00
|
|
|
// create router and make it accessible in the interface
|
|
|
|
addRouter: function(type, name, url, apikey) {
|
2019-06-11 02:18:34 +03:00
|
|
|
if (type === 'graphhopperBike' || type === 'graphhopperCar' || type === 'graphhopperFoot') {
|
|
|
|
var options = {};
|
|
|
|
if (type === 'graphhopperCar') {
|
|
|
|
options.urlParameters = {
|
|
|
|
vehicle: 'car' // available ones : car, foot, bike, bike2, mtb, racingbike, motorcycle
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if (type === 'graphhopperBike') {
|
|
|
|
options.urlParameters = {
|
|
|
|
vehicle: 'bike'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if (type === 'graphhopperFoot') {
|
|
|
|
options.urlParameters = {
|
|
|
|
vehicle: 'foot'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if (url) {
|
|
|
|
options.serviceUrl = url;
|
|
|
|
}
|
|
|
|
this.routers[type] = {
|
2019-06-10 19:06:29 +03:00
|
|
|
name: name,
|
2019-06-11 02:18:34 +03:00
|
|
|
router: L.Routing.graphHopper(apikey, options)
|
2019-06-10 19:06:29 +03:00
|
|
|
};
|
|
|
|
}
|
2019-06-11 02:26:54 +03:00
|
|
|
else if (type === 'osrmBike' || type === 'osrmCar' || type === 'osrmFoot') {
|
|
|
|
var options = {
|
|
|
|
serviceUrl: url,
|
|
|
|
suppressDemoServerWarning: true,
|
|
|
|
// this makes OSRM use our local translations
|
|
|
|
// otherwise it uses osrm-text-instructions which requires to import another lib
|
|
|
|
stepToText: function(e) {
|
|
|
|
}
|
2019-06-10 15:58:34 +03:00
|
|
|
};
|
2019-06-11 02:26:54 +03:00
|
|
|
if (type === 'osrmCar') {
|
|
|
|
options.profile = 'car';
|
|
|
|
}
|
|
|
|
else if (type === 'osrmBike') {
|
|
|
|
options.profile = 'bicycle';
|
|
|
|
}
|
|
|
|
else if (type === 'osrmFoot') {
|
|
|
|
options.profile = 'foot';
|
|
|
|
}
|
|
|
|
this.routers[type] = {
|
2019-06-10 19:06:29 +03:00
|
|
|
name: name,
|
2019-06-11 02:26:54 +03:00
|
|
|
router: L.Routing.osrmv1(options)
|
2019-06-10 19:06:29 +03:00
|
|
|
};
|
|
|
|
}
|
2019-06-11 02:04:30 +03:00
|
|
|
else if (type === 'mapbox') {
|
|
|
|
this.routers.mapbox = {
|
|
|
|
name: name,
|
|
|
|
router: L.Routing.mapbox(apikey)
|
|
|
|
};
|
|
|
|
}
|
2019-06-10 15:58:34 +03:00
|
|
|
else if (type === 'osrmDEMO') {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2019-04-22 20:04:57 +03:00
|
|
|
onRoutingError: function(e) {
|
2019-04-29 13:53:09 +03:00
|
|
|
var msg = e.error.target.responseText
|
|
|
|
try {
|
|
|
|
var json = $.parseJSON(e.error.target.responseText);
|
|
|
|
if (json.message) {
|
|
|
|
msg = json.message;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
}
|
|
|
|
OC.Notification.showTemporary(t('maps', 'Routing error:') + ' ' + msg);
|
2019-04-23 00:30:42 +03:00
|
|
|
routingController.onRoutingEnd();
|
|
|
|
},
|
|
|
|
|
|
|
|
onRoutingStart: function(e) {
|
|
|
|
$('#navigation-routing').addClass('icon-loading-small');
|
|
|
|
$('.leaflet-routing-reverse-waypoints').addClass('icon-loading-small');
|
|
|
|
},
|
|
|
|
|
|
|
|
onRoutingEnd: function(e) {
|
|
|
|
$('#navigation-routing').removeClass('icon-loading-small');
|
|
|
|
$('.leaflet-routing-reverse-waypoints').removeClass('icon-loading-small');
|
2019-04-29 13:53:09 +03:00
|
|
|
// TODO understand why routingstart is sometimes triggered after routesfound
|
|
|
|
// just in case routingstart is triggered again (weird):
|
|
|
|
setTimeout(function() {
|
|
|
|
$('#navigation-routing').removeClass('icon-loading-small');
|
|
|
|
$('.leaflet-routing-reverse-waypoints').removeClass('icon-loading-small');
|
|
|
|
}, 5000);
|
2019-04-22 19:15:57 +03:00
|
|
|
},
|
|
|
|
|
2019-06-10 19:06:29 +03:00
|
|
|
//// this has been tested with graphhopper
|
|
|
|
//setRouterVehicle: function(vehicle) {
|
|
|
|
// if (this.selectedRouter === 'graphhopper') {
|
|
|
|
// this.control.getRouter().options.urlParameters.vehicle = vehicle;
|
|
|
|
// }
|
|
|
|
// else if (this.selectedRouter === 'osrm') {
|
|
|
|
// this.control.getRouter().options.profile = vehicle.replace('bike', 'bicycle');
|
|
|
|
// }
|
|
|
|
// this.control.route();
|
|
|
|
//},
|
2019-04-22 19:15:57 +03:00
|
|
|
|
2019-04-22 04:55:42 +03:00
|
|
|
createMarker: function(i, wpt, n) {
|
|
|
|
var icon;
|
|
|
|
if (i === 0) {
|
|
|
|
icon = routingController.beginIcon;
|
|
|
|
}
|
|
|
|
else if (i === n - 1) {
|
|
|
|
icon = routingController.endIcon;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
icon = routingController.middleIcon;
|
|
|
|
}
|
|
|
|
var marker = L.marker(wpt.latLng, {icon: icon, draggable: true});
|
|
|
|
return marker;
|
|
|
|
},
|
|
|
|
|
2019-04-03 05:21:23 +03:00
|
|
|
exportRoute: function() {
|
2019-04-05 03:12:23 +03:00
|
|
|
if (this.control.hasOwnProperty('_selectedRoute')
|
|
|
|
&& this.control._selectedRoute.hasOwnProperty('coordinates')
|
|
|
|
&& this.control._selectedRoute.coordinates.length > 0
|
2019-04-03 05:21:23 +03:00
|
|
|
) {
|
2019-04-05 03:12:23 +03:00
|
|
|
var latLngCoords = this.control._selectedRoute.coordinates;
|
|
|
|
var gpxRteCoords = '';
|
|
|
|
for (var i=0; i < latLngCoords.length; i++) {
|
|
|
|
gpxRteCoords = gpxRteCoords + ' <rtept lat="' + latLngCoords[i].lat + '" lon="' + latLngCoords[i].lng + '">\n' +
|
|
|
|
' </rtept>\n';
|
|
|
|
}
|
|
|
|
var name = this.control._selectedRoute.name;
|
|
|
|
var totDist = this.control._selectedRoute.summary.totalDistance;
|
|
|
|
var totTime = this.control._selectedRoute.summary.totalTime;
|
|
|
|
|
|
|
|
$('#navigation-routing').addClass('icon-loading-small');
|
|
|
|
var req = {
|
|
|
|
coords: gpxRteCoords,
|
|
|
|
name: name,
|
|
|
|
totDist: totDist,
|
|
|
|
totTime: totTime
|
|
|
|
};
|
|
|
|
var url = OC.generateUrl('/apps/maps/exportRoute');
|
|
|
|
$.ajax({
|
|
|
|
type: 'POST',
|
|
|
|
url: url,
|
|
|
|
data: req,
|
|
|
|
async: true
|
|
|
|
}).done(function (response) {
|
|
|
|
OC.Notification.showTemporary(t('maps', 'Route exported in {path}', {path: response}));
|
|
|
|
}).always(function (response) {
|
|
|
|
$('#navigation-routing').removeClass('icon-loading-small');
|
|
|
|
}).fail(function() {
|
|
|
|
OC.Notification.showTemporary(t('maps', 'Failed to export current route'));
|
|
|
|
});
|
2019-04-03 05:21:23 +03:00
|
|
|
}
|
2019-04-08 15:37:47 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
contextRouteFrom: function(e) {
|
|
|
|
if (!routingController.enabled) {
|
|
|
|
routingController.toggleRouting();
|
|
|
|
}
|
2019-04-26 17:03:04 +03:00
|
|
|
routingController.setRouteFrom(e.latlng);
|
2019-04-08 15:37:47 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
contextRouteTo: function(e) {
|
|
|
|
if (!routingController.enabled) {
|
|
|
|
routingController.toggleRouting();
|
|
|
|
}
|
2019-04-26 17:03:04 +03:00
|
|
|
routingController.setRouteTo(e.latlng);
|
2019-04-08 15:37:47 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
contextRoutePoint: function(e) {
|
|
|
|
if (!routingController.enabled) {
|
|
|
|
routingController.toggleRouting();
|
|
|
|
}
|
2019-04-26 17:03:04 +03:00
|
|
|
routingController.addRoutePoint(e.latlng);
|
|
|
|
},
|
|
|
|
|
|
|
|
setRouteFrom: function(latlng) {
|
|
|
|
this.control.spliceWaypoints(0, 1, latlng);
|
|
|
|
},
|
|
|
|
|
|
|
|
setRouteTo: function(latlng) {
|
|
|
|
this.control.spliceWaypoints(this.control.getWaypoints().length - 1, 1, latlng);
|
|
|
|
},
|
|
|
|
|
2019-04-26 17:40:46 +03:00
|
|
|
setRoutePoint: function(i, latlng) {
|
|
|
|
this.control.spliceWaypoints(i, 1, latlng);
|
|
|
|
},
|
|
|
|
|
2019-04-26 17:03:04 +03:00
|
|
|
addRoutePoint: function(latlng) {
|
|
|
|
this.control.spliceWaypoints(this.control.getWaypoints().length - 1, 0, latlng);
|
2019-04-08 15:37:47 +03:00
|
|
|
},
|
2017-08-24 13:28:00 +03:00
|
|
|
};
|
|
|
|
|
2019-04-01 12:23:11 +03:00
|
|
|
var timeFilterController = {
|
2019-04-01 22:33:24 +03:00
|
|
|
min: 0,
|
|
|
|
max: Date.now()/1000,
|
2019-04-02 03:50:18 +03:00
|
|
|
minInitialized: false,
|
|
|
|
maxInitialized: false,
|
|
|
|
valueBegin: null,
|
|
|
|
valueEnd: null,
|
2019-04-01 22:33:24 +03:00
|
|
|
updateFilterTimeBegin: [],
|
|
|
|
updateFilterTimeEnd: [],
|
2019-04-01 23:23:14 +03:00
|
|
|
onUpdateCallbackBlock: false,
|
2019-04-02 03:50:18 +03:00
|
|
|
onChangeCallbackBlock: false,
|
2019-04-19 18:45:16 +03:00
|
|
|
slider : document.getElementById('timeRangeSlider'),
|
2019-04-02 10:57:26 +03:00
|
|
|
sliderConnect: null,
|
2019-04-02 03:50:18 +03:00
|
|
|
connect: function () {
|
|
|
|
noUiSlider.create(this.slider, {
|
|
|
|
start: [20, 80],
|
|
|
|
connect: true,
|
|
|
|
behaviour: 'drag',
|
|
|
|
tooltips: [{
|
|
|
|
to: function (x) {
|
2019-04-03 14:25:12 +03:00
|
|
|
return new Date(x*1000).toIsoString();
|
2019-04-02 03:50:18 +03:00
|
|
|
},
|
|
|
|
}, {
|
|
|
|
to: function (x) {
|
2019-04-03 14:25:12 +03:00
|
|
|
return new Date(x*1000).toIsoString();
|
2019-04-02 03:50:18 +03:00
|
|
|
}
|
|
|
|
}],
|
|
|
|
range: {
|
|
|
|
'min': 0,
|
|
|
|
'max': 1
|
2019-04-02 10:57:26 +03:00
|
|
|
}
|
2019-04-02 03:50:18 +03:00
|
|
|
});
|
2019-04-19 18:45:16 +03:00
|
|
|
this.sliderConnect = this.slider.getElementsByClassName('noUi-connect')[0];
|
2019-04-02 03:50:18 +03:00
|
|
|
this.updateSliderRange(this.min, this.max);
|
|
|
|
this.setSlider(this.min, this.max);
|
2019-04-01 22:33:24 +03:00
|
|
|
var that = this;
|
2019-04-02 03:50:18 +03:00
|
|
|
this.slider.noUiSlider.on('update', function(values, handle, unencoded, tap, positions) {
|
2019-04-01 22:33:24 +03:00
|
|
|
if (!that.onUpdateCallbackBlock){
|
|
|
|
that.onUpdateCallbackBlock = true;
|
|
|
|
if (handle === 0) {
|
2019-04-02 03:50:18 +03:00
|
|
|
that.valueBegin = unencoded[0];
|
|
|
|
photosController.updateTimeFilterBegin(that.valueBegin);
|
2019-04-09 13:07:06 +03:00
|
|
|
nonLocalizedPhotosController.updateTimeFilterBegin(that.valueBegin);
|
2019-04-04 20:47:41 +03:00
|
|
|
contactsController.updateTimeFilterBegin(that.valueBegin);
|
2019-04-01 22:33:24 +03:00
|
|
|
}
|
2019-04-02 03:50:18 +03:00
|
|
|
else {
|
|
|
|
that.valueEnd = unencoded[1];
|
|
|
|
photosController.updateTimeFilterEnd(that.valueEnd);
|
2019-04-09 13:07:06 +03:00
|
|
|
nonLocalizedPhotosController.updateTimeFilterEnd(that.valueEnd);
|
2019-04-04 20:47:41 +03:00
|
|
|
contactsController.updateTimeFilterEnd(that.valueEnd);
|
2019-04-02 03:50:18 +03:00
|
|
|
}
|
|
|
|
favoritesController.updateFilterDisplay();
|
2019-04-08 02:47:37 +03:00
|
|
|
tracksController.updateFilterDisplay();
|
2019-04-17 17:32:59 +03:00
|
|
|
devicesController.updateFilterDisplay();
|
2019-04-02 10:57:26 +03:00
|
|
|
|
2019-04-01 22:33:24 +03:00
|
|
|
that.onUpdateCallbackBlock = false;
|
2019-04-19 18:45:16 +03:00
|
|
|
if (Math.round(unencoded[0]) < Math.round(that.min) ||
|
|
|
|
Math.round(unencoded[1]) > Math.round(that.max) ||
|
|
|
|
positions[1] - positions[0] < 10
|
|
|
|
) {
|
|
|
|
that.sliderConnect.classList.add('timeRangeSlider-active');
|
2019-04-02 10:57:26 +03:00
|
|
|
} else {
|
2019-04-19 18:45:16 +03:00
|
|
|
that.sliderConnect.classList.remove('timeRangeSlider-active');
|
2019-04-02 10:57:26 +03:00
|
|
|
}
|
2019-04-01 22:33:24 +03:00
|
|
|
}
|
2019-04-02 03:50:18 +03:00
|
|
|
});
|
|
|
|
this.slider.noUiSlider.on('change', function(values, handle, unencoded, tap, positions) {
|
2019-04-02 10:57:26 +03:00
|
|
|
if (!that.onChangeCallbackBlock) {
|
2019-04-01 23:23:14 +03:00
|
|
|
that.onChangeCallbackBlock = true;
|
|
|
|
if (unencoded[0] < that.min) {
|
|
|
|
var delta = that.min-unencoded[0];
|
|
|
|
var r = that.max-that.min;
|
|
|
|
that.updateSliderRange(that.min - 25* delta*delta/r, that.max);
|
|
|
|
}
|
|
|
|
if (unencoded[1] > that.max) {
|
|
|
|
var delta = -that.max+unencoded[1];
|
|
|
|
var r = that.max-that.min;
|
|
|
|
that.updateSliderRange(that.min, that.max + 25*delta*delta/r);
|
|
|
|
}
|
|
|
|
if (positions[1] - positions[0] < 10) {
|
|
|
|
var m = (unencoded[0] + unencoded[1])/2;
|
2019-04-02 10:57:26 +03:00
|
|
|
var d = Math.max((unencoded[1] - unencoded[0])/2,1);
|
2019-04-01 23:23:14 +03:00
|
|
|
that.updateSliderRange(m-2.5*d, m+2.5*d);
|
|
|
|
that.setSlider(unencoded[0], unencoded[1]);
|
|
|
|
}
|
2019-04-19 18:45:16 +03:00
|
|
|
that.sliderConnect.classList.remove('timeRangeSlider-active');
|
2019-04-01 23:23:14 +03:00
|
|
|
that.onChangeCallbackBlock = false;
|
|
|
|
}
|
2019-04-01 22:33:24 +03:00
|
|
|
});
|
2019-04-02 13:16:57 +03:00
|
|
|
this.slider.ondblclick = function() {
|
|
|
|
that.updateSliderRangeFromController();
|
|
|
|
that.setSliderToMaxInterval();
|
|
|
|
};
|
2019-04-01 22:33:24 +03:00
|
|
|
},
|
2019-04-02 03:50:18 +03:00
|
|
|
updateSliderRange: function(min, max) {
|
2019-04-01 12:23:11 +03:00
|
|
|
var range = max - min;
|
2019-04-01 22:33:24 +03:00
|
|
|
this.slider.noUiSlider.updateOptions({
|
|
|
|
range: {
|
|
|
|
'min': min - range/10,
|
|
|
|
'max': max + range/10
|
2019-04-02 10:57:26 +03:00
|
|
|
},
|
2019-04-01 22:33:24 +03:00
|
|
|
});
|
2019-04-01 23:23:14 +03:00
|
|
|
this.min = min;
|
|
|
|
this.max = max;
|
2019-04-01 12:23:11 +03:00
|
|
|
},
|
2019-04-01 23:23:14 +03:00
|
|
|
setSlider: function(min, max) {
|
|
|
|
this.slider.noUiSlider.set([min, max]);
|
2019-04-02 03:50:18 +03:00
|
|
|
},
|
|
|
|
// when a controller's data has changed
|
2019-04-05 18:13:46 +03:00
|
|
|
// this changes the min/max slider reachable values (it does not set the values)
|
2019-04-06 03:18:23 +03:00
|
|
|
// it should be called when there are changes in controller data
|
|
|
|
// and when user wants to reset the slider to see everything
|
2019-04-02 03:50:18 +03:00
|
|
|
updateSliderRangeFromController: function() {
|
2019-04-05 18:13:46 +03:00
|
|
|
var i;
|
|
|
|
var mins = [];
|
|
|
|
var maxs = [];
|
|
|
|
var rawMins = [
|
2019-04-02 03:50:18 +03:00
|
|
|
favoritesController.firstDate,
|
2019-04-07 22:23:17 +03:00
|
|
|
tracksController.firstDate,
|
2019-04-04 20:47:41 +03:00
|
|
|
photosController.photoMarkersOldest,
|
2019-04-09 13:07:06 +03:00
|
|
|
nonLocalizedPhotosController.nonLocalizedPhotoMarkersOldest,
|
2019-04-17 17:32:59 +03:00
|
|
|
contactsController.contactMarkersOldest,
|
|
|
|
devicesController.firstDate
|
2019-04-02 03:50:18 +03:00
|
|
|
];
|
2019-04-05 18:13:46 +03:00
|
|
|
var rawMaxs = [
|
2019-04-02 03:50:18 +03:00
|
|
|
favoritesController.lastDate,
|
2019-04-07 22:23:17 +03:00
|
|
|
tracksController.lastDate,
|
2019-04-04 20:47:41 +03:00
|
|
|
photosController.photoMarkersNewest,
|
2019-04-09 13:07:06 +03:00
|
|
|
nonLocalizedPhotosController.nonLocalizedPhotoMarkersNewest,
|
2019-04-17 17:32:59 +03:00
|
|
|
contactsController.contactMarkersNewest,
|
|
|
|
devicesController.lastDate
|
2019-04-02 03:50:18 +03:00
|
|
|
];
|
2019-04-05 18:13:46 +03:00
|
|
|
// get rid of null values
|
|
|
|
for (i=0; i < rawMins.length; i++) {
|
|
|
|
if (rawMins[i] !== null) {
|
|
|
|
mins.push(rawMins[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i=0; i < rawMaxs.length; i++) {
|
|
|
|
if (rawMaxs[i] !== null) {
|
|
|
|
maxs.push(rawMaxs[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var cmin = null;
|
|
|
|
var cmax = null;
|
|
|
|
// get the min of all controllers
|
|
|
|
if (mins.length > 0) {
|
2019-04-06 03:18:23 +03:00
|
|
|
cmin = Math.min(...mins);
|
2019-04-05 18:13:46 +03:00
|
|
|
}
|
|
|
|
// get the max of all controllers
|
|
|
|
if (maxs.length > 0) {
|
2019-04-06 03:18:23 +03:00
|
|
|
cmax = Math.max(...maxs);
|
2019-04-05 18:13:46 +03:00
|
|
|
}
|
|
|
|
if (cmin !== null && cmax !== null) {
|
2019-04-21 05:50:55 +03:00
|
|
|
$(this.slider).fadeIn();
|
2019-04-05 18:13:46 +03:00
|
|
|
this.min = cmin;
|
|
|
|
this.max = cmax;
|
2019-04-02 04:53:46 +03:00
|
|
|
// avoid min == max
|
2019-04-05 18:13:46 +03:00
|
|
|
if (cmin === cmax) {
|
|
|
|
this.min = cmin - 10;
|
|
|
|
this.max = cmax + 10;
|
2019-04-02 04:53:46 +03:00
|
|
|
}
|
2019-04-02 03:50:18 +03:00
|
|
|
this.updateSliderRange(this.min, this.max);
|
|
|
|
}
|
2019-04-21 05:50:55 +03:00
|
|
|
else {
|
|
|
|
$(this.slider).fadeOut();
|
|
|
|
}
|
2019-04-02 03:50:18 +03:00
|
|
|
},
|
|
|
|
// on first data load, controllers want to set the slider values to global common max
|
|
|
|
setSliderToMaxInterval: function() {
|
|
|
|
this.setSlider(this.min, this.max);
|
2019-04-01 23:23:14 +03:00
|
|
|
}
|
2019-04-01 12:23:11 +03:00
|
|
|
};
|
|
|
|
|
2019-04-01 22:33:24 +03:00
|
|
|
|
2019-04-01 12:23:11 +03:00
|
|
|
var photosController = new PhotosController(optionsController, timeFilterController);
|
2019-04-09 13:27:23 +03:00
|
|
|
var nonLocalizedPhotosController = new NonLocalizedPhotosController(optionsController, timeFilterController, photosController);
|
2019-04-04 20:47:41 +03:00
|
|
|
var contactsController = new ContactsController(optionsController, timeFilterController);
|
2019-04-01 21:03:12 +03:00
|
|
|
var favoritesController = new FavoritesController(optionsController, timeFilterController);
|
2019-04-06 22:00:14 +03:00
|
|
|
var tracksController = new TracksController(optionsController, timeFilterController);
|
2019-04-17 02:06:07 +03:00
|
|
|
var devicesController = new DevicesController(optionsController, timeFilterController);
|
2017-08-31 00:40:37 +03:00
|
|
|
|
2019-04-02 03:50:18 +03:00
|
|
|
timeFilterController.connect();
|
2019-04-01 12:23:11 +03:00
|
|
|
|
2017-08-23 16:39:28 +03:00
|
|
|
var searchController = {
|
2019-04-26 16:12:49 +03:00
|
|
|
map: null,
|
2019-04-26 17:29:30 +03:00
|
|
|
SEARCH_BAR: 1,
|
|
|
|
ROUTING_FROM: 2,
|
|
|
|
ROUTING_TO: 3,
|
2019-04-26 17:40:46 +03:00
|
|
|
ROUTING_POINT: 4,
|
2019-04-27 02:43:00 +03:00
|
|
|
currentLocalAutocompleteData: [],
|
2019-04-26 16:12:49 +03:00
|
|
|
initController: function(map) {
|
|
|
|
this.map = map;
|
|
|
|
var that = this;
|
|
|
|
// Search
|
|
|
|
$('#search-form').submit(function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
that.submitSearchForm();
|
|
|
|
});
|
|
|
|
$('#search-submit').click(function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
that.submitSearchForm();
|
|
|
|
});
|
2019-06-25 20:04:42 +03:00
|
|
|
$('#route-submit').click(function(e) {
|
|
|
|
routingController.toggleRouting();
|
|
|
|
e.preventDefault();
|
|
|
|
});
|
2019-04-26 16:12:49 +03:00
|
|
|
$('#search-term').on('focus', function(e) {
|
|
|
|
$(this).select();
|
2019-04-26 17:29:30 +03:00
|
|
|
that.setSearchAutocomplete(that.SEARCH_BAR);
|
|
|
|
});
|
|
|
|
$('body').on('focus', '.leaflet-routing-geocoder input', function(e) {
|
|
|
|
var inputs = $('.leaflet-routing-geocoder input');
|
|
|
|
var nbInputs = inputs.length;
|
|
|
|
var index = inputs.index($(this));
|
|
|
|
if (index === 0) {
|
|
|
|
that.setSearchAutocomplete(that.ROUTING_FROM);
|
|
|
|
}
|
|
|
|
else if (index === nbInputs - 1) {
|
|
|
|
that.setSearchAutocomplete(that.ROUTING_TO);
|
|
|
|
}
|
2019-04-26 17:40:46 +03:00
|
|
|
else {
|
|
|
|
that.setSearchAutocomplete(that.ROUTING_POINT, index);
|
|
|
|
}
|
2019-04-26 16:12:49 +03:00
|
|
|
});
|
2019-04-26 17:51:03 +03:00
|
|
|
$('body').on('keyup', '.leaflet-routing-geocoder input', function(e) {
|
2019-04-27 01:52:18 +03:00
|
|
|
// if we press enter => disable autocomplete to let nominatim results dropdown appear
|
2019-04-26 17:51:03 +03:00
|
|
|
if (e.key === 'Enter') {
|
2019-04-27 01:52:18 +03:00
|
|
|
$(this).autocomplete('close');
|
|
|
|
$(this).autocomplete('disable');
|
|
|
|
}
|
|
|
|
// if any other key (except arrows up/down) is pressed => enable autocomplete again
|
|
|
|
else if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') {
|
|
|
|
$('.leaflet-routing-geocoder-result').removeClass('leaflet-routing-geocoder-result-open');
|
|
|
|
$(this).autocomplete('enable');
|
|
|
|
$(this).autocomplete('search');
|
2019-04-26 17:51:03 +03:00
|
|
|
}
|
|
|
|
});
|
2019-04-27 03:18:52 +03:00
|
|
|
// replace JQuery ui autocomplete matching function
|
|
|
|
// to make 'one three' match 'one two three' for example.
|
|
|
|
// search terms in the same order
|
|
|
|
$.ui.autocomplete.filter = function (array, terms) {
|
|
|
|
arrayOfTerms = terms.split(' ');
|
|
|
|
var term = $.map(arrayOfTerms, function (tm) {
|
|
|
|
return $.ui.autocomplete.escapeRegex(tm);
|
|
|
|
}).join('.*');
|
|
|
|
var matcher = new RegExp(term, 'i');
|
|
|
|
return $.grep(array, function (value) {
|
|
|
|
return matcher.test(value.label || value.value || value);
|
|
|
|
});
|
|
|
|
};
|
2019-04-27 04:25:32 +03:00
|
|
|
// search result add favorite
|
|
|
|
$('body').on('click', '.search-add-favorite', function(e) {
|
|
|
|
var lat = parseFloat($(this).attr('lat'));
|
|
|
|
var lng = parseFloat($(this).attr('lng'));
|
|
|
|
var name = $(this).parent().find('.location-header').text();
|
|
|
|
favoritesController.addFavoriteDB('', lat, lng, name);
|
|
|
|
that.map.closePopup();
|
|
|
|
});
|
2019-04-26 16:12:49 +03:00
|
|
|
},
|
|
|
|
|
2019-04-26 17:40:46 +03:00
|
|
|
setSearchAutocomplete: function(field, routingPointIndex=null) {
|
2019-04-26 17:29:30 +03:00
|
|
|
var fieldElement;
|
|
|
|
if (field === this.SEARCH_BAR) {
|
|
|
|
fieldElement = $('#search-term');
|
|
|
|
}
|
|
|
|
else if (field === this.ROUTING_FROM) {
|
|
|
|
fieldElement = $('.leaflet-routing-geocoder input').first();
|
|
|
|
}
|
|
|
|
else if (field === this.ROUTING_TO) {
|
|
|
|
fieldElement = $('.leaflet-routing-geocoder input').last();
|
|
|
|
}
|
2019-04-26 17:40:46 +03:00
|
|
|
else if (field === this.ROUTING_POINT) {
|
|
|
|
fieldElement = $('.leaflet-routing-geocoder input').eq(routingPointIndex);
|
|
|
|
}
|
2019-04-26 16:12:49 +03:00
|
|
|
var that = this;
|
|
|
|
var data = [];
|
|
|
|
// get favorites
|
|
|
|
var favData = favoritesController.getAutocompData();
|
|
|
|
data.push(...favData);
|
2019-04-26 16:25:52 +03:00
|
|
|
// get contacts
|
|
|
|
var contactData = contactsController.getAutocompData();
|
|
|
|
data.push(...contactData);
|
2019-04-26 16:41:47 +03:00
|
|
|
// get devices
|
|
|
|
var devData = devicesController.getAutocompData();
|
|
|
|
data.push(...devData);
|
2019-04-29 12:58:53 +03:00
|
|
|
data.push(...this.getExtraAutocompleteData(field));
|
2019-04-27 02:43:00 +03:00
|
|
|
that.currentLocalAutocompleteData = data;
|
2019-04-26 17:29:30 +03:00
|
|
|
fieldElement.autocomplete({
|
2019-04-26 16:12:49 +03:00
|
|
|
source: data,
|
|
|
|
select: function (e, ui) {
|
|
|
|
var it = ui.item;
|
|
|
|
if (it.type === 'favorite') {
|
|
|
|
that.map.setView([it.lat, it.lng], 15);
|
|
|
|
}
|
|
|
|
else if (it.type === 'contact') {
|
2019-04-26 16:25:52 +03:00
|
|
|
that.map.setView([it.lat, it.lng], 15);
|
2019-04-26 16:12:49 +03:00
|
|
|
}
|
|
|
|
else if (it.type === 'device') {
|
2019-04-27 03:34:44 +03:00
|
|
|
devicesController.zoomOnDevice(it.id);
|
2019-04-26 16:12:49 +03:00
|
|
|
}
|
2019-04-27 02:43:00 +03:00
|
|
|
else if (it.type === 'address') {
|
|
|
|
if (field === that.SEARCH_BAR) {
|
2019-04-28 23:44:50 +03:00
|
|
|
mapController.displaySearchResult([it.result]);
|
2019-04-27 02:43:00 +03:00
|
|
|
}
|
|
|
|
}
|
2019-04-28 23:44:50 +03:00
|
|
|
else if (it.type === 'mylocation') {
|
2019-04-27 04:57:58 +03:00
|
|
|
navigator.geolocation.getCurrentPosition(function (position) {
|
|
|
|
var lat = position.coords.latitude;
|
|
|
|
var lng = position.coords.longitude;
|
|
|
|
if (field === that.SEARCH_BAR) {
|
|
|
|
that.map.setView([lat, lng], 15);
|
|
|
|
}
|
|
|
|
if (field === that.SEARCH_BAR || field === that.ROUTING_TO) {
|
|
|
|
routingController.setRouteTo(L.latLng(lat, lng));
|
|
|
|
}
|
|
|
|
else if (field === that.ROUTING_FROM) {
|
|
|
|
routingController.setRouteFrom(L.latLng(lat, lng));
|
|
|
|
$('.leaflet-routing-geocoder input').last().focus();
|
|
|
|
}
|
|
|
|
else if (field === that.ROUTING_POINT) {
|
|
|
|
routingController.setRoutePoint(routingPointIndex, L.latLng(lat, lng));
|
|
|
|
$('.leaflet-routing-geocoder input').last().focus();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
2019-04-28 23:44:50 +03:00
|
|
|
else if (it.type === 'poi') {
|
|
|
|
that.submitSearchPOI(it.value, it.label);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// forward to routing controller
|
2019-04-26 17:29:30 +03:00
|
|
|
if (field === that.SEARCH_BAR || field === that.ROUTING_TO) {
|
|
|
|
routingController.setRouteTo(L.latLng(it.lat, it.lng));
|
|
|
|
}
|
|
|
|
else if (field === that.ROUTING_FROM) {
|
|
|
|
routingController.setRouteFrom(L.latLng(it.lat, it.lng));
|
|
|
|
$('.leaflet-routing-geocoder input').last().focus();
|
|
|
|
}
|
2019-04-26 17:40:46 +03:00
|
|
|
else if (field === that.ROUTING_POINT) {
|
|
|
|
routingController.setRoutePoint(routingPointIndex, L.latLng(it.lat, it.lng));
|
|
|
|
$('.leaflet-routing-geocoder input').last().focus();
|
|
|
|
}
|
2019-04-26 16:12:49 +03:00
|
|
|
}
|
|
|
|
}).data('ui-autocomplete')._renderItem = function(ul, item) {
|
2019-04-27 02:43:00 +03:00
|
|
|
var iconClass = 'icon-link';
|
2019-04-29 02:54:49 +03:00
|
|
|
var iconElem = '';
|
2019-04-26 16:12:49 +03:00
|
|
|
if (item.type === 'favorite') {
|
|
|
|
iconClass = 'icon-favorite';
|
|
|
|
}
|
|
|
|
else if (item.type === 'contact') {
|
|
|
|
iconClass = 'icon-group';
|
|
|
|
}
|
2019-04-27 02:43:00 +03:00
|
|
|
else if (item.type === 'device') {
|
2019-04-27 03:29:21 +03:00
|
|
|
if (item.subtype === 'computer') {
|
|
|
|
iconClass = 'icon-desktop';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
iconClass = 'icon-phone';
|
|
|
|
}
|
2019-04-27 02:43:00 +03:00
|
|
|
}
|
2019-04-28 23:44:50 +03:00
|
|
|
else if (item.type === 'mylocation') {
|
2019-04-27 04:57:58 +03:00
|
|
|
iconClass = 'icon-address';
|
|
|
|
}
|
2019-04-28 23:44:50 +03:00
|
|
|
else if (item.type === 'poi') {
|
2019-04-29 02:54:49 +03:00
|
|
|
iconClass = '';
|
|
|
|
iconElem = '<i class="far fa-dot-circle"></i>';
|
2019-04-28 23:44:50 +03:00
|
|
|
}
|
2019-04-27 02:55:38 +03:00
|
|
|
// shorten label if needed
|
|
|
|
var label = item.label;
|
|
|
|
if (label.length > 35) {
|
2019-04-28 23:44:50 +03:00
|
|
|
label = label.substring(0, 35) + '…';
|
2019-04-27 02:55:38 +03:00
|
|
|
}
|
2019-04-26 16:12:49 +03:00
|
|
|
var listItem = $('<li></li>')
|
|
|
|
.data('item.autocomplete', item)
|
2019-04-29 02:54:49 +03:00
|
|
|
.append('<a class="searchCompleteLink"><button class="searchCompleteIcon ' + iconClass + '">' + iconElem + '</button> ' + label + '</a>')
|
2019-04-26 16:12:49 +03:00
|
|
|
.appendTo(ul);
|
|
|
|
return listItem;
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
submitSearchForm: function() {
|
2019-04-27 02:43:00 +03:00
|
|
|
var that = this;
|
2019-04-26 16:12:49 +03:00
|
|
|
var str = $('#search-term').val();
|
|
|
|
if (str.length < 1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.search(str).then(function(results) {
|
|
|
|
if (results.length === 0) {
|
2019-04-28 23:44:50 +03:00
|
|
|
OC.Notification.showTemporary(t('maps', 'No search result'));
|
2019-04-26 16:12:49 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (results.length === 1) {
|
|
|
|
var result = results[0];
|
2019-04-28 23:44:50 +03:00
|
|
|
mapController.displaySearchResult([result]);
|
2019-04-26 16:12:49 +03:00
|
|
|
}
|
|
|
|
else {
|
2019-04-27 02:43:00 +03:00
|
|
|
var newData = [];
|
|
|
|
newData.push(...that.currentLocalAutocompleteData);
|
|
|
|
for (var i=0; i < results.length; i++) {
|
|
|
|
newData.push({
|
|
|
|
type: 'address',
|
|
|
|
label: results[i].display_name,
|
|
|
|
value: results[i].display_name,
|
|
|
|
result: results[i],
|
|
|
|
lat: results[i].lat,
|
|
|
|
lng: results[i].lon
|
|
|
|
});
|
|
|
|
}
|
|
|
|
$('#search-term').autocomplete('option', {source: newData});
|
|
|
|
$('#search-term').autocomplete('search');
|
2019-04-26 16:12:49 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2019-04-28 23:44:50 +03:00
|
|
|
submitSearchPOI: function(type, typeName) {
|
|
|
|
var that = this;
|
|
|
|
|
|
|
|
var mapBounds = this.map.getBounds();
|
|
|
|
var latMin = mapBounds.getSouth();
|
|
|
|
var latMax = mapBounds.getNorth();
|
|
|
|
var lngMin = mapBounds.getWest();
|
|
|
|
var lngMax = mapBounds.getEast();
|
|
|
|
this.searchPOI(type, latMin, latMax, lngMin, lngMax).then(function(results) {
|
|
|
|
if (results.length === 0) {
|
|
|
|
OC.Notification.showTemporary(t('maps', 'No {POItypeName} found', {POItypeName: typeName}));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mapController.displaySearchResult(results);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2019-04-29 12:58:53 +03:00
|
|
|
getExtraAutocompleteData: function(field) {
|
2019-04-28 23:44:50 +03:00
|
|
|
data = [];
|
|
|
|
if (navigator.geolocation && window.isSecureContext) {
|
|
|
|
data.push({
|
|
|
|
type: 'mylocation',
|
|
|
|
label: t('maps', 'My location'),
|
|
|
|
value: t('maps', 'My location')
|
|
|
|
});
|
|
|
|
}
|
2019-04-29 12:58:53 +03:00
|
|
|
if (field === this.SEARCH_BAR) {
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Restaurant'),
|
|
|
|
value: 'restaurant'
|
|
|
|
});
|
2019-04-30 15:53:28 +03:00
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Fast food'),
|
|
|
|
value: 'fast food'
|
|
|
|
});
|
2019-04-29 12:58:53 +03:00
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Bar'),
|
|
|
|
value: 'bar'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Supermarket'),
|
|
|
|
value: 'supermarket'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Cafe'),
|
|
|
|
value: 'cafe'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Library'),
|
|
|
|
value: 'library'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'School'),
|
|
|
|
value: 'school'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Sports centre'),
|
|
|
|
value: 'sports centre'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Gaz station'),
|
|
|
|
value: 'fuel'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Parking'),
|
|
|
|
value: 'parking'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Bicycle parking'),
|
|
|
|
value: 'bicycle parking'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Car rental'),
|
|
|
|
value: 'car rental'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'ATM'),
|
|
|
|
value: 'atm'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Pharmacy'),
|
|
|
|
value: 'pharmacy'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Cinema'),
|
|
|
|
value: 'cinema'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Public toilets'),
|
|
|
|
value: 'toilets'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Drinking water'),
|
|
|
|
value: 'water point'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Hospital'),
|
|
|
|
value: 'hospital'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Doctors'),
|
|
|
|
value: 'doctors'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Dentist'),
|
|
|
|
value: 'dentist'
|
|
|
|
});
|
|
|
|
data.push({
|
|
|
|
type: 'poi',
|
|
|
|
label: t('maps', 'Hotel'),
|
|
|
|
value: 'hotel'
|
|
|
|
});
|
|
|
|
}
|
2019-04-28 23:44:50 +03:00
|
|
|
return data;
|
|
|
|
},
|
|
|
|
|
2019-04-27 02:43:00 +03:00
|
|
|
isGeocodeable: function(str) {
|
2017-08-23 16:39:28 +03:00
|
|
|
var pattern = /^\s*\d+\.?\d*\,\s*\d+\.?\d*\s*$/;
|
|
|
|
return pattern.test(str);
|
|
|
|
},
|
|
|
|
search: function(str) {
|
2019-04-26 14:50:04 +03:00
|
|
|
var searchTerm = encodeURIComponent(str);
|
|
|
|
var apiUrl = 'https://nominatim.openstreetmap.org/search/' + searchTerm + '?format=json&addressdetails=1&extratags=1&namedetails=1&limit=8';
|
2017-08-23 16:39:28 +03:00
|
|
|
return $.getJSON(apiUrl, {}, function(response) {
|
|
|
|
return response;
|
|
|
|
});
|
|
|
|
},
|
2019-04-28 23:44:50 +03:00
|
|
|
searchPOI: function(type, latMin, latMax, lngMin, lngMax) {
|
2019-04-29 02:15:47 +03:00
|
|
|
var query, i;
|
2019-04-30 15:53:28 +03:00
|
|
|
var amenities = ['restaurant', 'fast food', 'bar', 'parking', 'hospital', 'cafe', 'school', 'bicycle parking', 'cinema', 'supermarket'];
|
2019-04-29 03:16:27 +03:00
|
|
|
var qs = ['atm', 'pharmacy', 'hotel', 'doctors', 'dentist', 'library', 'car rental', 'fuel', 'toilets', 'water point', 'sports centre'];
|
2019-04-29 02:15:47 +03:00
|
|
|
if (amenities.indexOf(type) !== -1) {
|
|
|
|
query = 'amenity='+encodeURIComponent(type);
|
2019-04-28 23:44:50 +03:00
|
|
|
}
|
2019-04-29 02:15:47 +03:00
|
|
|
else if (qs.indexOf(type) !== -1) {
|
|
|
|
query = 'q='+encodeURIComponent(type);
|
2019-04-28 23:44:50 +03:00
|
|
|
}
|
|
|
|
var apiUrl = 'https://nominatim.openstreetmap.org/search' +
|
2019-04-29 02:15:47 +03:00
|
|
|
'?format=json&addressdetails=1&extratags=1&namedetails=1&limit=100&' +
|
2019-04-28 23:44:50 +03:00
|
|
|
'viewbox=' + parseFloat(lngMin) + ',' + parseFloat(latMin) + ',' + parseFloat(lngMax) + ',' + parseFloat(latMax) + '&' +
|
|
|
|
'bounded=1&' + query;
|
|
|
|
return $.getJSON(apiUrl, {}, function(response) {
|
|
|
|
return response;
|
|
|
|
});
|
|
|
|
},
|
2017-08-23 16:39:28 +03:00
|
|
|
geocode: function(latlng) {
|
2019-04-27 02:43:00 +03:00
|
|
|
if (!this.isGeocodeable(latlng)) {
|
2019-04-26 14:50:04 +03:00
|
|
|
return;
|
|
|
|
}
|
2017-08-23 16:39:28 +03:00
|
|
|
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;
|
|
|
|
});
|
|
|
|
},
|
2017-08-23 18:55:58 +03:00
|
|
|
parseOsmResult: function(result) {
|
|
|
|
var add = result.address;
|
2017-08-23 20:35:07 +03:00
|
|
|
var road, postcode, city, state, name;
|
2019-04-26 14:50:04 +03:00
|
|
|
if (add.road) {
|
2017-08-23 20:35:07 +03:00
|
|
|
road = add.road;
|
2019-04-26 14:50:04 +03:00
|
|
|
if (add.house_number) {
|
|
|
|
road += ' ' + add.house_number;
|
|
|
|
}
|
2017-08-23 16:39:28 +03:00
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
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) {
|
2017-08-23 20:35:07 +03:00
|
|
|
state = add.state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var details = result.namedetails;
|
2019-04-26 14:50:04 +03:00
|
|
|
if (details.name) {
|
|
|
|
name = details.name;
|
|
|
|
}
|
2017-08-23 20:35:07 +03:00
|
|
|
|
|
|
|
var unformattedHeader;
|
2019-04-26 14:50:04 +03:00
|
|
|
if (name) {
|
|
|
|
unformattedHeader = name;
|
|
|
|
}
|
|
|
|
else if (road) {
|
|
|
|
unformattedHeader = road;
|
|
|
|
}
|
|
|
|
else if (city) {
|
|
|
|
unformattedHeader = city;
|
|
|
|
}
|
2017-08-23 20:35:07 +03:00
|
|
|
|
|
|
|
var unformattedDesc = '';
|
|
|
|
var needSeparator = false;
|
2017-08-24 13:30:14 +03:00
|
|
|
// add road to desc if it is not heading and exists (isn't heading, if 'name' is set)
|
2019-04-26 14:50:04 +03:00
|
|
|
if (name && road) {
|
2017-08-23 20:35:07 +03:00
|
|
|
unformattedDesc = road;
|
|
|
|
needSeparator = true;
|
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
if (postcode) {
|
|
|
|
if (needSeparator) {
|
2017-08-23 20:35:07 +03:00
|
|
|
unformattedDesc += ', ';
|
|
|
|
needSeparator = false;
|
|
|
|
}
|
|
|
|
unformattedDesc += postcode;
|
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
if (city) {
|
|
|
|
if (needSeparator) {
|
2017-08-23 20:35:07 +03:00
|
|
|
unformattedDesc += ', ';
|
|
|
|
needSeparator = false;
|
2019-04-26 14:50:04 +03:00
|
|
|
}
|
|
|
|
else if (unformattedDesc.length > 0) {
|
2017-08-23 20:35:07 +03:00
|
|
|
unformattedDesc += ' ';
|
2017-08-23 16:39:28 +03:00
|
|
|
}
|
2017-08-23 20:35:07 +03:00
|
|
|
unformattedDesc += city;
|
2017-08-23 16:39:28 +03:00
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
if (state && add && add.country_code == 'us') { // assume that state is only important for us addresses
|
|
|
|
if (unformattedDesc.length > 0) {
|
2017-08-24 13:30:14 +03:00
|
|
|
unformattedDesc += ' ';
|
2017-08-23 20:35:07 +03:00
|
|
|
}
|
|
|
|
unformattedDesc += '(' + state + ')';
|
|
|
|
}
|
|
|
|
|
2017-08-23 16:39:28 +03:00
|
|
|
var header = '<h2 class="location-header">' + unformattedHeader + '</h2>';
|
2019-04-26 14:50:04 +03:00
|
|
|
if (result.icon) {
|
|
|
|
header = '<div class="inline-wrapper"><img class="location-icon" src="' + result.icon + '" />' + header + '</div>';
|
|
|
|
}
|
2017-08-23 20:35:07 +03:00
|
|
|
var desc = '<span class="location-city">' + unformattedDesc + '</span>';
|
2019-04-27 04:25:32 +03:00
|
|
|
desc += '<button class="search-add-favorite" lat="'+result.lat+'" lng="'+result.lon+'">' +
|
|
|
|
'<span class="icon-favorite"> </span> ' + t('maps', 'Add to favorites') + '</button>';
|
2017-08-23 20:35:07 +03:00
|
|
|
|
|
|
|
// Add extras to parsed desc
|
2017-08-23 18:55:58 +03:00
|
|
|
var extras = result.extratags;
|
2019-04-26 14:50:04 +03:00
|
|
|
if (extras.opening_hours) {
|
2017-08-24 19:58:36 +03:00
|
|
|
desc += '<div id="opening-hours-header" class="inline-wrapper"><img class="popup-icon" src="'+OC.filePath('maps', 'img', 'recent.svg')+'" />';
|
2017-08-24 17:01:01 +03:00
|
|
|
var oh = new opening_hours(extras.opening_hours, result);
|
|
|
|
var isCurrentlyOpen = oh.getState();
|
|
|
|
var changeDt = oh.getNextChange();
|
|
|
|
var currentDt = new Date();
|
2019-04-30 12:47:41 +03:00
|
|
|
if (changeDt) {
|
|
|
|
var dtDiff = changeDt.getTime() - currentDt.getTime();
|
|
|
|
dtDiff = dtDiff / 60000; // get diff in minutes
|
|
|
|
if (isCurrentlyOpen) {
|
|
|
|
desc += '<span class="poi-open">' + t('maps', 'Open') + ' </span>';
|
|
|
|
if (dtDiff <= 60) {
|
|
|
|
desc += '<span class="poi-closes">, ' + t('maps', 'closes in {nb} minutes', {nb: parseInt(dtDiff)}) + '</span>';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
desc += '<span> ' + t('maps', 'until {date}', {date: changeDt.toLocaleTimeString()}) + '</span>';
|
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
}
|
|
|
|
else {
|
2019-04-30 12:47:41 +03:00
|
|
|
desc += '<span class="poi-closed">' + t('maps', 'Closed') + ' </span>';
|
|
|
|
desc += '<span class="poi-opens">' + t('maps', 'opens at {date}', {date: changeDt.toLocaleTimeString()}) + '</span>';
|
2017-08-24 17:01:01 +03:00
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
}
|
2019-04-27 04:05:51 +03:00
|
|
|
desc += '<img id="opening-hours-table-toggle-collapse" src="' +
|
|
|
|
OC.filePath('maps', 'img', 'triangle-s.svg') +
|
|
|
|
'" /><img id="opening-hours-table-toggle-expand" src="' +
|
|
|
|
OC.filePath('maps', 'img', 'triangle-e.svg') +
|
|
|
|
'" /></div>';
|
2017-08-24 17:01:01 +03:00
|
|
|
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);
|
2017-08-24 19:58:36 +03:00
|
|
|
desc += '<table id="opening-hours-table">';
|
2017-08-24 17:01:01 +03:00
|
|
|
// intervals should be 7, if 8, then first entry is interval after 00:00:00 from last day
|
2019-04-26 14:50:04 +03:00
|
|
|
if (intervals.length == 8) {
|
2017-08-24 17:01:01 +03:00
|
|
|
// 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);
|
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
for (var i=0; i<intervals.length; i++) {
|
2017-08-24 17:01:01 +03:00
|
|
|
var from = intervals[i][0];
|
|
|
|
var to = intervals[i][1];
|
|
|
|
var day = from.toLocaleDateString([], {weekday:'long'});
|
2019-04-26 14:50:04 +03:00
|
|
|
if (i==0) {
|
|
|
|
desc += '<tr class="selected">';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
desc += '<tr>';
|
|
|
|
}
|
2017-08-24 17:01:01 +03:00
|
|
|
desc += '<td class="opening-hours-day">' + day + '</td>';
|
|
|
|
var startTime = from.toLocaleTimeString();
|
|
|
|
var endTime =to.toLocaleTimeString();
|
|
|
|
desc += '<td class="opening-hours-hours">' + startTime + ' - ' + endTime + '</td>';
|
|
|
|
desc += '</tr>';
|
|
|
|
}
|
|
|
|
desc += '</table>';
|
2017-08-23 18:55:58 +03:00
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
if (extras.website) {
|
2017-08-24 18:57:49 +03:00
|
|
|
desc += '<div class="inline-wrapper"><img class="popup-icon" src="'+OC.filePath('maps', 'img', 'link.svg')+'" /><a href="' + extras.website + '" target="_blank">' + helpers.beautifyUrl(extras.website) + '</a></div>';
|
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
if (extras.phone) {
|
2017-08-24 18:57:49 +03:00
|
|
|
desc += '<div class="inline-wrapper"><img class="popup-icon" src="'+OC.filePath('maps', 'img', 'link.svg')+'" /><a href="tel:' + extras.phone + '" target="_blank">' + extras.phone + '</a></div>';
|
|
|
|
}
|
2019-04-26 14:50:04 +03:00
|
|
|
if (extras.email) {
|
2017-08-24 18:57:49 +03:00
|
|
|
desc += '<div class="inline-wrapper"><img class="popup-icon" src="'+OC.filePath('maps', 'img', 'mail.svg')+'" /><a href="mailto:' + extras.email + '" target="_blank">' + extras.email + '</a></div>';
|
2017-08-23 18:59:55 +03:00
|
|
|
}
|
2017-08-23 18:55:58 +03:00
|
|
|
|
2017-08-23 16:39:28 +03:00
|
|
|
return header + desc;
|
|
|
|
}
|
|
|
|
};
|
2019-04-19 16:28:41 +03:00
|
|
|
|
|
|
|
var helpers = {
|
|
|
|
beautifyUrl: function(url) {
|
|
|
|
return url.replace(/^(?:\w+:|)\/\/(?:www\.|)(.*[^\/])\/*$/, '$1');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-08-31 15:21:13 +04:00
|
|
|
})(jQuery, OC);
|