1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-30 05:19:57 +00:00

Geospatial Plugin: Support for custom popups (#8404)

* Allow width, height and maxZoom to be specified

* Add images to city marker tiddlers

* Initial support for custom popups

* Custom popup templates for the US and Canadian example data

* Popups should use the geomap as their parent widget

This lets root widget messages work

* Typo in default popup template

* Clean up the use of popup templates

* Allow GeoJSON features to be hidden via a checkbox

* Popup template for volcano dataset

* Add Natural Earth country data

* Optimise marker SVG
This commit is contained in:
Jeremy Ruston 2024-07-25 17:31:37 +01:00 committed by GitHub
parent acb2602d78
commit b1cd1306ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 224 additions and 48 deletions

View File

@ -4,11 +4,17 @@ tags: $:/tags/GeospatialDemo
This is a list of all the tiddlers containing ~GeoJSON feature collections in this wiki (identified by the tag <<tag "$:/tags/GeoFeature">>). A ~GeoJSON feature collection is a list of features, each of which consists of a geometry and associated metadata. This is a list of all the tiddlers containing ~GeoJSON feature collections in this wiki (identified by the tag <<tag "$:/tags/GeoFeature">>). A ~GeoJSON feature collection is a list of features, each of which consists of a geometry and associated metadata.
<ul> <ul>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/GeoFeature]sort[caption]]"> <$list filter="[all[shadows+tiddlers]tag[$:/tags/GeoFeature]sort[caption]]">
<li> <li>
<$link> <$checkbox
<$transclude field="caption"><$view field="title"/></$view> tiddler={{{ [[$:/config/GeospatialDemo/FeatureVisibility/]addsuffix<currentTiddler>] }}}
</$link> field="text" checked="show" unchecked="hide" default="show"
</li> >
</$list> <<lingo Description>>
</$checkbox>
<$link>
<$transclude field="caption"><$view field="title"/></$view>
</$link>
</li>
</$list>
</ul> </ul>

View File

@ -27,11 +27,12 @@ This demo requires that the API keys needed to access external services be obtai
<$geobaselayer title=<<currentTiddler>>/> <$geobaselayer title=<<currentTiddler>>/>
</$list> </$list>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/GeoMarker]]"> <$list filter="[all[tiddlers+shadows]tag[$:/tags/GeoMarker]]">
<$geolayer lat={{!!lat}} long={{!!long}} alt={{!!alt}} color={{!!color}} name={{!!caption}}/> <$geolayer lat={{!!lat}} long={{!!long}} alt={{!!alt}} color={{!!color}} name={{!!caption}} properties={{{ [[{}]jsonset[title],<currentTiddler>] }}}
popupTemplate="ui/PopupTemplate"/>
</$list> </$list>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/GeoFeature]]"> <$list filter="[all[tiddlers+shadows]tag[$:/tags/GeoFeature]] :filter[[$:/config/GeospatialDemo/FeatureVisibility/]addsuffix<currentTiddler>get[text]else[show]match[show]]">
<$geolayer json={{!!text}} color={{!!color}} name={{!!caption}}/> <$geolayer json={{!!text}} color={{!!color}} name={{!!caption}} popupTemplate={{!!popup-template}}/>
</$list> </$list>
</$geomap> </$geomap>
<<tabs tabsList:"[all[tiddlers+shadows]tag[$:/tags/GeospatialDemo]]" default:"GeoMarkers">> <<tabs tabsList:"[all[tiddlers+shadows]tag[$:/tags/GeospatialDemo]]" default:"GeoFeatures">>

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -0,0 +1,3 @@
title: cities/LimehouseTownHall/image
type: image/jpeg
tags: $:/tags/Demo/Cities

View File

@ -1,9 +1,11 @@
title: cities/LimehouseTownHall title: cities/LimehouseTownHall
tags: $:/tags/GeoMarker tags: $:/tags/GeoMarker $:/tags/Demo/Cities
caption: Limehouse Town Hall caption: Limehouse Town Hall
lat: 51.51216651476898 lat: 51.51216651476898
long: -0.03138562132137639 long: -0.03138562132137639
alt: 0 alt: 0
{{cities/LimehouseTownHall/image}}
This is Limehouse Town Hall! This is Limehouse Town Hall!

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -0,0 +1,3 @@
title: cities/Motovun/image
type: image/jpeg
tags: $:/tags/Demo/Cities

