-
-
Notifications
You must be signed in to change notification settings - Fork 360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow MVT filtering using WMS facade #7011
Allow MVT filtering using WMS facade #7011
Conversation
@SodOnBass - to get the linting passing on this pull request you can run the following (assuming you have Python installed):
We'd also need some tests to check this is working. I've had a look for MVT tests and it doesn't appear we currently have any - I'll take a look at adding a few basic cases. I've also sent a post to the dev mailing list asking for feedback on this - https://lists.osgeo.org/pipermail/mapserver-dev/2024-January/017094.html |
Update - there are tests for MVT added after the initial development at https://github.com/MapServer/MapServer/blob/main/msautotest/wxs/wms_mvt.map added in 6ab90ce Any update would require a new tests for |
Done and committed. Thank you. |
src/mapmvt.c
Outdated
if (!layer->resultcache) | ||
return msLayerNextShape(layer, shape); | ||
|
||
return msLayerGetShape(layer, shape, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there should be some validation that *iShape is in range before accessing layer->resultcache->results[]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rouault : You are 100% correct.
@geographika : Thank you for taking care
I get some strange differences when running the new MVT filter test between Windows and Linux (the CI build, and local vagrant output). The test is:
The results on Windows are correct, but the Linux has an extra 2 features that should have been filtered out: Feature in purple below: The same filter as PNG output doesn't have this feature. I can't think why there would be a difference between Windows and Linux MVT outputs - the other tests produce identical binary outputs for MVT. |
GEOS version? |
Both the CI version and Windows SDK appear to use |
The logs for running the tests produced identical output for both platforms, but also hinted at an error picked up in the review by @rouault about the need to check the shapeindex is in the cache, otherwise an error is created in
|
@geographika
I have got 27 features in total.
I could have miss something and will check again. |
@SodOnBass - the Windows results look correct - it is the Linux results that appear to be off - both when I run it using vagrant, and also the MapServer CI - see that failing test at https://github.com/MapServer/MapServer/actions/runs/7608524103/job/20717857736#step:3:8542 My Windows builds use The correct results are added to the test suite at https://github.com/SodOnBass/MapServer/blob/eb6c5d2bda46880c6938f07dce491241e8b8ed7d/msautotest/wxs/expected/wms_mvt_filtered.mvt Your results are different again than mine on Linux and appear to be missing one feature. There should be 28 results returned by the filter, and so are off by one. You should also get the following feature:
When I run on vagrant I get 30 features, including 2 where the
The vagrant build uses the following dependencies - |
src/mapmvt.c
Outdated
return msLayerNextShape(layer, shape); | ||
|
||
if ((*iShape) >= 0 && (*iShape) < layer->resultcache->numresults) { | ||
(*iShape)++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The increment should be done before the [0, numresults[ range check
I managed to get the test OK by manipulating iShape after the sanity check. I did not spend time figuring out why it could work on Windows. Nevertheless, we now have a kind of ugly solution, hence the TODO in my comment. I created msMVTGetNextShape() to avoid complex branching in msMVTWriteTile() while statement. Consequently, I had to find a way to handle the current cache result index while iterating since there is no getNextShape() equivalent. I guess I have to find a better way to handle 'cache result' versus 'no cache result' processing but this will probably involve more refactoring that I was initially expecting. |
@rouault @geographika |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels it is definitely on the right track. A few potential extra tunings possible. cf my 2 comments
src/mapmvt.c
Outdated
@@ -543,12 +543,34 @@ int msMVTWriteTile(mapObj *map, int sendheaders) { | |||
features_size = FEATURES_INCREMENT_SIZE; | |||
|
|||
msInitShape(&shape); | |||
while ((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { | |||
int nshapes; | |||
nshapes = layer->resultcache ? layer->resultcache->numresults |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a potential performance implication in doing msLayerGetShapeCount() (when layer->resultcache == NULL). Couldn't we avoid it in that situation to just use msLayerNextShape() as before ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it is good practice, but we could entirely rely on msLayerGetShape returned value.
src/mapmvt.c
Outdated
int nclasses = 0; | ||
int *classgroup = NULL; | ||
|
||
if (layer->classgroup && layer->numclasses > 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There might be a performance implication in doing msAllocateValidClassGroups / msFree within the loop. Looking at msQueryByFilter(), the call to msAllocateValidClassGroups is done outside the loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes of course. I don't know why I didn't see it...
@SodOnBass - thanks for persisting with this and the refactors. |
yes, excellent work. Just squashed & merged |
Example code to support #7010 discussion about filtering, through styles, MVT tile served by WMS 'facade'.
The main idea is to consider LAYER classgroup and/or resultcache to filter out features while rendering the tile.