Geospatial widget

Has anyone played around with the geospatial widget? I would like some idea as to its consistency, ease of use, etc. I have been trying it out on a simple TW but before adopting it to my 2000+ tiddler wiki, would like some idea as to its effects on my TW.

Bobj

I haven’t had problems so far with the Geospatial plugin. I don’t think it’s a “heavy” JavaScrpt plugin like some of the other ones are.
That said, as attractive as some of the JavaScript plugins are, I generally avoid them (you’ll know them because they prompt: “requires reload”) because they slow things down and they have sometimes crashed on certain devices, although, I’ve never had that happen with the Geospatial plugin.
It’s worth trying out, but fork it first and make sure to try it out on other devices (older mobile devices in particular). It has a lot of potential with customization.
I’m curious what you might be using it for.
Consider trying the same plugin through QGIS using its “qgis2web” plugin from which you can create stand-alone web pages of maps which is very impressive and customizable. Integrate these stand-alone pages into your TiddlyWiki using external links. I’ve yet to have any success embedding those leaflet maps into TW. But it is possible.

thanks @AlfieA, I’ll have a look at qgis2web plugin.

I am looking for a way to map the locations of individual statues in the community around Australia. Each item would obviously have a dedicated tiddler and if it has long and lat, then I would like to show that location in a map. I am also considering a map of Australia showing all items, which I gather geospatial can do by aggregating objects as the map zooms out.

As for the individual maps, I gather there is a map created at runtime when the tiddler is opened which may have an associated state tiddler to record the state of the map when it was last viewed. If this is on a per map basis, then I guess we’d end up with ~2000 state tiddlers. However, if the log and lat are coded into the geospatial call, then we might not need these but I can not figure out how to provide the right amount of zoom when the map is displayed. Maybe these state tiddlers are automatically deleted but if so when?

The maps might as well be compiled once as the items will rarely move. If they move we then just need to create a new map showing the new location.

Anyway, just ideas at this stage. All suggestions and feedback welcome.

bobj

Give these TiddlyTools add-ons a try:

TiddlyTools/Panels/Maps
TiddlyTools/Panels/Location
TiddlyTools/Panels/StreetView

The TiddlyTools Maps panel takes latitude/longitude coordinates as input, and if the GeoSpatial plugin is present, it uses it to display the corresponding roadmap (openstreetmap) or satellite (esri-world-imagery) view for those coordinates.

The relevant GeoSpatial code usage is found in the TidldyTools Maps showMap_enabled() macro, like this:

\define satellite() $:/plugins/tiddlywiki/geospatial/baselayers/esri-world-imagery
\define streetmap() $:/plugins/tiddlywiki/geospatial/baselayers/openstreetmap
...
<$geomap state=<<mapstate>> startPosition=bounds>
	<$geobaselayer title={{{ [<maptype>match[satellite]then<satellite>else<streetmap>] }}}/>
	<$list filter="[<find>get[selection]enlist-input[]] ~[[]]" variable=place>
		<$let item={{{ [prefix<places>getindex<place>] }}}
			   lat={{{ [<place>get[latitude]]  ~[<item>jsonget[latitude]]  ~[<item>split[,]nth[1]!match[]] ~[<lat>] }}}
			  long={{{ [<place>get[longitude]] ~[<item>jsonget[longitude]] ~[<item>split[,]nth[2]!match[]] ~[<long>] }}}>
		<$geolayer lat=<<lat>> long=<<long>> popupTemplate="TiddlyTools/Panels/Maps" properties={{{ [[{}]jsonset[place],<place>jsonset[lat],<lat>jsonset[long],<long>] }}}/>
		</$let>
	</$list>
</$geomap>

Note that if the GeoSpatial plugin is NOT installed, it falls back to display the corresponding roadmap or satellite view in an embedded interactive IFRAME using the Google Places API (requires a free Google API key).

If you have the TiddlyTools Location panel installed, this adds a “get GPS position” button to the TiddlyTools Maps panel that uses the GeoSpatial tm-request-geolocation message to retrieve the current latitude/longitude which are automaticallly stored in a JSON $:/temp/TiddlyTools/Location tiddler for futher use.

If the GeoSpatial plugin is NOT installed, you can install a TiddlyTools custom widget, TiddlyTools/Widgets/action-getGPS.js which uses the browser-native navigator.geolocation.getCurrentPosition() JS function to retrieve the current latitude/longitude. This custom widget also supports “continuous timed update” GPS scanning using the browser-native navigator.geolocation.watchPosition() JS function.

The TiddlyTools Location panel also adds a “save/select place” popup interface to the TiddlyTools Maps panel that lets you easily build up a list of stored latitude/longitude “places” that can be used later on even if neither the GeoSpatial Plugin or $action-getGPS widget is currently installed. Saved places are stored in your TiddlyWiki in a JSON $:/config tiddler (see $:/config/TiddlyTools/Places). You can use the popup interface to select either single or multiple saved locations that can be simulaneously shown in the TiddlyTools Maps panel using the GeoSpatial Plugin “marker” features.

