I was trying to serve vector tiles on the fly using an rpc function in superbase but somehow when the responce arrives in the front end using a custom protocol. the vector tiles are not displayed.
this is my rpc function in supabase and was trying to serve vectortiles on the fly but somehow the vector tiles are not displayed in maplibre. I dont know why
CREATE OR REPLACE FUNCTION mvt(z integer, x integer, y integer)
RETURNS text
LANGUAGE plpgsql
AS $$
DECLARE
mvt_output text;
BEGIN
WITH
-- Define the bounds of the tile using the provided Z, X, Y coordinates
bounds AS (
SELECT ST_TileEnvelope(z, x, y) AS geom
),
-- Transform the geometries from EPSG:4326 to EPSG:3857 and clip them to the tile bounds
mvtgeom AS (
SELECT
ST_AsMVTGeom(
ST_Transform(geometry, 3857), -- Transform the geometry to Web Mercator
bounds.geom,
4096, -- The extent of the tile in pixels (commonly 256 or 4096)
0, -- Buffer around the tile in pixels
true -- Clip geometries to the tile extent
) AS geom
FROM
property_geodata, bounds
WHERE
ST_Intersects(ST_Transform(geometry, 3857), bounds.geom)
)
-- Generate the MVT from the clipped geometries
SELECT INTO mvt_output encode(ST_AsMVT(mvtgeom, 'property_geodata', 4096, 'geom'),'base64')
FROM mvtgeom;
RETURN mvt_output;
END;
$$;
and the front end
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Vector Tiles with Background</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://unpkg.com/[email protected]/dist/maplibre-gl.css"
rel="stylesheet"
/>
<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="module">
// create a custom protocol
const SUPABASE_URL = "https://dyvbalizfhxpprjmubtf.supabase.co";
const SUPABASE_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImR5dmJhbGl6Zmh4cHByam11YnRmIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTU2NzkwNTMsImV4cCI6MjA3MTI1NTA1M30.-0PBMHUAMUv8Oa1Oc9hgaFqDlFXLHDStVVh6cNWRLK4";
import { createClient } from "https://esm.sh/@supabase/supabase-js@2";
const client = createClient(SUPABASE_URL, SUPABASE_KEY);
function base64ToArrayBuffer(base64) {
var binaryString = atob(base64);
var bytes = new Uint8Array(binaryString.length);
for (var i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}
maplibregl.addProtocol("supabase", async (params, abortController) => {
const re = new RegExp(/supabase:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/);
const result = params.url.match(re);
const { data, error } = await client.rpc("mvt", {
z: result[2],
x: result[3],
y: result[4],
});
const encoded = base64ToArrayBuffer(data);
if (!error) {
return { data: encoded };
} else {
throw new Error(`Tile fetch error:`);
}
});
var map = new maplibregl.Map({
container: "map",
style: {
version: 8,
sources: {
// OSM raster tiles
"osm-tiles": {
type: "raster",
tiles: ["https://tile.openstreetmap.org/{z}/{x}/{y}.png"],
tileSize: 256,
attribution: "© OpenStreetMap contributors",
},
// custom vector tiles
"custom-tiles": {
type: "vector",
tiles: ["supabase://mvt/{z}/{x}/{y}"],
minzoom: 2,
maxzoom: 15,
},
},
layers: [
// Background layer
{
id: "osm-base",
type: "raster",
source: "osm-tiles",
minzoom: 0,
maxzoom: 19,
},
// polygon vector tile layer
{
id: "polygon-outline",
type: "line",
source: "custom-tiles",
"source-layer": "property_geodata",
paint: {
"line-color": "red",
"line-width": 2,
},
},
],
},
center: [32.53589, 0.08],
zoom: 13,
});
map.on("click", (e) => {
const features = map.queryRenderedFeatures(e.point, {
layers: ["polygon-layer"],
});
if (features.length > 0) {
console.log("Clicked Feature:", features);
} else {
console.log(e);
console.log("No feature clicked.");
}
});
</script>
</body>
</html>
'