PageSourceSearch

https://www.sahara.it/wp-content/plugins/wp-gpx-maps/js/WP-GPX-Maps.js?ver=1.6.02

js sahara.it collected 2026-10-02 13:53:23 UTC 42,063 bytes, 1,507 lines download raw bytes

1/*
2Plugin Name: WP-GPX-Maps
3Plugin URI: http://www.devfarm.it/
4Description: Draws a gpx track with altitude graph
5Version: 1.6.02
6Author: Bastianon Massimo
7Author URI: http://www.devfarm.it/
8*/
9
10var WPGPXMAPS = {
11
12	Utils: {
13
14		// In case of multiple polylines this function divide the points of each polyline.
15		DividePolylinesPoints: function( mapData ) {
16
17			var lastCut = 0;
18
19			var result = [];
20
21			var _len = mapData.length;
22
23			for ( i = 0; i < _len; i++ ) {
24				if ( mapData[i] == null ) {
25					result.push( mapData.slice( lastCut == 0 ? 0 : lastCut + 1, i ) );
26					lastCut = i;
27				}
28			}
29
30			if ( ( _len - 1 ) != lastCut ) {
31				result.push( mapData.slice( lastCut ) );
32			}
33
34			return result;
35
36		},
37
38		GetItemFromArray: function( arr, index ) {
39			try {
40				return arr[index];
41			} catch ( e ) {
42				return [ 0, 0 ];
43			}
44		},
45
46
47	},
48
49	MapEngines: {
50
51		/* NOT WORKING AND TESTED! old code copy&pate */
52		GoogleMaps: function() {
53			this.map = null,
54			this.EventSelectChart = null,
55			this.Polylines = [],
56			this.init = function( targetElement, mapType, scrollWheelZoom, ThunderforestApiKey ) {
57
58				var mapTypeIds = [];
59				for ( var type in google.maps.MapTypeId ) {
60					mapTypeIds.push( google.maps.MapTypeId[type] );
61				}
62				mapTypeIds.push( 'OSM1' );
63				mapTypeIds.push( 'OSM2' );
64				mapTypeIds.push( 'OSM3' );
65				mapTypeIds.push( 'OSM4' );
66				mapTypeIds.push( 'OSM5' );
67				mapTypeIds.push( 'OSM6' );
68
69				var ngImageMarkers = [];
70
71				switch ( mapType ) {
72					case 'TERRAIN': { mapType = google.maps.MapTypeId.TERRAIN; break;}
73					case 'SATELLITE': { mapType = google.maps.MapTypeId.SATELLITE; break;}
74					case 'ROADMAP': { mapType = google.maps.MapTypeId.ROADMAP; break;}
75					case 'OSM1': { mapType = 'OSM1'; break;}
76					case 'OSM2': { mapType = 'OSM2'; break;}
77					case 'OSM3': { mapType = 'OSM3'; break;}
78					case 'OSM4': { mapType = 'OSM4'; break;}
79					case 'OSM5': { mapType = 'OSM5'; break;}
80					case 'OSM6': { mapType = 'OSM6'; break;}
81					default: { mapType = google.maps.MapTypeId.HYBRID; break;}
82				}
83
84				if ( mapType == 'TERRAIN' || mapType == 'SATELLITE' || mapType == 'ROADMAP' ) {
85
86					// google maps
87				} else {
88
89					// Show OpenStreetMaps credits
90					$( el_osm_credits ).show();
91				}
92
93				this.map = new google.maps.Map( el_map, {
94					mapTypeId: mapType,
95					scrollwheel: ( zoomOnScrollWheel == 'true' ),
96					mapTypeControlOptions: {
97						style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
98						mapTypeIds: mapTypeIds
99					}
100				});
101
102
103				this.map.mapTypes.set( 'OSM1', new google.maps.ImageMapType({
104					getTileUrl: function( coord, zoom ) {
105						return "https://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + '.png';
106					},
107					tileSize: new google.maps.Size( 256, 256 ),
108					name: 'OSM',
109					alt: 'Open Street Map',
110					maxZoom: 18
111				}) );
112
113
114				this.map.mapTypes.set( 'OSM2', new google.maps.ImageMapType({
115					getTileUrl: function( coord, zoom ) {
116						if ( hasThunderforestApiKey ) {
117							return "https://a.tile.thunderforest.com/cycle/" + zoom + "/" + coord.x + "/" + coord.y + ".png?apikey=" + ThunderforestApiKey;
118						} else {
119							return "http://a.tile.opencyclemap.org/cycle/" + zoom + "/" + coord.x + "/" + coord.y + '.png';
120						}
121					},
122					tileSize: new google.maps.Size( 256, 256 ),
123					name: 'OCM',
124					alt: 'Open Cycle Map',
125					maxZoom: 18
126				}));
127
128				this.map.mapTypes.set( 'OSM4', new google.maps.ImageMapType({
129					getTileUrl: function( coord, zoom ) {
130						if ( hasThunderforestApiKey ) {
131							return "https://a.tile.thunderforest.com/transport/" + zoom + "/" + coord.x + "/" + coord.y + ".png?apikey=" + ThunderforestApiKey;
132						} else {
133							return "http://a.tile2.opencyclemap.org/transport/" + zoom + "/" + coord.x + "/" + coord.y + '.png';
134						}
135					},
136					tileSize: new google.maps.Size(256, 256),
137					name: 'OCM-Tran',
138					alt: 'Open Cycle Map - Transport',
139					maxZoom: 18
140				}) );
141
142				this.map.mapTypes.set( 'OSM5', new google.maps.ImageMapType({
143					getTileUrl: function( coord, zoom ) {
144						if ( hasThunderforestApiKey ) {
145							return "https://a.tile.thunderforest.com/landscape/" + zoom + "/" 
145+ coord.x + "/" + coord.y + ".png?apikey=" + ThunderforestApiKey;
146						} else {
147							return "http://a.tile3.opencyclemap.org/landscape/" + zoom + "/" + coord.x + "/" + coord.y + '.png';
148						}
149					},
150					tileSize: new google.maps.Size( 256, 256 ),
151					name: 'OCM-Land',
152					alt: 'Open Cycle Map - Landscape',
153					maxZoom: 18
154				}) );
155
156				this.map.mapTypes.set( 'OSM6', new google.maps.ImageMapType({
157					getTileUrl: function( coord, zoom ) {
158						return "https://tile2.maptoolkit.net/terrain/" + zoom + "/" + coord.x + "/" + coord.y + '.png';
159					},
160					tileSize: new google.maps.Size( 256, 256 ),
161					name: 'MTK-Terr',
162					alt: 'MapToolKit - Terrain',
163					maxZoom: 18
164				}) );
165			},
166
167			this.AppPolylines = function( mapData, color1, currentIcon, startIcon, endIcon ) {
168
169				var points = [];
170				var lastCut = 0;
171				var polylinenes = [];
172				var polyline_number = 0;
173				var color = 0;
174				for ( i = 0; i < mapData.length; i++ ) {
175					if (mapData[i] == null) {
176
177						var poly = new google.maps.Polyline({
178							path: points.slice(lastCut,i),
179							strokeColor: color,
180							strokeOpacity: .7,
181							strokeWeight: 4,
182							map: this.map
183						});
184						polylinenes.push( poly );
185						lastCut = i;
186						polyline_number = polyline_number +1;
187
188						//var p = new google.maps.LatLng(mapData[i-1][0], mapData[i-1][1]);
189						//points.push(p);
190						//bounds.extend(p);
191					} else {
192						var p = new google.maps.LatLng( mapData[i][0], mapData[i][1]);
193						points.push( p );
194						bounds.extend( p );
195					}
196				}
197
198				if ( points.length != lastCut ) {
199					if ( polyline_number < color1.length ) {
200						color = color1[polyline_number];
201					} else {
202						color = color1[color1.length - 1];
203					}
204					var poly = new google.maps.Polyline({
205						path: points.slice( lastCut ),
206						strokeColor: color,
207						strokeOpacity: .7,
208						strokeWeight: 4,
209						map: this.map
210					});
211
212					polylinenes.push( poly );
213					currentPoints = [];
214					polyline_number = polyline_number + 1;
215				}
216
217				if ( startIcon != '' ) {
218					var startIconImage = new google.maps.MarkerImage( startIcon );
219					var startMarker = new google.maps.Marker({
220							  position: points[0],
221							  map: this.map,
222							  title: "Start",
223							  animation: google.maps.Animation.DROP,
224							  icon: startIconImage,
225							  zIndex: 10
226						  });
227
228				}
229
230				if ( endIcon != '' ) {
231					var endIconImage = new google.maps.MarkerImage( endIcon );
232					var startMarker = new google.maps.Marker({
233							  position: points[ points.length -1 ],
234							  map: this.map,
235							  title: "Start",
236							  animation: google.maps.Animation.DROP,
237							  icon: endIconImage,
238							  zIndex: 10
239						  });
240
241				}
242
243				var first = WPGPXMAPS.Utils.GetItemFromArray( mapData, 0 )
244
245				if ( currentIcon == '' ) {
246					currentIcon = "https://maps.google.com/mapfiles/kml/pal4/icon25.png";
247				}
248
249				var current = new google.maps.MarkerImage(currentIcon,
250					new google.maps.Size( 32, 32 ),
251					new google.maps.Point( 0 ,0 ),
252					new google.maps.Point( 16, 16 )
253				);
254
255				var marker = new google.maps.Marker({
256					position: new google.maps.LatLng( first[0], first[1] ),
257					title:"Start",
258					icon: current,
259					map: this.map,
260					zIndex: 10
261				});
262
263				for ( i = 0; i < polylinenes.length; i++ ) {
264
265					google.maps.event.addListener( polylinenes[i], 'mouseover', function( event ) {
266						if ( marker ) {
267							marker.setPosition( event.latLng );
268							marker.setTitle( lng.currentPosition );
269							if ( myChart ) {
270								var l1 = event.latLng.lat();
271								var l2 = event.latLng.lng();
272								var ci = getClosestIndex(mapData,l1,l2);
273								var activeElements = [];
274								var seriesLen = myChart.data.datasets.length;
275								for ( var i = 0; i<seriesLen;i++ ) {
276									activeElements.push( myChart.chart.getDatasetMeta( i ).data[ci] );
277								}
278								if ( activeElements.length > 0) {
279									myChart.options.customLine.x = activeElements[0]._model.x;
280									if ( isNaN( myChart.tooltip._eventPosition ) ) {
281										myChart.tooltip._eventPosition = {
282												x: activeElements[0]._model.x,
283												y: activeElements[0]._model.y
284											};
285									}
286									myChart.tooltip._active = activeElements;
287									myChart.tooltip.update ( true );
288									myChart.draw();
289								}
290
291							}
292						}
293					});
294				}
295
296
297			},
298			this.AddWaypoints = function( waypoints, waypointIcon ) {
299
300			},
301			this.MoveMarkerToPosition = function( LatLon, updateChart ) {
302
303			}
304		},
305
306		Leaflet: function() {
307			this.Bounds = [],
308			this.lng = {},
309			this.map = null,
310			this.EventSelectChart = null,
311			this.Polylines = [],
312			this.CurrentPositionMarker = null,
313			this.CurrentGPSPositionMarker = null,
314			this.init = function( targetElement, mapType, scrollWheelZoom, ThunderforestApiKey ) {
315
316				this.map = L.map( targetElement,
317					{
318						scrollWheelZoom : scrollWheelZoom,
319					}
320				);
321
322				// create fullscreen control
323				var fsControl = new L.Control.FullScreen();
324
325				// add fullscreen control to the map
326				this.map.addControl( fsControl );
327
328				L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
329					attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
330				}).addTo( this.map );
331
332				var hasThunderforestApiKey = ( ThunderforestApiKey + '' ).length > 0;
333
334				var baseMaps = {};
335
336				var overlayMaps = { };
337
338				var defaultMpaLayer = null;
339
340				if ( hasThunderforestApiKey ) {
341					baseMaps['Open Cycle Map'] = L.tileLayer( 'https://a.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=' + ThunderforestApiKey, {
342						maxZoom: 18,
343						attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
344							'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
345							'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
346					});
347
348					baseMaps['Open Cycle Map - Transport'] = L.tileLayer( 'https://a.tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=' + ThunderforestApiKey, {
349						maxZoom: 18,
350						attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
351							'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
352							'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
353					});
354
355					baseMaps['Open Cycle Map - Landscape'] = L.tileLayer( 'https://a.tile.thunderforest.com/landscape/{z}/{x}/{y}.png?apikey=' + ThunderforestApiKey, {
356						maxZoom: 18,
357						attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
358							'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
359							'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
360						});
361
362				} else {
363
364					baseMaps['Open Cycle Map'] = L.tileLayer( 'http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
365						maxZoom: 18,
366						attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
367							'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
368							'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
369					});
370
371					baseMaps['Open Cycle Map - Transport'] = L.tileLayer( 'https://a.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png', {
372						maxZoom: 18,
373						attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
374							'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
375							'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
376					});
377
378					baseMaps['Open Cycle Map - Landscape'] = L.tileLayer( 'https://a.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png', {
379						maxZoom: 18,
380						attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
381							'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
382							'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
383					});
384
385				}
386
387				baseMaps['Open Street Map'] = L.tileLayer( 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
388					maxZoom: 18,
389					attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
390						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
391						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
392				});
393
394
395				baseMaps['MapToolKit - Terrain'] = L.tileLayer( 'https://tile2.maptoolkit.net/terrain/{z}/{x}/{y}.png', {
396					maxZoom: 18,
397					attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
398						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
399						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
400				});
401
402				baseMaps['Humanitarian Map Style'] = L.tileLayer( 'https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
403					maxZoom: 18,
404					attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
405						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
406						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
407				});
408				/*
409				baseMaps['Open Ski Map'] = L.tileLayer( 'http://tiles.skimap.org/openskimap/{z}/{x}/{y}.png', {
410					maxZoom: 18,
411					attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
412						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
413						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
414				});
415				*/
416
417				baseMaps['Hike & Bike'] = L.tileLayer( 'http://toolserver.org/tiles/hikebike/{z}/{x}/{y}.png', {
418					maxZoom: 18,
419					attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
420						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
421						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
422				});
423
424				baseMaps['Open Sea Map'] = L.tileLayer( 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', {
425					maxZoom: 18,
426					attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
427						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
428						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
429				});
430
431
432				switch ( mapType ) {
433					case 'OSM1': {
434						baseMaps['Open Street Map'].addTo( this.map );
435						break;
436					}
437					case 'OSM2': {
438						baseMaps['Open Cycle Map'].addTo( this.map );
439						break;
440					}
441					case 'OSM4': {
442						baseMaps['Open Cycle Map - Transport'].addTo( this.map );
443						break;
444					}
445					case 'OSM5': {
446						baseMaps['Open Cycle Map - Landscape'].addTo( this.map );
447						break;
448					}
449					case 'OSM6': {
450						baseMaps['MapToolKit - Terrain'].addTo( this.map );
451						break;
452					}
453					case 'OSM7': {
454						baseMaps['Humanitarian Map Style'].addTo( this.map );
455						break;
456					}
457					case 'OSM8': {
458						baseMaps['Open Ski Map'].addTo( this.map );
459						break;
460					}
461					case 'OSM9': {
462						baseMaps['Hike & Bike'].addTo( this.map );
463						break;
464					}
465					case 'OSM10': {
466						baseMaps['Open Sea Map'].addTo( this.map );
467						break;
468					}
469
470					default: {
471						baseMaps['Open Street Map'].addTo( this.map );
472					}
473				}
474
475				L.control.layers( baseMaps, overlayMaps ).addTo( this.map );
476
477			},
478
479			this.AppPolylines = function( mapData, color1, currentIcon, startIcon, endIcon ) {
480
481				var first = WPGPXMAPS.Utils.GetItemFromArray( mapData, 0 );
482
483				if ( currentIcon == '' ) {
484					currentIcon = "https://maps.google.com/mapfiles/kml/pal4/icon25.png";
485				}
486
487				var CurrentPositionMarker = L.marker( first, { icon: L.icon ({
488					iconUrl: currentIcon,
489					iconSize:     [32, 32], // size of the icon
490					iconAnchor:   [16, 16], // point of the icon which will correspond to marker's location
491				})
492				});
493				CurrentPositionMarker.addTo( this.map );
494				CurrentPositionMarker.title = 'Start';
495
496				this.CurrentPositionMarker = CurrentPositionMarker;
497
498				var pointsArray = WPGPXMAPS.Utils.DividePolylinesPoints( mapData );
499
500				var lng = this.lng;
501				var EventSelectChart = this.EventSelectChart;
502
503				this.Bounds = mapData;
504
505				this.CenterMap();
506
507				for ( i = 0; i < pointsArray.length; i++ ) {
508
509					if ( i < color1.length ) {
510						color = color1[i];
511					} else {
512						color = color1[color1.length - 1];
513					}
514					try {
515						var polyline = L.polyline( pointsArray[i], {color: color} ).addTo( this.map );
516						this.Polylines.push( polyline );
517
518						var context = this;
519
520						this.Polylines[i].on('mousemove', function( e ) {
521							context.MoveMarkerToPosition( [e.latlng.lat, e.latlng.lng], true );
522						});
523					} catch ( err ) {
524					}
525
526				}
527
528				if ( startIcon != '' ) {
529
530					var startMarker = L.marker( mapData[0], {icon: L.icon( {
531						iconUrl: startIcon,
532						iconSize:     [32, 32], // size of the icon
533						iconAnchor:   [16, 16], // point of the icon which will correspond to marker's location
534					})
535					});
536					startMarker.addTo( this.map );
537					startMarker.title = 'Start';
538
539
540				}
541
542				if ( endIcon != '' ) {
543
544					var endMarker = L.marker( mapData[ mapData.length - 1 ], {icon: L.icon( {
545						iconUrl: endIcon,
546						iconSize:     [32, 32], // size of the icon
547						iconAnchor:   [16, 16], // point of the icon which will correspond to marker's location
548					})
549					});
550					endMarker.addTo( this.map );
551					endMarker.title = 'End';
552
553				}
554
555
556	/*
557				var current = new google.maps.MarkerImage(currentIcon,
558					new google.maps.Size(32, 32),
559					new google.maps.Point(0,0),
560					new google.maps.Point(16, 16)
561				);
562
563				var marker = new google.maps.Marker({
564					position: new google.maps.LatLng(first[0], first[1]),
565					title:"Start",
566					icon: current,
567					map: map,
568					zIndex: 10
569				});
570
571				for (i=0; i < polylinenes.length; i++)
572				{
573
574					google.maps.event.addListener(polylinenes[i],'mouseover',function(event){
575						if (marker)
576						{
577							marker.setPosition(event.latLng);
578							marker.setTitle(lng.currentPosition);
579							if (myChart)
580							{
581								var l1 = event.latLng.lat();
582								var l2 = event.latLng.lng();
583								var ci = getClosestIndex(mapData,l1,l2);
584								var activeElements = [];
585								var seriesLen = myChart.data.datasets.length;
586								for(var i=0; i<seriesLen;i++)
587								{
588									activeElements.push(myChart.chart.getDatasetMeta(i).data[ci]);
589								}
590								if (activeElements.length > 0)
591								{
592									myChart.options.customLine.x = activeElements[0]._model.x;
593									if (isNaN(myChart.tooltip._eventPosition))
594									{
595										myChart.tooltip._eventPosition = {
596												x: activeElements[0]._model.x,
597												y: activeElements[0]._model.y
598											};
599									}
600									myChart.tooltip._active = activeElements;
601									myChart.tooltip.update(true);
602									myChart.draw();
603								}
604
605							}
606						}
607					});
608				}
609
610		*/
611
612			},
613
614			this.AddWaypoints = function( waypoints, waypointIcon ) {
615
616				var icon = L.icon({
617					iconUrl: 'https://maps.google.com/mapfiles/ms/micons/flag.png',
618					iconSize:     [32, 32], // size of the icon
619					iconAnchor:   [16, 16], // point of the icon which will correspond to marker's location
620				});
621
622				if ( waypointIcon!='' ) {
623					icon = L.icon({
624						iconUrl: 'waypointIcon',
625						iconSize:     [32, 32], // size of the icon
626						iconAnchor:   [16, 16], // point of the icon which will correspond to marker's location
627					});
628				}
629
630				for ( i = 0; i < waypoints.length; i++ ) {
631					var wpt = waypoints[i];
632
633					this.Bounds.push( [wpt.lat,wpt.lon] );
634
635					var lat= wpt.lat;
636					var lon= wpt.lon;
637					var sym= wpt.sym;
638					var typ= wpt.type;
639
640					if ( icon.img ) {
641						icon.iconUrl = wpt.img;
642						wsh = '';
643					}
644
645					var marker = L.marker( [lat, lon], {icon: icon } );
646
647					var cnt = '';
648
649					if ( wpt.name=='' ) {
650						cnt = "<div>" + unescape( wpt.desc ) + "</div>";
651					} else {
652						cnt = "<div><b>" + wpt.name + "</b><br />" + unescape( wpt.desc ) + "</div>";
653					}
654
655					cnt += "<br /><p><a href='https://maps.google.com?daddr=" + lat + "," + lon + "' target='_blank'>Itin&eacute;raire</a></p>";
656
657					marker.addTo( this.map ).bindPopup( cnt );
658
659				}
660
661				this.CenterMap();
662
663			},
664
665			this.MoveMarkerToPosition = function( LatLon, updateChart ) {
666				if ( this.CurrentPositionMarker == null )
667					return;
668
669				this.CurrentPositionMarker.setLatLng( LatLon );
670
671				if ( this.lng )
672					this.CurrentPositionMarker.title = this.lng.currentPosition;
673
674				if ( updateChart == true && this.EventSelectChart )
675					this.EventSelectChart( LatLon );
676
677			},
678			this.CenterMap = function() {
679				this.map.fitBounds( this.Bounds );
680			};
681
682		}
683
684	}
685
686};
687
688(function( $ ) {
689
690    $.fn.wpgpxmaps = function( params ) {
691
692		var targetId = params.targetId;
693		var mapType = params.mapType;
694		var mapData = params.mapData;
695		var graphDist = params.graphDist;
696		var graphEle = params.graphEle;
697		var graphSpeed = params.graphSpeed;
698		var graphHr = params.graphHr;
699		var graphAtemp = params.graphAtemp;
700		var graphCad = params.graphCad;
701		var graphGrade = params.graphGrade;
702		var waypoints = params.waypoints;
703		var unit = params.unit;
704		var unitspeed = params.unitspeed;
705		var color1 = params.color1;
706		var color2 = params.color2;
707		var color3 = params.color3;
708		var color4 = params.color4;
709		var color5 = params.color5;
710		var color6 = params.color6;
711		var color7 = params.color7;
712		var chartFrom1 = params.chartFrom1;
713		var chartTo1 = params.chartTo1;
714		var chartFrom2 = params.chartFrom2;
715		var chartTo2 = params.chartTo2;
716		var startIcon = params.startIcon;
717		var waypointIcon = params.waypointIcon;
718		var endIcon = params.endIcon;
719		var currentIcon = params.currentIcon;
720		var zoomOnScrollWheel = params.zoomOnScrollWheel;
721		var lng = params.langs;
722		var pluginUrl = params.pluginUrl;
723		var usegpsposition = params.usegpsposition;
724		var currentpositioncon = params.currentpositioncon;
725		var ThunderforestApiKey = params.TFApiKey;
726
727		var hasThunderforestApiKey = ( ThunderforestApiKey + '' ).length > 0;
728
729		var _formats = [];
730
731		// Unit of measure settings
732		var l_s;
733		var l_x;
734		var l_y;
735		var l_grade = { suf : "%", dec : 1 };
736		var l_hr = { suf : "", dec : 0 };
737		var l_cad = { suf : "", dec : 0 };
738
739		var el = document.getElementById('wpgpxmaps_' + targetId);
740		var el_map = document.getElementById('map_' + targetId);
741		var el_chart = document.getElementById('chart_' + targetId);
742		var el_report = document.getElementById('report_' + targetId);
743		var el_osm_credits = document.getElementById('wpgpxmaps_' + targetId + '_osm_footer');
744
745		var mapWidth = el_map.style.width;
746
747		var map = new WPGPXMAPS.MapEngines.Leaflet();
748		map.lng = lng;
749		map.init( 'map_' + targetId,
750						mapType,
751						( zoomOnScrollWheel == 'true' ),
752						ThunderforestApiKey);
753
754		map.EventSelectChart = function( LatLon ) {
755
756			if ( myChart ) {
757				var l1 = LatLon[0];
758				var l2 = LatLon[1];
759				var ci = getClosestIndex( mapData, l1, l2 );
760				var activeElements = [];
761				var seriesLen = myChart.data.datasets.length;
762				for ( var i = 0; i < seriesLen;i++ ) {
763					activeElements.push( myChart.chart.getDatasetMeta( i ).data[ci]);
764				}
765				if ( activeElements.length > 0 ) {
766					myChart.options.customLine.x = activeElements[0]._model.x;
767					if ( isNaN( myChart.tooltip._eventPosition ) ) {
768						myChart.tooltip._eventPosition = {
769								x: activeElements[0]._model.x,
770								y: activeElements[0]._model.y
771							};
772					}
773					myChart.tooltip._active = activeElements;
774					myChart.tooltip.update( true );
775					myChart.draw();
776				}
777
778			}
779		}
780
781		//var bounds = new google.maps.LatLngBounds();
782
783
784		if ( usegpsposition == 'true'  ) {
785
786			// Try HTML5 geolocation
787			if ( navigator.geolocation ) {
788
789				var context = map;
790
791				navigator.geolocation.watchPosition( function( position ) {
792
793					var radius = position.coords.accuracy / 2;
794
795					// user position
796					var pos = [ position.coords.latitude, position.coords.longitude ];
797
798					if ( context.CurrentGPSPositionMarker == null ) {
799						if ( currentpositioncon == '' ) {
800							currentpositioncon = "https://maps.google.com/mapfiles/kml/pal4/icon25.png";
801						}
802
803						context.CurrentGPSPositionMarker = L.marker(pos, {icon: L.icon({
804							iconUrl: currentpositioncon,
805							iconSize: [ 32, 32 ], // size of the icon
806							iconAnchor: [ 16, 16 ] // point of the icon which will correspond to marker's location
807						})
808						})
809						.addTo( context.map )
810						.bindPopup( lng.currentPosition )
811						.openPopup();
812
813					} else {
814						context.CurrentGPSPositionMarker.setLatLng( pos );
815					}
816
817					context.Bounds.push( pos );
818
819					context.CenterMap();
820
821				},
822				function( e ) {
823
824					// some errors
825				},
826				{
827				enableHighAccuracy: false,
828				timeout: 5000,
829				maximumAge: 0
830				});
831			}
832
833		}
834
835
836		// Print WayPoints
837		if ( ! jQuery.isEmptyObject( waypoints ) && waypoints.length > 0 ) {
838			map.AddWaypoints( waypoints, waypointIcon );
839		}
840
841		// Print Images
842
843		jQuery("#ngimages_" + targetId).attr("style","display:block;position:absolute;left:-50000px");
844
845		var nggImages = jQuery("#ngimages_" + targetId + " span").toArray();
846
847		if (nggImages !== undefined && nggImages.length > 0)
848		{
849			var photos = [];
850
851			for (var i = 0; i < nggImages.length; i++) {
852
853				var ngg_span = nggImages[i];
854				var ngg_span_a = ngg_span.children[0];
855
856				var pos = [
857							Number(ngg_span.getAttribute("lat")),
858							Number(ngg_span.getAttribute("lon"))
859							];
860
861				map.Bounds.push(pos);
862
863				photos.push({
864							  "lat": pos[0],
865							  "lng": pos[1],
866							  "name": ngg_span_a.getAttribute("data-title"),
867							  "url": ngg_span_a.getAttribute("data-src"),
868							  "thumbnail": ngg_span_a.getAttribute("data-thumbnail")
869							});
870
871			}
872
873			if (photos.length > 0)
874			{
875				var photoLayer = L.photo.cluster().on('click', function(evt) {
876					  var photo = evt.layer.photo;
877					  var template = '<img src="{url}" /></a><p>{name}</p>';
878					  evt.layer.bindPopup(L.Util.template(template, photo), {
879							minWidth: 'auto',
880					  }).openPopup();
881				});
882
883				photoLayer.add(photos).addTo(map.map);
884
885				map.CenterMap();
886
887
888				/*
889				var showHideImagesCustomControl = L.Control.extend({
890
891					options: {
892						position: 'topleft'
893						//control position - allowed: 'topleft', 'topright', 'bottomleft', 'bottomright'
894					},
895
896				  onAdd: function (map) {
897
898					var container = document.createElement('img');
899					container.class= "leaflet-bar leaflet-control leaflet-control-custom"
900					container.style.backgroundColor = 'white';
901					container.style.width = '30px';
902					container.style.height = '30px';
903					container.src = pluginUrl + "/wp-gpx-maps/img/hideImages.png";
904					container.style.cursor = 'pointer';
905					container.title = lng.hideImages;
906
907					container.onclick = function(){
908
909						var isImagesHidden = (controlUIhi.isImagesHidden == true);
910						var mapDiv = map.getDiv();
911						var center = map.getCenter();
912
913						if (isImagesHidden)
914						{
915							for (var i=0; i<ngImageMarkers.length; i++) {
916								ngImageMarkers[i].setMap(map);
917							}
918							controlUIhi.src = pluginUrl + "/wp-gpx-maps/img/hideImages.png";
919							controlUIhi.title = lng.hideImages;
920						}
921						else
922						{
923							for (var i=0; i<ngImageMarkers.length; i++) {
924								ngImageMarkers[i].setMap(null);
925							}
926							controlUIhi.src = pluginUrl + "/wp-gpx-maps/img/showImages.png";
927							controlUIhi.title = lng.showImages;
928						}
929						controlUIhi.isImagesHidden = !isImagesHidden;
930						return false;
931
932					}
933
934					return container;
935				  },
936
937				});
938
939				map.map.addControl(new showHideImagesCustomControl());
940				*/
941
942			}
943
944		}
945
946		/*
947
948		// Nextgen Pro Lightbox FIX
949		var _xx = jQuery("#ngimages_" + targetId + " .nextgen_pro_lightbox");
950		if (_xx.length > 0)
951		{
952
953			var rnd1 = Math.random().toString(36).substring(7);
954			var rnd2 = Math.random().toString(36).substring(7);
955
956			//get first gallery without images
957			for (var _temp in galleries) {
958				var _gal = galleries[_temp];
959
960				if (_gal.source == "random_images" && _gal.wpgpxmaps != true )
961				{
962
963					_gal.source == "galleries";
964					_gal.wpgpxmaps = true;
965					_transient_id = _temp.replace("gallery_","")
966					_gal["entity_ids"] = [];
967					_gal["image_ids"] = [];
968					_gal["gallery_ids"] = [96];
969					for (var i=0;i<_xx.length;i++)
970					{
971						var __xx = jQuery(_xx[i]);
972						__xx.attr("data-nplmodal-gallery-id", _transient_id);
973						_gal["image_ids"].push(__xx.attr("data-image-id"));
974					}
975					break;
976				}
977			}
978		}
979		*/
980
981
982		// Print Track
983		if (mapData != '')
984		{
985			map.AppPolylines(mapData, color1, currentIcon, startIcon, endIcon);
986		}
987
988		/*
989		map.setCenter(bounds.getCenter());
990		map.fitBounds(bounds);
991		*/
992
993		// FIX post tabs
994		var $_tab = $(el).closest(".wordpress-post-tabs, .tab-pane").eq(0);
995		if ($_tab)
996		{
997			var contextMap = map;
998
999			var FixMapSize = function(e)
1000			{
1001				setTimeout(function(e){
1002					//google.maps.event.trigger(map, 'resize');
1003					contextMap.map.invalidateSize();
1004					contextMap.CenterMap();
1005					tabResized = true;
1006				}, 300);
1007			}
1008
1009			$(".wpsm_nav-tabs a").click(FixMapSize);
1010
1011			$("div > ul > li > a", $_tab).click(FixMapSize);
1012		}
1013
1014
1015		var graphh = jQuery('#myChart_' + params.targetId).css("height");
1016
1017		if (graphDist != '' && (graphEle != '' || graphSpeed != '' || graphHr != '' || graphAtemp != '' || graphCad != '') && graphh != "0px")
1018		{
1019
1020			var valLen = graphDist.length;
1021
1022
1023			if (unit=="1")
1024			{
1025				l_x = { suf : "mi", dec : 1 };
1026				l_y = { suf : "ft", dec : 0 };
1027			}
1028			else if (unit=="2")
1029			{
1030				l_x = { suf : "km", dec : 1 };
1031				l_y = { suf : "m", dec : 0 };
1032			}
1033			else if (unit=="3")
1034			{
1035				l_x = { suf : "NM", dec : 1 };
1036				l_y = { suf : "m", dec : 0 };
1037			}
1038			else if (unit=="4")
1039			{
1040				l_x = { suf : "mi", dec : 1 };
1041				l_y = { suf : "m", dec : 0 };
1042			}
1043			else if (unit=="5")
1044			{
1045				l_x = { suf : "NM", dec : 1 };
1046				l_y = { suf : "ft", dec : 0 };
1047			}
1048			else
1049			{
1050				l_x = { suf : "m", dec : 0 };
1051				l_y = { suf : "m", dec : 0 };
1052			}
1053
1054			var nn = 1111.1;
1055			var _nn = nn.toLocaleString();
1056			var _nnLen = _nn.length;
1057			var decPoint = _nn.substring(_nnLen - 2, _nnLen - 1);
1058			var thousandsSep = _nn.substring(1, 2);
1059
1060			if (decPoint == "1")
1061				decPoint = ".";
1062
1063			if (thousandsSep == "1")
1064				thousandsSep = "";
1065
1066			// define the options
1067			var hoptions = {
1068				type: 'line',
1069				data: {
1070					datasets: [],
1071				},
1072				borderWidth: 1,
1073				options: {
1074					animation: {
1075						//duration: 0, // general animation time
1076					},
1077					hover: {
1078						//animationDuration: 0, // duration of animations when hovering an item
1079					},
1080					//responsiveAnimationDuration: 0, // animation duration after a resize
1081					customLine: {
1082						color: 'gray'
1083					},
1084					scales: {
1085						yAxes: [],
1086			            xAxes: [{
1087			                type: 'linear',
1088							ticks: {
1089								suggestedMin: 0,
1090								max: graphDist[graphDist.length-1],
1091								// Include a dollar sign in the ticks
1092								callback: function(value, index, values) {
1093									return Math.round(value, l_x.dec) + l_x.suf;
1094								}
1095							}
1096			            }]
1097					},
1098					tooltips: {
1099						position: 'average',
1100						mode: 'index',
1101						intersect: false,
1102						callbacks : {
1103							title: function(tooltipItems, data) {
1104								//Return value for title
1105								var fpt = _formats[0];
1106								return Math.round(tooltipItems[0].xLabel, fpt.dec) + fpt.suf;;
1107							},
1108							label : function(tooltipItem, data) {
1109								// format list values
1110								var label = data.datasets[tooltipItem.datasetIndex].label || '';
1111								var fpt = _formats[tooltipItem.datasetIndex];
1112								if (label) {
1113									label += ': ';
1114								}
1115								label += Math.round(tooltipItem.yLabel, fpt.dec) + fpt.suf;
1116								return label;
1117							},
1118							footer : function(tooltipItem){
1119								// move the point in map
1120								var i = tooltipItem[0].index;
1121								var point = WPGPXMAPS.Utils.GetItemFromArray(mapData,i)
1122								map.MoveMarkerToPosition(point, false);
1123
1124							}
1125						}
1126					},
1127				},
1128
1129				plugins: [{
1130					beforeEvent: function(chart, e) {
1131						if ((e.type === 'mousemove')
1132						&& (e.x >= e.chart.chartArea.left)
1133						&& (e.x <= e.chart.chartArea.right)
1134						) {
1135							chart.options.customLine.x = e.x;
1136						}
1137					},
1138					afterDraw: function(chart, easing) {
1139						var ctx = chart.chart.ctx;
1140						var chartArea = chart.chartArea;
1141						var x = chart.options.customLine.x;
1142						if (!isNaN(x)) {
1143							ctx.save();
1144							ctx.strokeStyle = chart.options.customLine.color;
1145							ctx.moveTo(chart.options.customLine.x, chartArea.bottom);
1146							ctx.lineTo(chart.options.customLine.x, chartArea.top);
1147							ctx.stroke();
1148							ctx.restore();
1149						}
1150					}
1151				}],
1152
1153				labels : graphDist,
1154
1155			};
1156
1157			if (graphEle != '')
1158			{
1159
1160				var myData = mergeArrayForChart(graphDist, graphEle);
1161
1162				var yaxe = {
1163					type: 'linear',
1164					ticks: {
1165						// Include a dollar sign in the ticks
1166						callback: function(value, index, values) {
1167							return Math.round(value, l_y.dec) + l_y.suf;
1168						}
1169					},
1170					id: "y-axis-" + (hoptions.options.scales.yAxes.length + 1),
1171				};
1172
1173				if ( chartFrom1 != '' )
1174				{
1175					yaxe.min = chartFrom1;
1176					yaxe.startOnTick = false;
1177				}
1178				else {
1179					yaxe.min = myData.Min;
1180				}
1181
1182				if ( chartTo1 != '' )
1183				{
1184					yaxe.max = chartTo1;
1185					yaxe.endOnTick = false;
1186				}
1187				else {
1188					yaxe.max = myData.Max;
1189				}
1190				_formats.push(l_y)
1191				hoptions.options.scales.yAxes.push(yaxe);
1192				hoptions.data.datasets.push( wpgpxmapsGetDataset(lng.altitude, myData.Items, color2, yaxe.id ));
1193
1194			}
1195
1196			if (graphSpeed != '') {
1197				if (unitspeed == '6') /* min/100m */
1198				{
1199					l_s = { suf : "min/100m", dec : 2 };
1200				}
1201				else if (unitspeed == '5') /* knots */
1202				{
1203					l_s = { suf : "knots", dec : 2 };
1204				}
1205				else if (unitspeed == '4') /* min/miles */
1206				{
1207					l_s = { suf : "min/mi", dec : 2 };
1208				}
1209				else if (unitspeed == '3') /* min/km */
1210				{
1211					l_s = { suf : "min/km", dec : 2 };
1212				}
1213				else if (unitspeed == '2') /* miles/h */
1214				{
1215					l_s = { suf : "mi/h", dec : 0 };
1216				}
1217				else if (unitspeed == '1') /* km/h */
1218				{
1219					l_s = { suf : "km/h", dec : 0 };
1220				}
1221				else
1222				{
1223					l_s = { suf : "m/s", dec : 0 };
1224				}
1225
1226				var myData = mergeArrayForChart(graphDist, graphSpeed);
1227
1228				var yaxe = {
1229					type: 'linear',
1230					ticks: {
1231						// Include a dollar sign in the ticks
1232						callback: function(value, index, values) {
1233							return Math.round(value, l_s.dec) + l_s.suf;
1234						}
1235					},
1236					position: 'right',
1237					scalePositionLeft: false,
1238					id: "y-axis-" + (hoptions.options.scales.yAxes.length + 1),
1239				};
1240
1241				if ( chartFrom2 != '' )
1242				{
1243					yaxe.min = chartFrom2;
1244					yaxe.startOnTick = false;
1245				}
1246				else {
1247					yaxe.min = myData.Min;
1248				}
1249
1250				if ( chartTo2 != '' )
1251				{
1252					yaxe.max = chartTo2;
1253					yaxe.endOnTick = false;
1254				}
1255				else {
1256					yaxe.max = myData.Max;
1257				}
1258
1259
1260				_formats.push(l_s);
1261				hoptions.options.scales.yAxes.push(yaxe);
1262				hoptions.data.datasets.push( wpgpxmapsGetDataset(lng.speed, myData.Items, color3, yaxe.id ) );
1263
1264			}
1265
1266			if (graphHr != '')
1267			{
1268
1269				var myData = mergeArrayForChart(graphDist, graphHr);
1270
1271				var yaxe = {
1272					type: 'linear',
1273					ticks: {
1274						// Include a dollar sign in the ticks
1275						callback: function(value, index, values) {
1276							return Math.round(value, l_hr.dec) + l_hr.suf;
1277						}
1278					},
1279					position: 'right',
1280					scalePositionLeft: false,
1281					id: "y-axis-" + (hoptions.options.scales.yAxes.length + 1),
1282				};
1283
1284				hoptions.options.scales.yAxes.push(yaxe);
1285				hoptions.data.datasets.push( wpgpxmapsGetDataset(lng.heartRate, myData.Items, color4, yaxe.id ) );
1286				_formats.push(l_hr);
1287			}
1288
1289
1290			if (graphAtemp != '')
1291			{
1292
1293				var myData = mergeArrayForChart(graphDist, graphAtemp);
1294
1295				var yaxe = {
1296					type: 'linear',
1297					ticks: {
1298						// Include a dollar sign in the ticks
1299						callback: function(value, index, values) {
1300							return Math.round(value, 1) + "°C";
1301						}
1302					},
1303					position: 'right',
1304					scalePositionLeft: false,
1305					id: "y-axis-" + (hoptions.options.scales.yAxes.length + 1),
1306				};
1307
1308				hoptions.options.scales.yAxes.push(yaxe);
1309				hoptions.data.datasets.push( wpgpxmapsGetDataset(lng.atemp, my
1309Data.Items, color7, yaxe.id ) );
1310				_formats.push({ suf : "°C", dec : 1 });
1311
1312			}
1313
1314
1315			if (graphCad != '')
1316			{
1317
1318				var myData = mergeArrayForChart(graphDist, graphCad, true);
1319
1320				var yaxe = {
1321					type: 'linear',
1322					ticks: {
1323						// Include a dollar sign in the ticks
1324						callback: function(value, index, values) {
1325							return Math.round(value, l_cad.dec) + l_cad.suf;
1326						}
1327					},
1328					position: 'right',
1329					scalePositionLeft: false,
1330					id: "y-axis-" + (hoptions.options.scales.yAxes.length + 1),
1331				};
1332
1333				hoptions.options.scales.yAxes.push(yaxe);
1334				hoptions.data.datasets.push( wpgpxmapsGetDataset(lng.cadence, myData.Items, color5, yaxe.id) );
1335				_formats.push(l_cad);
1336
1337			}
1338
1339			if (graphGrade != '')
1340			{
1341
1342				var myData = mergeArrayForChart(graphDist, graphGrade);
1343
1344				var yaxe = {
1345					type: 'linear',
1346					ticks: {
1347						// Include a dollar sign in the ticks
1348						callback: function(value, index, values) {
1349							return Math.round(value, l_grade.dec) + l_grade.suf;
1350						}
1351					},
1352					position: 'right',
1353					scalePositionLeft: false,
1354					id: "y-axis-" + (hoptions.options.scales.yAxes.length + 1),
1355				};
1356
1357				_formats.push(l_grade);
1358				hoptions.options.scales.yAxes.push(yaxe);
1359				hoptions.data.datasets.push( wpgpxmapsGetDataset(lng.grade, myData.Items, color6, yaxe.id ) );
1360
1361			}
1362
1363			var ctx = document.getElementById("myChart_" + params.targetId).getContext('2d');
1364			var myChart = new Chart(ctx, hoptions);
1365
1366		}
1367		else  {
1368			jQuery("#myChart_" + params.targetId).css("display","none");
1369		}
1370
1371        return this;
1372    };
1373
1374	function mergeArrayForChart(distArr, dataArr, setZerosAsNull)
1375	{
1376		var l = distArr.length;
1377
1378		var items = new Array(l);
1379		var min=10000;
1380		var max=-10000;
1381
1382		for (i=0; i<l; i++)
1383		{
1384			if (distArr[i] != null)
1385			{
1386				var _item = dataArr[i];
1387
1388				if (setZerosAsNull === true && _item === 0)
1389				{
1390					_item = null;
1391				}
1392
1393				items[i] = {
1394								x: distArr[i],
1395								y:_item
1396							};
1397				if (_item > max)
1398					max = _item;
1399				if (_item < min)
1400					min = _item;
1401			}
1402		}
1403
1404		return {
1405			Items : items,
1406			Min : min,
1407			Max : max,
1408		}
1409
1410	}
1411
1412	function wpgpxmapsGetDataset(name,data,color, id) {
1413		return {
1414			label: name, // jQuery("<div/>").html(name).text(), // convert html special chars to text, ugly but it works
1415			data : data,
1416			borderColor: color,
1417			backgroundColor: hexToRgbA(color, .3),
1418			pointRadius: 0,
1419			borderWidth: 1,
1420			pointHoverRadius: 1,
1421			yAxisID: id,
1422		}
1423	}
1424
1425	function hexToRgbA(hex,a){
1426		var c;
1427		if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
1428			c= hex.substring(1).split('');
1429			if(c.length== 3){
1430				c= [c[0], c[0], c[1], c[1], c[2], c[2]];
1431			}
1432			c= '0x'+c.join('');
1433			return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+',' + a +')';
1434		}
1435		throw new Error('Bad Hex');
1436	}
1437
1438
1439	function getItemFromArray(arr,index)
1440	{
1441		try
1442		{
1443		  return arr[index];
1444		}
1445		catch(e)
1446		{
1447			return [0,0];
1448		}
1449	}
1450
1451
1452	function getClosestIndex(points,lat,lon)
1453	{
1454		var dd=10000;
1455		var ii=0;
1456		for (i=0; i < points.length; i++)
1457		{
1458			if (points[i]==null)
1459				continue;
1460
1461			var d = wpgpxmapsDist(points[i][0], points[i][1], lat, lon);
1462			if ( d < dd )
1463			{
1464				ii = i;
1465				dd = d;
1466			}
1467		}
1468		return ii;
1469	}
1470
1471	function getClosestImage(lat,lon,targetId)
1472	{
1473		var dd=10000;
1474		var img;
1475		var divImages = document.getElementById("ngimages_"+targetId);
1476		var img_spans = divImages.getElementsByTagName("span");
1477		for (var i = 0; i < img_spans.length; i++) {
1478			var imageLat = img_spans[i].getAttribute("lat");
1479			var imageLon = img_spans[i].getAttribute("lon");
1480
1481			imageLat = imageLat.replace(",", ".");
1482			imageLon = imageLon.replace(",", ".");
1483
1484			var d = wpgpxmapsDist(imageLat, imageLon, lat, lon);
1485			if ( d < dd )
1486			{
1487				img = img_spans[i];
1488				dd = d;
1489			}
1490		}
1491		return img;
1492	}
1493
1494	function isNumeric(input){
1495		var RE = /^-{0,1}\d*\.{0,1}\d+$/;
1496		return (RE.test(input));
1497	}
1498
1499	function wpgpxmapsDist(lat1,lon1,lat2,lon2)
1500	{
1501		// mathematically not correct but fast
1502		var dLat = (lat2-lat1);
1503		var dLon = (lon2-lon1);
1504		return Math.sqrt(dLat * dLat + dLon * dLon);
1505	}
1506
1507}( jQuery ));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.