The TiddlyTools StreetView panel displays an embedded interactive IFRAME using the Google Places API (requires a free Google API key) to show street-level views of the currently entered/selected latitude/longitude or saved place.

If you are using the Google Places API you can capture remote “snapshot” JPG image tiddlers from the TiddlyTools Maps and TiddlyTools StreetView panels. These images are then available as stand-alone tiddlers that you can export/import into other TiddlyWikis. The TiddlyTools Maps panel can also capture direct snapshots from the GeoSpatial maps display using the “experimental” 5.3.7-prerelease $:/plugins/tiddlywiki/dom-to-image plugin which you can currently get from my TiddlyTools site. Note that, while this is “5.3.7-prerelease”, it also DOES work with the current TWCore (v5.3.6).

Give these TiddlyTools panels a try. They may provide you with just what you need, or at the very least, give you some idea of what is possible.

enjoy,
-e

3 Likes

Thanks @EricShulman a lot to digest

bobj

Hi @EricShulman

Is it possible to save “places” as individual tiddlers and to list them in the JSON $:/config tiddler using a filter?

If so, how would the “place” tiddler be structured eg. would the title, lat, long be stored in fields or in the text field as say

"10 Downing Street, London, England": "51.5033029,-0.1276021",

I tried it with

{
<$list filter=[tag[TTplaces]]>
{{ !!text }}
<br>
</$list>
}

in the JSON $:/config tiddler but that does not work. Any advice?

Cheers, Rob

The Location panel (which defines the “places” selection popup) already supports having places as separate tiddlers. (I didn’t include this info in my previous post because didn’t want to make the “information overload” even worse!)

The code that builds the list of saved places looks like this:

\define places()	$:/config/TiddlyTools/Places
\define label()		[{!!address}] [{!!city}] [{!!state}] [{!!province}] [{!!postcode}] [{!!zip}] +[trim[]!match[]join[, ]]
...
<$set name=tids	filter="[has[latitude]has[longitude]has[address]!has[draft.of]] :sort:string[subfilter<label>]">
<$set name=all	filter="[prefix<places>] :map:flat[indexes[]] [enlist<tids>]">

Thus, there are actually several ways to define saved places:

  • As previously described, places can be listed in a JSON tiddler, $:/config/TiddlyTools/Places.
  • You can create additional separate config tiddlers containing more JSON place definitions.
    • All of these tiddlers must use $:/config/TiddlyTools/Places as a title prefix to be automatically shown in the “places” selection popup list.
    • For example, you could create $:/config/TiddlyTools/Places/NSW that only defines places in New South Wales and $:/config/TiddlyTools/Places/TAS that only defines places in Tasmania. Theoretically, you could create numerous $:/config/TiddlyTools/Places/... tiddlers, each containing just one place definition in JSON format.
  • You can create individual tiddlers containing separate place definitions. To be recognized as a “place tiddler”, a tiddler must contain as least three fields named latitude, longitude, and address. The address field can hold the entire descriptive text string for the place.
  • Alternatively, a place tiddler can use the address field to store just the “street address” portion of the descriptive text, and use additional optional fields named city, state, province, postcode, and zip to store the other parts of the full descriptive text string. This enables you to more easily build your own interfaces for creating and searching place tiddlers, using separate $edit-text widgets for each part of the descriptive text string.
    • Regardless of whether you use a single descriptive address field, or separate fields for each part of the place definition, ALL these fields are combined to construct a comma-separated descriptive text string that appears in the “places” selection popup list.
    • Note that province and postcode fields are generally used for Canadian addresses, but state and zip fields are used for US addresses.

Even given the above variations on defining places, your alternative suggestion of allowing use of an embedded $list widget to generate the contents of a $:/config/TiddlyTools/Places tiddler is interesting. I will experiment with adding this as another method for defining places that potentially permits even greater flexibility for handling place data input.

enjoy,
-e

Many thanks for that comprehensive explanation, @EricShulman.

I have experimented with that and have successfully displayed places on a map that are defined in individual tiddlers with the fields lattitude, longitude and address.

It would be super convenient to be able to filter the tiddlers that are displayed so I look forward to hearing how your experimentation goes!

Cheers, Rob

After some experimentation, I’ve found that it is not so simple to build place list index tiddlers from wikitext scripting “on-the-fly” (i.e, within the TiddlyTools Location code).

However, I did come up with a strategy for using wikitext scripting to define a separate $button that can assemble place list index tiddlers from separate tiddlers.