View File

@ -1,9 +1,11 @@
title: cities/Motovun title: cities/Motovun
tags: $:/tags/GeoMarker tags: $:/tags/GeoMarker $:/tags/Demo/Cities
icon: Motovun Jack.svg icon: Motovun Jack.svg
caption: Motovun caption: Motovun
lat: 45.336453407749225 lat: 45.336453407749225
long: 13.828231379455806 long: 13.828231379455806
alt: 0 alt: 0
{{cities/Motovun/image}}
This is Motovun! This is Motovun!

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -0,0 +1,3 @@
title: cities/NewYork/image
type: image/jpeg
tags: $:/tags/Demo/Cities

View File

@ -1,8 +1,10 @@
title: cities/NewYork title: cities/NewYork
tags: $:/tags/GeoMarker tags: $:/tags/GeoMarker $:/tags/Demo/Cities
caption: New York caption: New York
lat: 40.712778 lat: 40.712778
long: -74.006111 long: -74.006111
alt: 0 alt: 0
{{cities/NewYork/image}}
This is New York! This is New York!

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@ -0,0 +1,3 @@
title: cities/Oxford/image
type: image/jpeg
tags: $:/tags/Demo/Cities

View File

@ -1,8 +1,10 @@
title: cities/Oxford title: cities/Oxford
tags: $:/tags/GeoMarker tags: $:/tags/GeoMarker $:/tags/Demo/Cities
caption: Oxford caption: Oxford
lat: 51.751944 lat: 51.751944
long: -1.257778 long: -1.257778
alt: 0 alt: 0
{{cities/Oxford/image}}
This is Oxford! This is Oxford!

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,3 @@
title: cities/Toronto/image
type: image/jpeg
tags: $:/tags/Demo/Cities

View File

@ -1,8 +1,10 @@
title: cities/Toronto title: cities/Toronto
tags: $:/tags/GeoMarker tags: $:/tags/GeoMarker $:/tags/Demo/Cities
caption: Toronto caption: Toronto
lat: 43.651070 lat: 43.651070
long: -79.347015 long: -79.347015
alt: 0 alt: 0
{{cities/Toronto/image}}
This is Toronto! This is Toronto!

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -0,0 +1,3 @@
title: cities/Winchester/image
type: image/jpeg
tags: $:/tags/Demo/Cities

View File

@ -1,8 +1,10 @@
title: cities/Winchester title: cities/Winchester
tags: $:/tags/GeoMarker tags: $:/tags/GeoMarker $:/tags/Demo/Cities
caption: Winchester caption: Winchester
lat: 51.0632 lat: 51.0632
long: -1.308 long: -1.308
alt: 0 alt: 0
{{cities/Winchester/image}}
This is Winchester! This is Winchester!

View File

@ -0,0 +1,4 @@
title: $:/config/GeospatialDemo/FeatureVisibility/$:/
geospatialdemo/features/harvard-volcanoes-of-the-world: hide
geospatialdemo/features/natural-earth-countries-low-res: hide

View File

@ -0,0 +1,12 @@
title: $:/geospatialdemo/features/canada-census-subdivision-millesime/popupTemplate
!!! Canadian Census Subdivision Boundary
|!Field |!English |!French |
|Year |<$text text={{{ [<feature>jsonget[properties],[year]] }}}/> |<|
|Province Code |<$text text={{{ [<feature>jsonget[properties],[prov_code]join[,]] }}}/> |<|
|Province Name |<$text text={{{ [<feature>jsonget[properties],[prov_name_en]join[,]] }}}/> |<$text text={{{ [<feature>jsonget[properties],[prov_name_fr]join[,]] }}}/> |
|Census Division Code |<$text text={{{ [<feature>jsonget[properties],[cd_code]join[,]] }}}/> |<|
|Census Division Name |<$text text={{{ [<feature>jsonget[properties],[cd_name_en]join[,]] }}}/> |<$text text={{{ [<feature>jsonget[properties],[cd_name_fr]join[,]] }}}/> |
|Census Subdivision Code |<$text text={{{ [<feature>jsonget[properties],[csd_area_code]join[,]] }}}/> |<|
|Census Subdivision Name |<$text text={{{ [<feature>jsonget[properties],[csd_name_en]join[,]] }}}/> |<$text text={{{ [<feature>jsonget[properties],[csd_name_fr]join[,]] }}}/> |

