使用 PostGIS 生成矢量圖塊

使用 PostGIS 生成矢量圖塊

您喜歡視聽學習嗎?觀看視頻指南!

或者直接跳到代碼

Overture Maps Foundation是由亞馬遜、Meta、微軟和 tomtom 發起的聯合開發基金會項目,旨在創建可靠、易于使用、可互操作的開放地圖數據。

Overture Maps 允許我們以GeoJSON格式下載開放地圖數據(例如名勝古跡),我們可以將其轉換為 SQL 并導入 Supabase 上的 Postgres 數據庫。

使用 PostGIS,我們可以以編程方式生成矢量圖塊,并使用 supabase-js 將它們提供給我們的 MapLibre GL 客戶端。

矢量圖塊是地理數據包,被打包成預定義的大致正方形的“圖塊”,以便在網絡上傳輸。客戶端請求的地圖數據是一組“圖塊”,對應于預定義大小和位置的方形土地區域。

特別是對于大型數據集,這樣做的好處是數據傳輸大大減少,因為只需要傳輸當前視口內和當前縮放級別的數據。

在本教程中,您將學習

  • 使用 Overture Maps 以 GeoJSON 格式下載開放地圖地點數據。
  • 使用 GDAL ogr2ogr 將 GeoJSON 轉換為 SQL 語句。
  • 使用 psql 將位置數據和 JSON 元數據導入您的 Supabase Postgres 數據庫。
  • 使用 PostGISST_AsMVT將與圖塊層對應的一組行聚合為二進制矢量圖塊表示。
  • addProtocol通過使用 supabase-js 進行遠程過程調用,使用 MapLibre可視化大型 PostGIS 表。
  • 使用 supabase-js 按需獲取其他 JSON 元數據

使用 Overture Maps 下載開放地圖數據

Overture Maps 提供了一個Python 命令行工具來下載感興趣區域內的數據并將其轉換為幾種常見的地理空間文件格式。

我們可以使用以下命令將新加坡的地點下載到 GeoJSON 文件中:

overturemaps download --bbox=103.570233,1.125077,104.115855,1.490957 -f geojson --type=place -o places.geojson

根據邊界框的大小,這可能需要相當長的時間!

將 GeoJSON 轉換為SQL

下一步,我們可以使用GDAL ogr2ogr將 GeoJSON 文件轉換為 PostGIS 兼容的 SQL 文件。

您可以GDAL通過安裝homebrew brew install gdal或按照下載說明進行操作。

PG_USE_COPY=true ogr2ogr -f pgdump places.sql places.geojson

將位置數據導入 Supabase

在專用的單獨架構上啟用 Supabase 數據庫上的 PostGIS 擴展gis。為此,您可以導航到SQL 編輯器并運行以下 SQL,或者您可以從數據庫擴展設置中啟用擴展。(也可使用國內版supabase)

由于 PostGIS 的計算量可能很大,我們建議在專用的單獨模式上啟用它,例如名為gis

CREATE SCHEMA IF NOT EXISTS "gis";
CREATE EXTENSION IF NOT EXISTS "postgis" WITH SCHEMA "gis";

將打開的地圖數據導入到placesSupabase中的表中:

psql -h aws-0-us-west-1.pooler.supabase.com -p 5432 -d postgres -U postgres.project-ref < places.sql

您可以在Supabase 儀表板的數據庫設置中找到憑據。

啟用 RLS 并創建公共讀取策略

我們希望地點數據可以公開獲取,因此我們可以創建一個允許公開讀取的行級安全策略。

在您的 Supabase 儀表板中,導航到SQL 編輯器并運行以下命令:

ALTER TABLE "public"."places" ENABLE ROW LEVEL SECURITY;CREATE POLICY "Enable read access for all users" ON "public"."places" FOR SELECT USING (true);

使用PostGIS生成矢量圖塊

為了在客戶端請求時以編程方式生成矢量圖塊,我們需要創建一個 Postgres 函數,可以通過遠程過程調用來調用它。在 SQL 編輯器中,運行:

CREATE OR REPLACE FUNCTION mvt(z integer, x integer, y integer)
RETURNS text
LANGUAGE plpgsql
AS $$
DECLAREmvt_output text;
BEGINWITH-- Define the bounds of the tile using the provided Z, X, Y coordinatesbounds AS (SELECT ST_TileEnvelope(z, x, y) AS geom),-- Transform the geometries from EPSG:4326 to EPSG:3857 and clip them to the tile boundsmvtgeom AS (SELECT-- include the name and id only at zoom 13 to make low-zoom tiles smallerCASEWHEN z > 13 THEN idELSE NULLEND AS id,CASEWHEN z > 13 THEN names::json->>'primary'ELSE NULLEND AS primary_name,categories::json->>'main' as main_category,ST_AsMVTGeom(ST_Transform(wkb_geometry, 3857), -- Transform the geometry to Web Mercatorbounds.geom,4096, -- The extent of the tile in pixels (commonly 256 or 4096)0,    -- Buffer around the tile in pixelstrue  -- Clip geometries to the tile extent) AS geomFROMplaces, boundsWHEREST_Intersects(ST_Transform(wkb_geometry, 3857), bounds.geom))-- Generate the MVT from the clipped geometriesSELECT INTO mvt_output encode(ST_AsMVT(mvtgeom, 'places', 4096, 'geom'),'base64')FROM mvtgeom;RETURN mvt_output;
END;
$$;

為了限制通過網絡發送的數據量,我們限制了矢量圖塊中包含的元數據量。例如,我們為縮放級別添加了一個條件,并且只有當用戶放大到 13 級以上時才返回地名。

使用 supabase-js 從 MapLibre GL 客戶端獲取矢量瓦片

index.html您可以在GitHub上找到完整的代碼。在這里,我們將重點介紹如何向 MapLibreGL 添加新協議,以通過 supabase-js 獲取 bas64 編碼的二進制矢量瓦片數據,以便 MapLibre GL 可以在用戶與地圖交互時獲取和呈現數據:

index.html

const client = supabase.createClient('your-supabase-api-url', 'your-supabase-anon-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:`)}
})

注冊 supabase 協議后,我們現在可以將其添加到 MapLibre GL 源中,并放置在底圖(如Protomaps)之上,例如:

index.html

// ...
const map = new maplibregl.Map({hash: true,container: 'map',style: {version: 8,glyphs: 'https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf',sources: {supabase: {type: 'vector',tiles: ['supabase://boston/{z}/{x}/{y}'],attribution: '? <a href="https://overturemaps.org">Overture Maps Foundation</a>',},protomaps: {type: 'vector',url: 'https://api.protomaps.com/tiles/v3.json?key=your-protomaps-api-key',attribution: 'Basemap ? <a href="https://openstreetmap.org">OpenStreetMap</a>',},},},
})
// ...

按需獲取額外的 JSON 元數據

為了限制通過網絡發送的數據量,我們不會對矢量圖塊本身中的所有元數據進行編碼,而是設置一個 onclick 處理程序以在 MapLibre GL 彈出窗口中按需獲取其他元數據:

index.html

// ..
const popup = new maplibregl.Popup({closeButton: true,closeOnClick: false,maxWidth: 'none',
})function loadDetails(element, id) {element.innerHTML = 'loading...'client.from('places').select(`websites,socials,phones,addresses,source:  sources->0->dataset`).eq('id', id).single().then(({ data, error }) => {if (error) return console.error(error)element.parentElement.innerHTML = `<pre>${JSON.stringify(data, null, 2)}</pre>`})
}map.on('click', 'overture-pois-text', async (e) => {if (e.features.length > 0) {const feature = e.features[0]console.log(feature)popup.setHTML(`<table style="font-size:12px"><tr><td>id:</td><td>${feature.properties.id}</td></tr><tr><td>name:</td><td>${feature.properties.primary_name}</td></tr><tr><td>main_category:</td><td>${feature.properties.main_category}</td></tr><tr><td>details:</td><td><span οnclick="loadDetails(this, '${feature.properties.id}')">load details</span></td></tr></table>`)popup.setLngLat(e.lngLat)popup.addTo(map)}
})
// ...

結論

PostGIS 功能強大,可讓您以編程方式從存儲在 Postgres 中的表行生成矢量圖塊。與 Supabase 自動生成的 REST API 和 supabase-js 客戶端庫配合使用,您可以輕松構建交互式地理空間應用程序!

更多 Supabase

  • 觀看視頻指南
  • 國內版suapbase
  • 查找代碼
  • 使用 Protomaps 在 Supabase 存儲上自托管地圖
  • PostGIS 入門
  • PostGIS 文檔指南

原文章:https://supabase.com/blog/postgis-generate-vector-tiles

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39141.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39141.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39141.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【面試系列】產品經理高頻面試題及詳細解答

歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;歡迎訂閱相關專欄&#xff1a; ?? 全網最全IT互聯網公司面試寶典&#xff1a;收集整理全網各大IT互聯網公司技術、項目、HR面試真題. ?? AIGC時代的創新與未來&#xff1a;詳細講解AIGC的概念、核心技術、…

工業讀碼器與商用掃碼器的區別

條碼二維碼在數字信息化應用越來越廣泛&#xff0c;掃碼器成為了數據收集和處理的重要工具&#xff0c;無論是工廠生產和物流包裹朔源追蹤&#xff0c;還是商場超市掃碼收銀和餐飲娛樂等場景&#xff0c;均能看到掃碼器的輔助&#xff0c;市場上的掃碼器種類繁多&#xff0c;在…

【力扣】贖金信

&#x1f525;博客主頁&#xff1a; 我要成為C領域大神&#x1f3a5;系列專欄&#xff1a;【C核心編程】 【計算機網絡】 【Linux編程】 【操作系統】 ??感謝大家點贊&#x1f44d;收藏?評論?? 本博客致力于知識分享&#xff0c;與更多的人進行學習交流 ? 給你兩個字符串…

C++ //練習 14.20 為你的Sales_data類定義加法和復合賦值運算符。

C Primer&#xff08;第5版&#xff09; 練習 14.20 練習 14.20 為你的Sales_data類定義加法和復合賦值運算符。 環境&#xff1a;Linux Ubuntu&#xff08;云服務器&#xff09; 工具&#xff1a;vim 代碼塊 struct Sales_data{Sales_data(const string &s, unsigned …

研發都認為DBA很Low?我反手一個嘴巴子

作者&#xff1a;IT邦德 中國DBA聯盟(ACDU)成員&#xff0c;10余年DBA工作經驗&#xff0c; Oracle、PostgreSQL ACE CSDN博客專家及B站知名UP主&#xff0c;全網粉絲10萬 擅長主流Oracle、MySQL、PG、高斯及Greenplum備份恢復&#xff0c; 安裝遷移&#xff0c;性能優化、故障…

antd(5.x) Popover 的content有個modal,關不掉了

問題描述&#xff1a; 如上圖所示&#xff0c;我的提示modal 關不掉了&#xff0c;思考問題癥結在handleVisibleChange const content (<div className{styles.box}>別的樣式</div>{/* 鏈接 */}<div className{styles.linkBox}><Modaltitle{提示}open{…

C# 語法特性

theme: smartblue C#5&#xff1a; C#5 語法特性 - 掘金 (juejin.cn)C#6&#xff1a; C#6 語法特性 - 掘金 (juejin.cn)C#7&#xff1a; C#7 語法特性 - 掘金 (juejin.cn)C#8: C#8 語法特性 - 掘金 (juejin.cn)C#9: C#9 語法特性 - 掘金 (juejin.cn)c#10: c#10 語法特性 - 掘金…

C# 中的并發和并行

介紹 并發和并行是現代編程中的關鍵概念&#xff0c;可幫助開發人員創建高效、響應迅速、高性能的應用程序。在 C# 中&#xff0c;這些概念尤其重要&#xff0c;因為該語言對多線程和異步編程提供了強大的支持。本文介紹了 C# 中的并發和并行&#xff0c;包括關鍵概念、優點和…

武漢星起航:跨境電商流量紅利爆發,2023年出海企業迎突破增長

在數字時代的浪潮中&#xff0c;中國跨境電商以驚人的爆發力嶄露頭角&#xff0c;成為全球貿易的璀璨新星。2023年數據顯示&#xff0c;跨境電商出口額高達1.83萬億元&#xff0c;同比增長19.6%&#xff0c;這一顯著增速不僅刷新紀錄&#xff0c;更為眾多出海企業帶來了前所未有…

每周算法(week 1)【leetcode1~10】

前言 今天開始刷面試算法題&#xff0c;雖然之前在藍橋杯、程序設計天梯賽中拿過兩個省一和一個國三&#xff0c;但是基本靠的都是我對 Java 語言的熟悉&#xff0c;至于算法我只會基本的雙指針、快慢指針、差分數組等&#xff0c;最擅長的其實還是暴力。但是自認為應付面試還是…

