Using ST_AsMVT
Matthew Shaw
shawmat.sl6 at gmail.com
Sun Jul 6 05:40:43 PDT 2025
I'm struggling to understand how to use ST_AsMVT. It doesn't exist as a
true function, but this PSQL command shows that it does exist as an "agg"
\df *st_asmvt*
Schema | Name | Result data type |
Argument data types
| Type
--------+--------------+------------------+----------------------------------------------------------------------------------------------------------------------+------
public | st_asmvt | bytea | anyelement
| agg
public | st_asmvt | bytea | anyelement, text
| agg
public | st_asmvt | bytea | anyelement, text, integer
| agg
public | st_asmvt | bytea | anyelement, text, integer, text
| agg
public | st_asmvt | bytea | anyelement, text, integer,
text, text
| agg
public | st_asmvtgeom | geometry | geom geometry, bounds box2d,
extent integer DEFAULT 4096, buffer integer DEFAULT 256, clip_geom boolean
DEFAULT true | func
The MapLibre Martin server relies on one MVT being assembled from all the
geometries in the underlying. The following query successfully finds 93
geometries for tile .../highways/12/1019/671
SELECT
ST_AsMVTGeom(geom,
ST_TileEnvelope(11,1019, 671),
4096, 64, true) AS geom,
class
FROM openstreetmap.highway
WHERE geom && ST_Transform(ST_TileEnvelope(11,1019, 671), 4326)
But as soon as I try to invoke ST_AsMVT, it errors:
select ST_AsMVT(tile, 'highways'::text, 4096, 'geom'::text, array['class'])
from
(SELECT
ST_AsMVTGeom(geom,
ST_TileEnvelope(11,1019, 671),
4096, 64, true) AS geom,
class
FROM openstreetmap.highway
WHERE geom && ST_Transform(ST_TileEnvelope(11,1019, 671), 4326)) as tile
ERROR: function st_asmvt(record, text, integer, text, text[]) does not
exist LINE 3: select ST_AsMVT(tile, 'highways'::text, 4096, 'geom'::text,
... ^ HINT: No function matches the given name and argument types. You
might need to add explicit type casts.
All I'm doing is following the pattern in the Maplibre Martin
documentation. It suggests defining functions like this:
CREATE OR REPLACE
FUNCTION function_zxy_query(z integer, x integer, y integer)
RETURNS bytea AS $$
DECLARE
mvt bytea;
BEGIN
SELECT INTO mvt *ST_AsMVT*(tile, 'function_zxy_query', 4096, 'geom') FROM (
SELECT
ST_AsMVTGeom(
ST_Transform(ST_CurveToLine(geom), 3857),
ST_TileEnvelope(z, x, y),
4096, 64, true) AS geom
FROM table_source
WHERE geom && ST_Transform(ST_TileEnvelope(z, x, y), 4326)
) as tile WHERE geom IS NOT NULL;
RETURN mvt;
END
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
I spent time checking my PostGIS installation. ST_AsMVT doesnt exist as a
function on any of the PostGIS server installations I have access to, so
it's not obviously a defective installation.
I'd welcome some help fixing this. Yes, Martin can (and does) work with
direct reference to tables, but functions are necessary to manage what's
included at various zoom levels.
Thanks
*Matthew Shaw*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20250706/816ca7e9/attachment.htm>
More information about the postgis-users
mailing list