View File

@ -3,3 +3,4 @@ caption: Canada Census Subdivisions Millesime
type: application/json type: application/json
tags: $:/tags/GeoFeature tags: $:/tags/GeoFeature
color: #f8f color: #f8f
popup-template: $:/geospatialdemo/features/canada-census-subdivision-millesime/popupTemplate

View File

@ -0,0 +1,10 @@
title: $:/geospatialdemo/features/harvard-volcanoes-of-the-world/popupTemplate
!!! Harvard Volcanoes of the World
|Number |<$text text={{{ [<feature>jsonget[properties],[NUMBER_]] }}}/> |
|Name |<$text text={{{ [<feature>jsonget[properties],[NAME_]] }}}/> |
|Location |<$text text={{{ [<feature>jsonget[properties],[LOCATION]] }}}/> |
|Type |<$text text={{{ [<feature>jsonget[properties],[TYPE_]] }}}/> |
|Status |<$text text={{{ [<feature>jsonget[properties],[STATUS]] }}}/> |
|Time Frame |<$text text={{{ [<feature>jsonget[properties],[TIME_FRAME]] }}}/> |

View File

@ -1,5 +1,6 @@
title: $:/geospatialdemo/features/harvard-volcanoes-of-the-world title: $:/geospatialdemo/features/harvard-volcanoes-of-the-world
caption: Harvard Volcanoes of the World caption: Harvard Volcanoes of the World
type: application/json type: application/json
tags: $:/tags/GeoFeature/Hidden tags: $:/tags/GeoFeature
color: #f88 color: #f88
popup-template: $:/geospatialdemo/features/harvard-volcanoes-of-the-world/popupTemplate

View File

@ -0,0 +1,32 @@
title: $:/geospatialdemo/features/natural-earth-countries-low-res/popupTemplate
!!! Countries of the World from Natural Earth
''<$text text={{{ [<feature>jsonget[properties],[name_en]] }}}/>'' (<$text text={{{ [<feature>jsonget[properties],[formal_en]] }}}/>)
<div style=`height: 10em; overflow: scroll;`>
<table>
<thead>
<tr>
<th>
Field
</th>
<th>
Value
</th>
</tr>
</thead>
<tbody>
<$list filter="[<feature>jsonindexes[properties]]">
<tr>
<td>
<$text text=<<currentTiddler>>/>
</td>
<td>
<$text text={{{ [<feature>jsonget[properties],<currentTiddler>] }}}/>
</td>
</tr>
</$list>
</tbody>
</table>
</div>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
title: $:/geospatialdemo/features/natural-earth-countries-low-res
caption: Countries of the World from Natural Earth
type: application/json
tags: $:/tags/GeoFeature
color: #88f
popup-template: $:/geospatialdemo/features/natural-earth-countries-low-res/popupTemplate

View File

@ -0,0 +1,6 @@
title: $:/geospatialdemo/features/us-states/popupTemplate
!!! US State Boundary
|State |<$text text={{{ [<feature>jsonget[properties],[name]] }}}/> |
|Population Density |<$text text={{{ [<feature>jsonget[properties],[density]] }}}/> |

View File

@ -3,3 +3,4 @@ caption: US State Boundaries
type: application/json type: application/json
tags: $:/tags/GeoFeature tags: $:/tags/GeoFeature
color: #88f color: #88f
popup-template: $:/geospatialdemo/features/us-states/popupTemplate

View File

@ -14,7 +14,7 @@ title: ui/geofeature
state=<<qualify "$:/state/demo-map">> state=<<qualify "$:/state/demo-map">>
startPosition="bounds" startPosition="bounds"
> >
<$geolayer json={{!!text}} color={{!!color}}/> <$geolayer json={{!!text}} color={{!!color}} popupTemplate={{!!popup-template}}/>
</$geomap> </$geomap>
!! Intersect with other features !! Intersect with other features

