This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | /** |
||
2 | * ownCloud - maps |
||
3 | * |
||
4 | * This file is licensed under the Affero General Public License version 3 or |
||
5 | * later. See the COPYING file. |
||
6 | * |
||
7 | * @author Sander Brand <[email protected]> |
||
8 | * @copyright Sander Brand 2014 |
||
9 | */ |
||
10 | /** Testing |
||
11 | */ |
||
12 | |||
13 | Array.prototype.clean = function(deleteValue) { |
||
14 | for (var i = 0; i < this.length; i++) { |
||
15 | if (this[i] == deleteValue) { |
||
16 | this.splice(i, 1); |
||
17 | i--; |
||
18 | } |
||
19 | } |
||
20 | return this; |
||
21 | }; |
||
22 | Array.prototype.unique = function() { |
||
23 | var unique = []; |
||
24 | for (var i = 0; i < this.length; i++) { |
||
25 | if (unique.indexOf(this[i]) == -1) { |
||
26 | unique.push(this[i]); |
||
27 | } |
||
28 | } |
||
29 | return unique; |
||
30 | }; |
||
31 | |||
32 | function debounce(func, wait, immediate) { |
||
33 | var timeout; |
||
34 | return function() { |
||
35 | var context = this; |
||
36 | var args = arguments; |
||
37 | var later = function() { |
||
38 | timeout = null; |
||
39 | if(!immediate) func.apply(context, args); |
||
40 | } |
||
0 ignored issues
–
show
|
|||
41 | var callNow = immediate && !timeout; |
||
42 | clearTimeout(timeout); |
||
43 | timeout = setTimeout(later, wait); |
||
44 | if(callNow) func.apply(context, args); |
||
45 | } |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
46 | } |
||
47 | |||
48 | (function($, OC) { |
||
49 | |||
50 | var shadowMarkerUrl = OC.filePath('maps', 'img', 'icons/marker-shadow.svg'); |
||
51 | var normalMarkerImg = OC.filePath('maps', 'img', 'icons/marker-icon.svg'); |
||
52 | var normalMarkerIcon = L.icon({ |
||
53 | iconUrl : normalMarkerImg, |
||
54 | shadowUrl : shadowMarkerUrl, |
||
55 | iconSize : [32, 32], |
||
56 | iconAnchor : [16, 32], |
||
57 | popupAnchor : [0, -32], |
||
58 | shadowAnchor : [6, 23] |
||
59 | }); |
||
60 | |||
61 | var favMarkerImg = OC.filePath('maps', 'img', 'icons/favMarker.svg'); |
||
62 | var favMarkerIcon = L.icon({ |
||
63 | iconUrl : favMarkerImg, |
||
64 | shadowUrl : shadowMarkerUrl, |
||
65 | iconSize : [32, 32], |
||
66 | iconAnchor : [16, 32], |
||
67 | popupAnchor : [0, -32], |
||
68 | shadowAnchor : [6, 23] |
||
69 | }); |
||
70 | |||
71 | function addGeocodeMarker(latlng) { |
||
72 | Maps.droppedPin = new L.marker(latlng, {icon: normalMarkerIcon}); |
||
73 | geocoder.reverse(latlng, 67108864, function(results) { |
||
74 | var result = results[0]; |
||
75 | setTimeout(function() { |
||
76 | var popupHtml = ''; |
||
77 | var properties = result.properties; |
||
78 | var address = properties; |
||
79 | if(!geocodeSearch.apiKeySet()) address = properties.address; //address is stored depending on which geocoder is used |
||
80 | popupHtml = Maps.getPoiPopupHTML(address).innerHTML; |
||
81 | toolKit.addMarker(Maps.droppedPin, popupHtml, true); |
||
82 | }, 50); |
||
83 | |||
84 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
85 | } |
||
86 | |||
87 | $.fn.clickToggle = function(func1, func2) { |
||
88 | var funcs = [func1, func2]; |
||
89 | this.data('toggleclicked', 0); |
||
90 | this.click(function() { |
||
91 | var data = $(this).data(); |
||
92 | var tc = data.toggleclicked; |
||
93 | $.proxy(funcs[tc], this)(); |
||
94 | data.toggleclicked = (tc + 1) % 2; |
||
95 | }); |
||
96 | return this; |
||
97 | }; |
||
98 | |||
99 | // initialize map when page ready |
||
100 | $(document).ready(function() { |
||
101 | marker = null; |
||
102 | circle = null; |
||
103 | firstRun = true; |
||
104 | |||
105 | var attribution = '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'; |
||
106 | |||
107 | var mapQuest = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', { |
||
108 | attribution : attribution, |
||
109 | subdomains : "1234" |
||
110 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
111 | /* var mapbox = L.tileLayer('https://a.tiles.mapbox.com/v3/liedman.h9ekn0f1/{z}/{x}/{y}.png', { |
||
112 | attribution : attribution + ' Tiles <a href="https://www.mapbox.com/about/maps/">MapBox</a>' |
||
113 | }) |
||
114 | var blackAndWhite = L.tileLayer('http://{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png', { |
||
115 | attribution : attribution |
||
116 | }) |
||
117 | |||
118 | var airial = L.tileLayer('http://server.arcgisonline.com/ArcGIS/' + 'rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { |
||
119 | attribution : attribution + ' Tiles © Esri', |
||
120 | subdomains : "1234" |
||
121 | })*/ |
||
122 | |||
123 | /*var clouds = L.tileLayer('http://{s}.tile.openweathermap.org/map/clouds/{z}/{x}/{y}.png', { |
||
124 | attribution : 'Map data © <a href="http://openweathermap.org">OpenWeatherMap</a>', |
||
125 | opacity : 0.5 |
||
126 | }) |
||
127 | var wind = L.tileLayer('http://{s}.tile.openweathermap.org/map/wind/{z}/{x}/{y}.png', { |
||
128 | attribution : 'Map data © <a href="http://openweathermap.org">OpenWeatherMap</a>', |
||
129 | opacity : 0.5 |
||
130 | }) |
||
131 | var temperature = L.tileLayer('http://{s}.tile.openweathermap.org/map/temp/{z}/{x}/{y}.png', { |
||
132 | attribution : 'Map data © <a href="http://openweathermap.org">OpenWeatherMap</a>', |
||
133 | opacity : 0.5 |
||
134 | }) |
||
135 | |||
136 | var seamarks = L.tileLayer('http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', { |
||
137 | attribution : 'Map data © <a href="http://openweathermap.org">OpenSeaMap</a>', |
||
138 | opacity : 1.0 |
||
139 | }) |
||
140 | |||
141 | var none = L.tileLayer('http://{s}.tile.openweathermap.org/map/temp/{z}/{x}/{y}.png', { |
||
142 | attribution : '', |
||
143 | opacity : 0.0 |
||
144 | })*/ |
||
145 | |||
146 | var oldPosition = $.jStorage.get('location', { |
||
147 | lat : 21.303210151521565, |
||
148 | lng : 6.15234375 |
||
149 | }); |
||
150 | var oldZoom = $.jStorage.get('zoom', 3); |
||
151 | |||
152 | map = L.map('map', { |
||
153 | center : new L.LatLng(oldPosition.lat, oldPosition.lng), |
||
154 | zoom : oldZoom, |
||
155 | zoomControl : false, |
||
156 | layers : [mapQuest] |
||
157 | }), |
||
158 | |||
159 | map.options.minZoom = 3; |
||
0 ignored issues
–
show
Did you forget to assign or call a function?
This error message can for example pop up if you forget to assign the result of a function call to a variable or pass it to another function: function someFunction(x) {
(x > 0) ? callFoo() : callBar();
}
// JSHint expects you to assign the result to a variable:
function someFunction(x) {
var rs = (x > 0) ? callFoo() : callBar();
}
// If you do not use the result, you could also use if statements in the
// case above.
function someFunction(x) {
if (x > 0) {
callFoo();
} else {
callBar();
}
}
![]() |
|||
160 | var hash = new L.Hash(map); |
||
161 | /*var baseMaps = { |
||
162 | "MapBox" : mapbox, |
||
163 | "Mapnik" : mapnik, |
||
164 | "Black and White" : blackAndWhite, |
||
165 | "Airial" : airial |
||
166 | };*/ |
||
167 | |||
168 | //map.addControl(new L.Control.Compass()); |
||
169 | /*map.addControl(new L.Control.Zoom({ |
||
170 | position: 'bottomright' |
||
171 | }));*/ |
||
172 | map.addControl(new L.Control.Gps({ |
||
173 | minZoom : 14, |
||
174 | autoActive: 1, |
||
175 | style : { |
||
176 | radius : 16, //marker circle style |
||
177 | weight : 3, |
||
178 | color : '#0A00FF', |
||
179 | fill : true |
||
180 | }, |
||
181 | position : 'topleft', |
||
182 | })); |
||
183 | $('.leaflet-control-layers-overlays').removeProp('multiple'); |
||
184 | map.on('popupopen', function(e) { |
||
185 | currentMarker = e.popup._source; |
||
186 | }); |
||
187 | routing = L.Routing.control({ |
||
188 | waypoints : [], |
||
189 | plan : L.Routing.plan(this.waypoints, { |
||
190 | createMarker: function(i, wp) { |
||
191 | return L.marker(wp.latLng, { |
||
192 | draggable: true, |
||
193 | icon: normalMarkerIcon |
||
194 | }); |
||
195 | }, |
||
196 | routeWhileDragging: true |
||
197 | }), |
||
198 | //geocoder : geocoder, |
||
199 | routeWhileDragging: true, |
||
200 | fitSelectedRoutes: true, |
||
201 | show: false |
||
202 | }).addTo(map); |
||
203 | |||
204 | routing.getPlan().on('waypointschanged', function(e) { |
||
205 | geocodeSearch.waypointsChanged(e); |
||
206 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
207 | |||
208 | apiKey = ''; |
||
209 | |||
210 | geocodeSearch.addGeocoder(); |
||
211 | |||
212 | // properly style as input field |
||
213 | //$('#searchContainer').find('input').attr('type', 'text'); |
||
214 | |||
215 | map.on('zoomend', function(e) { |
||
216 | var zoom = map.getZoom(); |
||
217 | if(!$.jStorage.get('pois') || zoom < 9) return; //only show POIs on reasonable levels |
||
218 | Maps.displayPoiIcons(zoom); |
||
219 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
220 | |||
221 | $.post(OC.generateUrl('/apps/maps/api/1.0/apikey/getKey'), null, function(data){ |
||
222 | if(data.id != null && data.apiKey != null) { |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
223 | apiKey = data.apiKey; |
||
224 | document.getElementById('apiKey').value = apiKey; |
||
225 | geocoder = L.Control.Geocoder.mapzen(apiKey); |
||
226 | } else { |
||
227 | geocoder = L.Control.Geocoder.nominatim(); |
||
228 | } |
||
229 | }); |
||
230 | |||
231 | map.on('mousedown', function(e) { |
||
232 | Maps.mouseDowntime = new Date().getTime(); |
||
233 | }); |
||
234 | |||
235 | map.on('mouseup', function(e) { |
||
236 | if (e.originalEvent.target.className !== 'leaflet-tile leaflet-tile-loaded' && e.originalEvent.target.nodeName != 'svg') |
||
237 | return; |
||
238 | |||
239 | var curTime = new Date().getTime(); |
||
240 | if (Maps.droppedPin) { |
||
241 | map.removeLayer(Maps.droppedPin); |
||
242 | Maps.droppedPin = false; |
||
243 | } |
||
244 | if (/*(curTime - Maps.mouseDowntime) > 200 && */Maps.dragging === false) {//200 = 2 seconds |
||
245 | addGeocodeMarker(e.latlng); |
||
246 | } |
||
247 | }); |
||
248 | |||
249 | map.on("dragstart", function() { |
||
250 | Maps.dragging = true; |
||
251 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
252 | map.on("dragend zoomend", function(e) { |
||
253 | Maps.saveCurrentLocation(e); |
||
254 | Maps.dragging = false; |
||
255 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
256 | |||
257 | $(document).on('click', '.toggle-children', function(e) { |
||
258 | var subCat = $(this).parent().find('ul'); |
||
259 | if (subCat.is(":visible")) { |
||
260 | subCat.slideUp(); |
||
261 | } else { |
||
262 | subCat.removeClass('hidden'); |
||
263 | subCat.slideDown(); |
||
264 | } |
||
265 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
266 | |||
267 | function convertLatLon(latD, lonD, latDir, lonDir){ |
||
268 | var lon = lonD[0] + lonD[1]/60 + lonD[2]/(60*60); |
||
269 | var lat = latD[0] + latD[1]/60 + latD[2]/(60*60); |
||
270 | if (latDir == "S") { |
||
271 | lat = lat * -1; |
||
272 | } |
||
273 | if(lonDir == "W"){ |
||
274 | lon = lon * -1; |
||
275 | } |
||
276 | return { |
||
277 | lat: lat, |
||
278 | lon: lon |
||
279 | }; |
||
280 | } |
||
281 | $('.photoLayer').clickToggle(function() { |
||
282 | OC.dialogs.filepicker("Select your photo", function addJpegFile(path){ |
||
283 | for(i=0; i<path.length; i++){ |
||
284 | var p = path[i]; |
||
285 | if(p.indexOf('/') === 0) p = p.substr(1); |
||
286 | var separator = p.lastIndexOf('/'); |
||
287 | var dir = p.substr(0, separator); |
||
288 | var file = p.substr(separator + 1); |
||
289 | var picUrl = OC.generateUrl('apps/files/ajax/download.php?dir={dir}&files={file}', { |
||
290 | dir: dir, |
||
291 | file: file |
||
292 | }); |
||
293 | new ImageInfo( |
||
294 | picUrl, |
||
295 | (function (element){ |
||
0 ignored issues
–
show
It is generally not recommended to make functions within a loop.
While making functions in a loop will not lead to any runtime error, the code might not behave as you expect as the variables in the scope are not imported by value, but by reference. Let’s take a look at an example: var funcs = [];
for (var i=0; i<10; i++) {
funcs.push(function() {
alert(i);
});
}
funcs[0](); // alert(10);
funcs[1](); // alert(10);
/// ...
funcs[9](); // alert(10);
If you would instead like to bind the function inside the loop to the value of the variable during that specific iteration, you can create the function from another function: var createFunc = function(i) {
return function() {
alert(i);
};
};
var funcs = [];
for (var i=0; i<10; i++) {
funcs.push(createFunc(i));
}
funcs[0](); // alert(0)
funcs[1](); // alert(1)
// ...
funcs[9](); // alert(9)
![]() |
|||
296 | return function (imageinfo){ |
||
297 | var exif = imageinfo.getAllFields().exif; |
||
298 | var latD = exif.GPSLatitude; |
||
299 | var lonD = exif.GPSLongitude; |
||
300 | var latDir = exif.GPSLatitudeRef; |
||
301 | var lonDir = exif.GPSLongitudeRef; |
||
302 | var latlon = convertLatLon(latD, lonD, latDir, lonDir); |
||
303 | var photoIcon = L.icon({ |
||
304 | iconUrl: picUrl, |
||
305 | iconSize : [42, 49], |
||
306 | iconAnchor : [21, 49], |
||
307 | popupAnchor : [0, -49], |
||
308 | className : 'photo-marker' |
||
309 | }); |
||
310 | |||
311 | var markerHTML = '<h2>' + file + "</h2>"; |
||
312 | /*markerHTML += '<br />Latitude: ' + latlon.lat + " " + latDir; |
||
313 | markerHTML += '<br />Longitude: ' + latlon.lon + " " + lonDir; |
||
314 | markerHTML += '<br />Altitude: ' + exif.GPSAltitude + "m";*/ |
||
315 | var marker = L.marker([latlon.lat, latlon.lon], { |
||
316 | icon : photoIcon |
||
317 | }); |
||
318 | toolKit.addMarker(marker, markerHTML); |
||
319 | }; |
||
320 | })(this) |
||
321 | ).readFileData(); |
||
322 | } |
||
323 | }, true, ["image/jpeg", "image/png", "image/gif"], true); |
||
324 | }, function() { |
||
325 | //TODO |
||
326 | }); |
||
327 | |||
328 | /* Favorites layer: Show by default, remember visibility */ |
||
329 | $('.favoriteLayer').click(function() { |
||
330 | if($.jStorage.get('favorites')) { |
||
331 | favorites.hide(); |
||
332 | $.jStorage.set('favorites', false); |
||
333 | $('#favoriteMenu').removeClass('active').addClass('icon-star').removeClass('icon-starred'); |
||
334 | } else { |
||
335 | favorites.show(); |
||
336 | $.jStorage.set('favorites', true); |
||
337 | $('#favoriteMenu').addClass('active').addClass('icon-starred').removeClass('icon-star'); |
||
338 | } |
||
339 | }); |
||
340 | if($.jStorage.get('favorites') === null) { |
||
341 | favorites.show(); |
||
342 | $.jStorage.set('favorites', true); |
||
343 | $('#favoriteMenu').addClass('active').addClass('icon-starred').removeClass('icon-star'); |
||
344 | } |
||
345 | if($.jStorage.get('favorites')) { |
||
346 | favorites.show(); |
||
347 | $('#favoriteMenu').addClass('active').addClass('icon-starred').removeClass('icon-star'); |
||
348 | } else { |
||
349 | favorites.hide(); |
||
350 | } |
||
351 | |||
352 | /* POI layer: Show by default, remember visibility */ |
||
353 | $('.poiLayer').click(function() { |
||
354 | if($.jStorage.get('pois')) { |
||
355 | Maps.hidePoiIcons(); |
||
356 | $.jStorage.set('pois', false); |
||
357 | //$('#poiMenu').removeClass('active').addClass('icon-star').removeClass('icon-starred'); |
||
358 | } else { |
||
359 | Maps.displayPoiIcons(map.getZoom()); |
||
360 | $.jStorage.set('pois', true); |
||
361 | //$('#poiMenu').addClass('active').addClass('icon-starred').removeClass('icon-star'); |
||
362 | } |
||
363 | }); |
||
364 | if($.jStorage.get('pois') === null) { |
||
365 | Maps.displayPoiIcons(map.getZoom()); |
||
366 | $.jStorage.set('pois', true); |
||
367 | //$('#poiMenu').addClass('active').addClass('icon-starred').removeClass('icon-star'); |
||
368 | } |
||
369 | if($.jStorage.get('pois')) { |
||
370 | Maps.displayPoiIcons(map.getZoom()); |
||
371 | //$('#poiMenu').addClass('active').addClass('icon-starred').removeClass('icon-star'); |
||
372 | } else { |
||
373 | Maps.hidePoiIcons(); |
||
374 | } |
||
375 | |||
376 | |||
377 | $('.contactLayer').clickToggle(function() { |
||
378 | Maps.loadAdressBooks() |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
379 | }, function() { |
||
380 | favorites.hide() |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
381 | }); |
||
382 | $(document).on('click', '.subLayer', function() { |
||
383 | var layerGroup = $(this).attr('data-layerGroup'); |
||
384 | var layerValue = $(this).attr('data-layerValue'); |
||
385 | var isVisible = $(this).find('i').length; |
||
386 | |||
387 | if (isVisible == 1) { |
||
388 | $('.' + layerValue).css({ |
||
389 | 'visibility' : 'hidden' |
||
390 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
391 | $(this).find('i').remove(); |
||
392 | Maps.updateLayers(false, false); |
||
393 | } else { |
||
394 | $('.' + layerValue).css({ |
||
395 | 'visibility' : 'visible' |
||
396 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
397 | $(this).append('<i class="icon-toggle fright micon activeLayer"></i>'); |
||
398 | //if($('.'+layerValue).length==0){ |
||
399 | Maps.updateLayers(layerGroup, layerValue); |
||
400 | /*} else{ |
||
401 | Maps.updateLayers(false,false); |
||
402 | }*/ |
||
403 | |||
404 | } |
||
405 | }); |
||
406 | |||
407 | $(document).on('click', '.device', function() { |
||
408 | var isVisible = $(this).find('i').length; |
||
409 | var dId = $(this).attr('data-deviceId') |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
410 | if (isVisible == 1) { |
||
411 | $(this).find('i').remove(); |
||
412 | Maps.clearDevicePositions(); |
||
413 | Maps.clearDevicePosistionHistory(dId); |
||
414 | var index = Maps.activeDevices.indexOf(dId); |
||
415 | Maps.activeDevices.splice(index, 1); |
||
416 | Maps.loadDevicesLastPosition(); |
||
417 | } else { |
||
418 | Maps.activeDevices.push(dId); |
||
419 | Maps.loadDevicesLastPosition(); |
||
420 | $(this).append('<i class="icon-toggle fright micon"></i>'); |
||
421 | } |
||
422 | }); |
||
423 | |||
424 | $(document).on('click', '.keepDeviceCentered', function(e) { |
||
425 | var isVisible = $(this).parent().find('i').length; |
||
426 | var dId = $(this).parent().attr('data-deviceId') |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
427 | e.stopPropagation() |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
428 | if ($(this).hasClass('tracOn')) { |
||
429 | $(this).removeClass('tracOn'); |
||
430 | Maps.traceDevice = null; |
||
431 | } else { |
||
432 | $('.keepDeviceCentered').removeClass('tracOn'); |
||
433 | $(this).addClass('tracOn'); |
||
434 | if (!isVisible) { |
||
435 | Maps.activeDevices.push(dId); |
||
436 | Maps.traceDevice = dId; |
||
437 | Maps.loadDevicesLastPosition(); |
||
438 | $(this).parent().append('<i class="icon-toggle fright micon"></i>'); |
||
439 | } else { |
||
440 | Maps.traceDevice = dId; |
||
441 | Maps.loadDevicesLastPosition(); |
||
442 | } |
||
443 | } |
||
444 | |||
445 | }); |
||
446 | |||
447 | /** |
||
448 | * Setup datepickers |
||
449 | */ |
||
450 | $('.datetime').datetimepicker({ |
||
451 | dateFormat : 'dd-mm-yy', |
||
452 | minDate : -900 |
||
453 | }); |
||
454 | |||
455 | $(document).on('click', '#setApiKey', function(e) { |
||
456 | var value = document.getElementById('apiKey').value; |
||
457 | if(value.length == 0) return; |
||
0 ignored issues
–
show
It is recommended to use
=== to compare with 0 .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
458 | var formData = { |
||
459 | key : value |
||
460 | }; |
||
461 | $.post(OC.generateUrl('/apps/maps/api/1.0/apikey/addKey'), formData, function(data){ |
||
462 | }); |
||
463 | }); |
||
464 | |||
465 | $(document).on('click', '.deviceHistory', function(e) { |
||
466 | var isVisible = $(this).parent().find('i').length; |
||
467 | var dId = $(this).parent().attr('data-deviceId'); |
||
468 | var _this = this; |
||
469 | e.stopPropagation(); |
||
470 | if (!isVisible) { |
||
471 | $(".datetime").datepicker("disable"); |
||
472 | $('#showHistoryPopup').dialog({ |
||
473 | open : function() { |
||
474 | $(".datetime").datepicker("enable"); |
||
475 | var currentDate = new Date(); |
||
476 | var month = ((currentDate.getMonth() * 1 + 1) < 10) ? '0' + (currentDate.getMonth() * 1 + 1) : (currentDate.getMonth() * 1 + 1); |
||
477 | $('#deviceHistory [name="startDate"]').val(currentDate.getDate() + '-' + month + '-' + currentDate.getFullYear() + ' 00:00'); |
||
478 | }, |
||
479 | buttons : { |
||
480 | "Cancel" : function() { |
||
481 | $(this).dialog('destroy'); |
||
482 | }, |
||
483 | "Ok" : function() { |
||
484 | var startDate = $('#deviceHistory [name="startDate"]').val(); |
||
485 | var endDate = $('#deviceHistory [name="endDate"]').val(); |
||
486 | var keepCenter = $('#deviceHistory [name="keepCenter"]').is(':checked'); |
||
487 | Maps.loadDevicePosistionHistory(dId, keepCenter, startDate, endDate); |
||
488 | $(_this).parent().append('<i class="icon-toggle fright micon"></i>'); |
||
489 | $(this).dialog('destroy'); |
||
490 | } |
||
491 | } |
||
492 | }); |
||
493 | } else { |
||
494 | Maps.clearDevicePosistionHistory(dId); |
||
495 | $(this).parent().find('i').remove(); |
||
496 | } |
||
497 | |||
498 | }); |
||
499 | |||
500 | /** |
||
501 | * Custom search function |
||
502 | */ |
||
503 | /* searchItems = []*/ |
||
504 | searchTimeout = 0; |
||
505 | |||
506 | /** |
||
507 | * setDestination on click |
||
508 | */ |
||
509 | map.locate({ |
||
510 | setView : false, |
||
511 | watch : false |
||
512 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
513 | map.on('locationfound', function doRouteCalc(e) { |
||
514 | currentlocation = [e.latitude, e.longitude]; |
||
515 | |||
516 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
517 | $(document).on('click', '.setDestination', function() { |
||
518 | |||
519 | var latlng = $(this).attr('data-latlng'); |
||
520 | var end = latlng.split(','); |
||
521 | end[0] = end[0] * 1; |
||
522 | end[1] = end[1] * 1; |
||
523 | //map.removeLayer(routing); |
||
524 | |||
525 | routing.setWaypoints([ |
||
526 | L.Routing.waypoint(L.latLng(currentlocation[0], currentlocation[1]), ""), |
||
527 | L.Routing.waypoint(L.latLng(end[0], end[1]), "") |
||
528 | ]); |
||
529 | |||
530 | map.closePopup(); |
||
531 | }); |
||
532 | /** |
||
533 | * Clear route |
||
534 | */ |
||
535 | $(document).on('click', '.clearroute', function() { |
||
536 | routing.setWaypoints([]); |
||
537 | }); |
||
538 | |||
539 | }); |
||
540 | // End document ready |
||
541 | function onLocationFound(e) { |
||
542 | var radius = e.accuracy / 2; |
||
543 | if (marker != null) { |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
544 | map.removeLayer(marker); |
||
545 | } |
||
546 | if (circle != null) { |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
547 | map.removeLayer(circle); |
||
548 | } |
||
549 | |||
550 | marker = L.marker(e.latlng, {icon: normalMarkerIcon}).addTo(map); |
||
551 | //.bindPopup("You are within " + radius + " meters from this point").openPopup(); |
||
552 | if (radius < 5000) { |
||
553 | circle = L.circle(e.latlng, radius).addTo(map); |
||
554 | } |
||
555 | |||
556 | if (firstRun) { |
||
557 | map.panTo(e.latlng); |
||
558 | var maxZoom = 16; |
||
559 | map.setZoom(14); |
||
560 | firstRun = false; |
||
561 | } |
||
562 | } |
||
563 | |||
564 | geocodeSearch = { |
||
565 | results : [], |
||
566 | waypoints : [], |
||
567 | markers : [], |
||
568 | apiKeySet : function() { |
||
569 | return apiKey != null && apiKey.length > 0; |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
570 | }, |
||
571 | addGeocoder : function() { |
||
572 | var geocoderInputs = document.getElementsByClassName('geocoder'); |
||
573 | var elems = 0; |
||
574 | if(geocoderInputs != null) elems = geocoderInputs.length; |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
575 | if(elems == 7) return;//only allow 5 via points |
||
576 | var timeoutId; |
||
577 | var searchCont = document.getElementById('search'); |
||
578 | var geocoderDiv = document.createElement('div'); |
||
579 | geocoderDiv.className = 'geocoder-container'; |
||
580 | var input = document.createElement('input'); |
||
581 | input.type = 'text'; |
||
582 | input.className = 'geocoder not-geocoded'; |
||
583 | var debounceTimeout = 500; |
||
584 | if(!geocodeSearch.apiKeySet()) debounceTimeout = 1000; |
||
585 | input.addEventListener('input', debounce(function() { |
||
586 | geocodeSearch.performGeocode(input) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
587 | }, debounceTimeout)); |
||
588 | input.addEventListener('keyup', function(e) { |
||
589 | var key = e.which || e.keyCode; |
||
590 | if(key !== 13) return; //not enter/return key |
||
591 | e.preventDefault(); |
||
592 | var result = null; |
||
593 | if(geocodeSearch.results.length > 0) { |
||
594 | result = geocodeSearch.results[0]; |
||
595 | } else { |
||
596 | var results = geocodeSearch.performInlineGeocode(input); |
||
597 | if(results != null && results.length > 0) result = results[0]; |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
598 | } |
||
599 | if(result == null) return; |
||
0 ignored issues
–
show
It is recommended to use
=== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
600 | input.className = input.className.replace('not-geocoded', 'is-geocoded'); |
||
601 | var marker = L.marker(result.center, {icon: normalMarkerIcon}); |
||
602 | geocodeSearch.markers.push([[input.id], [marker]]); |
||
603 | toolKit.addMarker(marker, result.name); |
||
604 | var points = document.getElementsByClassName('is-geocoded'); |
||
605 | if(points.length < 2 && result.bbox != null) { |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
606 | map.fitBounds(result.bbox); |
||
607 | }; |
||
0 ignored issues
–
show
|
|||
608 | input.value = result.name; |
||
609 | geocodeSearch.clearResults(input); |
||
610 | geocodeSearch.computeRoute(); |
||
611 | }); |
||
612 | input.addEventListener('blur', geocodeSearch.clearResults(input)); |
||
613 | var list = document.createElement('ul'); |
||
614 | list.className = 'geocoder-list'; |
||
615 | list.style.display = 'none'; |
||
616 | |||
617 | var btn = document.createElement('button'); |
||
618 | |||
619 | if(elems == 0) { |
||
0 ignored issues
–
show
It is recommended to use
=== to compare with 0 .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
620 | geocoderDiv.id = 'geocoder-container-start'; |
||
621 | input.id = 'geocoder-start'; |
||
622 | list.id = 'geocoder-results-start'; |
||
623 | input.placeholder = 'Start address'; |
||
624 | |||
625 | btn.className = 'icon-add geocoder-button'; |
||
626 | btn.id = 'geocoder-add'; |
||
627 | btn.addEventListener('click', function() { |
||
628 | geocodeSearch.addGeocoder(); |
||
629 | }); |
||
630 | |||
631 | geocoderDiv.appendChild(input); |
||
632 | geocoderDiv.appendChild(list); |
||
633 | geocoderDiv.appendChild(btn); |
||
634 | searchCont.appendChild(geocoderDiv); |
||
635 | } else if(elems == 1) { |
||
636 | geocoderDiv.id = 'geocoder-container-end'; |
||
637 | input.id = 'geocoder-end'; |
||
638 | list.id = 'geocoder-results-end'; |
||
639 | input.placeholder = 'End address'; |
||
640 | |||
641 | btn.className = 'icon-close geocoder-button'; |
||
642 | btn.id = 'geocoder-remove-end'; |
||
643 | btn.addEventListener('click', function() { |
||
644 | geocodeSearch.removeGeocoder(geocoderDiv); |
||
645 | }); |
||
646 | |||
647 | geocoderDiv.appendChild(input); |
||
648 | geocoderDiv.appendChild(list); |
||
649 | geocoderDiv.appendChild(btn); |
||
650 | searchCont.appendChild(geocoderDiv); |
||
651 | } else { |
||
652 | var id = elems - 2; |
||
653 | geocoderDiv.id = 'geocoder-container-' + id; |
||
654 | input.id = 'geocoder-' + id; |
||
655 | list.id = 'geocoder-results-' + id; |
||
656 | input.placeholder = 'Via address '/* + (id+1)*/; |
||
657 | |||
658 | btn.className = 'icon-close geocoder-button'; |
||
659 | btn.id = 'geocoder-remove-' + id; |
||
660 | btn.addEventListener('click', function() { |
||
661 | geocodeSearch.removeGeocoder(geocoderDiv); |
||
662 | }); |
||
663 | |||
664 | var children = searchCont.childNodes; |
||
665 | var childLength = children.length; |
||
666 | geocoderDiv.appendChild(input); |
||
667 | geocoderDiv.appendChild(list); |
||
668 | geocoderDiv.appendChild(btn); |
||
669 | searchCont.insertBefore(geocoderDiv, children[childLength-1]); |
||
670 | } |
||
671 | }, |
||
672 | removeGeocoder : function(div) { |
||
673 | var geocoderInputs = document.getElementsByClassName('geocoder'); |
||
674 | var elems = 0; |
||
675 | if(geocoderInputs != null) elems = geocoderInputs.length; |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
676 | var isGeocoded = div.getElementsByClassName('is-geocoded'); |
||
677 | if(isGeocoded.length > 0) { |
||
678 | geocodeSearch.removeMarker(isGeocoded[0].id) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
679 | } |
||
680 | //alert(div.getElementById('geocoder-end').toSource()) |
||
681 | if(div.id == 'geocoder-container-end') { |
||
682 | var children = div.parentElement.childNodes; |
||
683 | var childLength = children.length; |
||
684 | var newEndDiv = children[childLength-2]; |
||
685 | var newInput = newEndDiv.getElementsByClassName('geocoder')[0]; |
||
686 | var newList = newEndDiv.getElementsByClassName('geocoder-list')[0]; |
||
687 | var newButton = newEndDiv.getElementsByClassName('geocoder-button')[0]; |
||
688 | newEndDiv.id = 'geocoder-container-end'; |
||
689 | newInput.id = 'geocoder-end'; |
||
690 | newList.id = 'geocoder-results-end'; |
||
691 | if(document.getElementsByClassName('geocoder').length - 1 > 1) { |
||
692 | newInput.placeholder = 'End address'; |
||
693 | } |
||
694 | newButton.id = 'geocoder-remove-end'; |
||
695 | } |
||
696 | div.parentElement.removeChild(div); |
||
697 | }, |
||
698 | removeMarker : function(id) { |
||
699 | var remIndex = -1; |
||
700 | for(var i=0; i<geocodeSearch.markers.length; ++i) { |
||
701 | var curr = geocodeSearch.markers[i]; |
||
702 | if(curr[0] == id) { |
||
703 | remIndex = i; |
||
704 | map.removeLayer(curr[1][0]); |
||
705 | break; |
||
706 | } |
||
707 | } |
||
708 | if(remIndex >= 0) { |
||
709 | geocodeSearch.markers.splice(remIndex, 1); |
||
710 | geocodeSearch.computeRoute(); |
||
711 | } |
||
712 | }, |
||
713 | clearResults : function(input) { |
||
714 | geocodeSearch.results = []; |
||
715 | var idParts = input.id.split('-'); |
||
716 | var id = idParts[0] + '-results-' + idParts[1]; |
||
717 | var list = document.getElementById(id); |
||
718 | if(list == null) return; |
||
0 ignored issues
–
show
It is recommended to use
=== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
719 | list.innerHTML = ''; |
||
720 | list.style.display = 'none'; |
||
721 | }, |
||
722 | performInlineGeocode : function(input) { |
||
723 | var query = input.value; |
||
724 | var results = []; |
||
725 | geocodeSearch.clearResults(input); |
||
726 | input.className = input.className.replace('is-geocoded', 'not-geocoded'); |
||
727 | geocodeSearch.removeMarker(input.id); |
||
728 | if(query.length < 3) return; |
||
729 | geocoder.geocode(query, function(data) { |
||
730 | $.each(data, function(index, cont) { |
||
731 | results.push(cont); |
||
732 | }); |
||
733 | var formData = { |
||
734 | name : query |
||
735 | }; |
||
736 | $.post(OC.generateUrl('/apps/maps/api/1.0/favorite/getFavoritesByName'), formData, function(data){ |
||
737 | $.each(data, function(index, content) { |
||
738 | content.center = L.latLng(content.lat, content.lng); |
||
739 | content.bbox = null; |
||
740 | content.type = 'favorite'; |
||
741 | $.each(data, function(index, cont) { |
||
742 | results.push(cont); |
||
743 | }); |
||
744 | }); |
||
745 | }); |
||
746 | }, null); |
||
747 | return results; |
||
748 | }, |
||
749 | performGeocode : function(input) { |
||
750 | var query = input.value; |
||
751 | geocodeSearch.clearResults(input); |
||
752 | input.className = input.className.replace('is-geocoded', 'not-geocoded'); |
||
753 | geocodeSearch.removeMarker(input.id); |
||
754 | if(query.length < 3) return; |
||
755 | geocoder.geocode(query, function(data) { |
||
756 | geocodeSearch.addResults(data); |
||
757 | var formData = { |
||
758 | name : query |
||
759 | }; |
||
760 | $.post(OC.generateUrl('/apps/maps/api/1.0/favorite/getFavoritesByName'), formData, function(data){ |
||
761 | $.each(data, function(index, content) { |
||
762 | content.center = L.latLng(content.lat, content.lng); |
||
763 | content.bbox = null; |
||
764 | content.type = 'favorite'; |
||
765 | geocodeSearch.addResults(data); |
||
766 | }); |
||
767 | geocodeSearch.displayResults(input); |
||
768 | }); |
||
769 | }, null); |
||
770 | //TODO search for contacts |
||
771 | }, |
||
772 | addResults : function(searchResults) { |
||
773 | $.each(searchResults, function(index, cont) { |
||
774 | geocodeSearch.results.push(cont); |
||
775 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
776 | }, |
||
777 | displayResults : function(input) { |
||
778 | var idParts = input.id.split('-'); |
||
779 | var id = idParts[0] + '-results-' + idParts[1]; |
||
780 | var list = document.getElementById(id); |
||
781 | $.each(geocodeSearch.results, function(index, content) { |
||
782 | var li = document.createElement('li'); |
||
783 | li.appendChild(document.createTextNode(content.name)); |
||
784 | li.setAttribute('id', 'entry-' + index); |
||
785 | var className = 'geocoder-list-item'; |
||
786 | if(content.type == 'favorite') className += ' icon-starred'; |
||
787 | li.setAttribute('class', className); |
||
788 | li.addEventListener('click', function() { |
||
789 | input.className = input.className.replace('not-geocoded', 'is-geocoded'); |
||
790 | var marker = L.marker(content.center, {icon: normalMarkerIcon}); |
||
791 | geocodeSearch.markers.push([[input.id], [marker]]); |
||
792 | toolKit.addMarker(marker, content.name); |
||
793 | var points = document.getElementsByClassName('is-geocoded'); |
||
794 | if(points.length < 2 && content.bbox != null) { |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
795 | map.fitBounds(content.bbox); |
||
796 | }; |
||
0 ignored issues
–
show
|
|||
797 | input.value = content.name; |
||
798 | geocodeSearch.clearResults(input); |
||
799 | geocodeSearch.computeRoute(); |
||
800 | }); |
||
801 | list.appendChild(li); |
||
802 | }, null); |
||
803 | list.style.display = 'block'; |
||
804 | }, |
||
805 | computeRoute : function() { |
||
806 | geocodeSearch.waypoints = []; |
||
807 | var points = document.getElementsByClassName('is-geocoded'); |
||
808 | if(points.length < 2) return; |
||
809 | $.each(points, function(i) { |
||
810 | var id = $(this).attr('id'); |
||
811 | var val = $(this).val(); |
||
812 | for(var i=0; i<geocodeSearch.markers.length; ++i) { |
||
0 ignored issues
–
show
|
|||
813 | var curr = geocodeSearch.markers[i]; |
||
814 | if(curr[0] == id) { |
||
815 | geocodeSearch.waypoints.push(L.Routing.waypoint(curr[1][0]._latlng, val)); |
||
816 | map.removeLayer(curr[1][0]); |
||
817 | } |
||
818 | } |
||
819 | }); |
||
820 | routing.setWaypoints(geocodeSearch.waypoints); |
||
821 | routing.on('routeselected', function(e) { |
||
822 | var r = e.route; |
||
823 | var name = r.name; |
||
824 | var time = r.summary.totalTime; |
||
825 | var distance = r.summary.totalDistance; |
||
826 | if(distance >= 1000) distance = parseFloat(distance/1000).toFixed(1) + 'km'; |
||
827 | else distance += 'm'; |
||
828 | time = Math.ceil(time / 60); // time as minutes |
||
829 | var hours = Math.floor(time / 60); |
||
830 | var minutes = time % 60; |
||
831 | alert('Route ' + name + ' is ' + distance + ' long and takes about ' + hours + ':' + minutes); |
||
832 | }); |
||
833 | }, |
||
834 | waypointsChanged : function(e) { |
||
835 | var wps = e.waypoints; |
||
836 | var wpscount = wps.length; |
||
837 | var inputcount = document.getElementById('search').childNodes.length; |
||
838 | while(wpscount > inputcount) { |
||
839 | geocodeSearch.addGeocoder(); |
||
840 | inputcount++; |
||
841 | } |
||
842 | var inputContainers = document.getElementById('search').childNodes; |
||
843 | $.each(wps, function(idx, wp) { |
||
844 | var name = wp.name; |
||
845 | if(name == null || name == '') { |
||
0 ignored issues
–
show
It is recommended to use
=== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() It is recommended to use
=== to compare with .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
846 | geocoder.reverse(wp.latLng, 67108864, function(data) { |
||
847 | var input = inputContainers[idx].getElementsByClassName('geocoder')[0]; |
||
848 | data = data[0]; |
||
849 | input.value = data.name; |
||
850 | wp.name = data.name; |
||
851 | wp.latLng = data.center; |
||
852 | }); |
||
853 | } |
||
854 | }); |
||
855 | } |
||
856 | }, |
||
857 | |||
858 | mapSearch = { |
||
859 | searchItems : [], |
||
860 | _ids : [], |
||
861 | getSearchResults : function(data, callback) { |
||
862 | $.getJSON(OC.generateUrl('/apps/maps/search'), data, function renderSearchResults(r) { |
||
863 | callback(r) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
864 | }) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
865 | }, |
||
866 | |||
867 | showResultsOnMap : function(r) { |
||
868 | if (map.getZoom() <= 14) { |
||
869 | var zoomMSG = '<div class="leaflet-control-minZoomIndecator leaflet-control" style="border-radius: 3px; padding: 3px 7px; display: block; background: rgba(255, 255, 255, 0.701961);">Results might be limited due current zoom, zoom in to get more</div>' |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
870 | $('.leaflet-top.leaflet-middle').html(zoomMSG); |
||
871 | } else { |
||
872 | $('.leaflet-control-minZoomIndecator ').remove(); |
||
873 | } |
||
874 | console.log(r) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() |
|||
875 | |||
876 | $.each(r.contacts, function() { |
||
877 | var contact = this; |
||
878 | if ($.inArray(contact.id, mapSearch._ids) != -1) { |
||
879 | return; |
||
880 | } |
||
881 | if (contact.location) { |
||
882 | if (contact.thumbnail) { |
||
883 | var imagePath = contact.thumbnail; |
||
884 | var iconImage = L.icon({ |
||
885 | iconUrl : imagePath, |
||
886 | iconSize : [42, 49], |
||
887 | iconAnchor : [21, 49], |
||
888 | popupAnchor : [0, -49], |
||
889 | className : 'contact-icon' |
||
890 | }); |
||
891 | } else { |
||
892 | var imagePath = OC.filePath('maps', 'img', 'icons/marker_anonPerson.png'); |
||
0 ignored issues
–
show
|
|||
893 | var iconImage = L.icon({ |
||
0 ignored issues
–
show
|
|||
894 | iconUrl : imagePath, |
||
895 | iconSize : [42, 49], |
||
896 | iconAnchor : [21, 49], |
||
897 | popupAnchor : [0, -49] |
||
898 | }); |
||
899 | } |
||
900 | |||
901 | for(i=0; i<contact.location.length; i++){ |
||
902 | if(contact.location[i] == null) continue; |
||
0 ignored issues
–
show
It is recommended to use
=== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
903 | var markerHTML = '<h2>' + contact.FN + "</h2>"; |
||
904 | var street = [contact.ADR[i][0], contact.ADR[i][1], contact.ADR[i][2]].clean('').join('<br />'); |
||
905 | var city = (contact.ADR[i][3]) ? contact.ADR[i][3] : ''; |
||
906 | markerHTML += '<br />' + street + ", " + city; |
||
907 | markerHTML += (contact.TEL) ? '<br />Tel: ' + escape(contact.TEL[0]) : ''; |
||
908 | var marker = L.marker([contact.location[i].lat * 1, contact.location[i].lon * 1], { |
||
909 | icon : iconImage |
||
910 | }); |
||
911 | toolKit.addMarker(marker, markerHTML) |
||
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: ![]() There were too many errors found in this file; checking aborted after 48%.
If JSHint finds too many errors in a file, it aborts checking altogether because it suspects a configuration issue. Further Reading: ![]() |
|||
912 | mapSearch.searchItems.push(marker); |
||
913 | } |
||
914 | } |
||
915 | mapSearch._ids.push(contact.id) |
||
916 | }) |
||
917 | |||
918 | $.each(r.addresses, function() { |
||
919 | if ($.inArray(this.place_id, mapSearch._ids) != -1) { |
||
920 | return; |
||
921 | } |
||
922 | var markerHTML = this.display_name.replace(',', '<br />'); |
||
923 | var marker = new L.marker([this.lat * 1, this.lon * 1], { |
||
924 | icon: normalMarkerIcon} |
||
925 | ); |
||
926 | toolKit.addMarker(marker, markerHTML) |
||
927 | mapSearch.searchItems.push(marker); |
||
928 | mapSearch._ids.push(this.place_id) |
||
929 | |||
930 | }); |
||
931 | |||
932 | $.each(r.nodes, function() { |
||
933 | if ($.inArray(this.place_id, mapSearch._ids) != -1) { |
||
934 | return; |
||
935 | } |
||
936 | var iconImage = toolKit.getPoiIcon(this.type) |
||
937 | var markerHTML = this.display_name.replace(',', '<br />'); |
||
938 | if (iconImage) { |
||
939 | var marker = L.marker([this.lat * 1, this.lon * 1], { |
||
940 | icon : iconImage |
||
941 | }); |
||
942 | } else { |
||
943 | var marker = new L.marker([this.lat * 1, this.lon * 1], { |
||
944 | icon: normalMarkerIcon |
||
945 | }); |
||
946 | } |
||
947 | toolKit.addMarker(marker, markerHTML) |
||
948 | mapSearch.searchItems.push(marker); |
||
949 | mapSearch._ids.push(this.place_id) |
||
950 | |||
951 | }); |
||
952 | |||
953 | }, |
||
954 | |||
955 | clearSearchResults : function() { |
||
956 | for ( i = 0; i < mapSearch.searchItems.length; i++) { |
||
957 | map.removeLayer(mapSearch.searchItems[i]); |
||
958 | } |
||
959 | mapSearch.searchItems = [] |
||
960 | } |
||
961 | } |
||
962 | |||
963 | Maps = { |
||
964 | addressbooks : [], |
||
965 | addresses : [], |
||
966 | tempArr : [], |
||
967 | tempCounter : 0, |
||
968 | tempTotal : 0, |
||
969 | activeLayers : [], |
||
970 | poiMarker : [], |
||
971 | overpassLayers : [], |
||
972 | mouseDowntime : 0, |
||
973 | droppedPin : {}, |
||
974 | dragging : false, |
||
975 | activeDevices : [], |
||
976 | deviceMarkers : [], |
||
977 | trackMarkers : {}, |
||
978 | trackingTimer : {}, |
||
979 | deviceTimer : 0, |
||
980 | historyTrack : {}, |
||
981 | traceDevice : null, |
||
982 | arrowHead : {}, |
||
983 | displayPoiIcons : function(zoomLevel) { |
||
984 | $.each(poiLayers, function(i, layer) { |
||
985 | $.each(layer, function(group, values) { |
||
986 | $.each(values, function(j, value) { |
||
987 | var overpassLayer = new L.OverPassLayer({ |
||
988 | minZoom: 9, |
||
989 | query: 'node({{bbox}})[' + group + '=' + value + '];out;', |
||
990 | onSuccess: function(data) { |
||
991 | for ( i = 0; i < data.elements.length; i++) { |
||
992 | e = data.elements[i]; |
||
993 | if (e.id in this.instance._ids) { |
||
994 | return; |
||
995 | } |
||
996 | this.instance._ids[e.id] = true; |
||
997 | var pos = new L.LatLng(e.lat, e.lon); |
||
998 | var popup = Maps.getPoiPopupHTML(e.tags).innerHTML; |
||
999 | poiIcon = toolKit.getPoiIcon(value); |
||
1000 | if (poiIcon) { |
||
1001 | var marker = L.marker(pos, { |
||
1002 | icon : poiIcon, |
||
1003 | }).bindPopup(popup); |
||
1004 | Maps.poiMarker.push(marker); |
||
1005 | toolKit.addMarker(marker, popup) |
||
1006 | } |
||
1007 | } |
||
1008 | } |
||
1009 | }); |
||
1010 | map.addLayer(overpassLayer); |
||
1011 | Maps.overpassLayers.push(overpassLayer); |
||
1012 | }); |
||
1013 | }); |
||
1014 | }); |
||
1015 | }, |
||
1016 | hidePoiIcons : function() { |
||
1017 | $.each(Maps.overpassLayers, function(i, layer) { |
||
1018 | map.removeLayer(layer); |
||
1019 | }); |
||
1020 | Maps.overpassLayers = []; |
||
1021 | $.each(Maps.poiMarker, function(i, marker) { |
||
1022 | map.removeLayer(marker); |
||
1023 | }); |
||
1024 | Maps.poiMarker = []; |
||
1025 | }, |
||
1026 | getPoiPopupHTML : function(tags) { |
||
1027 | var div = document.createElement('div'); |
||
1028 | |||
1029 | var housenr = ''; |
||
1030 | var street = ''; |
||
1031 | var city = ''; |
||
1032 | var postcode = ''; |
||
1033 | var suburb = ''; |
||
1034 | if(tags['addr:street']) street = tags['addr:street']; |
||
1035 | else if(tags['road']) street = tags['road']; |
||
1036 | else if(tags['footway']) street = tags['footway']; |
||
1037 | if(tags['addr:housenumber']) housenr = tags['addr:housenumber']; |
||
1038 | else if(tags['house_number']) housenr = tags['house_number']; |
||
1039 | if(tags['addr:postcode']) postcode = tags['addr:postcode']; |
||
1040 | else if(tags['postcode']) postcode = tags['postcode']; |
||
1041 | if(tags['addr:city']) city = tags['addr:city']; |
||
1042 | else if(tags['town']) city = tags['town']; |
||
1043 | else if(tags['city']) city = tags['city']; |
||
1044 | if(tags['suburb']) suburb = tags['suburb']; |
||
1045 | else if(tags['city_district']) suburb = tags['city_district']; |
||
1046 | |||
1047 | var title = document.createElement('h2'); |
||
1048 | var titleTxt = ''; |
||
1049 | if(tags['name']) titleTxt = tags['name']; |
||
1050 | else if(tags['building']) titleTxt = tags['building']; |
||
1051 | //use street as title fallback |
||
1052 | else if(street.length > 0) { |
||
1053 | titleTxt = street; |
||
1054 | if(housenr.length > 0) titleTxt += ' ' + housenr; |
||
1055 | } |
||
1056 | title.appendChild(document.createTextNode(titleTxt)); |
||
1057 | div.appendChild(title); |
||
1058 | |||
1059 | var addr = ''; |
||
1060 | if(street.length > 0) addr += street; |
||
1061 | if(housenr.length > 0) addr += ' ' + housenr; |
||
1062 | if(postcode.length > 0) addr += ', ' + postcode; |
||
1063 | if(city.length > 0) addr += ' ' + city; |
||
1064 | if(suburb.length > 0) addr += ' (' + suburb + ')'; |
||
1065 | div.appendChild(document.createTextNode(addr)); |
||
1066 | if(tags['phone']) { |
||
1067 | var phoneDiv = document.createElement('div'); |
||
1068 | var phone = document.createElement('a'); |
||
1069 | var phoneN = tags['phone']; |
||
1070 | if(phoneN.startsWith('+')) phoneN = phoneN.substring(1); |
||
1071 | phone.setAttribute('href', 'tel://' + phoneN); |
||
1072 | phone.appendChild(document.createTextNode(tags['phone'])); |
||
1073 | phoneDiv.appendChild(phone); |
||
1074 | div.appendChild(phoneDiv); |
||
1075 | } |
||
1076 | if(tags['website']) { |
||
1077 | var webDiv = document.createElement('div'); |
||
1078 | var web = document.createElement('a'); |
||
1079 | var webN = tags['website']; |
||
1080 | web.setAttribute('href', webN); |
||
1081 | web.setAttribute('target', '_blank'); |
||
1082 | web.appendChild(document.createTextNode(webN)); |
||
1083 | webDiv.appendChild(web); |
||
1084 | div.appendChild(webDiv); |
||
1085 | } |
||
1086 | if(tags['email']) { |
||
1087 | var mailDiv = document.createElement('div'); |
||
1088 | var mail = document.createElement('a'); |
||
1089 | var mailN = tags['email']; |
||
1090 | mail.setAttribute('href', 'mailto:' + mailN); |
||
1091 | mail.appendChild(document.createTextNode(mailN)); |
||
1092 | mailDiv.appendChild(mail); |
||
1093 | div.appendChild(mailDiv); |
||
1094 | } |
||
1095 | return div; |
||
1096 | }, |
||
1097 | loadAdressBooks : function() { |
||
1098 | if($('#contactMenu').length == 0) return; |
||
1099 | Maps.addressbooks = []; |
||
1100 | $.get(OC.generateUrl('apps/contacts/addressbooks/'), function(r) { |
||
1101 | $.each(r.addressbooks, function() { |
||
1102 | var book = { |
||
1103 | 'id' : this.id, |
||
1104 | 'backend' : this.backend |
||
1105 | } |
||
1106 | Maps.addressbooks.push(book); |
||
1107 | }) |
||
1108 | //Load addresses in array |
||
1109 | $.each(Maps.addressbooks, function(ai) { |
||
1110 | $.get(OC.generateUrl('/apps/contacts/addressbook/' + this.backend + '/' + this.id + '/contacts'), function(r) { |
||
1111 | $.each(r.contacts, function(ci) { |
||
1112 | var name = this.data.FN[0].value; |
||
1113 | var adr = {}; |
||
1114 | var orgAdr = {}; |
||
1115 | if(this.data.ADR){ |
||
1116 | for(var i=0; i< this.data.ADR.length; i++){ |
||
1117 | var currAddr = this.data.ADR[i].value; |
||
1118 | //remove empty cells (didn't work with delete or any other function...thus: ugly code |
||
1119 | for (var j=currAddr.length-1; j>=0; j--) { |
||
1120 | if (currAddr[j] === null || currAddr[j] === undefined || currAddr[j] === "") { |
||
1121 | currAddr.splice(j,1); |
||
1122 | } |
||
1123 | } |
||
1124 | adr[i] = currAddr.toString().replace(/,/g, ", "); |
||
1125 | orgAdr[i] = this.data.ADR[i].value; |
||
1126 | } |
||
1127 | |||
1128 | } |
||
1129 | if(!adr[0]) return true; |
||
1130 | var addr = { |
||
1131 | 'name': name, |
||
1132 | 'add': adr, |
||
1133 | 'orgAdd': orgAdr |
||
1134 | }; |
||
1135 | Maps.addresses.push(addr); |
||
1136 | }); |
||
1137 | }); |
||
1138 | }); |
||
1139 | //end |
||
1140 | Maps.loadContacts(); |
||
1141 | }) |
||
1142 | }, |
||
1143 | removePosistionHistory : function(deviceId) { |
||
1144 | for ( i = 0; i < Maps.trackMarkers[deviceId].length; i++) { |
||
1145 | map.removeLayer(Maps.trackMarkers[deviceId][i]); |
||
1146 | } |
||
1147 | if (Maps.historyTrack[deviceId]) { |
||
1148 | map.removeLayer(Maps.historyTrack[deviceId]); |
||
1149 | map.removeLayer(Maps.arrowHead[deviceId]); |
||
1150 | } |
||
1151 | clearTimeout(Maps.trackingTimer[deviceId]); |
||
1152 | }, |
||
1153 | |||
1154 | loadDevicePosistionHistory : function(deviceId, trackCurrentPosition, from, till) { |
||
1155 | var trackCurrentPosition = (trackCurrentPosition) ? true : false; |
||
1156 | var from = (from) ? from : ''; |
||
1157 | var till = (till) ? till : ''; |
||
1158 | var data = { |
||
1159 | devices : deviceId, |
||
1160 | 'from' : from, |
||
1161 | 'till' : till |
||
1162 | }; |
||
1163 | |||
1164 | if (!Maps.trackMarkers[deviceId]) { |
||
1165 | Maps.trackMarkers[deviceId] = []; |
||
1166 | Maps.arrowHead[deviceId] = []; |
||
1167 | Maps.historyTrack[deviceId] = []; |
||
1168 | Maps.trackingTimer[deviceId] = []; |
||
1169 | } |
||
1170 | |||
1171 | clearTimeout(Maps.trackingTimer); |
||
1172 | $.get(OC.generateUrl('/apps/maps/api/1.0/location/loadLocations'), data, function(response) { |
||
1173 | var locations = response[deviceId]; |
||
1174 | var points = []; |
||
1175 | var bounds = [] |
||
1176 | var lastPosition = locations[0]; |
||
1177 | for ( i = 0; i < Maps.trackMarkers[deviceId].length; i++) { |
||
1178 | map.removeLayer(Maps.trackMarkers[deviceId][i]); |
||
1179 | } |
||
1180 | if (Maps.historyTrack[deviceId]) { |
||
1181 | map.removeLayer(Maps.historyTrack[deviceId]); |
||
1182 | map.removeLayer(Maps.arrowHead[deviceId]); |
||
1183 | } |
||
1184 | if (locations.length === 0) { |
||
1185 | OC.Notification.showTimeout('No results'); |
||
1186 | return; |
||
1187 | } |
||
1188 | var lastPObject = L.latLng(lastPosition.lat, lastPosition.lng) //distanceTo |
||
1189 | $.each(locations, function(k, location) { |
||
1190 | var markerHTML = ''; |
||
1191 | var marker = new L.marker([location.lat * 1, location.lng * 1]); |
||
1192 | var point = new L.LatLng(location.lat * 1, location.lng * 1); |
||
1193 | //bounds.push(marker.getBounds()); |
||
1194 | var markerHTML = location.name + '<br />'; |
||
1195 | markerHTML += 'Lat: ' + location.lat + ' Lon: ' + location.lng + '<br />'; |
||
1196 | markerHTML += 'Speed: ' + location.speed + '<br />' |
||
1197 | markerHTML += 'Time: ' + new Date(location.timestamp * 1000).toLocaleString("nl-NL") |
||
1198 | var marker = new L.marker([location.lat * 1, location.lng * 1], { |
||
1199 | icon: normalMarkerIcon |
||
1200 | }); |
||
1201 | if(Math.round(lastPObject.distanceTo(point))> 15){ //If markers are more then 15m between each other |
||
1202 | console.log('Distance from last point: ',Math.round(lastPObject.distanceTo(point))); |
||
1203 | Maps.trackMarkers[location.deviceId].push(marker); |
||
1204 | toolKit.addMarker(marker, markerHTML); |
||
1205 | points.push(point); |
||
1206 | } |
||
1207 | lastPObject = point; |
||
1208 | }); |
||
1209 | points.reverse(); |
||
1210 | Maps.historyTrack[deviceId] = new L.Polyline(points, { |
||
1211 | color : 'green', |
||
1212 | weight : 6, |
||
1213 | opacity : 0.5, |
||
1214 | smoothFactor : 1 |
||
1215 | |||
1216 | }); |
||
1217 | Maps.historyTrack[deviceId].addTo(map); |
||
1218 | Maps.arrowHead[deviceId] = L.polylineDecorator(Maps.historyTrack[deviceId]).addTo(map); |
||
1219 | Maps.arrowHead[deviceId].setPatterns([{ |
||
1220 | offset : '0%', |
||
1221 | repeat : 100, |
||
1222 | symbol : L.Symbol.arrowHead({ |
||
1223 | pixelSize : 25, |
||
1224 | polygon : false, |
||
1225 | pathOptions : { |
||
1226 | stroke : true |
||
1227 | } |
||
1228 | }) |
||
1229 | }]); |
||
1230 | Maps.trackingTimer[deviceId] = setTimeout(function() { |
||
1231 | Maps.loadDevicePosistionHistory(deviceId, trackCurrentPosition, from, till); |
||
1232 | }, 60000) |
||
1233 | if (trackCurrentPosition && lastPosition.deviceId == Maps.traceDevice) { |
||
1234 | map.panTo(new L.LatLng(lastPosition.lat, lastPosition.lng)); |
||
1235 | } |
||
1236 | }); |
||
1237 | }, |
||
1238 | clearDevicePosistionHistory : function(deviceId) { |
||
1239 | for ( i = 0; i < Maps.trackMarkers[deviceId].length; i++) { |
||
1240 | map.removeLayer(Maps.trackMarkers[deviceId][i]); |
||
1241 | } |
||
1242 | map.removeLayer(Maps.historyTrack[deviceId]); |
||
1243 | map.removeLayer(Maps.arrowHead[deviceId]); |
||
1244 | clearTimeout(Maps.trackingTimer[deviceId]); |
||
1245 | Maps.trackMarkers[deviceId] = []; |
||
1246 | }, |
||
1247 | loadDevicesLastPosition : function() { |
||
1248 | var data = { |
||
1249 | devices : Maps.activeDevices.join(','), |
||
1250 | limit : 1 |
||
1251 | }; |
||
1252 | clearTimeout(Maps.deviceTimer); |
||
1253 | if (Maps.activeDevices.length > 0) { |
||
1254 | $.get(OC.generateUrl('/apps/maps/api/1.0/location/loadLocations'), data, function(response) { |
||
1255 | Maps.clearDevicePositions(); |
||
1256 | $.each(response, function(deviceId, location) { |
||
1257 | console.log(deviceId, location); |
||
1258 | var device = location[0]; |
||
1259 | if (!device) |
||
1260 | return; |
||
1261 | |||
1262 | var markerHTML = device.name + '<br />'; |
||
1263 | markerHTML += 'Lat: ' + device.lat + ' Lon: ' + device.lng + '<br />'; |
||
1264 | markerHTML += 'Speed: ' + device.speed + '<br />' |
||
1265 | markerHTML += 'Time: ' + new Date(device.timestamp * 1000).toLocaleString("nl-NL") |
||
1266 | var marker = new L.marker([device.lat * 1, device.lng * 1], { |
||
1267 | icon: normalMarkerIcon |
||
1268 | }); |
||
1269 | toolKit.addMarker(marker, markerHTML) |
||
1270 | Maps.deviceMarkers.push(marker); |
||
1271 | if (device.deviceId == Maps.traceDevice) { |
||
1272 | map.panTo(new L.LatLng(device.lat * 1, device.lng * 1)); |
||
1273 | } |
||
1274 | }); |
||
1275 | Maps.deviceTimer = setTimeout(Maps.loadDevicesLastPosition, 60000); |
||
1276 | }); |
||
1277 | } |
||
1278 | }, |
||
1279 | clearDevicePositions : function() { |
||
1280 | for ( i = 0; i < Maps.deviceMarkers.length; i++) { |
||
1281 | map.removeLayer(Maps.deviceMarkers[i]); |
||
1282 | } |
||
1283 | Maps.deviceMarkers = []; |
||
1284 | }, |
||
1285 | |||
1286 | loadContacts : function() { |
||
1287 | Maps.tempArr = []; |
||
1288 | Maps.tempTotal = 0; |
||
1289 | Maps.tempCounter = 0; |
||
1290 | $.each(Maps.addressbooks, function(ai) { |
||
1291 | $.get(OC.generateUrl('/apps/contacts/addressbook/' + this.backend + '/' + this.id + '/contacts'), function(r) { |
||
1292 | $.each(r.contacts, function(ci) { |
||
1293 | Maps.tempArr.push(this); |
||
1294 | if (ai == Maps.addressbooks.length - 1 && ci == r.contacts.length - 1) { |
||
1295 | Maps.getContactPositionData(); |
||
1296 | Maps.tempTotal = Maps.tempArr.length; |
||
1297 | $('#loadingContacts').show(); |
||
1298 | } |
||
1299 | }); |
||
1300 | }); |
||
1301 | }); |
||
1302 | }, |
||
1303 | getContactPositionData : function() { |
||
1304 | |||
1305 | if (Maps.tempArr.length > 0) { |
||
1306 | temp = Maps.tempArr.pop(); |
||
1307 | var contact = toolKit.vcardToObject(temp); |
||
1308 | toolKit.adresLookup(contact.adr, function(d) { |
||
1309 | var curperson = $.extend({}, d, contact); |
||
1310 | try { |
||
1311 | toolKit.addFavContactMarker(curperson); |
||
1312 | } catch(e) { |
||
1313 | |||
1314 | } |
||
1315 | var total = Maps.tempTotal; |
||
1316 | var index = Maps.tempCounter |
||
1317 | var percent = Math.round((index / total * 100) * 100) / 100; |
||
1318 | toolKit.setProgress(percent); |
||
1319 | $('#cCounter').text(index + 1 + ' of ' + (total * 1 + 1)); |
||
1320 | Maps.tempCounter++; |
||
1321 | if (index == total) |
||
1322 | $('#loadingContacts').hide() |
||
1323 | Maps.getContactPositionData(); |
||
1324 | }) |
||
1325 | } |
||
1326 | }, |
||
1327 | |||
1328 | saveCurrentLocation : function(e) { |
||
1329 | var center = map.getBounds().getCenter(); |
||
1330 | var location = { |
||
1331 | lat : center.lat, |
||
1332 | lng : center.lng |
||
1333 | }; |
||
1334 | $.jStorage.set('location', location) |
||
1335 | $.jStorage.set('zoom', e.target._zoom) |
||
1336 | }, |
||
1337 | |||
1338 | showContact : function(data) { |
||
1339 | |||
1340 | } |
||
1341 | } |
||
1342 | toolKit = { |
||
1343 | addMarker : function(marker, markerHTML, openPopup, fav) { |
||
1344 | if(marker == null || marker._latlng == null) return; |
||
1345 | fav = fav || false; |
||
1346 | var openPopup = (openPopup) ? true : false; |
||
1347 | var latlng = marker._latlng.lat + ',' + marker._latlng.lng; |
||
1348 | var markerHTML2 = '<div class="'; |
||
1349 | if(fav) { |
||
1350 | markerHTML2 += 'icon-starred removeFromFav" fav-id="' + marker.options.id + '"'; |
||
1351 | var editButton = document.createElement('button'); |
||
1352 | editButton.className = 'icon-rename editFav'; |
||
1353 | var titleEnd = markerHTML.indexOf('</h2>') + 5; |
||
1354 | markerHTML = markerHTML.slice(0, titleEnd) + editButton.outerHTML + markerHTML.slice(titleEnd); |
||
1355 | } else { |
||
1356 | markerHTML2 += 'icon-star addToFav"'; |
||
1357 | } |
||
1358 | markerHTML2 += ' data-latlng="' + latlng + '" style="float: left;"></div><div class="marker-popup-content">' + markerHTML + '</div><div><a class="setDestination" data-latlng="' + latlng + '">Navigate here</a></div>'; |
||
1359 | marker.addTo(map).bindPopup(markerHTML2); |
||
1360 | marker.on('mouseover', function (e) { |
||
1361 | var tgt = e.originalEvent.fromElement || e.originalEvent.relatedTarget; |
||
1362 | var parent = this._getParent(tgt, 'leaflet-popup'); |
||
1363 | if(parent == marker._popup._container) return true; |
||
1364 | marker.openPopup(); |
||
1365 | }, this); |
||
1366 | marker.on('mouseout', function (e) { |
||
1367 | var tgt = e.originalEvent.toElement || e.originalEvent.relatedTarget; |
||
1368 | if(this._getParent(tgt, 'leaflet-popup')) { |
||
1369 | L.DomEvent.on(marker._popup._container, 'mouseout', this._popupMouseOut, this); |
||
1370 | return true; |
||
1371 | } |
||
1372 | marker.closePopup(); |
||
1373 | }, this); |
||
1374 | if (openPopup === true) { |
||
1375 | setTimeout(function() { |
||
1376 | //L.popup().setLatLng([marker._latlng.lat, marker._latlng.lng]).setContent("I am a standalone popup.").openOn(map); |
||
1377 | marker.openPopup(); |
||
1378 | }, 50); |
||
1379 | } |
||
1380 | }, |
||
1381 | _getParent: function(element, className) { |
||
1382 | var parent = element.parentNode; |
||
1383 | while (parent != null) { |
||
1384 | if (parent.className && L.DomUtil.hasClass(parent, className)) |
||
1385 | return parent; |
||
1386 | parent = parent.parentNode; |
||
1387 | } |
||
1388 | return false; |
||
1389 | }, |
||
1390 | _popupMouseOut: function(e) { |
||
1391 | if(marker == null || marker._popup == null) return false; |
||
1392 | L.DomEvent.off(marker._popup, 'mouseout', this._popupMouseOut, this); |
||
1393 | var tgt = e.toElement || e.relatedTarget; |
||
1394 | if (this._getParent(tgt, 'leaflet-popup')) return true; |
||
1395 | if (tgt == this._icon) return true; |
||
1396 | marker.closePopup(); |
||
1397 | }, |
||
1398 | getPoiIcon : function(icon) { |
||
1399 | return toolKit.toMakiMarkerIcon(icon.replace(' ', '')); |
||
1400 | }, |
||
1401 | |||
1402 | toMakiMarkerIcon : function(type) { |
||
1403 | var mapper = { |
||
1404 | 'aerialway' : [ 'aerialway' ], |
||
1405 | 'airfield' : [ 'airfield' ], |
||
1406 | 'airport' : [ 'airport' ], |
||
1407 | 'alcohol-shop' : [ 'alcohol-shop', 'alcohol', 'beverages' ], |
||
1408 | 'america-football' : [ 'america-football' ], |
||
1409 | 'art-gallery' : [ 'art-gallery', 'gallery', 'artwork', 'paint' ], |
||
1410 | 'bakery' : [ 'bakery' ], |
||
1411 | 'bank' : [ 'bank', 'atm' ], |
||
1412 | 'bar' : [ 'bar' ], |
||
1413 | 'baseball' : [ 'baseball' ], |
||
1414 | 'basketball' : [ 'basketball' ], |
||
1415 | 'beer' : [ 'beer', , 'biergarten', 'pub' ], |
||
1416 | 'bicycle' : [ 'bicycle', 'bicycle_parking' ], |
||
1417 | 'building' : [ 'building' ], |
||
1418 | 'bus' : [ 'bus', 'bus_stop', 'bus_station'], |
||
1419 | 'cafe' : [ 'cafe' ], |
||
1420 | 'camera' : [ 'camera', 'viewpoint' ], |
||
1421 | 'campsite' : [ 'campsite', 'camp_site', 'caravan_site' ], |
||
1422 | 'car' : [ 'car' ], |
||
1423 | 'cemetery' : [ 'cemetery' ], |
||
1424 | 'chemist' : [ 'chemist' ], |
||
1425 | 'cinema' : [ 'cinema' ], |
||
1426 | 'circle' : [ 'circle' ], |
||
1427 | 'circle-stroked' : [ 'circle-stroked' ], |
||
1428 | 'city' : [ 'city' ], |
||
1429 | 'clothing-store' : [ 'clothing-store', 'clothes' ], |
||
1430 | 'college' : [ 'college' ], |
||
1431 | 'commercial' : [ 'commercial' ], |
||
1432 | 'cricket' : [ 'cricket' ], |
||
1433 | 'cross' : [ 'cross' ], |
||
1434 | 'dam' : [ 'dam' ], |
||
1435 | 'danger' : [ 'danger' ], |
||
1436 | 'dentist' : [ 'dentist' ], |
||
1437 | 'disability' : [ 'disability' ], |
||
1438 | 'dog-park' : [ 'dog-park' ], |
||
1439 | 'embassy' : [ 'embassy' ], |
||
1440 | 'emergency-telephone' : [ 'emergency-telephone' ], |
||
1441 | 'entrance' : [ 'entrance' ], |
||
1442 | 'farm' : [ 'farm' ], |
||
1443 | 'fast-food' : [ 'fast-food' ], |
||
1444 | 'ferry' : [ 'ferry' ], |
||
1445 | 'fire-station' : [ 'fire-station', 'fire_station' ], |
||
1446 | 'fuel' : [ 'fuel' ], |
||
1447 | 'garden' : [ 'garden' ], |
||
1448 | 'gift' : [ 'gift' ], |
||
1449 | 'golf' : [ 'golf' ], |
||
1450 | 'grocery' : [ 'grocery', 'supermarket', 'deli', 'convenience', 'greengrocer', 'fishmonger', 'butcher', 'marketplace' ], |
||
1451 | 'hairdresser' : [ 'hairdresser' ], |
||
1452 | 'harbor' : [ 'harbor' ], |
||
1453 | 'heart' : [ 'heart' ], |
||
1454 | 'heliport' : [ 'heliport' ], |
||
1455 | 'hospital' : [ 'hospital' ], |
||
1456 | 'ice-cream' : [ 'ice-cream' ], |
||
1457 | 'industrial' : [ 'industrial' ], |
||
1458 | 'land-use' : [ 'land-use' ], |
||
1459 | 'laundry' : [ 'laundry' ], |
||
1460 | 'library' : [ 'library', 'books' ], |
||
1461 | 'lighthouse' : [ 'lighthouse' ], |
||
1462 | 'lodging' : [ 'lodging', 'hotel', 'guest_house', 'hostel', 'motel' ], |
||
1463 | 'logging' : [ 'logging' ], |
||
1464 | 'london-underground' : [ 'london-underground' ], |
||
1465 | 'marker' : [ 'marker' ], |
||
1466 | 'marker-stroked' : [ 'marker-stroked' ], |
||
1467 | 'minefield' : [ 'minefield' ], |
||
1468 | 'mobilephone' : [ 'mobilephone', 'mobile_phone', 'gsm' ], |
||
1469 | 'monument' : [ 'monument' ], |
||
1470 | 'museum' : [ 'museum' ], |
||
1471 | 'music' : [ 'music' ], |
||
1472 | 'oil-well' : [ 'oil-well' ], |
||
1473 | 'park' : [ 'park' ], |
||
1474 | 'parking' : [ 'parking' ], |
||
1475 | 'parking-garage' : [ 'parking-garage', 'parking-entrance' ], |
||
1476 | 'pharmacy' : [ 'pharmacy', 'drugstore' ], |
||
1477 | 'pitch' : [ 'pitch', 'sports' ], |
||
1478 | 'place-of-worship' : [ 'place-of-worship', 'place_of_worship' ], |
||
1479 | 'playground' : [ 'playground' ], |
||
1480 | 'police' : [ 'police' ], |
||
1481 | 'polling-place' : [ 'polling-place' ], |
||
1482 | 'post' : [ 'post', 'post_box', 'post_office' ], |
||
1483 | 'prison' : [ 'prison' ], |
||
1484 | 'rail' : [ 'rail' ], |
||
1485 | 'rail-above' : [ 'rail-above' ], |
||
1486 | 'rail-light' : [ 'rail-light' ], |
||
1487 | 'rail-metro' : [ 'rail-metro' ], |
||
1488 | 'rail-underground' : [ 'rail-underground' ], |
||
1489 | 'religious-christian' : [ 'religious-christian' ], |
||
1490 | 'religious-jewish' : [ 'religious-jewish' ], |
||
1491 | 'religious-muslim' : [ 'religious-muslim' ], |
||
1492 | 'restaurant' : [ 'restaurant' ], |
||
1493 | 'roadblock' : [ 'roadblock' ], |
||
1494 | 'rocket' : [ 'rocket' ], |
||
1495 | 'school' : [ 'school', 'kindergarten' ], |
||
1496 | 'scooter' : [ 'scooter' ], |
||
1497 | 'shop' : [ 'shop', 'general', 'bag', 'furniture', 'variety_store', 'houseware', 'department_store', 'florist', 'outdoor', 'kiosk', 'kitchen', 'shoes', 'jewelry', 'sports' ], |
||
1498 | 'skiing' : [ 'skiing' ], |
||
1499 | 'slaughterhouse' : [ 'slaughterhouse' ], |
||
1500 | 'soccer' : [ 'soccer' ], |
||
1501 | 'square' : [ 'square' ], |
||
1502 | 'square-stroked' : [ 'square-stroked' ], |
||
1503 | 'star' : [ 'star' ], |
||
1504 | 'star-stroked' : [ 'star-stroked' ], |
||
1505 | 'suitcase' : [ 'suitcase' ], |
||
1506 | 'swimming' : [ 'swimming', 'swimming_pool' ], |
||
1507 | 'telephone' : [ 'telephone', 'phone' ], |
||
1508 | 'tennis' : [ 'tennis' ], |
||
1509 | 'theatre' : [ 'theatre' ], |
||
1510 | 'toilets' : [ 'toilets' ], |
||
1511 | 'town' : [ 'town' ], |
||
1512 | 'town-hall' : [ 'town-hall', 'townhall' ], |
||
1513 | 'triangle' : [ 'triangle' ], |
||
1514 | 'triangle-stroked' : [ 'triangle-stroked' ], |
||
1515 | 'village' : [ 'village' ], |
||
1516 | 'warehouse' : [ 'warehouse' ], |
||
1517 | 'waste-basket' : [ 'waste-basket' ], |
||
1518 | 'water' : [ 'water' ], |
||
1519 | 'wetland' : [ 'wetland' ], |
||
1520 | 'zoo' : [ 'zoo' ] |
||
1521 | } |
||
1522 | var iconUrl = OC.filePath('maps', 'vendor', 'maki/src/'); |
||
1523 | var iconSuffix = '-18.svg'; |
||
1524 | var name; |
||
1525 | var icon; |
||
1526 | $.each(mapper, function(iconName, types) { |
||
1527 | if (types.indexOf(type) > -1) { |
||
1528 | name = iconName; |
||
1529 | icon = iconUrl + iconName + iconSuffix; |
||
1530 | return false; |
||
1531 | } |
||
1532 | }) |
||
1533 | return L.icon({ |
||
1534 | className: type + ' maki-icon', |
||
1535 | icon: name, |
||
1536 | iconUrl : icon, |
||
1537 | iconSize : [18, 18], |
||
1538 | iconAnchor : [9, 18], |
||
1539 | popupAnchor : [0, -18] |
||
1540 | }); |
||
1541 | }, |
||
1542 | toFAClass : function(type) { |
||
1543 | var mapper = { |
||
1544 | 'shopping-cart' : ['supermarkt', 'supermarket', 'department_store', 'deli'], |
||
1545 | 'medkit' : ['hospital'], |
||
1546 | 'cutlery' : ['fast_food', 'restaurant'], |
||
1547 | 'beer' : ['pub'], |
||
1548 | 'credit-card' : ['atm'], |
||
1549 | 'graduation-cap' : ['school'], |
||
1550 | 'lightbulb-o' : ['electronics'], |
||
1551 | 'cut' : ['hairdresser'], |
||
1552 | 'info' : ['information'], |
||
1553 | 'refresh' : ['recycling'], |
||
1554 | 'asterisk' : ['attraction', 'theme_park'], |
||
1555 | 'cogs' : ['car_repair'], |
||
1556 | 'wrench' : ['doityourself'], |
||
1557 | 'music' : ['hifi'], |
||
1558 | 'gift' : ['gift'], |
||
1559 | 'globe' : ['travel_agency'], |
||
1560 | 'minus' : ['bench', 'picnic_site'], |
||
1561 | 'desktop' : ['computer'], |
||
1562 | 'eye' : ['optician'], |
||
1563 | 'cubes' : ['toys'], |
||
1564 | 'file-picture' : ['photo'], |
||
1565 | 'copy' : ['copyshop'], |
||
1566 | 'paw' : ['pet'], |
||
1567 | 'clock-o' : ['clock'], |
||
1568 | 'key' : ['locksmith'], |
||
1569 | 'video-camera' : ['video'], |
||
1570 | 'magic' : ['party'], |
||
1571 | 'road' : ['living_street'], |
||
1572 | 'home' : ['residential'] |
||
1573 | } |
||
1574 | var returnClass = false; |
||
1575 | $.each(mapper, function(faClass, types) { |
||
1576 | if (types.toString().indexOf(type) > -1) { |
||
1577 | returnClass = faClass |
||
1578 | } else { |
||
1579 | } |
||
1580 | }) |
||
1581 | if (returnClass == false) |
||
1582 | console.log('Type icon not found: ' + type) |
||
1583 | return returnClass; |
||
1584 | }, |
||
1585 | vcardToObject : function(vcard) { |
||
1586 | var contact = {}; |
||
1587 | |||
1588 | $.each(vcard.data, function(k, v) { |
||
1589 | if(vcard.data.photo == true){ |
||
1590 | var uid = vcard.metadata['id']; |
||
1591 | var parent = vcard.metadata['parent']; |
||
1592 | var backend = vcard.metadata['backend']; |
||
1593 | contact.thumbnail = 'apps/contacts/addressbook/' + backend + '/' + parent + '/contact/' + uid + '/photo'; |
||
1594 | contact.thumbnail = OC.generateUrl(contact.thumbnail); |
||
1595 | } |
||
1596 | if (v[0]) { |
||
1597 | if ($.isArray(v[0]['value'])) { |
||
1598 | if (k === 'ADR') { |
||
1599 | var adr = { |
||
1600 | street : v[0]['value'][0] + v[0]['value'][1] + v[0]['value'][2], |
||
1601 | city : v[0]['value'][3], |
||
1602 | postalCode : v[0]['value'][5], |
||
1603 | country : v[0]['value'][6] |
||
1604 | } |
||
1605 | contact[k.toLowerCase()] = adr; |
||
1606 | } else { |
||
1607 | contact[k.toLowerCase()] = v[0]['value'].clean('').join(','); |
||
1608 | } |
||
1609 | } else { |
||
1610 | contact[k.toLowerCase()] = v[0]['value']; |
||
1611 | } |
||
1612 | } else { |
||
1613 | console.log(k, v) |
||
1614 | } |
||
1615 | }) |
||
1616 | return contact; |
||
1617 | }, |
||
1618 | /** |
||
1619 | * |
||
1620 | * @param {Object} street+houseno,City,Country |
||
1621 | * @param {Function} callback func |
||
1622 | */ |
||
1623 | adresLookup : function(address, callback) { |
||
1624 | |||
1625 | if(address !== undefined){ |
||
1626 | var getData = { |
||
1627 | street : address.street, |
||
1628 | city : address.city, |
||
1629 | country : address.country |
||
1630 | } |
||
1631 | } else { |
||
1632 | var getData = null; |
||
1633 | } |
||
1634 | $.getJSON(OC.generateUrl('/apps/maps/adresslookup'), getData, function(r) { |
||
1635 | callback(r) |
||
1636 | }) |
||
1637 | }, |
||
1638 | currentMarker : null, |
||
1639 | favMarkers : [], |
||
1640 | addFavContactMarker : function(contact) { |
||
1641 | if (contact.thumbnail) { |
||
1642 | var imagePath = contact.thumbnail |
||
1643 | var iconImage = L.icon({ |
||
1644 | iconUrl : imagePath, |
||
1645 | iconSize : [42, 49], |
||
1646 | iconAnchor : [21, 49], |
||
1647 | popupAnchor : [0, -49], |
||
1648 | className : 'contact-icon' |
||
1649 | }); |
||
1650 | } else { |
||
1651 | var imagePath = OC.filePath('maps', 'img', 'icons/marker_anonPerson.png'); |
||
1652 | var iconImage = L.icon({ |
||
1653 | iconUrl : imagePath, |
||
1654 | iconSize : [42, 49], |
||
1655 | iconAnchor : [21, 49], |
||
1656 | popupAnchor : [0, -49] |
||
1657 | }); |
||
1658 | } |
||
1659 | |||
1660 | var markerHTML = '<h2>' + contact.fn + "</h2>"; |
||
1661 | var street = (contact.adr.street) ? contact.adr.street : ''; |
||
1662 | var city = (contact.adr.city) ? contact.adr.city : ''; |
||
1663 | markerHTML += '<br />' + street + " " + city; |
||
1664 | markerHTML += (contact.tel) ? '<br />Tel: ' + escape(contact.tel) : ''; |
||
1665 | var marker = L.marker([contact.lat * 1, contact.lon * 1], { |
||
1666 | icon : iconImage |
||
1667 | }); |
||
1668 | toolKit.addMarker(marker, markerHTML) |
||
1669 | toolKit.favMarkers.push(marker); |
||
1670 | }, |
||
1671 | removeFavMarkers : function() { |
||
1672 | for ( i = 0; i < toolKit.favMarkers.length; i++) { |
||
1673 | map.removeLayer(toolKit.favMarkers[i]); |
||
1674 | } |
||
1675 | toolKit.favMarkers = [] |
||
1676 | }, |
||
1677 | |||
1678 | setProgress : function(percent) { |
||
1679 | var $element = $('#progressBar'); |
||
1680 | var progressBarWidth = percent * $element.width() / 100; |
||
1681 | $element.find('div').animate({ |
||
1682 | width : progressBarWidth |
||
1683 | }, 50); |
||
1684 | } |
||
1685 | } |
||
1686 | |||
1687 | poiLayers = { |
||
1688 | 9 : { |
||
1689 | shop : [ |
||
1690 | 'supermarket', 'bicycle' |
||
1691 | ], |
||
1692 | amenity : [ |
||
1693 | 'atm', 'coffee_shop', 'restaurant', 'swimming_pool', 'library', 'toilets', 'post_box', 'bar' |
||
1694 | ], |
||
1695 | tourism : [ |
||
1696 | 'hotel' |
||
1697 | ] |
||
1698 | }, |
||
1699 | 10 : {}, |
||
1700 | 11: {}, |
||
1701 | 12 : {}, |
||
1702 | 13 : {}, |
||
1703 | 14 : {}, |
||
1704 | 15 : {} |
||
1705 | }, |
||
1706 | |||
1707 | poiTypes = { |
||
1708 | shop : ['atm', 'coffee_shop', 'restaurant', 'supermarket', 'bicycle', 'hotel', 'swimming_pool', 'library', 'toilets', 'post_box', 'bar'], |
||
1709 | //TODO: define proper categories: |
||
1710 | // Restaurants/food/coffeeshops/bars, Hotels/hostels, Touristic sites, Wifi, Transport, Fuel, Parking, Supermarket, ATM/Bank, Entertainment, Hospital/Pharmacy, Police, Toilets, Post |
||
1711 | //shop : ['supermarket', 'bakery', 'car', 'stationery', 'hairdresser', 'mobile_phone', 'convenience', 'newsagent', 'kiosk', 'computer', 'clothes', 'variety_store', 'hearing_aids', 'florist', 'handicraft', 'candle', 'antique', 'pet', 'massage', 'electronics', 'laundry', 'doityourself', 'sports', 'jewelry', 'musical_instrument', 'chemist', 'shoes', 'beverages', 'toys', 'fishing', 'copyshop', 'beauty', 'bag', 'paint', 'bicycle', 'communication', 'furniture', 'alcohol', 'deli', 'optician', 'books', 'car_repair', 'butcher', 'outdoor', 'motorcycle', 'estate_agent', 'photo', 'gift', 'travel_agency', 'tea', 'wine', 'medical_supply', 'department_store', 'dry_cleaning', 'video', 'second_hand', 'greengrocer', 'erotic', 'curtain', 'haberdashery', 'garden_centre', 'art', 'fashion', 'bags', 'accessoires', 'confectionery', 'ice_cream', 'organic', 'music', 'boutique', 'interior', 'kitchen', 'vacant', 'tattoo', 'mall', 'camera', 'gallery', 'rc_models', 'coffee', 'bicycle_rental', 'photographer', 'ticket', 'charity', 'Shisha', 'hats', 'funeral_directors', 'locksmith', 'fabric', 'hardware', 'shoe_repair', 'hifi', 'fabrics', 'tailor', 'anime', 'market', 'grocery', 'no', 'surf', 'tobacco', 'animals', 'currency_exchange', 'souvenirs', 'internet-tele-cafe', 'photography', 'car_parts', 'antiques', 'bed', 'skating', 'ceramics', 'internet cafe', 'frame', 'brushes', 'fish', 'callshop', 'glass', 'comics', 'pottery', 'internet_cafe', 'stamps', 'radiotechnics', 'interior_decoration', 'carrental', 'interior_design', 'gramophone', 'Trödel', 'unused', 'watches', 'jewellery', 'tatoo', 'travelling', 'telecommunication', 'cigarettes', 'sports food', 'perfumery', 'unknown', 'orthopedics', 'fire_extinguisher', 'fishmonger', 'wholesale', 'lights', 'carpet', 'office_supplies', 'parquet', 'porcelain', 'lamps', 'make-up', 'art_gallery', 'telecom', 'underwear', 'watch', 'tableware', 'scuba_diving', 'christmas', 'tanning', 'craft', 'leather', 'for rent', 'glaziery', 'seafood', 'Sicherheitstechnik', 'coffee machines', 'alteration', 'decoration', 'sport_bet', 'seefood', 'mobile phone service', 'window_blind', 'tyres', 'cheese', 'medical', 'sewing-machine', 'Kaugummi-Automaten', 'Kaugummi-Automat', 'baby', 'games', 'piercing', 'Elektrohaushaltsgeräte', 'electrician', 'glasses', 'circus', 'food', 'marine', 'lottery', 'Hockey', 'electric', 'coins', 'metal workshop', 'nails', 'general', 'tanning_salon', 'crafts', 'household', 'floor', 'baby_goods', 'Patissier', 'delicatessen', 'telephone', 'Hema', 'soft_drugs', 'board_games', 'lingerie', 'candy', 'cd', 'stones', 'spiritual', 'health', 'juice', 'hemp_products', 'smartshop', 'cannabis', 'frozen_yoghurt', 'art_supplies', 'cigar', 'department', 'sok_shop', 'realestate', 'lighting', 'generic', 'nail', 'ink', 'traiteur', 'toko', 'key', 'gsm', 'artist', 'hearth', 'framing', 'espresso_machine', 'knives', 'rental', 'thrift_store', 'snacks', 'tobacconist', 'disused:butcher', 'party', 'audiologist', 'housewares', 'Fashion', 'printing', 'chandler', 'Shoes', 'Electronics', 'softdrugs', 'houseware', 'textiles', 'perfume'], |
||
1712 | //amenity : ["post_box", "police", "atm", "recycling", "parking", "fuel", "telephone", "school", "pub", "doctors", "arts_centre", "cafe", "fast_food", "restaurant", "place_of_worship", "bank", "bicycle_parking", "drinking_water", "theatre", "bar", "bench", "waste_disposal", "nightclub", "pharmacy", "bicycle_rental", "post_office", "charging_station", "waste_basket", "vending_machine", "kindergarten", "marketplace", "dentist", "ev_charging", "bureau_de_change", "library", "cinema", "toilets", "car_wash", "fountain", "boat_rental", "taxi", "bus_parking", "public_building", "driving_school", "physical therapy", "coffee_shop", "embassy", "vacant", "coffeeshop", "ice_cream", "car_rental", "swimming_pool", "university", "casino", "community_centre", "lost_found", "grit_bin", "clock", "parking_entrance", "sauna", "brothel", "ferry_terminal", "fitness_center", "bus_station", "college", "fire_station", "health_centre", "townhall", "hospital", "veterinary", "gym", "fablab", "money_transfer", "kitchen_studio", "tanning_salon", "tanning", "studio"], |
||
1713 | //tourism : ["artwork", "hostel", "attraction", "hotel", "information", "museum", "gallery", "viewpoint", "picnic_site", "guest_house", "theme_park", "apartment", "zoo", "camp_site", "chalet", "motel", "citytour", "aquarium"] |
||
1714 | } |
||
1715 | |||
1716 | mapSettings = { |
||
1717 | openTrackingSettings : function() { |
||
1718 | $.get(OC.generateUrl('/apps/maps/api/1.0/location/loadDevices'), function(d) { |
||
1719 | var tableHTML; |
||
1720 | $.each(d, function() { |
||
1721 | tableHTML += '<tr><td>' + this.name + '</td><td>' + this.hash + '</td><td><div class="icon-delete icon" data-deviceId="' + this.id + '"></div></td></tr>'; |
||
1722 | }); |
||
1723 | $('#trackingDevices tbody').html(tableHTML); |
||
1724 | }) |
||
1725 | $('#trackingSettingsPopup').dialog({ |
||
1726 | buttons : { |
||
1727 | "Close" : function() { |
||
1728 | $(this).dialog('destroy'); |
||
1729 | $('#addtracking')[0].reset() |
||
1730 | } |
||
1731 | } |
||
1732 | |||
1733 | }); |
||
1734 | }, |
||
1735 | saveDevice : function() { |
||
1736 | if ($('#addtracking input').val() == '') |
||
1737 | return |
||
1738 | var formData = { |
||
1739 | name : $('#addtracking input').val() |
||
1740 | }; |
||
1741 | $.post(OC.generateUrl('/apps/maps/api/1.0/location/adddevice'), formData, function(d) { |
||
1742 | $('#trackingDevices tbody').append('<tr><td>' + formData.name + '</td><td>' + d.hash + '</td><td><div class="icon-delete icon" data-deviceId="' + d.id + '"></div></td></tr>'); |
||
1743 | $('#addtracking input').val(''); |
||
1744 | }); |
||
1745 | }, |
||
1746 | |||
1747 | deleteDevice : function(e) { |
||
1748 | var dId = $(this).attr('data-deviceId'); |
||
1749 | $(this).parent().parent().remove(); |
||
1750 | ///api/1.0/location/removedevice |
||
1751 | var formData = { |
||
1752 | deviceId : dId |
||
1753 | }; |
||
1754 | $.post(OC.generateUrl('/apps/maps/api/1.0/location/removedevice'), formData); |
||
1755 | |||
1756 | } |
||
1757 | } |
||
1758 | |||
1759 | favorites = { |
||
1760 | favArray : [], |
||
1761 | add : function(){ |
||
1762 | var latlng = $(this).attr('data-latlng').split(','); |
||
1763 | var popup = document.getElementsByClassName('leaflet-popup-content')[0]; |
||
1764 | var favicon = popup.getElementsByTagName('div')[0]; |
||
1765 | var content = popup.getElementsByTagName('div')[1]; |
||
1766 | |||
1767 | var popupText = content.innerHTML; |
||
1768 | var orgTitle = content.getElementsByTagName('h2')[0].innerHTML; |
||
1769 | var titleLength = '<h2>' + orgTitle + '</h2>'.length; |
||
1770 | content.innerHTML = popupText.substring(titleLength); |
||
1771 | var formData = { |
||
1772 | lat : latlng[0], |
||
1773 | lng : latlng[1], |
||
1774 | name : orgTitle |
||
1775 | }; |
||
1776 | $.post(OC.generateUrl('/apps/maps/api/1.0/favorite/addToFavorites'), formData, function(data) { |
||
1777 | var markerHTML = '<h2>' + formData.name + '</h2>'; |
||
1778 | var marker = L.marker([formData.lat, formData.lng], { |
||
1779 | icon : favMarkerIcon, |
||
1780 | id : data.id |
||
1781 | }); |
||
1782 | map.removeLayer(currentMarker); |
||
1783 | currentMarker = null; |
||
1784 | toolKit.addMarker(marker, markerHTML, true, true); |
||
1785 | favorites.favArray.push(marker); |
||
1786 | }); |
||
1787 | }, |
||
1788 | show : function(){ |
||
1789 | $.post(OC.generateUrl('/apps/maps/api/1.0/favorite/getFavorites'), null, function(data){ |
||
1790 | for(var i=0; i<data.length; i++){ |
||
1791 | var fav = data[i]; |
||
1792 | |||
1793 | var markerHTML = '<h2>' + fav.name + '</h2>'; |
||
1794 | var marker = L.marker([fav.lat, fav.lng], { |
||
1795 | icon : favMarkerIcon, |
||
1796 | id : fav.id |
||
1797 | }); |
||
1798 | toolKit.addMarker(marker, markerHTML, false, true); |
||
1799 | favorites.favArray.push(marker); |
||
1800 | } |
||
1801 | }); |
||
1802 | }, |
||
1803 | hide : function(){ |
||
1804 | for(var i=0; i<favorites.favArray.length; i++){ |
||
1805 | map.removeLayer(favorites.favArray[i]); |
||
1806 | } |
||
1807 | favorites.favArray = []; |
||
1808 | }, |
||
1809 | remove : function(){ |
||
1810 | var id = $(this).attr('fav-id'); |
||
1811 | var formData = { |
||
1812 | id : id |
||
1813 | }; |
||
1814 | $.post(OC.generateUrl('/apps/maps/api/1.0/favorite/removeFromFavorites'), formData, function(data){ |
||
1815 | for(i=0; i<favorites.favArray.length; ++i) { |
||
1816 | if(favorites.favArray[i].options.id == id) { |
||
1817 | //TODO this code toggles the star icon and the add/remove methods. Should be used as soon as the marker replacement works |
||
1818 | var popup = document.getElementsByClassName('leaflet-popup-content')[0]; |
||
1819 | var favicon = popup.getElementsByTagName('div')[0]; |
||
1820 | var newClass = favicon.className.replace('icon-starred', 'icon-star'); |
||
1821 | favicon.className = newClass.replace('removeFromFav', 'addToFav'); |
||
1822 | var removedFav = favorites.favArray.splice(i,1)[0]; |
||
1823 | addGeocodeMarker(removedFav.getLatLng()); |
||
1824 | map.removeLayer(removedFav); |
||
1825 | return; |
||
1826 | } |
||
1827 | } |
||
1828 | }); |
||
1829 | }, |
||
1830 | edit : function() { |
||
1831 | var popup = document.getElementsByClassName('leaflet-popup-content')[0]; |
||
1832 | var favicon = popup.getElementsByTagName('div')[0]; |
||
1833 | var id = favicon.getAttributeNode('fav-id').value; |
||
1834 | var content = popup.getElementsByTagName('div')[1]; |
||
1835 | var titleNode = content.getElementsByTagName('h2')[0]; |
||
1836 | var title = titleNode.innerHTML; |
||
1837 | var button = content.getElementsByClassName('editFav')[0]; |
||
1838 | var input = document.createElement('input'); |
||
1839 | input.type = 'text'; |
||
1840 | input.value = title; |
||
1841 | titleNode.parentNode.replaceChild(input, titleNode); |
||
1842 | button.className = 'confirmFavEdit icon-checkmark'; |
||
1843 | $(document).on('click', '.confirmFavEdit', function() { |
||
1844 | button.className = 'icon-rename editFav'; |
||
1845 | if(title != input.value) title = input.value; |
||
1846 | titleNode.innerHTML = title; |
||
1847 | content.replaceChild(titleNode, input); |
||
1848 | var formData = { |
||
1849 | name : title, |
||
1850 | id : id |
||
1851 | }; |
||
1852 | $.post(OC.generateUrl('/apps/maps/api/1.0/favorite/updateFavorite'), formData, function(data){ |
||
1853 | }); |
||
1854 | $(document).off('click', '.confirmFavEdit'); |
||
1855 | }); |
||
1856 | } |
||
1857 | } |
||
1858 | |||
1859 | $(document).on('click', '#tracking-settings', mapSettings.openTrackingSettings); |
||
1860 | $(document).on('click', '#addtracking button', mapSettings.saveDevice); |
||
1861 | $(document).on('click', '#trackingDevices .icon-delete', mapSettings.deleteDevice); |
||
1862 | $(document).on('click', '.addToFav', favorites.add); |
||
1863 | $(document).on('click', '.removeFromFav', favorites.remove); |
||
1864 | $(document).on('click', '.editFav', favorites.edit) |
||
1865 | |||
1866 | /** |
||
1867 | * Extend the OC.Notification object with our own methods |
||
1868 | */ |
||
1869 | OC.Notification.showTimeout = function(text, timeout, isHTML) { |
||
1870 | isHTML = (!isHTML) ? false : true; |
||
1871 | OC.Notification.hide(); |
||
1872 | if (OC.Notification.notificationTimer) { |
||
1873 | clearTimeout(notificationTimer); |
||
1874 | } |
||
1875 | timeout = (!timeout) ? 3000 : timeout; |
||
1876 | if (isHTML) { |
||
1877 | OC.Notification.showHtml(text); |
||
1878 | } else { |
||
1879 | OC.Notification.show(text); |
||
1880 | } |
||
1881 | OC.Notification.notificationTimer = setTimeout(function() { |
||
1882 | OC.Notification.hide(); |
||
1883 | }, timeout); |
||
1884 | } |
||
1885 | })(jQuery, OC); |
||
1886 |
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.
Further Readings: