0

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>

'

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.