mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-09-19 18:59:42 +00:00
046437acf0
This is the beginnings of a new core plugin to add geospatial capabilities, building on the JSON operators that we now have in the core. It uses the libraries leaflet.js for mapping and turf.js for geospatial calculations.
110 lines
3.0 KiB
JavaScript
110 lines
3.0 KiB
JavaScript
/*\
|
|
title: $:/plugins/tiddlywiki/geospatial/geomap.js
|
|
type: application/javascript
|
|
module-type: widget
|
|
|
|
Leaflet map widget
|
|
|
|
\*/
|
|
(function(){
|
|
|
|
/*jslint node: true, browser: true */
|
|
/*global $tw: false */
|
|
"use strict";
|
|
|
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
|
|
|
var GeomapWidget = function(parseTreeNode,options) {
|
|
this.initialise(parseTreeNode,options);
|
|
};
|
|
|
|
/*
|
|
Inherit from the base widget class
|
|
*/
|
|
GeomapWidget.prototype = new Widget();
|
|
|
|
/*
|
|
Render this widget into the DOM
|
|
*/
|
|
GeomapWidget.prototype.render = function(parent,nextSibling) {
|
|
// Housekeeping
|
|
this.parentDomNode = parent;
|
|
this.computeAttributes();
|
|
this.execute();
|
|
// Render a wrapper for the map
|
|
var domNode = this.document.createElement("div");
|
|
domNode.style.width = "100%";
|
|
domNode.style.height = "600px";
|
|
// Insert it into the DOM
|
|
parent.insertBefore(domNode,nextSibling);
|
|
this.domNodes.push(domNode);
|
|
// Render the map
|
|
if($tw.browser) {
|
|
this.renderMap(domNode);
|
|
}
|
|
};
|
|
|
|
GeomapWidget.prototype.renderMap = function(domNode) {
|
|
var self = this;
|
|
// Get Leaflet
|
|
var L = require("$:/plugins/tiddlywiki/geospatial/leaflet.js");
|
|
// Create and position the map
|
|
const map = L.map(domNode).setView([51.505, -0.09], 13);
|
|
// Setup the tile layer
|
|
const tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
maxZoom: 19,
|
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
}).addTo(map);
|
|
// Create default icon
|
|
const myIcon = new L.Icon({
|
|
iconUrl: $tw.utils.makeDataUri(this.wiki.getTiddlerText("$:/plugins/tiddlywiki/geospatial/images/markers/pin"),"image/svg+xml"),
|
|
iconSize: [38, 95],
|
|
shadowSize: [50, 64],
|
|
iconAnchor: [22, 94],
|
|
popupAnchor: [-3, -76]
|
|
});
|
|
// Add scale
|
|
L.control.scale().addTo(map);
|
|
// Add US states overlay
|
|
const layer = L.geoJSON($tw.utils.parseJSONSafe(self.wiki.getTiddlerText("$:/plugins/geospatial/demo/features/us-states"),[])).addTo(map);
|
|
// Create markers
|
|
if(this.geomapMarkerFilter) {
|
|
var titles = this.wiki.filterTiddlers(this.geomapMarkerFilter);
|
|
$tw.utils.each(titles,function(title) {
|
|
var tiddler = self.wiki.getTiddler(title);
|
|
if(tiddler) {
|
|
var lat = $tw.utils.parseNumber(tiddler.fields.lat || "0"),
|
|
long = $tw.utils.parseNumber(tiddler.fields.long || "0"),
|
|
alt = $tw.utils.parseNumber(tiddler.fields.alt || "0"),
|
|
caption = tiddler.fields.caption || title;
|
|
var m = L.marker([lat,long,alt],{icon: myIcon}).bindPopup(caption).addTo(map);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
/*
|
|
Compute the internal state of the widget
|
|
*/
|
|
GeomapWidget.prototype.execute = function() {
|
|
this.geomapMarkerFilter = this.getAttribute("markers");
|
|
};
|
|
|
|
/*
|
|
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
|
*/
|
|
GeomapWidget.prototype.refresh = function(changedTiddlers) {
|
|
var changedAttributes = this.computeAttributes();
|
|
if($tw.utils.count(changedAttributes) > 0) {
|
|
this.refreshSelf();
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
exports.geomap = GeomapWidget;
|
|
|
|
})();
|
|
|