PageSourceSearch

https://www.blessgans.de/typo3conf/ext/db_tracking/Resources/Public/JS/db_tracking_map_leaflet.js?1663242921

js blessgans.de collected 2026-10-02 12:18:51 UTC 16,747 bytes, 428 lines download raw bytes

1var isTouchSupported = "ontouchend" in document;
2var delay = (function(){
3    var timer = 0;
4    return function(callback, ms){
5        clearTimeout (timer);
6        timer = setTimeout(callback, ms);
7    };
8})();
9var currentDateRange = {min:0, max:0};
10var map;
11var trackingdata = {};
12function allDates() {
13    daterangebounds = $("#daterange").dateRangeSlider("bounds");
14    $("#daterange").dateRangeSlider("values", daterangebounds.min, daterangebounds.max);
15    return false;
16}
17function zoomToFit() {
18    bounds = L.latLngBounds();
19    points = false;
20    for (i in trackingdata) { 
21        if (trackingdata[i].visible) {
22            for (p in trackingdata[i].points) {
23                bounds.extend(trackingdata[i].points[p]);
24                points = true;
25            }
26        }
27    }
28    if (points) {
29        map.fitBounds(bounds);
30    }
31    return false;
32}
33function mapOnResize() {
34    var navheight_for_map = $("#tx_dbtracking_map").height()-245;
35    var navheight_for_nav = $("#tx_dbtracking_map li").length*$("#tx_dbtracking_map li").height()*1.5+10;
36    var navheight = navheight_for_nav;
37    if (navheight_for_map<navheight)
38        navheight = navheight_for_map;
39    $("#tx_dbtracking_map .tx_dbtracking_nav").height(navheight);
40    $(".daterange").width($("#tx_dbtracking_map").width()-36);
41    $("#daterange").width($("#tx_dbtracking_map").width()-160);
42    $("#daterange").dateRangeSlider("resize");
43    setTimeout(function(){ map.invalidateSize()}, 400);
44}
45$(document).ready(function() {
46    $(window).resize(function() {
47        mapOnResize();
48    });
49    function daterangeChanged(daterange) {
50        currentDateRange.min = Math.round(daterange.values.min.getTime()/1000);
51        currentDateRange.max = Math.round(daterange.values.max.getTime()/1000);
52        for (i in trackingdata) { 
53            if (trackingdata[i].visible) {
54                trackingdata[i].refreshLayer();
55            }
56        }
57    }
58
59    var currentDateRange = {min:0, max:0};
60    function updateDaterange() {
61        var timestamp_min = false;
62        var timestamp_max = false;
63        for (i in trackingdata) {
64            animal =  trackingdata[i];
65            if (animal.visible) {
66                if (timestamp_min===false || animal.timestamp_min<timestamp_min)
67                { timestamp_min = animal.timestamp_min; }
68                if (timestamp_max===false || animal.timestamp_max>timestamp_max)
69                { timestamp_max = animal.timestamp_max; }
70            }
71        };
72        $("#daterange").dateRangeSlider("bounds", new Date(timestamp_min*1000), new Date(timestamp_max*1000));
73        if (toLoad==0) { 
74            // all initial data has been loaded
75            $("#daterange").show();
76            $("#daterange").bind("valuesChanged", function(e, data){
77                daterangeChanged(data);
78                if (initializing && toLoad==0) {
79
80                    allDates();
81                    setTimeout(function() {
82                        if (mapPositionMode=='showall') {
83                            zoomToFit();
84                        }
85                        else if (mapPositionMode=='lastfix') {
86                            for (key in trackingdata) break;
87                            if (trackingdata[key].markers.length>0) {
88                                point = trackingdata[key].markers[trackingdata[key].markers.length-1].getLatLng();
89                                map.setView(point, mapZoom);
90                            }
91                        }
92                        else if (mapPositionMode=='manual') {
93                            map.setView([mapCenter[0], mapCenter[1]], mapZoom);
94                        }
95                        initializing = false;
96                        $("#tx_dbtracking_map").css("visibility", "visible");
97                    }, 500);
98                }
99            });
100            $("#daterange").dateRangeSlider("values", new Date(0), new Date(1));
101            $("#daterange").dateRangeSlider("values", new Date(timestamp_min*1000), new Date(timestamp_max*1000));
102            allDates();
103        }
104    }
105    var year = false;
106    var toLoad = 0;
107    map = L.map("tx_dbtracking_map", {
108        center: mapCenter, 
109        zoom: mapZoom,
110        minZoom: 2,
111        maxZoom: 14,
112        zoomControl: false
113    });
114    var layerStandard = L.tileLayer('https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png', {
115            minZoom: 1,
116            maxZoom: 14,
117            attribution: '&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
118            }).addTo(map);
119    var layerSat = L.layerGroup();
120    // SAT needs mapbox api key
121     /*
122    var layerSat = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
123          attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
124          minZoom: 1,
125          maxZoom: 14,
126          id: 'mapbox/satellite-streets-v11',
127          tileSize: 512,
128          zoomOffset: -1,
129          accessToken: 'mapboxapikey'
130    });
131    */
132    // topgraphisch
133    var layerOutdoors = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
134        minZoom: 1,
135        maxZoom: 14,
136        attribution: '&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap</a>-Mitwirkende, SRTM | Kartendarstellung: &copy; <a href="http://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
137    });
138
139    var ctrlLayerSelector = L.control({position: 'topleft'});
140    ctrlLayerSelector.onAdd = function (map) {
141        var div = L.DomUtil.create('div', 'leaflet-bar info mycontrol');
142        div.innerHTML = '<div class="btn-group"><button id="layer-standard" class="changemaplayer btn btn-sm btn-primary active">Karte</button><!-- button id="layer-sat" class="changemaplayer btn btn-sm btn-primary">Satellit</button--><button id="layer-outdoors" class="changemaplayer btn btn-sm btn-primary">Gelände</button></div>';
143        return div;
144    };
145    ctrlLayerSelector.addTo(map);
146    $("#layer-sat").on("click", function() {
147        if ($(this).hasClass("active")) return;
148        map.removeLayer(layerStandard).removeLayer(layerOutdoors).addLayer(layerSat);
149        $(".changemaplayer").removeClass("active");
150        $(this).addClass("active");
151    });
152    $("#layer-standard").on("click", function() {
153        if ($(this).hasClass("active")) return;
154        map.removeLayer(layerSat).removeLayer(layerOutdoors).addLayer(layerStandard);
155        $(".changemaplayer").removeClass("active");
156        $(this).addClass("active");
157    });
158    $("#layer-outdoors").on("click", function() {
159        if ($(this).hasClass("active")) return;
160        map.removeLayer(layerSat).removeLayer(layerStandard).addLayer(layerOutdoors);
161        $(".changemaplayer").removeClass("active");
162        $(this).addClass("active");
163    });
164    var zoomControl = L.control.zoom().addTo(map);
165    map.addControl(new L.Control.Fullscreen());
166    map.on('fullscreenchange', function () {
167	if (map.isFullscreen()) {
168		$("#pageheader").css("zIndex", 1);
169	}
170	else {
171		$("#pageheader").css("zIndex", 11);
172	}
173        mapOnResize();
174	
175    });
176    var loadingindicator = L.control({position: 'topright'});
177    loadingindicator.onAdd = function () {
178        var div = L.DomUtil.create('div', 'leaflet-bar info mycontrol loadingindicator');
179        div.innerHTML = '<div class="content">Daten werden geladen ...</div>';
180        return div;
181    };
182    var daterangeControl = L.control({position: 'bottomright'});
183    daterangeControl.onAdd = function () {
184        var div = L.DomUtil.create('div', 'leaflet-bar info mycontrol daterange');
185        div.innerHTML = '<div id="alldates"><a href="#" onclick="return allDates();" title="Unset date limit"></a></div><div id="daterange"></div>';
186        L.DomEvent.on(div, 'click dblclick', function(ev) {
187            L.DomEvent.stopPropagation(ev);
188        });
189        L.DomEvent.on(div, 'mouseover touchstart', function(ev) {
190            map.dragging.disable();
191        });
192        L.DomEvent.on(div, 'mouseout touchend', function(ev) {
193            map.dragging.enable();
194        });
195        return div;
196    };
197    map.addControl(daterangeControl);
198
199
200    var selectanimalControl = L.control({position: 'topright'});
201    selectanimalControl.onAdd = function () {
202        var div = L.DomUtil.create('div', 'leaflet-bar info mycontrol selectanimal');
203        var html = '<ul class="tx_dbtracking_nav">'+$(".tx_dbtracking_nav").html()+'</ul>'
204        $(".tx_dbtracking_nav").remove();
205        div.innerHTML = html;
206        L.DomEvent.on(div, 'click dblclick', function(ev) {
207            L.DomEvent.stopPropagation(ev);
208        });
209        L.DomEvent.on(div, 'mousewheel mouseover touchstart', function(ev) {
210            map.dragging.disable();
211            map.scrollWheelZoom.disable();
212        });
213        L.DomEvent.on(div, 'mousewheel mouseout touchend', function(ev) {
214            map.dragging.enable();
215            map.scrollWheelZoom.disable();
216        });
217        return div;
218    };
219    map.addControl(selectanimalControl);
220
221    var showallControl = L.control({position: 'bottomright'});
222    showallControl.onAdd = function () {
223        var div = L.DomUtil.create('div', 'leaflet-bar info mycontrol showall');
224        div.innerHTML = '<div id="zoomout"><a href="#" onclick="return zoomToFit();" title="Pan/Zoom to show all points"></a></div>';
225        L.DomEvent.on(div, 'click dblclick', function(ev) {
226            L.DomEvent.stopPropagation(ev);
227        });
228        return div;
229    };
230    map.addControl(showallControl);
231
232
233    $(".animaltoggle").prop('checked', false);
234    $('#daterange').dateRangeSlider({
235        arrows: true,
236        step: {"days":1},
237        formatter: function(d) {
238            return $.datepicker.formatDate('dd.mm.yy', d);
239        }
240    });
241    initializing = true;
242    $.each($(".animaltoggle"), function() {
243        if (toLoad!=preselect) { 
244            $(this).prop('checked', true);
245            toLoad = toLoad+1;
246            toggleAnimal($(this));
247        }
248    });
249    mapOnResize();
250    $(".animaltoggle").on("click", function() {
251        toggleAnimal($(this)); 
252    });
253    $("#daterange, li, #zoomout, #alldates").tooltip();
254    // toggle animals, load trackingdata
255    function toggleAnimal(control) {
256        if (!trackingdata[$(control).attr("id")]) {
257            $(".ui-tooltip").remove();
258            setstatus("Loading "+$(control).data("name")+" ...", false);
259            $.getJSON($(control).data("url"), '', function(data, textStatus, jqXHR) {
260                trackingdata[$(control).attr("id")] = new AnimalTrack(map, $(control).attr("id"), data);
261                setstatus(trackingdata[$(control).attr("id")].animal.name+": Loaded "+trackingdata[$(control).attr("id")].markers.length+ " points.", true);
262                toggleAnimal(control);
263                allDates();
264            });
265            return;
266        }
267        if ($(control).prop('checked')) {
268            trackingdata[$(control).attr("id")].show();
269        }
270        else {
271            trackingdata[$(control).attr("id")].hide();
272        }
273        toLoad = toLoad-1;
274        if (toLoad<0) toLoad = 0;
275        updateDaterange(map);
276    }
277    function setstatus(newStatus, fadeOut) {
278        map.addControl(loadingindicator);
279        $(".loadingindicator .content").show();
280        $(".loadingindicator .content").html(newStatus);
281        if (fadeOut) {
282            delay(function() {
283                $(".loadingindicator .content").fadeOut(1000);
284                delay(function() {
285                    loadingindicator.remove();
286                }, 1000);
287            }, 1000);
288        }
289    }
290
291    var colors = {
292        0:  "#ff0000",
293        1:  "#00ff00",
294        2:  "#ff00ff",
295        3:  "#0000ff",
296        4:  "#ffff00"
297    }
298    var circleStyle = function(color, size) {
299        if (size==1) radius = 4;
300        if (size>1)  radius = 6;
301        if (size>5)  radius = 8;
302        if (size>10) radius = 10;
303
304        return {
305            fillColor: color,
306            radius: radius,
307            stroke: true,
308            color: "black",
309            weight: 0.75,
310            opacity: 0.7,
311            fillOpacity: 0.75,
312            className: "marker",
313            pane: "markerPane"
314        };
315    };
316    function AnimalTrack(map, animal, data) {
317        var me = this;
318        this.layer = L.layerGroup().addTo(map);
319        this.polylinelayer = L.layerGroup().addTo(map);
320        this.id = animal;
321        this.animal = data.animal;
322        this.color = colors[this.animal.color];
323        this.points = [];
324        this.markers = [];
325        this.polyline = 0;
326        this.arrowHead = 0;
327        this.visible = true;
328        this.initialized = false;
329        this.timestamp_min = Number.MAX_VALUE;
330        this.timestamp_max = 0;
331        this.info = '';
332        if (!data)
333            return false;
334        this.uid = data.animal.uid;
335        this.initialized = true;
336        if (data.timestamp_min && data.timestamp_max) {
337            this.timestamp_min = data.timestamp_min;
338            this.timestamp_max = data.timestamp_max;
339        }
340        if (data.points.length>0) {
341            this.info = data.points.length+ " Points.<br />"+(new Date(this.timestamp_min*1000).format("d.m.Y"))+" - "+(new Date(this.timestamp_max*1000).format("d.m.Y"));
342            if (this.animal.description) 
343                this.info += "<br /><hr />"+this.animal.description;
344        }
345        else {
346            this.info = "No data.";
347        }
348        $("#nav"+this.id).tooltip({content: this.info});
349
350        this.refreshLayer = function() {
351            if (this.polyline) {
352                this.polyline.removeFrom(this.polylinelayer);
353            }
354            if (this.arrowHead) {
355                this.arrowHead.removeFrom(this.polylinelayer);
356            }
357            this.points = [];
358            for (m=0; m<this.markers.length; m++) {
359                if (this.markers[m].dbt_timestamp_end>=currentDateRange.min
360                        && this.markers[m].dbt_timestamp<=currentDateRange.max+60*60*24) {
361                    this.markers[m].addTo(this.layer);
362                    this.points.push(this.markers[m].dbt_point);
363                }
364                else { 
365                    this.markers[m].removeFrom(this.layer);
366                }
367            }
368            this.polyline = L.polyline(this.points, {color: this.color, weight: 2}).addTo(this.polylinelayer);
369            this.arrowHead = L.polylineDecorator(this.polyline, {
370                patterns: [
371                {repeat: 100, offset: 50, offsetEnd: 50, symbol: L.Symbol.arrowHead({pixelSize: 15, polygon: false, pathOptions: {color: this.color, stroke: true}})}
372                ]
373            }).addTo(this.polylinelayer);
374        }
375
376        this.addPoint = function(lat, lng, text, size, timestamp, timestamp_end, uid) {
377            if (size) {        
378                var markerTooltip = document.createElement("div");
379                markerTooltip.innerHTML = '<b>' + this.animal.name + '</b><br />' + text ;
380                var point = [lat, lng];
381                this.points.push(point);
382                var marker = L.circleMarker(point, circleStyle(this.color, size)).addTo(this.layer);
383                marker.dbt_timestamp = timestamp;
384                marker.dbt_timestamp_end = timestamp_end;
385                marker.dbt_point = point;
386                var pop = L.popup().setContent(markerTooltip);
387                marker.bindPopup(pop);
388                this.markers.push(marker);
389            }
390        };
391
392        var that = this;
393        $.each(data.points, function(i, point) {
394            me.addPoint ( parseFloat(point.lat),
395                    parseFloat(point.lng),
396                    point.text,
397                    point.size,
398                    point.timestamp,
399                    point.timestamp_end,
400                    that.uid
401                    );
402        });
403        this.refreshLayer();
404
405        this.show = function() {
406            if (this.visible)
407                return;
408            if (this.markers.length==0) {
409                setstatus(this.animal.name+": no data!", true);
410                return;
411            }
412            this.layer.addTo(map);
413            this.polylinelayer.addTo(map);
414            this.refreshLayer();
415            this.visible = true;
416        }
417        this.hide = function() {
418            if (!this.visible)
419                return;
420            this.layer.removeFrom(map);
421            this.polylinelayer.removeFrom(map);
422            this.visible =false;
423        }
424
425
426    }
427});
428

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.