View File

@ -67,7 +67,7 @@ title: ui/geomarker
state=<<qualify "$:/state/demo-map">> state=<<qualify "$:/state/demo-map">>
startPosition="bounds" startPosition="bounds"
> >
<$geolayer lat={{!!lat}} long={{!!long}} alt={{!!alt}} color={{!!color}}/> <$geolayer lat={{!!lat}} long={{!!long}} alt={{!!alt}} color={{!!color}} properties={{{ [[{}]jsonset[title],<currentTiddler>] }}} popupTemplate="ui/PopupTemplate"/>
</$geomap> </$geomap>
!! Distance to other markers !! Distance to other markers

View File

@ -0,0 +1,9 @@
title: ui/PopupTemplate
<div width="300px">
<$let currentTiddler={{{ [<feature>jsonget[properties],[title]] }}}>
<$link><$text text=<<currentTiddler>>/></$link>
<!-- <$codeblock code={{{ [<feature>] }}}/> -->
<$transclude $tiddler=<<currentTiddler>> $mode="block"/>
</$let>
</div>

View File

@ -17,8 +17,10 @@ The following attributes are supported:
|''alt'' |Optional altitude of marker if json attribute missing | |''alt'' |Optional altitude of marker if json attribute missing |
|''draggable'' |Set to "yes" to make the marker draggable | |''draggable'' |Set to "yes" to make the marker draggable |
|''updateActions'' |Optional actions when the marker is dragged other otherwise modified. The variables ''lat'' and ''long'' contain the new coordinates of the marker | |''updateActions'' |Optional actions when the marker is dragged other otherwise modified. The variables ''lat'' and ''long'' contain the new coordinates of the marker |
|''properties'' |<<.from-version "5.3.6">> Optional JSON properties to be attached to the marker (only supported for non-JSON layers) |
|''popupTemplate'' |<<.from-version "5.3.6">> Optional template to be used for popups. The template is rendered with the variable ''feature'' containing the JSON text of the feature |
Note that the `<$geolayer>` widget can be used in one of two modes: Note that the `<$geolayer>` widget can be used in one of two modes:
* With the ''json'' attibute specifying the layer to be drawn * With the ''json'' attibute specifying the layer to be drawn
* With the ''lat'', ''long'' and optional ''alt'' attributes specifying a marker to be drawn * With the ''lat'', ''long'' and optional ''alt'' and ''properties'' attributes specifying a marker to be drawn

View File