Let’s suppose you have some tiddlers tagged with TTPlace, where each tiddler’s title is the description (“address”) of the place, and the tiddler’s text field contains latitude,longitude values. You can then create a tiddler (e.g., “MakeMyPlacesList”) that gathers all the separate TTPlace tiddlers into a single JSON index tiddler, like this:

<$let tid="$:/config/TiddlyTools/Places/MyPlacesList">
<$button> make MyPlacesList index from separate places
<$list filter="[tag[TTPlace]]">
   <$action-setfield $tiddler=<<tid>> $index={{!!title}} $value={{!!text}}/>
</$list>
</$button>

Then, after running this wikiscript, you can optionally delete the individual TTPlace tiddlers, since all the needed information is now collected in a single JSON index tiddler.

Also, while investigating this strategy, I realized that the CURRENT TiddlyTools Location “place list” code can work with a mix of JSON index tiddlers and/or dictionary index tiddlers (which use a simpler syntax that is easier to type). While JSON index tiddlers look like this:

{
"index":"value",
"index":"value",
"index":"value"
}

dictionary index tiddlers look like this:

index: value
index: value
index: value

i.e., you can omit the enclosing curly brackets, the quotes around index and value, and the trailing comma at the end of each line. The only limitation of the dictionary index format is that the index text cannot contain any colon (:) characters, as the index is not enclosed in quotes and the colon is used as the separator (aka, “delimiter”) between the index and value on each line.

To generate a dictionary index tiddler instead of a JSON index tiddler, all you need to do is to set the target tiddler’s type field to application/x-tiddler-dictionary before writing the list of index/value output, like this:

<$let tid="$:/config/TiddlyTools/Places/MyPlacesList">
<$button> make <<tid>> index from separate places
<$action-setfield $tiddler=<<tid>> type="application/x-tiddler-dictionary"/>
<$list filter="[tag[TTPlace]]">
   <$action-setfield $tiddler=<<tid>> $index={{!!title}} $value={{!!text}}/>
</$list>
</$button>

Hopefully, the above gives you some more ideas for implementing your own strategy for defining “places”.

Let me know how it goes…

enjoy,
-e

That’s very helpful, @EricShulman

I’ll let you know how I get on with that.

Cheers, Rob

Hi @EricShulman

That all works. I have been trying to amend the code so that I can select the tag from a dropdown list of available tags, rather than the tag being embedded in the code.

All the “places” are tagged with place, but each place is tagged with a second tag eg waterfall or monument. I want the dropdown list to display the secondary tags.

I have had some success using the EditTextWidget, where the required tag is entered into a field, but not using the SelectWidget where a list of tags is generated using a filter.

How might I do this?

Cheers, Rob

Something like this should do:

<$select field=target>
   <$list filter="[tag[place]get[tags]enlist-input[]unique[]] -[[place]]">
      <option><<currentTiddler>></option>
   </$list>
</$select>

Notes:

  • Get all tiddlers tagged with place
  • For each of these tiddlers, use get[tags] to fetch their tag field value (which contains a list of individual tags)
  • For each tags field value, use enlist-input[] to get each individual tag as a separate item
  • Eliminate any repeated use of the same individual tag
  • Finally, eliminate the place tag from the result

enjoy,
-e

Thanks, @EricShulman. The dropdown list shows the correct tags.

So I thought that I should replace

<$list filter="[tag[TTPlace]]">

with

<$list filter="[tag[{!!target}]]">

but clearly not as that does not list the tiddlers tagged with the value in the field target.

What have I done wrong?

Cheers, Rob

In filter syntax, the brackets around a filter parameter indicate how to interpret that parameter:

  • Use square brackets for literal text, i.e., [tag[TTPlace]]
  • Use curly brackets for tiddler field references, i.e., [tag{!!target}]
  • Use angle brackets for variable references, i.e., [tag<somevar>]

-e

Wunderbar!! Thank you so much @EricShulman. That has been really informative and opens up all sorts of interesting uses.

I hope our exchange will also benefit @Bob_Jansen and others.

Much appreciated. Cheers, Rob

@Rob_Jopling and others, this has been a very illuminating exchange. Thank you all for your time and input. You are right, this has been really informative and opens up all sorts of interesting uses.

It just goes to show how helpful the Tiddlywiki cohort of people are.

bobj

1 Like

I appreciate that @EricShulman has suggested an alternative to the geospatial plugin, I am continuing to try this plugin to get to know things better. So please bear with me on any questions.

I am trying to use the width and height parameters to the geospatial plugin but no mater what I enter, the rendered map remains the same size.

Can someone please explain what units shouldbe used in setting these parameters.

FYI, I plan to trial @EricShulman 's suggestions after I have conquered geospatial.

bobj

Hi @Bob_Jansen

I have also been testing the Geospatial Plugin and have tried to change the size of the map window by adjusting the width and height parameters in the without success.

If anyone can give us some help, that would be great.

Cheers, Rob