Kimi 上下文緩存功能開啟公測!降低使用費用,加快模型相應速度

7月2日&#xff0c;系統之家發布消息&#xff0c;月之暗面科技有限公司旗下的Kimi開放平臺正式推出上下文緩存功能&#xff0c;并已開放公測。這項功能專為處理頻繁請求和大量重復引用初始上下文的場景設計&#xff0c;能有效降低使用長文本模型的成本&#xff0c;并顯著提升處…

基于java+springboot+vue實現的旅游管理系統(文末源碼+Lw)227

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術&#xff0c;讓傳統數據信息的管理升級為軟件存儲&#xff0c;歸納&#xff0c;集中處理數據信息的管理方式。本旅游管理系統就是在這樣的大環境下誕生&#xff0c;其可以幫助使用者在短時間內處理完畢龐大的數據信息&a…

HMM,EM算法(Expectation-Maximization Algorithm) VAE)以及KL散度

HMM&#xff0c;EM算法&#xff08;Expectation-Maximization Algorithm&#xff09; VAE&#xff09;以及KL散度 最大化對數似然&#xff08;或稱為最大化對數似然函數&#xff09;是在統計學中用來估計模型參數的一種常用方法。其基本思想是找到一組參數值&#xff0c;使得在…

本地文本向量模型的部署提供兼容openai的接口

前言 之前部署了fastgpt官方文檔的一個,提供的一個m3e-large的向量模型打包的docker鏡像,雖然使用起來整體效果還可以,但是有些文本向量相似度匹配的結果還是不太滿意的,目前,網絡上層出不窮的帶推理文本向量,想體驗一下,于是我基于modelscope庫封裝了一個兼容open ai的…

探索視覺世界:深入了解目標檢測算法的奧秘

目標檢測算法 一、介紹目標檢測算法的背景和意義1.1 目標檢測的定義和應用場景1.2 目標檢測算法的發展歷程 二、目標檢測算法分類2.1 傳統目標檢測算法2.1.1 基于分類器的目標檢測算法2.1.2 基于模板匹配的目標檢測算法 2.2 深度學習目標檢測算法2.2.1 兩階段目標檢測算法2.2.2…

Android Gradle 開發與應用 (四): 多模塊構建與組件化,提升Android開發效率的途徑

目錄 1. 多模塊構建的基本概念 2. 組件化的基本概念 3. 多模塊構建與組件化的優勢 4. 多模塊構建的實現方法 5. 組件化的實現方法 6. 多模塊構建與組件化的實踐 7. 案例分析 8. 未來展望 結語 隨著移動應用的功能日益復雜&#xff0c;單一模塊開發方式的弊端愈加明顯。…

全國范圍內嚴格推行雙休制才是勞動力使用方面面向未來和可持續發展的

我有以下理由&#xff1a; 合法依規 每天不超8小時、每周不超過40小時&#xff0c;這是國務院令第146號&#xff0c;很多年前就明確要求的&#xff0c;在國有企業和事業單位也早就推行了很多年的&#xff1b;對確有實際需要的崗位&#xff0c;也有經過行政審批的“不定時工作…

2024年廣東省食品安全管理員考試精選練習題庫

76.已具有主體資格的企業申請食品流通可&#xff0c;該企業的&#xff08;&#xff09;為可申請人。 A.投資者 B.經營負責人 C.本身 答案&#xff1a;C 77.食用亞硝酸鹽的銷售只面向&#xff08;&#xff09;。 A.食品生產加工行業 B.餐飲業 C.食品流通單位 答案&…

微軟賬戶和本地賬戶有什么區別?如何切換登錄賬戶?

Windows 操作系統是目前世界上比較流行的操作系統之一&#xff0c;在使用 Windows 系統的時候都需要我們進行登錄&#xff0c;其中我們可以使用微軟賬戶或者本地賬戶進行登錄&#xff0c;那本地賬戶和微軟賬戶有什么區別&#xff1f;下面就帶大家了解一下微軟賬戶和本地賬戶。 …

基于機器學習的零售商品銷售數據預測系統

1 項目介紹 1.1 研究目的和意義 在電子商務日益繁榮的今天&#xff0c;精準預測商品銷售數據成為商家提升運營效率、優化庫存管理以及制定營銷策略的關鍵。為此&#xff0c;開發了一個基于深度學習的商品銷售數據預測系統&#xff0c;該系統利用Python編程語言與Django框架&a…