Monday, November 6, 2017

More Mapbox! Using querySourceFeatures() ... or not

The project where I've been exploring Mapbox GL API continues along, and everyone is quite pleased with how it's coming along. Here's another technical posting, this time about something we needed which did not work out.

The need: One of the map layers is hydrology regions. When one is selected, it would be great to highlight it and also zoom the map to it.

Highlighting is already done and working just fine. I went with a filtering technique to swap between a choropleth of all regions, and a highlight of the one region. That's great.

Zooming though, implies that we have the bounding box coordinates handy for the selected region. Can we get these from the API, since it has the records? Answer: No.

querySourceFeatures Does Not Query


Mapbox API does provide a method that sounds promising: querySourceFeatures()  But it doesn't do what you're thinking. It queries only the vector tiles which are currently visible in the map viewport. As such, it can only query features that are already on the map and is not a search/query mechanism for your dataset.

Example code:
// specify the URL of the tileset when declaring the Source
// and ALSO its suffixed name when connecting it to a Layer
map.addSource('myplaces', {
    "type": "vector",
    "url": "mapbox://mapbox.abcde12345"
});
map.addLayer({
    "id": "places",
    "source": "myplaces",
    "source-layer": "MyPlaces-abc123",
    "type": "fill",
    "paint": {
        "fill-outline-color": "rgba(0,0,0,0)",
        "fill-color": "rgba(0,0,0,0)"
    }
});
var results = map.querySourceFeatures('myplaces', {
   sourceLayer: 'places',
   filter: [ '==', 'name', 'Montana' ],
});
console.log(results);

Limitations and expectations are:

  • The setup is a bit goofy, that you must program in both the URL of your Mapbox tileset (when creating the Source) and also the readable suffixed name of it (when adding the Layer).
  • The Source isn't actually useful unless there is also a Layer and the Layer is on the map. You can render with 0 alpha to make it invisible, but it must be on the map.
  • The query only searches within the vector tiles currently visible on the map. As you pan and zoom, you'll see that results changes even if your query does not.
The use case demonstrated by the Mapbox demos, is basically limited to querying what's under your mouse. And sadly, this does seem to be all that it's good for. querySourceFeatures() is basically the same thing as queryRenderedFeatures()except that you can specify the "click filtering" without changing the filters used for rendering.


So, What Now?


Mapbox offers a fairly new service called Datasets. When you upload your dataset, unlike Tilesets which are digested into vector tiles, this one is digested into a database and exposed as a GeoJSON structure. This can then be queried and downloaded, and there's mention of an editing and authoring environment as well.

Of course, this means uploading a second copy of these datasets just for querying purposes, which isn't so great for maintainability.

In our case, we were already loading a CSV of metadata used for constructing other UI elements and populating some statistical tables. As such, it was no problem to add to that CSV some new bbox_s, bbox_e, bbox_n, bbox_e fields to facilitate the zooming behavior. As such, I did not get an opportunity to work with Datasets this time.

No comments:

Post a Comment