diff --git a/appinfo/routes.php b/appinfo/routes.php
index e9f7b5363..e4948c65d 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -22,6 +22,7 @@
['name' => 'photos#getPhotosFromDb', 'url' => '/photos', 'verb' => 'GET'],
['name' => 'photos#getNonLocalizedPhotosFromDb', 'url' => '/photos/nonlocalized', 'verb' => 'GET'],
['name' => 'photos#placePhotos', 'url' => '/photos', 'verb' => 'POST'],
+ ['name' => 'photos#resetPhotosCoords', 'url' => '/photos', 'verb' => 'DELETE'],
// contacts
['name' => 'contacts#getContacts', 'url' => '/contacts', 'verb' => 'GET'],
diff --git a/css/style.css b/css/style.css
index 6eab6cbfd..09fc793bd 100644
--- a/css/style.css
+++ b/css/style.css
@@ -19,7 +19,7 @@
}
#search-term {
margin-right: 0px !important;
- width: 200px;
+ width: 294px;
}
#timeRangeSlider {
@@ -96,8 +96,11 @@
max-width: 50vw;
}
+#opening-hours-table td {
+ padding: 0 5px 0 5px;
+}
#opening-hours-table {
- margin-left: 25px;
+ width: 100%;
display: none;
}
@@ -234,14 +237,25 @@ tr.selected td {
border-radius: 50%;
}
+.leaflet-marker-contact.contact-marker:after {
+ bottom: 18px;
+ border-width: 12px 8px 0;
+}
+.leaflet-marker-device.device-marker:after {
+ bottom: 18px;
+ border-width: 12px 7px 0;
+}
.leaflet-marker-nonLocalizedPhoto.nonLocalizedPhoto-marker:after,
+.leaflet-marker-photo.photo-marker:after {
+ bottom: 17px;
+ border-width: 11px 8px 0;
+}
.leaflet-marker-contact.contact-marker:after,
.leaflet-marker-device.device-marker:after,
+.leaflet-marker-nonLocalizedPhoto.nonLocalizedPhoto-marker:after,
.leaflet-marker-photo.photo-marker:after {
content:"";
position: relative;
- bottom: 16px;
- border-width: 10px 10px 0;
border-style: solid;
border-color: var(--color-main-background) transparent;
display: block;
@@ -304,9 +318,14 @@ tr.selected td {
padding: 3px;
}
+.leaflet-marker-favorite-tooltip,
+.leaflet-marker-device-tooltip,
+.leaflet-marker-track-tooltip,
.leaflet-marker-contact-tooltip,
.leaflet-marker-photo-tooltip {
opacity: 1 !important;
+ background-color: var(--color-main-background);
+ color: var(--color-main-text);
}
.leaflet-marker-photo-tooltip {
padding: 1px;
@@ -356,10 +375,6 @@ tr.selected td {
line-height: 1.7;
font-size: 20px;
}
-#dummylogo {
- display: none;
- content: url("images/.png");
-}
.easy-button-button img {
width: 100%;
height: 100%;
@@ -494,6 +509,9 @@ tr.selected td {
text-align: center;
}
/* Overriden routing/geocoder style */
+.leaflet-routing-geocoder-result tr {
+ line-height: 35px;
+}
/* hide button if placeholder is shown i.e. if field is empty */
.leaflet-routing-geocoder > input:placeholder-shown + span {
display: none;
@@ -520,7 +538,7 @@ tr.selected td {
.leaflet-routing-remove-waypoint::after {
right: 6px !important;
width: 18px !important;
- height: 10px !important;
+ height: 5px !important;
background-color: var(--color-main-background) !important;
}
.leaflet-routing-remove-waypoint:hover:after {
@@ -528,6 +546,7 @@ tr.selected td {
}
.leaflet-routing-alt table {
white-space: normal;
+ width: 100%;
}
.leaflet-routing-alt td:nth-child(2),
.leaflet-routing-alt td:nth-child(3) {
@@ -584,3 +603,26 @@ tr.selected td {
word-wrap: break-word;
white-space: normal;
}
+.searchCompleteIcon {
+ background-color: inherit;
+ border: 0px;
+ height: 35px;
+ padding-top: 15px;
+}
+.searchCompleteLink {
+ line-height: 35px;
+}
+.search-add-favorite {
+ margin-left: auto;
+ margin-right: auto;
+ display: block;
+}
+.search-result-popup {
+ width: 250px;
+}
+.search-result-popup .leaflet-popup-content {
+ line-height: 25px !important;
+}
+.ui-autocomplete {
+ z-index: 9999;
+}
diff --git a/js/contactsController.js b/js/contactsController.js
index 265a8c5ff..8a1206954 100644
--- a/js/contactsController.js
+++ b/js/contactsController.js
@@ -1,5 +1,6 @@
function ContactsController (optionsController, timeFilterController) {
this.contact_MARKER_VIEW_SIZE = 40;
+ this.contactLayer = null;
this.contactsDataLoaded = false;
this.contactsRequestInProgress = false;
this.optionsController = optionsController;
@@ -217,7 +218,7 @@ ContactsController.prototype = {
var avatar = this.generateAvatar(marker.data.photo) || this.getUserImageIconUrl();
var img = ' ' +
'
' + escapeHTML(basename(markerData.name)) + '
';
- marker.bindTooltip(img, {permanent: false, className: "leaflet-marker-contact-tooltip"});
+ marker.bindTooltip(img, {permanent: false, className: 'leaflet-marker-contact-tooltip', direction: 'top', offset: L.point(0, -25)});
markers.push(marker);
}
return markers;
@@ -488,5 +489,25 @@ ContactsController.prototype = {
this.showLayer();
},
+
+ getAutocompData: function() {
+ var that = this;
+ var mData;
+ var data = [];
+ if (this.map.hasLayer(this.contactLayer)) {
+ this.contactLayer.eachLayer(function (l) {
+ mData = l.data;
+ data.push({
+ type: 'contact',
+ label: mData.name,
+ value: mData.name,
+ lat: mData.lat,
+ lng: mData.lng
+ });
+ });
+ }
+ return data;
+ },
+
};
diff --git a/js/devicesController.js b/js/devicesController.js
index aa0dfcd89..27a0e7611 100644
--- a/js/devicesController.js
+++ b/js/devicesController.js
@@ -56,6 +56,11 @@ DevicesController.prototype = {
var id = $(this).parent().parent().parent().parent().attr('device');
that.toggleDeviceLine(id, true);
});
+ $('body').on('click', '.contextToggleLine', function(e) {
+ var id = $(this).parent().parent().attr('devid');
+ that.toggleDeviceLine(id, true);
+ that.map.closePopup();
+ });
// toggle devices
$('body').on('click', '#navigation-devices > a', function(e) {
that.toggleDevices();
@@ -78,6 +83,11 @@ DevicesController.prototype = {
var id = $(this).parent().parent().parent().parent().attr('device');
that.askChangeDeviceColor(id);
});
+ $('body').on('click', '.contextChangeDeviceColor', function(e) {
+ var id = $(this).parent().parent().attr('devid');
+ that.askChangeDeviceColor(id);
+ that.map.closePopup();
+ });
$('body').on('change', '#devicecolorinput', function(e) {
that.okColor();
});
@@ -334,15 +344,9 @@ DevicesController.prototype = {
else {
imgurl = OC.generateUrl('/svg/core/clients/phone?color='+color.replace('#', ''));
}
- var rgbc = hexToRgb(color);
- var textcolor = 'black';
- if (rgbc.r + rgbc.g + rgbc.b < 3 * 80) {
- textcolor = 'white';
- }
$('').appendTo('body');
// subgroup layer
@@ -781,7 +776,10 @@ FavoritesController.prototype = {
var fav = this._map.favoritesController.favorites[favid];
var cat = fav.category ? fav.category.replace(' ', '-') : this._map.favoritesController.defaultCategory.replace(' ', '-');
var favTooltip = this._map.favoritesController.getFavoriteTooltipContent(fav);
- e.target.bindTooltip(favTooltip, {className: 'tooltipfav-' + cat});
+ e.target.bindTooltip(favTooltip, {
+ className: 'leaflet-marker-favorite-tooltip tooltipfav-' + cat,
+ direction: 'top'
+ });
e.target.openTooltip();
},
@@ -1145,5 +1143,32 @@ FavoritesController.prototype = {
OC.Notification.showTemporary(t('maps', 'Failed to import favorites'));
});
},
+
+ getAutocompData: function() {
+ var that = this;
+ var fav, favid;
+ var data = [];
+ if (that.map.hasLayer(that.cluster)) {
+ for (var cat in this.categoryLayers) {
+ layer = this.categoryLayers[cat];
+ if (this.map.hasLayer(layer)) {
+ layer.eachLayer(function (l) {
+ fav = that.favorites[l.favid];
+ if (fav.name) {
+ data.push({
+ type: 'favorite',
+ label: fav.name,
+ value: fav.name,
+ lat: fav.lat,
+ lng: fav.lng
+ });
+ }
+ });
+ }
+ }
+ }
+ return data;
+ },
+
}
diff --git a/js/nonLocalizedPhotosController.js b/js/nonLocalizedPhotosController.js
index 29f3eb5ce..576aa902e 100644
--- a/js/nonLocalizedPhotosController.js
+++ b/js/nonLocalizedPhotosController.js
@@ -321,9 +321,9 @@ NonLocalizedPhotosController.prototype = {
return OC.generateUrl('core') + '/preview.png?file=' + encodeURI(filename) + '&x=32&y=32';
},
- /* Preview size 375x211 is used in files details view */
+ /* Preview size 341x256 is commonly found in preview folder */
generatePreviewUrl: function (fileId) {
- return OC.generateUrl('core') + '/preview?fileId=' + fileId + '&x=349&y=349&a=1';
+ return OC.generateUrl('core') + '/preview?fileId=' + fileId + '&x=341&y=256&a=1';
},
getImageIconUrl: function() {
diff --git a/js/photosController.js b/js/photosController.js
index 51bd89211..5aea796cf 100644
--- a/js/photosController.js
+++ b/js/photosController.js
@@ -11,6 +11,8 @@ function PhotosController (optionsController, timeFilterController) {
this.photoMarkersLastVisible = -1;
this.timeFilterBegin = 0;
this.timeFilterEnd = Date.now();
+
+ this.movingPhotoPath = null;
}
PhotosController.prototype = {
@@ -51,6 +53,19 @@ PhotosController.prototype = {
$(this).parent().parent().parent().find('>.app-navigation-entry-menu').addClass('open');
}
});
+ $('body').on('click', '.movephoto', function(e) {
+ var ul = $(this).parent().parent();
+ var filePath = ul.attr('filepath');
+ that.movingPhotoPath = filePath;
+ that.enterMovePhotoMode();
+ that.map.closePopup();
+ });
+ $('body').on('click', '.resetphoto', function(e) {
+ var ul = $(this).parent().parent();
+ var filePath = ul.attr('filepath');
+ that.resetPhotoCoords([filePath]);
+ that.map.closePopup();
+ });
// expand navigation
$('body').on('click', '#navigation-photos', function(e) {
if (e.target.tagName === 'LI' && $(e.target).attr('id') === 'navigation-photos') {
@@ -201,12 +216,65 @@ PhotosController.prototype = {
var img = ' ' +
'' + dateStr + '
' +
'' + escapeHTML(basename(markerData.path)) + '
';
- marker.bindTooltip(img, {permanent: false, className: "leaflet-marker-photo-tooltip"});
+ marker.bindTooltip(img, {permanent: false, className: 'leaflet-marker-photo-tooltip', direction: 'right', offset: L.point(0, -30)});
+ marker.on('contextmenu', this.photoMouseRightClick);
markers.push(marker);
}
return markers;
},
+ photoMouseRightClick: function(e) {
+ var filePath = e.target.data.path;
+
+ e.target.unbindPopup();
+ var popupContent = this._map.photosController.getPhotoContextPopupContent(filePath);
+ e.target.bindPopup(popupContent, {
+ closeOnClick: true,
+ className: 'popovermenu open popupMarker',
+ offset: L.point(-5, 9)
+ });
+ e.target.openPopup();
+ },
+
+ getPhotoContextPopupContent: function(filePath) {
+ var moveText = t('maps', 'Move');
+ var resetText = t('maps', 'Remove geo data');
+ var res =
+ '' +
+ ' ' +
+ ' ' +
+ ' ' + moveText + ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' + resetText + ' ' +
+ ' ' +
+ ' ' +
+ ' ';
+ return res;
+ },
+
+ enterMovePhotoMode: function() {
+ $('.leaflet-container').css('cursor', 'crosshair');
+ this.map.on('click', this.movePhotoClickMap);
+ OC.Notification.showTemporary(t('maps', 'Click on the map to move the photo, press ESC to cancel'));
+ },
+
+ leaveMovePhotoMode: function() {
+ $('.leaflet-container').css('cursor', 'grab');
+ this.map.off('click', this.movePhotoClickMap);
+ this.movingPhotoPath = null;
+ },
+
+ movePhotoClickMap: function(e) {
+ var lat = e.latlng.lat;
+ var lng = e.latlng.lng;
+ var filePath = this.photosController.movingPhotoPath;
+ this.photosController.leaveMovePhotoMode();
+ this.photosController.placePhotos([filePath], [lat], [lng]);
+ },
+
updateTimeFilterRange: function() {
this.updateMyFirstLastDates();
this.timeFilterController.updateSliderRangeFromController();
@@ -291,9 +359,9 @@ PhotosController.prototype = {
return OC.generateUrl('core') + '/preview.png?file=' + encodeURI(filename) + '&x=32&y=32';
},
- /* Preview size 375x211 is used in files details view */
+ /* Preview size 341x256 is commonly found in preview folder */
generatePreviewUrl: function (fileId) {
- return OC.generateUrl('core') + '/preview?fileId=' + fileId + '&x=349&y=349&a=1';
+ return OC.generateUrl('core') + '/preview?fileId=' + fileId + '&x=341&y=256&a=1';
},
getImageIconUrl: function() {
@@ -372,5 +440,43 @@ PhotosController.prototype = {
});
},
+ resetPhotoCoords: function(paths) {
+ var that = this;
+ $('#navigation-photos').addClass('icon-loading-small');
+ $('.leaflet-container').css('cursor', 'wait');
+ var req = {
+ paths: paths
+ };
+ var url = OC.generateUrl('/apps/maps/photos');
+ $.ajax({
+ type: 'DELETE',
+ url: url,
+ data: req,
+ async: true
+ }).done(function (response) {
+ OC.Notification.showTemporary(t('maps', '{nb} photos reset', {nb: response}));
+ if (response > 0) {
+ that.photosDataLoaded = false;
+ for (var i=0; i < that.photoMarkers.length; i++) {
+ that.photoLayer.removeLayer(that.photoMarkers[i]);
+ }
+ that.photoMarkers = [];
+ that.photoMarkersOldest = null;
+ that.photoMarkersNewest = null;
+ that.photoMarkersFirstVisible = 0;
+ that.photoMarkersLastVisible = -1;
+ that.timeFilterBegin = 0;
+ that.timeFilterEnd = Date.now();
+
+ that.showLayer();
+ }
+ }).always(function (response) {
+ $('#navigation-photos').removeClass('icon-loading-small');
+ $('.leaflet-container').css('cursor', 'grab');
+ }).fail(function(response) {
+ OC.Notification.showTemporary(t('maps', 'Failed to reset photos coordinates') + ': ' + response.responseText);
+ });
+ },
+
};
diff --git a/js/script.js b/js/script.js
index db2f1b971..fd998f8f7 100644
--- a/js/script.js
+++ b/js/script.js
@@ -13,8 +13,10 @@
contactsController.initLayer(mapController.map);
mapController.map.contactsController = contactsController;
tracksController.initController(mapController.map);
+ tracksController.map.tracksController = tracksController;
devicesController.initController(mapController.map);
mapController.map.devicesController = devicesController;
+ searchController.initController(mapController.map);
// once controllers have been set/initialized, we can restore option values from server
optionsController.restoreOptions();
@@ -27,39 +29,6 @@
$('#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);
- routingController.control.spliceWaypoints(routingController.control.getWaypoints().length - 1, 1, new L.LatLng(result.lat, result.lon));
- }
- else {
- console.log('multiple results');
- var result = results[0];
- mapController.displaySearchResult(result);
- routingController.control.spliceWaypoints(routingController.control.getWaypoints().length - 1, 1, new L.LatLng(result.lat, result.lon));
- }
- });
- }
-
document.onkeydown = function (e) {
e = e || window.event;
if (e.key === 'Escape') {
@@ -69,6 +38,9 @@
if (contactsController.movingBookid !== null) {
contactsController.leaveMoveContactMode();
}
+ if (photosController.movingPhotoPath !== null) {
+ photosController.leaveMovePhotoMode();
+ }
}
};
window.onclick = function(event) {
@@ -264,7 +236,7 @@
});
var name = result.display_name;
var popupContent = searchController.parseOsmResult(result);
- this.searchMarker.bindPopup(popupContent);
+ this.searchMarker.bindPopup(popupContent, {className: 'search-result-popup'});
this.searchMarker.addTo(this.map);
this.searchMarker.openPopup();
this.map.flyTo([result.lat, result.lon], 15, {duration: 1});
@@ -452,7 +424,7 @@
$('.leaflet-control-layers').toggle();
// main layers buttons
- var esriImageUrl = $('#dummylogo').css('content').replace('url("', '').replace('")', '').replace('.png', 'esri.jpg');
+ var esriImageUrl = OC.filePath('maps', 'css/images', 'esri.jpg');
this.esriButton = L.easyButton({
position: 'bottomright',
states: [{
@@ -464,7 +436,7 @@
}
}]
});
- var osmImageUrl = $('#dummylogo').css('content').replace('url("', '').replace('")', '').replace('.png', 'osm.png');
+ var osmImageUrl = OC.filePath('maps', 'css/images', 'osm.png');
this.osmButton = L.easyButton({
position: 'bottomright',
states: [{
@@ -746,24 +718,37 @@
if (!routingController.enabled) {
routingController.toggleRouting();
}
- var control = routingController.control;
- control.spliceWaypoints(0, 1, e.latlng);
+ routingController.setRouteFrom(e.latlng);
},
contextRouteTo: function(e) {
if (!routingController.enabled) {
routingController.toggleRouting();
}
- var control = routingController.control;
- control.spliceWaypoints(control.getWaypoints().length - 1, 1, e.latlng);
+ routingController.setRouteTo(e.latlng);
},
contextRoutePoint: function(e) {
if (!routingController.enabled) {
routingController.toggleRouting();
}
- var control = routingController.control;
- routingController.control.spliceWaypoints(control.getWaypoints().length - 1, 0, e.latlng);
+ 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);
+ },
+
+ setRoutePoint: function(i, latlng) {
+ this.control.spliceWaypoints(i, 1, latlng);
+ },
+
+ addRoutePoint: function(latlng) {
+ this.control.spliceWaypoints(this.control.getWaypoints().length - 1, 0, latlng);
},
};
@@ -953,19 +938,245 @@
timeFilterController.connect();
var searchController = {
- isGeocodeabe: function(str) {
+ map: null,
+ SEARCH_BAR: 1,
+ ROUTING_FROM: 2,
+ ROUTING_TO: 3,
+ ROUTING_POINT: 4,
+ currentLocalAutocompleteData: [],
+ 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();
+ });
+ $('#search-term').on('focus', function(e) {
+ $(this).select();
+ 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);
+ }
+ else {
+ that.setSearchAutocomplete(that.ROUTING_POINT, index);
+ }
+ });
+ $('body').on('keyup', '.leaflet-routing-geocoder input', function(e) {
+ // if we press enter => disable autocomplete to let nominatim results dropdown appear
+ if (e.key === 'Enter') {
+ $(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');
+ }
+ });
+ // 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);
+ });
+ };
+ // 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();
+ });
+ },
+
+ setSearchAutocomplete: function(field, routingPointIndex=null) {
+ 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();
+ }
+ else if (field === this.ROUTING_POINT) {
+ fieldElement = $('.leaflet-routing-geocoder input').eq(routingPointIndex);
+ }
+ var that = this;
+ var data = [];
+ // get favorites
+ var favData = favoritesController.getAutocompData();
+ data.push(...favData);
+ // get contacts
+ var contactData = contactsController.getAutocompData();
+ data.push(...contactData);
+ // get devices
+ var devData = devicesController.getAutocompData();
+ data.push(...devData);
+ if (navigator.geolocation && window.isSecureContext) {
+ data.push({
+ type: 'location',
+ label: t('maps', 'My location'),
+ value: t('maps', 'My location')
+ });
+ }
+ that.currentLocalAutocompleteData = data;
+ fieldElement.autocomplete({
+ 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') {
+ that.map.setView([it.lat, it.lng], 15);
+ }
+ else if (it.type === 'device') {
+ devicesController.zoomOnDevice(it.id);
+ }
+ else if (it.type === 'address') {
+ if (field === that.SEARCH_BAR) {
+ mapController.displaySearchResult(it.result);
+ }
+ }
+ else if (it.type === 'location') {
+ 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;
+ }
+ 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();
+ }
+ else if (field === that.ROUTING_POINT) {
+ routingController.setRoutePoint(routingPointIndex, L.latLng(it.lat, it.lng));
+ $('.leaflet-routing-geocoder input').last().focus();
+ }
+ }
+ }).data('ui-autocomplete')._renderItem = function(ul, item) {
+ var iconClass = 'icon-link';
+ if (item.type === 'favorite') {
+ iconClass = 'icon-favorite';
+ }
+ else if (item.type === 'contact') {
+ iconClass = 'icon-group';
+ }
+ else if (item.type === 'device') {
+ if (item.subtype === 'computer') {
+ iconClass = 'icon-desktop';
+ }
+ else {
+ iconClass = 'icon-phone';
+ }
+ }
+ else if (item.type === 'location') {
+ iconClass = 'icon-address';
+ }
+ // shorten label if needed
+ var label = item.label;
+ if (label.length > 35) {
+ label = label.substring(0, 35) + '...';
+ }
+ var listItem = $(' ')
+ .data('item.autocomplete', item)
+ .append(' ' + label + ' ')
+ .appendTo(ul);
+ return listItem;
+ };
+ },
+
+ submitSearchForm: function() {
+ var that = this;
+ var str = $('#search-term').val();
+ if (str.length < 1) {
+ return;
+ }
+
+ this.search(str).then(function(results) {
+ if (results.length === 0) {
+ return;
+ }
+ else if (results.length === 1) {
+ var result = results[0];
+ mapController.displaySearchResult(result);
+ routingController.setRouteTo(L.latLng(result.lat, result.lon));
+ }
+ else {
+ var result = results[0];
+ 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');
+ }
+ });
+ },
+
+ isGeocodeable: 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';
+ var searchTerm = encodeURIComponent(str);
+ 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;
+ if (!this.isGeocodeable(latlng)) {
+ return;
+ }
var splits = latlng.split(',');
var lat = splits[0].trim();
var lon = splits[1].trim();
@@ -977,64 +1188,87 @@
parseOsmResult: function(result) {
var add = result.address;
var road, postcode, city, state, name;
- if(add.road) {
+ if (add.road) {
road = add.road;
- if(add.house_number) road += ' ' + add.house_number;
+ if (add.house_number) {
+ road += ' ' + add.house_number;
+ }
+ }
+ if (add.postcode) {
+ postcode = add.postcode;
}
- 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) {
+ 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;
+ if (details.name) {
+ name = details.name;
+ }
var unformattedHeader;
- if(name) unformattedHeader = name;
- else if(road) unformattedHeader = road;
- else if(city) unformattedHeader = city;
+ 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) {
+ if (name && road) {
unformattedDesc = road;
needSeparator = true;
}
- if(postcode) {
- if(needSeparator) {
+ if (postcode) {
+ if (needSeparator) {
unformattedDesc += ', ';
needSeparator = false;
}
unformattedDesc += postcode;
}
- if(city) {
- if(needSeparator) {
+ if (city) {
+ if (needSeparator) {
unformattedDesc += ', ';
needSeparator = false;
- } else if(unformattedDesc.length > 0) {
+ }
+ 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) {
+ 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 = '';
- if(result.icon) header = '' + header + '
';
+ if (result.icon) {
+ header = '' + header + '
';
+ }
var desc = '' + unformattedDesc + ' ';
+ desc += '' +
+ ' ' + t('maps', 'Add to favorites') + ' ';
// Add extras to parsed desc
var extras = result.extratags;
- if(extras.opening_hours) {
+ if (extras.opening_hours) {
desc += '';
+ desc += ' ';
var todayStart = currentDt;
todayStart.setHours(0);
todayStart.setMinutes(0);
@@ -1064,17 +1304,21 @@
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) {
+ 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';
- else desc += '';
+ if (i==0) {
+ desc += ' ';
+ }
+ else {
+ desc += ' ';
+ }
desc += '' + day + ' ';
var startTime = from.toLocaleTimeString();
var endTime =to.toLocaleTimeString();
@@ -1083,13 +1327,13 @@
}
desc += '
';
}
- if(extras.website) {
+ if (extras.website) {
desc += '';
}
- if(extras.phone) {
+ if (extras.phone) {
desc += '';
}
- if(extras.email) {
+ if (extras.email) {
desc += '';
}
diff --git a/js/tracksController.js b/js/tracksController.js
index 034d22462..751cae1a5 100644
--- a/js/tracksController.js
+++ b/js/tracksController.js
@@ -56,6 +56,11 @@ TracksController.prototype = {
var id = parseInt($(this).parent().parent().parent().parent().attr('track'));
that.removeTrackDB(id);
});
+ $('body').on('click', '.contextRemoveTrack', function(e) {
+ var id = parseInt($(this).parent().parent().attr('trackid'));
+ that.removeTrackDB(id);
+ that.map.closePopup();
+ });
// remove all tracks
$('body').on('click', '#remove-all-tracks', function(e) {
that.removeAllTracksDB();
@@ -121,6 +126,12 @@ TracksController.prototype = {
var id = $(this).parent().parent().parent().parent().attr('track');
that.askChangeTrackColor(id);
});
+ // context menu event
+ $('body').on('click', '.contextChangeTrackColor', function(e) {
+ var id = parseInt($(this).parent().parent().attr('trackid'));
+ that.askChangeTrackColor(id);
+ that.map.closePopup();
+ });
$('body').on('change', '#trackcolorinput', function(e) {
that.okColor();
});
@@ -128,6 +139,11 @@ TracksController.prototype = {
var id = $(this).attr('track');
that.showTrackElevation(id);
});
+ $('body').on('click', '.contextShowElevation', function(e) {
+ var id = parseInt($(this).parent().parent().attr('trackid'));
+ that.showTrackElevation(id);
+ that.map.closePopup();
+ });
$('body').on('click', '.showTrackElevation', function(e) {
var id = $(this).parent().parent().parent().parent().attr('track');
that.showTrackElevation(id);
@@ -653,7 +669,13 @@ TracksController.prototype = {
icon: this.trackDivIcon[id]
}
);
- mm.bindTooltip(brify(name, 20), {className: coloredTooltipClass});
+ mm.bindTooltip(brify(name, 20), {
+ className: coloredTooltipClass + ' leaflet-marker-track-tooltip',
+ direction: 'top',
+ offset: L.point(0, -15)
+ });
+ mm.trackid = id;
+ mm.on('contextmenu', this.trackMouseRightClick);
var popupText = this.getWaypointPopupText(id, name, lat, lon, cmt, desc, ele, linkText, linkUrl, sym);
mm.bindPopup(popupText);
@@ -903,7 +925,11 @@ TracksController.prototype = {
if (this.tracks[id].file_name !== name) {
tooltipText = tooltipText + ' ' + escapeHTML(name);
}
- l.bindTooltip(tooltipText, {sticky: true, className: coloredTooltipClass});
+ l.bindTooltip(tooltipText, {
+ sticky: true,
+ className: coloredTooltipClass + ' leaflet-marker-track-tooltip',
+ direction: 'top'
+ });
// border layout
var bl;
bl = L.polyline(latlngs,
@@ -924,17 +950,64 @@ TracksController.prototype = {
});
bl.on('mouseout', function() {
});
- bl.bindTooltip(tooltipText, {sticky: true, className: coloredTooltipClass});
+ bl.bindTooltip(tooltipText, {
+ sticky: true,
+ className: coloredTooltipClass + ' leaflet-marker-track-tooltip',
+ direction: 'top'
+ });
l.on('mouseover', function() {
that.trackLayers[id].bringToFront();
});
l.on('mouseout', function() {
});
+ l.trackid = id;
+ l.on('contextmenu', this.trackMouseRightClick);
+ bl.trackid = id;
+ bl.on('contextmenu', this.trackMouseRightClick);
return date;
},
+ trackMouseRightClick: function(e) {
+ var id = e.target.trackid;
+
+ e.target.unbindPopup();
+ var popupContent = this._map.tracksController.getTrackContextPopupContent(id);
+ e.target.bindPopup(popupContent, {
+ closeOnClick: true,
+ className: 'popovermenu open popupMarker',
+ offset: L.point(-4, 5)
+ });
+ e.target.openPopup(e.latlng);
+ e.preventDefault();
+ },
+
+ getTrackContextPopupContent: function(id) {
+ var colorText = t('maps', 'Change track color');
+ var elevationText = t('maps', 'Show track elevation');
+ var removeText = t('maps', 'Remove');
+ var res =
+ '' +
+ ' ' +
+ ' ' +
+ ' ' + colorText + ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' + elevationText + ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' + removeText + ' ' +
+ ' ' +
+ ' ' +
+ ' ';
+ return res;
+ },
+
zoomOnTrack: function(id) {
if (this.mainLayer.hasLayer(this.mapTrackLayers[id])) {
this.map.fitBounds(this.mapTrackLayers[id].getBounds(), {padding: [30, 30]});
@@ -990,15 +1063,9 @@ TracksController.prototype = {
setTrackCss: function(id, color) {
$('style[track='+id+']').remove();
- var rgbc = hexToRgb(color);
- var textcolor = 'black';
- if (rgbc.r + rgbc.g + rgbc.b < 3 * 80) {
- textcolor = 'white';
- }
$('