@ -9,9 +9,13 @@ The `<$geomap>` widget displays an interactive map using [[Leaflet.js|https://le
The following attributes are supported: The following attributes are supported:
|!Attribute |!Description | |!Attribute |!Description |
|''width'' |<<.from-version "5.3.6">> The width of the map in CSS units (defaults to `100%`) |
|''height'' |<<.from-version "5.3.6">> The height of the map in CSS units (defaults to `600px`) |
|''state'' |The title of a state tiddler used to track the state of the map in the `zoom`, `long` and `lat` fields | |''state'' |The title of a state tiddler used to track the state of the map in the `zoom`, `long` and `lat` fields |
|''startPosition'' |Optional keyword representing the starting position for the map: "world" (the default) shows the entire map, "bounds" zooms to the bounds of the loaded layers | |''startPosition'' |Optional keyword representing the starting position for the map: "world" (the default) shows the entire map, "bounds" zooms to the bounds of the loaded layers |
|''layersPanel'' |Optional starting status for the layers panel: "collapsed" (the default) causes the layers panel to initially be shown collapsed, "open" causes the layers panel to initially be shown opened | |''layersPanel'' |Optional starting status for the layers panel: "collapsed" (the default) causes the layers panel to initially be shown collapsed, "open" causes the layers panel to initially be shown opened |
|''maxZoom'' |<<.from-version "5.3.6">> Optional maximum zoom level, from 1 to the maximum zoom level supported by the background layer |
|''popupTemplate'' |<<.from-version "5.3.6">> Optional template to be used for popups. The template is rendered with the variable ''feature'' containing the JSON text of the feature |
If no base layers are defined by `<$geobaselayer>` widgets within the `<$geomap>` widget then all the available base layers will be loaded by the equivalent of the following code: If no base layers are defined by `<$geobaselayer>` widgets within the `<$geomap>` widget then all the available base layers will be loaded by the equivalent of the following code:
@ -61,6 +65,25 @@ If no base layers are defined by `<$geobaselayer>` widgets within the `<$geomap>
<$data $tiddler="$:/plugins/tiddlywiki/geospatial"/> <$data $tiddler="$:/plugins/tiddlywiki/geospatial"/>
</$testcase> </$testcase>
<$testcase>
<$data
title="Description"
text="Map with geomarker with popup"
/>
<$data $filter="[tag[$:/tags/Demo/Cities]sort[title]]"/>
<$data title="Output" text="""<$geomap
state=<<qualify "$:/state/demo-map">>
popupTemplate="ui/PopupTemplate"
>
<$list filter="[all[tiddlers+shadows]tag[$:/tags/GeoMarker]]">
<$geolayer lat={{!!lat}} long={{!!long}} alt={{!!alt}} color={{!!color}} properties={{{ [[{}]jsonset[title],<currentTiddler>] }}}/>
</$list>
</$geomap>
"""/>
<$data $tiddler="ui/PopupTemplate"/>
<$data $tiddler="$:/plugins/tiddlywiki/geospatial"/>
</$testcase>
<$testcase> <$testcase>
<$data <$data
title="Description" title="Description"

View File

@ -1,9 +1 @@
<?xml version="1.0" encoding="utf-8"?> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 365 560"><path fill="#00AEEF" stroke="#000" stroke-width="5" d="M182.9 551.7c0 .1.2.3.2.3s175.2-269 175.2-357.4c0-130.1-88.8-186.7-175.4-186.9C96.3 7.9 7.5 64.5 7.5 194.6 7.5 283 182.8 552 182.8 552l.1-.3zm-60.7-364.5c0-33.6 27.2-60.8 60.8-60.8 33.6 0 60.8 27.2 60.8 60.8S216.5 248 182.9 248c-33.5 0-60.7-27.2-60.7-60.8z"/></svg>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 365 560">
<g>
<path fill="#00AEEF" stroke="#000000" stroke-width="5" d="M182.9,551.7c0,0.1,0.2,0.3,0.2,0.3S358.3,283,358.3,194.6c0-130.1-88.8-186.7-175.4-186.9
C96.3,7.9,7.5,64.5,7.5,194.6c0,88.4,175.3,357.4,175.3,357.4S182.9,551.7,182.9,551.7z M122.2,187.2c0-33.6,27.2-60.8,60.8-60.8
c33.6,0,60.8,27.2,60.8,60.8S216.5,248,182.9,248C149.4,248,122.2,220.8,122.2,187.2z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 645 B

After

Width:  |  Height:  |  Size: 382 B

View File

@ -0,0 +1,3 @@
title: $:/plugins/tiddlywiki/geospatial/templates/default-popup-template
Feature: <$text text={{{ [<feature>] }}}/>

View File

@ -48,8 +48,7 @@ GeomapWidget.prototype.render = function(parent,nextSibling) {
this.contentRoot.render(this.contentContainer,null); this.contentRoot.render(this.contentContainer,null);
// Render a wrapper for the map // Render a wrapper for the map
this.domNode = this.document.createElement("div"); this.domNode = this.document.createElement("div");
this.domNode.style.width = "100%"; this.setMapSize();
this.domNode.style.height = "600px";
// Insert it into the DOM // Insert it into the DOM
parent.insertBefore(this.domNode,nextSibling); parent.insertBefore(this.domNode,nextSibling);
this.domNodes.push(this.domNode); this.domNodes.push(this.domNode);
@ -63,7 +62,13 @@ GeomapWidget.prototype.render = function(parent,nextSibling) {
GeomapWidget.prototype.renderMap = function() { GeomapWidget.prototype.renderMap = function() {
var self = this; var self = this;
// Create the map // Create the map
this.map = $tw.Leaflet.map(this.domNode); var options = {
};
if(this.geomapMaxZoom) {
options.maxZoom = $tw.utils.parseInt(this.geomapMaxZoom);
}
this.map = $tw.Leaflet.map(this.domNode,options);
// No layers rendered // No layers rendered
this.renderedLayers = []; this.renderedLayers = [];
this.baseLayers = []; this.baseLayers = [];
@ -73,16 +78,17 @@ GeomapWidget.prototype.renderMap = function() {
$tw.Leaflet.control.scale().addTo(this.map); $tw.Leaflet.control.scale().addTo(this.map);
// Listen for pan and zoom events and update the state tiddler // Listen for pan and zoom events and update the state tiddler
this.map.on("moveend zoomend",function(event) { this.map.on("moveend zoomend",function(event) {
if(self.geomapStateTitle) { if(self.hasAttribute("state")) {
var c = self.map.getCenter(), var stateTitle = self.getAttribute("state"),
c = self.map.getCenter(),
lat = "" + c.lat, lat = "" + c.lat,
long = "" + c.lng, long = "" + c.lng,
zoom = "" + self.map.getZoom(), zoom = "" + self.map.getZoom(),
tiddler = self.wiki.getTiddler(self.geomapStateTitle); tiddler = self.wiki.getTiddler(stateTitle);
// Only write the tiddler if the values have changed // Only write the tiddler if the values have changed
if(!tiddler || tiddler.fields.lat !== lat || tiddler.fields.long !== long || tiddler.fields.zoom !== zoom) { if(!tiddler || tiddler.fields.lat !== lat || tiddler.fields.long !== long || tiddler.fields.zoom !== zoom) {
self.wiki.addTiddler(new $tw.Tiddler({ self.wiki.addTiddler(new $tw.Tiddler({
title: self.geomapStateTitle, title: stateTitle,
lat: lat, lat: lat,
long: long, long: long,
zoom: zoom zoom: zoom
@ -161,8 +167,10 @@ GeomapWidget.prototype.refreshMap = function() {
}); });
this.map.addLayer(markers); this.map.addLayer(markers);
// Process embedded geolayer widgets // Process embedded geolayer widgets
var defaultPopupTemplateTitle = self.getAttribute("popupTemplate","$:/plugins/tiddlywiki/geospatial/templates/default-popup-template");
this.findChildrenDataWidgets(this.contentRoot.children,"geolayer",function(widget) { this.findChildrenDataWidgets(this.contentRoot.children,"geolayer",function(widget) {
var jsonText = widget.getAttribute("json"), var jsonText = widget.getAttribute("json"),
popupTemplateTitle = widget.getAttribute("popupTemplate",defaultPopupTemplateTitle),
geoJson = []; geoJson = [];
if(jsonText) { if(jsonText) {
// Layer is defined by JSON blob // Layer is defined by JSON blob
@ -171,7 +179,8 @@ GeomapWidget.prototype.refreshMap = function() {
// Layer is defined by lat long fields // Layer is defined by lat long fields
var lat = $tw.utils.parseNumber(widget.getAttribute("lat","0")), var lat = $tw.utils.parseNumber(widget.getAttribute("lat","0")),
long = $tw.utils.parseNumber(widget.getAttribute("long","0")), long = $tw.utils.parseNumber(widget.getAttribute("long","0")),
alt = $tw.utils.parseNumber(widget.getAttribute("alt","0")); alt = $tw.utils.parseNumber(widget.getAttribute("alt","0")),
properties = widget.getAttribute("properties");
geoJson = { geoJson = {
"type": "FeatureCollection", "type": "FeatureCollection",
"features": [ "features": [
@ -184,6 +193,9 @@ GeomapWidget.prototype.refreshMap = function() {
} }
] ]
}; };
if(properties) {
geoJson.features[0].properties = $tw.utils.parseJSONSafe(properties);
}
} }
var draggable = widget.getAttribute("draggable","no") === "yes", var draggable = widget.getAttribute("draggable","no") === "yes",
layer = $tw.Leaflet.geoJSON(geoJson,{ layer = $tw.Leaflet.geoJSON(geoJson,{
@ -205,9 +217,23 @@ GeomapWidget.prototype.refreshMap = function() {
return marker; return marker;
}, },
onEachFeature: function(feature,layer) { onEachFeature: function(feature,layer) {
if(feature.properties) { layer.bindPopup(function() {
layer.bindPopup(JSON.stringify(feature.properties,null,4)); var widget = self.wiki.makeTranscludeWidget(popupTemplateTitle, {
} document: self.document,
parentWidget: self,
parseAsInline: false,
importPageMacros: true,
variables: {
feature: JSON.stringify(feature)
}
});
var container = self.document.createElement("div");
widget.render(container,null);
self.wiki.addEventListener("change",function(changes) {
widget.refresh(changes,container,null);
});
return container;
});
} }
}).addTo(self.map); }).addTo(self.map);
var name = widget.getAttribute("name") || ("Untitled " + untitledCount++); var name = widget.getAttribute("name") || ("Untitled " + untitledCount++);
@ -226,12 +252,12 @@ GeomapWidget.prototype.refreshMap = function() {
overlayLayers[layer.name] = layer.layer; overlayLayers[layer.name] = layer.layer;
}); });
this.layerControl = $tw.Leaflet.control.layers(baseLayers,overlayLayers,{ this.layerControl = $tw.Leaflet.control.layers(baseLayers,overlayLayers,{
collapsed: this.geomapLayersPanel !== "open" collapsed: this.getAttribute("layersPanel") !== "open"
}).addTo(this.map); }).addTo(this.map);
// Restore the saved map position and zoom level // Restore the saved map position and zoom level
if(!this.setMapView()) { if(!this.setMapView()) {
// If there was no saved position then look at the startPosition attribute // If there was no saved position then look at the startPosition attribute
switch(this.geomapStartPosition) { switch(this.getAttribute("startPosition")) {
case "bounds": case "bounds":
var bounds = null; var bounds = null;
$tw.utils.each(this.renderedLayers,function(layer) { $tw.utils.each(this.renderedLayers,function(layer) {
@ -259,6 +285,11 @@ GeomapWidget.prototype.refreshMap = function() {
Set the map center and zoom level from the values in the state tiddler. Returns true if the map view was successfully set 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() { GeomapWidget.prototype.setMapView = function() {
// Set the maximum zoom level
if(this.hasAttribute("maxZoom")) {
this.map.setMaxZoom($tw.utils.parseInt(this.getAttribute("maxZoom")));
}
// Set the view to the content of the state tiddler
var stateTiddler = this.geomapStateTitle && this.wiki.getTiddler(this.geomapStateTitle); var stateTiddler = this.geomapStateTitle && this.wiki.getTiddler(this.geomapStateTitle);
if(stateTiddler) { 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)); this.map.setView([$tw.utils.parseNumber(stateTiddler.fields.lat,0),$tw.utils.parseNumber(stateTiddler.fields.long,0)], $tw.utils.parseNumber(stateTiddler.fields.zoom,0));
@ -267,13 +298,15 @@ GeomapWidget.prototype.setMapView = function() {
return false; return false;
}; };
GeomapWidget.prototype.setMapSize = function() {
this.domNode.style.width = this.getAttribute("width","100%");
this.domNode.style.height = this.getAttribute("height","600px");
};
/* /*
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.geomapStartPosition = this.getAttribute("startPosition");
this.geomapLayersPanel = this.getAttribute("layersPanel");
}; };
/* /*
@ -286,9 +319,12 @@ GeomapWidget.prototype.refresh = function(changedTiddlers) {
if(result) { if(result) {
this.refreshMap(); this.refreshMap();
} else { } else {
// Reset the width and height and max zoom if they have changed
if(changedAttributes.width || changedAttributes.height) {
this.setMapSize();
}
// If we're not doing a full refresh, reset the position if the state tiddler has changed // If we're not doing a full refresh, reset the position if the state tiddler has changed
if(changedAttributes.state || changedTiddlers[this.geomapStateTitle]) { if(changedAttributes.state || (this.hasAttribute("state") && changedTiddlers[this.getAttribute("state")]) || changedAttributes.maxZoom) {
this.geomapStateTitle = this.getAttribute("state");
this.setMapView(); this.setMapView();
} }
} }