1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-12-25 17:40:29 +00:00

Track map pan and zoom state in a state tiddler

This commit is contained in:
jeremy@jermolene.com 2023-03-10 12:45:20 +00:00
parent 449562eea2
commit 3699780f90
4 changed files with 53 additions and 8 deletions

View File

@ -13,6 +13,7 @@ title: $:/plugins/tiddlywiki/geospatial/demo/ui/geolayer
<$geomap <$geomap
layers="[<currentTiddler>]" layers="[<currentTiddler>]"
state=<<qualify "$:/state/demo-map">>
/> />
!! Intersect with other layers !! Intersect with other layers

View File

@ -65,6 +65,7 @@ title: $:/plugins/tiddlywiki/geospatial/demo/ui/geomarker
<$geomap <$geomap
markers="[<currentTiddler>]" markers="[<currentTiddler>]"
state=<<qualify "$:/state/demo-map">>
/> />
!! Distance to other markers !! Distance to other markers

View File

@ -12,6 +12,7 @@ title: $:/plugins/tiddlywiki/geospatial/demos
<$geomap <$geomap
markers="[all[tiddlers+shadows]tag[$:/tags/GeoMarker]]" markers="[all[tiddlers+shadows]tag[$:/tags/GeoMarker]]"
layers="[all[tiddlers+shadows]tag[$:/tags/GeoLayer]]" layers="[all[tiddlers+shadows]tag[$:/tags/GeoLayer]]"
state=<<qualify "$:/state/demo-map">>
/> />
<<tabs tabsList:"[all[tiddlers+shadows]tag[$:/tags/GeospatialDemo]]" default:"$:/plugins/tiddlywiki/geospatial/demo/markers">> <<tabs tabsList:"[all[tiddlers+shadows]tag[$:/tags/GeospatialDemo]]" default:"$:/plugins/tiddlywiki/geospatial/demo/markers">>

View File

@ -46,16 +46,20 @@ GeomapWidget.prototype.render = function(parent,nextSibling) {
GeomapWidget.prototype.renderMap = function(domNode) { GeomapWidget.prototype.renderMap = function(domNode) {
var self = this; var self = this;
// Create and position the map // Create the map
const map = $tw.Leaflet.map(domNode).setView([51.505, -0.09], 13); this.map = $tw.Leaflet.map(domNode);
map.fitWorld(); // Set the position
if(!this.setMapView()) {
// Default to showing the whole world
this.map.fitWorld();
}
// Setup the tile layer // Setup the tile layer
const tiles = $tw.Leaflet.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { const tiles = $tw.Leaflet.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19, maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map); }).addTo(this.map);
// Disable Leaflet attribution // Disable Leaflet attribution
map.attributionControl.setPrefix(""); this.map.attributionControl.setPrefix("");
// Create default icon // Create default icon
const iconProportions = 365/560, const iconProportions = 365/560,
iconHeight = 50; iconHeight = 50;
@ -66,7 +70,25 @@ GeomapWidget.prototype.renderMap = function(domNode) {
popupAnchor: [0, -iconHeight] // Position of the popup anchor relative to the icon anchor popupAnchor: [0, -iconHeight] // Position of the popup anchor relative to the icon anchor
}); });
// Add scale // Add scale
$tw.Leaflet.control.scale().addTo(map); $tw.Leaflet.control.scale().addTo(this.map);
// Listen for pan and zoom events
this.map.on("moveend zoomend",function(event) {
if(self.geomapStateTitle) {
var c = self.map.getCenter(),
lat = "" + c.lat,
long = "" + c.lng,
zoom = "" + self.map.getZoom(),
tiddler = self.wiki.getTiddler(self.geomapStateTitle);
if(!tiddler || tiddler.fields.lat !== lat || tiddler.fields.long !== long || tiddler.fields.zoom !== zoom) {
self.wiki.addTiddler(new $tw.Tiddler({
title: self.geomapStateTitle,
lat: lat,
long: long,
zoom: zoom
}));
}
}
});
// Track the geolayers filter // Track the geolayers filter
this.trackerGeoLayersFilter = new FilterTracker({ this.trackerGeoLayersFilter = new FilterTracker({
wiki: this.wiki, wiki: this.wiki,
@ -80,7 +102,7 @@ GeomapWidget.prototype.renderMap = function(domNode) {
color: (tiddler && tiddler.getFieldString("color")) || "yellow" color: (tiddler && tiddler.getFieldString("color")) || "yellow"
} }
} }
}).addTo(map); }).addTo(self.map);
return layer; return layer;
}, },
leave: function(title,tiddler,data) { leave: function(title,tiddler,data) {
@ -91,7 +113,7 @@ GeomapWidget.prototype.renderMap = function(domNode) {
var markers = $tw.Leaflet.markerClusterGroup({ var markers = $tw.Leaflet.markerClusterGroup({
maxClusterRadius: 40 maxClusterRadius: 40
}); });
map.addLayer(markers); this.map.addLayer(markers);
this.trackerGeoMarkersFilter = new FilterTracker({ this.trackerGeoMarkersFilter = new FilterTracker({
wiki: this.wiki, wiki: this.wiki,
widget: this, widget: this,
@ -118,10 +140,23 @@ GeomapWidget.prototype.renderMap = function(domNode) {
}); });
}; };
/*
Set the map center and zoom level from the values in the state tiddler. Returns true if the map view was successfully set
*/
GeomapWidget.prototype.setMapView = function() {
var stateTiddler = this.geomapStateTitle && this.wiki.getTiddler(this.geomapStateTitle);
if(stateTiddler) {
this.map.setView([$tw.utils.parseNumber(stateTiddler.fields.lat,0),$tw.utils.parseNumber(stateTiddler.fields.long,0)], $tw.utils.parseNumber(stateTiddler.fields.zoom,0));
return true;
}
return false;
};
/* /*
Compute the internal state of the widget Compute the internal state of the widget
*/ */
GeomapWidget.prototype.execute = function() { GeomapWidget.prototype.execute = function() {
this.geomapStateTitle = this.getAttribute("state");
this.geomapLayerFilter = this.getAttribute("layers"); this.geomapLayerFilter = this.getAttribute("layers");
this.geomapMarkerFilter = this.getAttribute("markers"); this.geomapMarkerFilter = this.getAttribute("markers");
}; };
@ -136,6 +171,13 @@ GeomapWidget.prototype.refresh = function(changedTiddlers) {
this.refreshSelf(); this.refreshSelf();
return true; return true;
} }
// Set zoom and position if the state tiddler has changed
if(changedAttributes.state) {
this.geomapStateTitle = this.getAttribute("state");
}
if(changedAttributes.state || changedTiddlers[this.geomapStateTitle]) {
this.setMapView();
}
// Check whether the layers or markers need updating // Check whether the layers or markers need updating
this.trackerGeoLayersFilter.refresh(changedTiddlers); this.trackerGeoLayersFilter.refresh(changedTiddlers);
this.trackerGeoMarkersFilter.refresh(changedTiddlers); this.trackerGeoMarkersFilter.refresh(changedTiddlers);