PageSourceSearch

https://members.rivercanalrescue.co.uk/_content/Pex.Components/pex/leafletInterop.8rfgfnfewx.js

js rivercanalrescue.co.uk collected 2026-10-02 06:37:57 UTC 14,603 bytes, 476 lines download raw bytes

1maps = {};
2layers = {};
3
4window.pexLeaflet = {
5	create: function (map, objectReference) {
6		var leafletMap = L.map(map.id, {
7			center: map.center,
8			zoom: map.zoom,
9			zoomControl: map.zoomControl,
10			minZoom: map.minZoom ? map.minZoom : undefined,
11			maxZoom: map.maxZoom ? map.maxZoom : undefined,
12			maxBounds: map.maxBounds && map.maxBounds.item1 && map.maxBounds.item2 ? L.latLngBounds(map.maxBounds.item1, map.maxBounds.item2) : undefined,
13		});
14
15		connectMapEvents(leafletMap, objectReference);
16		maps[map.id] = leafletMap;
17		layers[map.id] = [];
18	},
19	dispose: function (mapId) {
20		var map = maps[mapId];
21		if (map && map.remove) {
22			map.off();
23			map.remove();
24		}
25	},
26	invalidateSize: function (mapId) {
27		var map = maps[mapId];
28		if (map) {
29			map.invalidateSize();
30		}
31	},
32	addTilelayer: function (mapId, tileLayer) {
33		const layer = L.tileLayer(tileLayer.urlTemplate, {
34			attribution: tileLayer.attribution,
35			pane: tileLayer.pane,
36			// ---
37			tileSize: tileLayer.tileSize ? L.point(tileLayer.tileSize.width, tileLayer.tileSize.height) : undefined,
38			opacity: tileLayer.opacity,
39			updateWhenZooming: tileLayer.updateWhenZooming,
40			updateInterval: tileLayer.updateInterval,
41			zIndex: tileLayer.zIndex,
42			bounds: tileLayer.bounds && tileLayer.bounds.item1 && tileLayer.bounds.item2 ? L.latLngBounds(tileLayer.bounds.item1, tileLayer.bounds.item2) : undefined,
43			// ---
44			minZoom: tileLayer.minimumZoom,
45			maxZoom: tileLayer.maximumZoom,
46			subdomains: tileLayer.subdomains,
47			errorTileUrl: tileLayer.errorTileUrl,
48			zoomOffset: tileLayer.zoomOffset,
49			// TMS
50			zoomReverse: tileLayer.isZoomReversed,
51			detectRetina: tileLayer.detectRetina,
52			// crossOrigin
53		});
54		addLayer(mapId, layer, tileLayer.id);
55	},
56	addMbTilesLayer: function (mapId, mbTilesLayer, objectReference) {
57		const layer = L.tileLayer.mbTiles(mbTilesLayer.urlTemplate, {
58			attribution: mbTilesLayer.attribution,
59			minZoom: mbTilesLayer.minimumZoom,
60			maxZoom: mbTilesLayer.maximumZoom
61		});
62		addLayer(mapId, layer, mbTilesLayer.id);
63	},
64	addShapefileLayer: function (mapId, shapefileLayer, objectReference) {
65		const layer = L.shapefile(shapefileLayer.urlTemplate);
66		addLayer(mapId, layer, shapefileLayer.id);
67	},
68	addMarker: function (mapId, marker, objectReference) {
69		var options = {
70			...createInteractiveLayer(marker),
71			keyboard: marker.isKeyboardAccessible,
72			title: marker.title,
73			alt: marker.alt,
74			zIndexOffset: marker.zIndexOffset,
75			opacity: marker.opacity,
76			riseOnHover: marker.riseOnHover,
77			riseOffset: marker.riseOffset,
78			pane: marker.pane,
79			bubblingMouseEvents: marker.isBubblingMouseEvents,
80			draggable: marker.draggable,
81			autoPan: marker.useAutopan,
82			autoPanPadding: marker.autoPanPadding,
83			autoPanSpeed: marker.autoPanSpeed,
84			rotationAngle:marker.rotationAngle
85		};
86
87		if (marker.icon !== null) {
88			options.icon = createIcon(marker.icon);
89		}
90		const mkr = L.marker(marker.position, options);
91		connectMarkerEvents(mkr, objectReference);
92		addLayer(mapId, mkr, marker.id);
93		setTooltipAndPopupIfDefined(marker, mkr);
94	},
95	addPolyline: function (mapId, polyline, objectReference) {
96		const layer = L.polyline(shapeToLatLngArray(polyline.shape), createPolyline(polyline));
97		addLayer(mapId, layer, polyline.id);
98		setTooltipAndPopupIfDefined(polyline, layer);
99	},
100	updatePolyline: function (mapId, polyline) {
101		let layer = layers[mapId].find(l => l.id === polyline.id);
102		if (layer !== undefined) {
103			layer.setLatLngs(shapeToLatLngArray(polyline.shape));
104		}
105	},
106	addPolygon: function (mapId, polygon, objectReference) {
107		const layer = L.polygon(shapeToLatLngArray(polygon.shape), createPolyline(polygon));
108		addLayer(mapId, layer, polygon.id);
109		setTooltipAndPopupIfDefined(polygon, layer);
110	},
111	updatePolygon: function (mapId, polygon) {
112		let layer = layers[mapId].find(l => l.id === polygon.id);
113		if (layer !== undefined) {
114			layer.setLatLngs(shapeToLatLngArray(polygon.shape));
115		}
116	},
117	addRectangle: function (mapId, rectangle, objectReference) {
118		const layer = L.rectangle([[rectangle.shape.bottom, rectangle.shape.left], [rectangle.shape.top, rectangle.shape.right]], createPolyline(rectangle));
119		addLayer(mapId, layer, rectangle.id);
120		setTooltipAndPopupIfDefined(rectangle, layer);
121	},
122	updateRectangle: function (mapId, rectangle) {
123		let layer = layers[mapId].find(l => l.id === rectangle.id);
124		if (layer !== undefined) {
125			layer.setBounds([[rectangle.shape.bottom, rectangle.shape.left], [rectangle.shape.top, rectangle.shape.right]]);
126		}
127	},
128	addCircle: function (mapId, circle, objectReference) {
129		const layer = L.circle(circle.position,
130			{
131				...createPath(circle),
132				radius: circle.radius
133			});
134		addLayer(mapId, layer, circle.id);
135		setTooltipAndPopupIfDefined(circle, layer);
136	},
137	updateCircle: function (mapId, circle) {
138		let layer = layers[mapId].find(l => l.id === circle.id);
139		if (layer !== undefined) {
140			layer.setRadius(circle.radius);
141			layer.setLatLng(circle.position);
142		}
143	},
144	addImageLayer: function (mapId, image, objectReference) {
145		const layerOptions = {
146			...createInteractiveLayer(image),
147			opacity: image.opacity,
148			alt: image.alt,
149			crossOrigin: image.crossOrigin,
150			errorOverlayUrl: image.errorOverlayUrl,
151			zIndex: image.zIndex,
152			className: image.className
153		};
154
155		const corner1 = L.latLng(image.corner1.x, image.corner1.y);
156		const corner2 = L.latLng(image.corner2.x, image.corner2.y);
157		const bounds = L.latLngBounds(corner1, corner2);
158
159		const imgLayer = L.imageOverlay(image.url, bounds, layerOptions);
160		addLayer(mapId, imgLayer);
161	},
162	addGeoJsonLayer: function (mapId, geodata, objectReference) {
163		const geoDataObject = JSON.parse(geodata.geoJsonData);
164		var options = {
165			...createInteractiveLayer(geodata),
166			title: geodata.title,
167			bubblingMouseEvents: geodata.isBubblingMouseEvents,
168			onEachFeature: function onEachFeature(feature, layer) {
169				connectInteractionEvents(layer, objectReference);
170			}
171		};
172
173		const geoJsonLayer = L.geoJson(geoDataObject, options);
174		addLayer(mapId, geoJsonLayer, geodata.id);
175	},
176	removeLayer: function (mapId, layerId) {
177		const remainingLayers = layers[mapId].filter((layer) => layer.id !== layerId);
178		const layersToBeRemoved = layers[mapId].filter((layer) => layer.id === layerId); // should be only one ...
179		layers[mapId] = remainingLayers;
180
181		layersToBeRemoved.forEach(m => m.removeFrom(maps[mapId]));
182	},
183	updatePopupContent: function (mapId, layerId, content) {
184		let layer = layers[mapId].find(l => l.id === layerId);
185		if (layer !== undefined) {
186			var popup = layer.getPopup();
187			if (popup !== undefined) {
188				popup.setContent(content);
189			}
190		}
191	},
192	updateTooltipContent: function (mapId, layerId, content) {
193		let layer = layers[mapId].find(l => l.id === layerId);
194		if (layer !== undefined) {
195			var tooltip = layer.getTooltip();
196			if (tooltip !== undefined) {
197				tooltip.setContent(content);
198			}
199		}
200	},
201	fitBounds: function (mapId, corner1, corner2, padding, maxZoom) {
202		const corner1LL = L.latLng(corner1.x, corner1.y);
203		const corner2LL = L.latLng(corner2.x, corner2.y);
204		const mapBounds = L.latLngBounds(corner1LL, corner2LL);
205		maps[mapId].fitBounds(mapBounds, {
206			padding: padding == null ? null : L.point(padding.x, padding.y),
207			maxZoom: maxZoom
208		});
209	},
210	panTo: function (mapId, position, animate, duration, easeLinearity, noMoveStart) {
211		const pos = L.latLng(position.x, position.y);
212		maps[mapId].panTo(pos, {
213			animate: animate,
214			duration: duration,
215			easeLinearity: easeLinearity,
216			noMoveStart: noMoveStart
217		});
218	},
219	setView: function (mapId, position, zoom) {
220		const pos = L.latLng(position.x, position.y);
221		maps[mapId].setView(pos, zoom);
222	},
223	flyTo: function (mapId, position, zoom) {
224		const pos = L.latLng(position.x, position.y);
225		maps[mapId].flyTo(pos, zoom, { animate: true, duration:1 });
226	},
227	getCenter: function (mapId) {
228		return maps[mapId].getCenter();
229	},
230	getZoom: function (mapId) {
231		return maps[mapId].getZoom();
232	},
233	setZoom: function (mapId, zoomLevel) {
234		maps[mapId].setZoom(zoomLevel);
235	},
236	getBounds: function (mapId) {
237		var bounds = maps[mapId].getBounds();
238		return [bounds.getNorthWest(), bounds.getSouthEast()];
239	},
240	zoomIn: function (mapId, e) {
241		const map = maps[mapId];
242
243		if (map.getZoom() < map.getMaxZoom()) {
244			map.zoomIn(map.options.zoomDelta * (e.shiftKey ? 3 : 1));
245		}
246	},
247	zoomOut: function (mapId, e) {
248		const map = maps[mapId];
249
250		if (map.getZoom() > map.getMinZoom()) {
251			map.zoomOut(map.options.zoomDelta * (e.shiftKey ? 3 : 1));
252		}
253	}
254};
255
256function createIcon(icon) {
257	return L.icon({
258		iconUrl: icon.url,
259		iconRetinaUrl: icon.retinaUrl,
260		iconSize: icon.size ? L.point(icon.size.width, icon.size.height) : null,
261		iconAnchor: icon.anchor ? L.point(icon.anchor.x, icon.anchor.y) : null,
262		popupAnchor: L.point(icon.popupAnchor.x, icon.popupAnchor.y),
263		tooltipAnchor: L.point(icon.tooltipAnchor.x, icon.tooltipAnchor.y),
264		shadowUrl: icon.shadowUrl,
265		shadowRetinaUrl: icon.shadowRetinaUrl,
266		shadowSize: icon.shadowSize ? L.point(icon.shadowSize.width, icon.shadowSize.height) : null,
267		shadowSizeAnchor: icon.shadowSizeAnchor ? L.point(icon.shadowSizeAnchor.width, icon.shadowSizeAnchor.height) : null,
268		className: icon.className
269	})
270}
271
272function shapeToLatLngArray(shape) {
273	var latlngs = [];
274	shape.forEach(pts => {
275		var ll = [];
276		pts.forEach(p => ll.push([p.x, p.y]));
277		latlngs.push(ll);
278	});
279
280	return latlngs;
281}
282
283function createPolyline(polyline) {
284	return {
285		...createPath(polyline),
286		smoothFactor: polyline.smoothFactor,
287		noClip: polyline.noClipEnabled
288	};
289}
290
291function createPath(path) {
292	return {
293		...createInteractiveLayer(path),
294		stroke: path.drawStroke,
295		color: getColorString(path.strokeColor),
296		weight: path.strokeWidth,
297		opacity: path.strokeOpacity,
298		lineCap: path.lineCap,
299		lineJoin: path.lineJoin,
300		dashArray: path.strokeDashArray,
301		dashOffset: path.strokeDashOffset,
302		fill: path.fill,
303		fillColor: getColorString(path.fillColor),
304		fillOpacity: path.fillOpacity,
305		fillRule: path.fillRule
306	};
307}
308
309function createInteractiveLayer(layer) {
310	return {
311		...createLayer(layer),
312		interactive: layer.isInteractive,
313		bubblingMouseEvents: layer.isBubblingMouseEvents
314	};
315}
316
317function createLayer(obj) {
318	return {
319		id: obj.id,
320		pane: obj.pane,
321		attribution: obj.attribution
322	};
323}
324
325function getColorString(color) {
326	return "rgb(" + color.r + "," + color.g + "," + color.b + ")";
327}
328
329function unbindTooltipAndPopupIfDefined(layer) {
330	if (layer.getTooltip()) {
331		layer.unbindTooltip();
332	}
333	if (layer.getPopup()) {
334		layer.unbindPopup();
335	}
336}
337
338function setTooltipAndPopupIfDefined(layer, jsLayer) {
339	if (layer.tooltip) {
340		addTooltip(jsLayer, layer.tooltip);
341	}
342	if (layer.popup) {
343		addPopup(jsLayer, layer.popup);
344	}
345}
346
347function addTooltip(layerObj, tooltip) {
348	layerObj.bindTooltip(tooltip.content,
349		{
350			pane: tooltip.pane,
351			offset: L.point(tooltip.offset.x, tooltip.offset.y),
352			direction: tooltip.direction,
353			permanent: tooltip.isPermanent,
354			sticky: tooltip.isSticky,
355			opacity: tooltip.opacity
356		});
357}
358
359function addPopup(layerObj, popup) {
360	layerObj.bindPopup(popup.content, {
361		pane: popup.pane,
362		className: popup.className,
363		maxWidth: popup.maximumWidth,
364		minWidth: popup.minimumWidth,
365		autoPan: popup.autoPanEnabled,
366		autoPanPaddingTopLeft: popup.autoPanPaddingTopLeft ? L.point(popup.autoPanPaddingTopLeft.x, popup.autoPanPaddingTopLeft.y) : null,
367		autoPanPaddingBottomRight: popup.autoPanPaddingBottomRight ? L.point(popup.autoPanPaddingBottomRight.x, popup.autoPanPaddingBottomRight.y) : null,
368		autoPanPadding: L.point(popup.autoPanPadding.x, popup.autoPanPadding.y),
369		keepInView: popup.keepInView,
370		closeButton: popup.showCloseButton,
371		autoClose: popup.autoClose,
372		closeOnEscapeKey: popup.closeOnEscapeKey,
373	});
374}
375
376function addLayer(mapId, layer, layerId) {
377	layer.id = layerId;
378	layers[mapId].push(layer);
379	layer.addTo(maps[mapId]);
380}
381
382// #region events
383
384// removes properties that can cause circular references
385function cleanupEventArgsForSerialization(eventArgs) {
386
387	const propertiesToRemove = [
388		"target",
389		"sourceTarget",
390		"propagatedFrom",
391		"originalEvent",
392		"tooltip",
393		"popup"
394	];
395
396	const copy = {};
397
398	for (let key in eventArgs) {
399		if (!propertiesToRemove.includes(key) && eventArgs.hasOwnProperty(key)) {
400			copy[key] = eventArgs[key];
401		}
402	}
403
404	return copy;
405}
406
407function mapEvents(mapElement, objectReference, eventHandlerDict) {
408	for (let key in eventHandlerDict) {
409
410		const handlerName = eventHandlerDict[key];
411
412		mapElement.on(key, function (eventArgs) {
413			objectReference.invokeMethodAsync(handlerName,
414				cleanupEventArgsForSerialization(eventArgs));
415		});
416	}
417}
418
419function connectMapEvents(map, objectReference) {
420
421	connectInteractionEvents(map, objectReference);
422
423	mapEvents(map, objectReference, {
424		"zoomlevelschange": "NotifyZoomLevelsChange",
425		"resize": "NotifyResize",
426		"viewreset": "NotifyViewReset",
427		"zoomstart": "NotifyZoomStart",
428		"movestart": "NotifyMoveStart",
429		"zoom": "NotifyZoom",
430		"move": "NotifyMove",
431		"zoomend": "NotifyZoomEnd",
432		"moveend": "NotifyMoveEnd",
433	});
434}
435
436function connectLayerEvents(layer, objectReference) {
437	mapEvents(layer, objectReference, {
438		"popupopen": "NotifyPopupOpen",
439		"popupclose": "NotifyPopupClose",
440		"tooltipopen": "NotifyTooltipOpen",
441		"tooltipclose": "NotifyTooltipClose",
442	});
443}
444
445function connectInteractiveLayerEvents(interactiveLayer, objectReference) {
446
447	connectLayerEvents(interactiveLayer, objectReference);
448	connectInteractionEvents(interactiveLayer, objectReference);
449}
450
451function connectMarkerEvents(marker, objectReference) {
452
453	connectInteractiveLayerEvents(marker, objectReference);
454
455	mapEvents(marker, objectReference, {
456		"move": "NotifyMove",
457		"dragstart": "NotifyDragStart",
458		"movestart": "NotifyMoveStart",
459		"drag": "NotifyDrag",
460		"dragend": "NotifyDragEnd",
461		"moveend": "NotifyMoveEnd",
462	});
463}
464
465function connectInteractionEvents(interactiveObject, objectReference) {
466
467	mapEvents(interactiveObject, objectReference, {
468		"click": "NotifyClick",
469		"dblclick": "NotifyDblClick",
470		"mouseover": "NotifyMouseOver",
471		"mouseout": "NotifyMouseOut",
472		"contextmenu": "NotifyContextMenu",
473	});
474}
475
476// #endregion

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.