Skip to content

PYR1-1786 Set vector tile layers to 1x1 metatiling - #102

Merged
danielhvs merged 2 commits into
mainfrom
PYR1-1786-vector-tile-metatiling
Sep 23, 2026
Merged

danielhvs merged 2 commits into
mainfrom
PYR1-1786-vector-tile-metatiling

Conversation

@danielhvs

Copy link
Copy Markdown
Collaborator

Purpose

Register vector tile layers with a 1x1 metatile instead of the 4x4 GeoServer gives them by default. Fire perimeters stopped drawing on development because every vector tile request for fire-detections_fire-history:fire-history returned a GWC 400.

GeoServer 2.27 (GEOS-12037, commit b46c98a9, 2026-01-16) started routing vector tiles through the same metatile as rasters, measured against the WMS max rendering memory. The class is absent in 2.26.x and earlier, which is why production on 2.19.6 never saw this.

  1. rest-api/update-cached-layer-metatiling sets the metatile size while keeping the mime formats and grid subsets GeoServer already holds, and sets no TIME filter - vector stores carry no time dimension
  2. core/file-specs->vector-gwc-specs selects the geopackage and shapefile stores, alongside the existing imagemosaic filter that feeds the TIME filter updates
  3. add-directory-to-workspace-aux! walks those layers back to 1x1 after registering them

Why geosync

GeoServer auto-creates the tile layer for a vector store from the gwc-gs*.xml defaults, which put application/vnd.mapbox-vector-tile first and the metatile at 4x4. Lowering that default in pyrecast-gcp-deployment would also strip metatiling from every raster layer on the same GeoServer, where 4x4 has been correct for years. geosync is the only thing that knows which layers are vector.

The existing update-cached-layer was not reusable: it hardcodes png/jpeg mime formats, which would drop mapbox-vector-tile and break the client, and it writes a TIME regex filter these layers have no dimension for.

The numbers

Counted against /srv/gis/fire_detections/fire-history/fire-history.gpkg for the failing tile z=5 col=4 row=11:

  1. Features the single tile needs: 57
  2. Features the 4x4 metatile pulls: 16,623
  3. Features in the whole layer: 17,579

At that zoom the metatile swallows 95% of the CONUS dataset to paint one Pacific Northwest tile.

Related Issues

Closes PYR1-1786

Testing

Module Impacted

GWC tile layer registration for geopackage and shapefile stores.

Steps

  1. clojure -M:test-runner - 8 tests, 35 assertions, including the two new rest-api-test cases and file-specs->vector-gwc-specs-test
  2. clj-kondo --lint src test - 0 errors, 0 warnings
  3. On development, set metaWidthHeight to 1x1 for the fire-history tile layer, which is what this code now does at registration
  4. Replay the tiles that were returning 400: z=5 col=4/5/6/7 rows 11-12, z=6 col=9 row=22, z=6 col=10 row=23, z=4 col=2 row=5
  5. Check catalina.out for MVT metatile memory cap exceeded

Desired Outcome

All eight previously-failing tiles return HTTP 200 with vector tile payloads from 4.5 KB to 2.2 MB, and no MVT metatile memory cap exceeded appears afterwards. Both confirmed on development.

Not exercised: the geosync code path itself against a live GeoServer. The GeoServer admin credential was unavailable in this session, so step 3 set the tile layer config directly rather than through this code. The REST body it produces is covered by the unit tests.

Screenshots

N/A - the visible change is fire perimeters drawing again.

GeoServer 2.27 (GEOS-12037) started routing vector tiles through the same
metatile as rasters, measured against the WMS max rendering memory. One 4x4
metatile of fire-history pulls 16,623 of its 17,579 features to paint a tile
that needs 57, so GeoServer aborts and GWC answers 400 for every tile in the
metatile. Fire perimeters stopped drawing.

GeoServer auto-creates these tile layers from the gwc-gs*.xml defaults, which
set 4x4, and geosync is the only thing that knows the layers exist.

1. Add rest-api/update-cached-layer-metatiling, which sets the metatile size
   while keeping the mime formats and grid subsets GeoServer already holds and
   setting no TIME filter
2. Add core/file-specs->vector-gwc-specs for the geopackage and shapefile
   stores, alongside the imagemosaic filter that feeds the TIME filter updates
3. Walk those layers back to 1x1 after registering them
@danielhvs
danielhvs force-pushed the PYR1-1786-vector-tile-metatiling branch from 318c26e to 5f05f2b Compare September 22, 2026 22:38
The old test timed a 5ms Thread/sleep inside a with-redefs stub to assert peak
concurrency was 1, which made it slow, timing-dependent, and really an assertion
about mapv rather than about our code.

1. Extract cached-layer-delete-ok? so the accept/reject decision is a pure
   function of the status code, returning a boolean rather than the set hit
2. Test it on plain values: no stub, no sleep, no timing

This drops the sequential-execution assertion. The reason to stay sequential is
still recorded in the delete-cached-layers! docstring.
@danielhvs
danielhvs marked this pull request as ready for review September 23, 2026 15:58
@danielhvs
danielhvs merged commit 3af114a into main Sep 23, 2026
1 check passed
@danielhvs
danielhvs deleted the PYR1-1786-vector-tile-metatiling branch September 23, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants