Panoramax JuraMap trail views


JuraMap


Notes

A simplified version of the deprecated proof-of-concept TrekView Explorer has been used for the panoramic viewing of JuraMap trails. This Rails-based server is being replaced by the backend and web API of a Panoramax instance for storing and viewing field photos. The trails are displayed on the "Trails" layer of the detailed raster JuraMap.

The background map tiles for the Panoramax trails layer is the vector JuraMap which is rendered using TileKiln, as explained in an Implementation Note.

The menu system for the raster JuraMap allows a Panoramax web viewer to be displayed using a modal (the Panoramax web viewer derived from the Geovisio web viewer is demonstrated here). The same approach can be used for the vector JuraMap.

1. Dynamic alignment

A major issue arose. It is unclear how the Geovisio/Panoramax viewer's map can be centred dynamically so as to align with the base map. As discussed below, one way to achieve alignment is to set an intial centre for the Geovisio web viewer and then to calculate the map centre when the base map is moved.

2. Distance between photos

The JuraMap trails are historic trails (i.e., probably existed at the end of the 19th century). As shown on the vector JuraMap , the trails involve hiking (OpenStreetMap sac_scale = hiking) or mountain hiking (sac_scale = mountain_hiking) with visibility ranging from "excellent" through "intermediate" to "bad".

The speed of walking is generally fairly slow and the distance between photos need only be about 100 to 200 metres in most cases (we do not plan to use the shorter distances needed for feature detection models).

Using a Google Pixel 4a smartphone, it is proving fairly difficult to establish Panoramax settings that avoid having duplicate photos which break the line representing the sequence of photos that is shown on the Panoramax map.

The problem may be the smartphone's relatively inacurate GPS. This is demonstrated in the Panoramax viewer where photos appear to correspond to points that are a few metres from trails. Moreover, the EXIF coordinate data for some photos are transferred to the next photo. Repositioning the photos is needed (using, for example, the JSOM OpenStreetMap editor with the photoadjust and photo_geotagging plugins).

3. Photo sequence mapping

To make sure that a sequence of photos that are separated by a fairly long distance (typically 100 to 200 metres), the variable ST_Length has changed from 50 to 300 in the Postgresql database function "compute_sequence_geometry" (thus making a multiline geometry for the sequence, spliting each picture separated by more than 300 meters). This changed can be made using pgAdmin or by executing a Python migration.after editing the file in "geovisio/migrations" with the name starting with "20240813".

  1. Playback speed

The other significant change was to force the time duration of the web-viewer's playback of each photo in a sequence to be the maximum. This was done by adding "&speed=3000" to the urlHash variable described below or by setting a viewer option ("transition:3000") according to the web viewer API documentation.

This change is for the variable "TransitionDuration Changes" which is the duration of stay on a picture during a sequence play. It is not immediately clear how the duration can be set more elegantly to the maximum value (speed = 3000). It may also be necesssary to set the Flask environment variable PIC_MAX_STAY_DURATION=3000.

Setting a constant playback speed of 3000 (or a smaller value for a shorter duration) was needed because the drop-down in the Geovisio web viewer to adjust the sequence playback speed sometimes was not displayed for an unknown reason.


Installation

1. Geovisio API

Installing a Postgresql database followed the normal procedure for OpenStreetMap editing and rendering applications. Installing the Panoramax API is straightforward (see gitlab repository).

Regarding API settings, for initial testing it is useful to use Flask and simply execute in a terminal:

  • flask run

with an .env file of the form:


FLASK_APP=geovisio

DB_URL=postgres://user:user@localhost:5432/geovisio

FS_URL=/home/user/geovisio/data

INFRA_NB_PROXIES=1

FLASK_RUN_HOST=0.0.0.0

PICTURE_PROCESS_DERIVATES_STRATEGY=PREPROCESS

API_ACCEPT_DUPLICATE

PIC_MAX_STAY_DURATION=3000


It is noted that the Geovisio API is set up to run behind an Apache2 proxy (hence the environment setting "INFRA_NB_PROXIES=1", see documentation).

2. Geovisio (Panoramax) web viewer

To integrate the Geovisio web viewer into the JuraMap raster app, following the documentation the most straightforward approach was to clone the repository, rename its directory from "web-viewer" to "geovisio-viewer" for clearer identification, and execute in terminal:

  • cd geovisio-viewer
  • npm install
  • npm build

The files "geovisio-viewer/build/index.js" and "geovisio-viewer/build/index.css" were then copied to the JuraMap raster map web directory called "history" (i.e., to "/var/www/html/history" for a Ubuntu 18.04 system).

To integrate in the JuraMap raster app, a Leaflet Bootstrap modal (see repository) was set up that had as its body statement:

  • <div id="viewer" class="fullpage">

which is the same as the statement used for the Geovisio web viewer (see the file "geovisio-viewer/build/viewer.html").

The JuraMap raster app uses Leaflet.ActiveLayers so a Leaflet layerGroup is needed for the "Trails" layer of Panoramax photos that are displayed using the Bootstrap modal:

  • var viewerLayer1 = new L.layerGroup(viewer)
  • this.trails = {name:"Trails", layer:viewerLayer1}

The key statement in the JuraMap raster Javascript is:

  • viewer = new Geovisio.Viewer("viewer,"https://geovisio.juramap.org/api",{transition:3000,style:"https://www.juramap.org/tiles/pnorman.json",map:{center: mapCenterCoords, startWide:true, minZoom:19, maxZoom:19}});

where:

  • "https://geovisio.juramap.org/api" is the Geovision (Panoramax) API address;
  • "https://www.juramap.org/tiles/pnorman.json" is the address of the JuraMap vector map TileKiln renderer.

The web viewer's API Reference is crucial. Aside from the options for "map" (i.e., "options.map") "startWide", "minZoom" and "maxZoom" also listed are "raster", "center", "zoom", "bounds", and "geocoder". According to the API Reference "raster" must be a MapLibre raster source definition, so all the options may not work for a web viewer that uses a vector map as a background source.

However, alignment of the base map and the viewer map seems to work if:

  • the centre is initially set as center:[6.61,46.48] for an initial map centre at latitude 46.48 and longitude 6.61;

Once the base map is moved, the viewer map is aligned by calculating mapCentre according to the maplibre-gl LngLatLike object definition and an URL hash:

  • var latCentre = map.getCenter().lat.toFixed(6);
  • var lngCentre = map.getCenter().lng.toFixed(6);
  • var jsonDataAry = [{"coordinates":[lngCenter, latCenter]}];
  • mapCenter = jsonDataAry[0].coordinates;
  • var urlHash = mapZoom+"/"+latCenter+"/"+lngCenter+"&focus=map&map="+mapZoom+"/"+latCenter+"/"+lngCenter
  • window.location.hash = urlHash;

28 September 2024

PeterBoswell.com