Tuesday, March 23, 2021
Where the RF Meets the Road
Wednesday, March 10, 2021
Advanced Static Route Maps With OpenStreetMap
When using the Tesoro choosedataset/routemap feature - which generates a static map using the Leaflet library for OpenStreetMap - you can draw multiple routes on a single map just by using the Choose File menu more than once without refreshing the web page.
The default properties used by Tesoro for route maps gives the route a color of red and a weight (pixel width) of 3.0, where these are both properties supported by the Leaflet polyline API. This is what you saw in the images in A Static Route Map Display Using OpenStreetMap.
You can override this for all routes on the same map by specifying Leaflet polyline options (including color, weight, and others) as keyword=value pairs in URL query parameters. When you do this, your URL will look something like this example, which specifies a yellow polyline with a weight of 3.
http://tesoro/tesoro/choosedataset.html?color=yellow&weight=3
You can also specify options for a specific route by including the Leaflet polyline options as properties in the original dataset, just as its PATH property contains the array of coordinate pairs. When you do this, your dataset will look something like this example (but probably a lot longer), which specifies a blue polyline with a weight of 6.
{
"color": "blue",
"weight": 6.0,
"PATH": [
[ 39.7943158, -105.1533988 ]
, [ 39.7943148, -105.1533981 ]
, [ 39.7943140, -105.1533973 ]
, [ 39.7943136, -105.1533960 ]
]
}
You can use both together, generating multiple polylines on the same map, some with your modified default options, some with more specific options.
Below is a map with two routes, one yellow, one blue, each defined with its own dataset, each imported by its own Choose Dataset dialog. The yellow route was colored using the URL query parameters which changed the default color from red to yellow. The blue route was specified by a color property inside the dataset itself for blue.
The properties in the dataset will override the URL query properties. The order in which you choose the datasets may also be important for your specific application, since successive routes will be rendered on top of prior routes. Changing the weight you use for each route can improve the readability of a multi-route map. Changing the color property of a route can also make it more readable on a specific map, depending on the background colors used in the map.
Tuesday, March 09, 2021
A Static Route Map Display Using OpenStreetMap
Sometimes I need a moving map display in real-time to track my projects at they move around in the field. Sometimes I want to playback a stored dataset of geolocation coordinates. And sometimes I want to see a static route map that shows the path a project took in the field. This latest addition to my Tesoro project does that. As before, it uses the Leaflet client-side JavaScript library and an OpenStreetMap tile server.
Here are a couple of static route maps generated from geolocation datasets collected from field testing. (You can click on either one to see a larger version.)
This new feature adds another web page, choosedataset.html, and another client-side JavaScript program, routemap.js, to the project. As with the moving map display, occasionally useful information is displayed in the browser's JavaScript log, as shown in the second image.
(Blogger kind of sucks for rendering code. Each example below in the monospace font is intended to be a single line.)
My Hazer C-based GNSS software stores geolocation data in a Comma Separated Value (CSV) format that makes it simple to import into spreadsheets and to post process for other uses. Each line of the CSV dataset looks like this.
"neon", 1299, 4, 0, 10, 1600356403.090779879, 1600356402.000000000, 39.7328371, -105.1543085, 0., 1766.500, 1745.000, 0., 4.948000, 127.340000000, -1.10049, 0.40705, 127.34082, 0.52130, 0.46396, 1.12472, 0, 0\n
My moving map display described in A Moving Map Display Using OpenStreetMap and subsequent articles steers the moving map, in real-time or in playback, using JSON datagrams, each datagram containing the coordinates for the next point. Each individual datagram looks like this.
{ "NAM": "neon", "NUM": 1300, "TIM": 1600356403, "LAT": 39.7328281, "LON": -105.1542851, "MSL": 1766.500, "LBL": "2020-09-17T15:26:43Z" }\n
The dataset used by the static route map is a JSON object containing an array of latitude and longitude coordinates. All of the points on the route are contained in a single array that is imported by the new software and stored in memory for processing. The dataset looks like this (although is typically much larger).
{ "PATH": [ [ 39.7762445, -105.1621035 ], [ 39.7762428, -105.1622863 ], [ 39.7762416, -105.1624700 ], [ 39.7762408, -105.1626533 ], [ 39.7762401, -105.1628366 ], [ 39.7762396, -105.1630200 ] ] }
Hazer contains scripts to convert its CSV format into JSON datagrams for playback
csvplayback 192.168.1.253:tesoro dat/yodel/20200917/vehicle.csv
or in real-time
csvfollow 192.168.1.253:tesoro dat/yodel/20200915/vehicle.csv
or into a JSON dataset
csvdataset < dat/yodel/20200915/vehicle.csv > vehicle.json
which can be used directly by the Tesoro map software.
Because the JSON object for the static route map has to all be stored in memory for processing by the Leaflet library, there is a limit to how many points you can render at a time. I ran into the same issue using the XML-based Keyhole Markup Language (KML) when rendering routes with Google Earth. But the second image above rendered a dataset of more than 8500 data points, collected from a field test almost two and a half hours long, with no discernible delay.
But for those really large datasets, the Hazer csvdataset script takes an optional modulo argument to sample the incoming CSV data. The Hazer gpstool utility stores CSV records at approximately 1Hz. So an argument of 10 would sample every tenth data point, capturing the target location about every ten seconds. But no matter the argument value, the first and last data points are included so that the start and end of the route is always rendered.
csvdataset 10 < dat/yodel/20200915/vehicle.csv > vehicle.json
Saturday, March 06, 2021
Catus Amat Arca Archa
As is well known, cats are the natural enemies of vampires. This has been clearly established by overwhelming empirical evidence. This is because cats recognize that vampires can take the form of bats, which are just a kind of flying mouse (German: "fledermaus" or "flitter mouse"). Also, cats are naturally aggressive towards any creature that tries to unseat them as the apex predator. Finally, cats must challenge anything that threatens the cushy situation cats have created for themselves with their human domestic servants, whom vampires consider to be merely livestock. [Ref: J. A. Lindqvist, Let the Right One In ("Låt den rätte komma in"), St. Martin's Griffin, 2004]
Vampires are repelled by the Christian cross, not due to its religious symbolism, but because vampires have a cognitive bias against right angles. Again, there is a wealth of research about this, the most widely accepted hypothesis being that vampires predate the evolution of humans by hundreds of thousands of years, having evolved long long before our distant ancestors introduced artifacts built with right angles, angles which typically do not appear in nature. Vampire brains never evolved the ability to deal with right angles, which may also explain why humans prefer Euclidian architecture, as a form of defense. [Ref: P. Watts, Blindsight, Tor, 2006]
This is why cats are attracted to boxes. Or even squares drawn on the ground. They feel safe from vampires, their natural enemies, when inside boxes because they know that the vampires will be repelled by the right angles found in boxes. The fact that cats began cohabiting with humans when we began building structures incorporating right angles cannot be a coincidence.
This startling and enlightening revelation came to me this morning during an argument with one of my Beloved Feline Overlords while I was trying to break down some old cardboard boxes for recycling - an argument my BFO, of course, won.
I refer to this hypothesis as catus amat arca archa.
I await the accolades that are sure to follow this major insight.
Acknowledgements
The author would like to acknowledge his BFO and lab assistant Sophia for her significant contributions to this research effort.
Thursday, March 04, 2021
The OpenStreetMap Moving Map on Mobile Devices
One of the advantages of implementing tools as web applications is that it opens the possibility of running them on a wide variety of platforms, with browsers that support JavaScript and HTML5, with little or no additional effort. I'm a little embarrassed to admit that it just recently occurred to me that I should be able to run my OpenStreetMap (OSM) Moving Map web app on my iPad and iPhone. So I did. It worked fine.
Here is a screen snapshot from my iPad using Safari.
Here is one from my iPhone 7, also using Safari.
And for good measure, here is a screenshot from my Google Pixel 4 development phone using Chrome under Android 11. It worked fine too.
I routinely run the web app on Safari, Firefox, and Chrome on my desktop Mac or my Mac laptop, and on Firefox and Chrome on an x86_64 Linux server. Now I can add genuine mobile devices to that list.
But wait! There's more!
I described in prior articles about this project, code-named Tesoro, how the server-side JavaScript program channel.js serves as a conduit between my Hazer C-based GPS software in the field, which forwards geolocation data in JSON over UDP, and my web application whose OSM-based moving map is steered by that incoming data stream. Alas, channel.js only services a single data source at a time (although you can run several instances simultaneously using different UDP port numbers).
Tesoro now includes another server-side JavaScript program, controller.js, that can handle an arbitrary number of geolocation data sources concurrently, all using the same UDP port number, and provide an individual URL for each one for the Tesoro web application. I have an instance of controller.js executing now on one of the Raspberry Pis that runs 24x7 at the Palatial Overclock Estate, serving as the sink for any geolocation project in the field (or for a playback of the dataset collected from any such project), and as the source of that same data for any moving map displays on my internal network.