Closed rogup closed 3 months ago
In my initial investigation, I transformed our GeoJSON data into a tileset (.mbtiles file) using the OSS https://github.com/felt/tippecanoe. The resulting file is ~50MB.
tippecanoe -z8 -kg -o test-500000.mbtiles -l initiatives -r1 test-500000.geojson
I then uploaded the tileset to MapTiler, which allows me to host 1 tileset for free. It can then be used directly in MapLibre as the initial source. I've forked the MM branch we were using for previous demos and done a rough implementation on this branch https://github.com/DigitalCommons/mykomap/commits/cwm-test-maps-maplibre/. The resulting map build is deployed here: https://dev.maps.solidarityeconomy.coop/experiment/cwm-test-maps/
In response to some of the questions we need to answer:
The appearance of the clusters generated by Tippecanoe is different to SuperCluster. Some of the clusters are quite bunched up and don't look as good. A next step is to try using this library instead, which will hopefully be consistent https://github.com/ChrisLoer/supertiler
Edit: the above published map is now using a tileset I generated with SuperTiler (with a few tweaks to get it working since it wasn't updated for 5 years. Maybe we can eventually publish this working fork if we end up using it) The command I used was
node supertiler.js -i test-500000.geojson -o test-500000_supercluster.mbtiles --minZoom 0 --maxZoom 8 --radius 60 --storeClusterExpansionZoom true --logPerformance
Just trying this map above, and I don't see any pins? In the console there are several errors like this:
Error: Source layer "initiatives" does not exist on source "initiatives-vector" as specified by style layer "clusters".
_validateLayer maplibre-gl.js:46
[snip stack trace, which is entirely within MapBox]
MapView map.ts:183
MapPresenter map.ts:15
createPresenter map-ui.ts:112
createMap map-ui.ts:86
initUI ui.ts:60
webRun index.ts:192
(Except that the name of the style layer changes in each case)
I've checked WebGL is enabled in my browser, which is LibreWolf (i.e. Firefox) 128.0-1 on Ubuntu 22.04, repeated on my laptop (LW 127.9.2-1 on Ubuntu 22.04, also Firefox nightly 111.0a1)
It looks like Mapbox can do client-side filtering of vector sources https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#setfilter
However, this isn't going to work with our clustering, since we want the clustering to change to match the new filtered result. We can't change the geometry of the clusters in a vector tileset at runtime, only the appearance/visibility. So we're definitely going to need to add a GeoJSON source for filter functionality.
Just trying this map above, and I don't see any pins? In the console there are several errors like this:
@wu-lee Sorry, I was just messing around with the tilesets so the API URL was wrong. I've fixed it now.
To finish off this investigation, I tried to get the GeoJSON to download in the background on a worker thread so that API requests to the tileserver are not blocked and the map stays responsive.
The code is here https://github.com/DigitalCommons/mykomap/commits/cwm-test-maps-maplibre/ and the demo map is published here: https://dev.maps.solidarityeconomy.coop/experiment/cwm-test-maps/
I'm seeing that the download successfully works in the background, and the map is responsive but the clustering is slower to respond to zooming in/out whilst the background download is happening. I think this may be because a lot of the network bandwith is being used, despite not totally blocking everything. It's okay and good enough that I think we should go ahead with this vector tile solution. Maybe there are ways to improve the UX further, e.g. by downloading the GeoJSON more gradually in chunks over a longer period of time and/or waiting until the first filter/search is performed by the user.
Once the download has finished, there's a split second where the UI is unresponsive, when the map re-renders the canvas using the new GeoJSON source and the markers flicker. I think this is okay, and not too noticeable.
Background
Downloading and rendering a large GeoJSON source in MapLibre takes a lot of time (~5s on a very fast internet connection), which is problematic because we need the map to be usable sooner. There are probably many places in the world where this takes much longer due to internet speeds.
In our in-person planning day, we didn't have time to properly think about a solution for what to do in the meantime whilst the full JSON is downloading. We made a rough decision to display a small subset of the data initially, with no zoom past a certain point and no filter/search functionality, until the full dataset has downloaded.
It's worth doing more investigation into using a vector tileset, since this may provide better functionality and a smoother UX. Vector tilesets are basically designed for this purpose, where pieces of data are quickly fetched depending on the zoom and current lng-lat bounds, without having to download the full set of data.
[EDIT]: Conclusions from this investigation