[GIS筆記] SHP 轉檔的亂碼陷阱:從「百年舊堤」案例看編碼偵測的重要性

在將既有的 GIS 開放資料(如 QGIS 專案中的 Shapefile)整合進 WalkGIS 系統時,最常遇到的挑戰往往不是座標轉換,而是文字編碼(Encoding)。 最近在處理「濁水溪流域情報地圖」中的「百年舊堤」圖層時,我遇到了一個經典的亂碼案例。這篇文章將紀錄問題的成因、誤判的過程,以及最終的正確解法,作為未來處理 GIS 舊資料的參考。 案例背景 我試圖將一份名為 23座百年舊堤.shp 的檔案匯入我的 WalkGIS SQLite 資料庫。 1. 初次嘗試:預設轉檔的失敗 一開始,我直接將 SHP 轉為 KML/KMZ 進行預覽。結果在 KML 中,所有的堤防名稱都變成了無法辨識的亂碼,如: 偌 這些字並不是常見的「」或亂數,而是顯示為 PUA (Private Use Area) 區域的罕見字元。這是一個強烈的訊號,代表編碼解讀錯誤。 2. 直覺誤判:這一定是 Big5 台灣早期的 GIS 資料(尤其是政府開放資料),絕大多數的 .dbf 屬性表都使用 Big5 (CP950) 編碼。當看見中文變亂碼時,直覺反應通常是:「啊,這一定是工具用 UTF-8 去讀 Big5 造成的。」 於是我在 Python 腳本中強制指定了編碼: # 錯誤的嘗試 gdal.SetConfigOption("SHAPE_ENCODING", "CP950") 結果出乎意料:亂碼依然存在,甚至變成了另一種形式的亂碼。如果您嘗試用各種 Big5/Latin1 交叉解碼都無效,那問題可能比想像中複雜。 真相:雙重編碼災難 為了找出真相,我使用 ogrinfo 指令進行了雙盲測試(A/B Testing): 測試 A:指定 CP950 ogrinfo -al -so --config SHAPE_ENCODING CP950 "23座百年舊堤.shp" > Name (String) = 偌 (亂碼) 測試 B:不指定 (預設/UTF-8) ...

2026-01-11 · 1 min · 198 words · Wuulong

[GIS筆記] 如何補完官方地圖沒有的「隱藏版」溪流?從濁水溪看資料擴充策略

在處理台灣水利地理資訊時,常會發現政府公開的「中央管河川」圖資(如 RIVERL.shp)或河川代碼表,往往只記錄到一定規模以上的河川。很多在地人熟知的區域排水、野溪或深山源頭(如濁水溪上游的霧社溪)並不在名冊上。 這篇筆記記錄了我在 WalkGIS 專案中,如何運用 AI 助理與網路資源,像拼圖一樣將這些「隱藏版」溪流補回資料庫的過程,並將其標準化為可重複執行的 Task。 1. 發現缺漏 (The Gap) 在整理「濁水溪」圖資時,我對照了目前的 GIS 圖資與網路搜尋結果,發現幾個明顯的斷層: 深山源頭缺失:地圖上有畫出濁水溪,但官方 CSV 名冊卻沒有列出其源頭「霧社溪」。 知名支流不見:如「萬大溪」、「丹大溪」雖然在 CSV 名冊上有名字,但因為不是主要治理河段,在部分公開 SHP 圖資中完全沒有線條。 在地小溪隱形:如「益則坑溪」、「栗棲溪」,是當地的戲水秘境或土石流潛勢溪流,但在中央級的資料中找不到。 這些「缺漏」對於一般用途可能無傷大雅,但對於要進行深度走讀(River Walk)的我們來說,少了它們就像拼圖少了一塊。 2. 補完策略 (The Strategy) 我的目標是建立一份「完整的流域戶口名簿」。即使手上暫時沒有這些溪流的精確 GIS 線條,也要先把它們的名字及**輩分關係(注入哪條河)**記錄下來。 步驟 A:查找「隱藏版」名單 透過網路搜尋(Google Search / Wikipedia / 縣市政府水利規劃報告),找出那些屬於濁水溪流域但未被登錄的河川。例如這次我新發現了: 霧社溪 栗棲溪 獅尾堀溪 益則坑溪…等 步驟 B:確認「輩分關係」 (Topology) 這是最關鍵的一步。在 GIS 資料庫中,我們不只要知道這條溪叫什麼,更要知道它從哪裡來、往哪裡去。也就是確認它是直接注入濁水溪(第一層),還是先注入其他支流(第二層)。 我使用了以下工具來進行「親緣鑑定」: OpenStreetMap (OSM):使用 Overpass Turbo 查詢,如果運氣好(如霧社溪),Relation 中會直接標註 destination=濁水溪。 地方政府報告:例如從「南投縣管區域排水規劃」中,確認了「獅尾堀溪」是濁水溪左岸的支流。 地理推斷:如「益則坑溪」位於水里鄉民和村,該村緊鄰濁水溪,推測直接注入主流可能性大。 步驟 C:修訂 CSV 結構 為了將新發現納入系統,我在 河川代碼主從.csv 中手動增補資料。為了不與官方 6 碼數字衝突,我設計了一套「非官方編碼規則」: ...

2026-01-11 · 1 min · 120 words · Wuulong

[GIS筆記] 運用 AI 助理 Antigravity 整理「流域情報開放地圖」:以濁水溪為例

最近在研究 LASS 社群維護的 「流域情報開放地圖」 QGIS 專案,這是一個集結了政府開放資料與民間調適計畫成果的龐大資料庫。 資料雖豐富,但若只想專注於特定流域(例如:濁水溪),要從全台的圖資中「萃取」並「整理」出有結構的資料,手動操作相當繁瑣。這次我嘗試透過 AI 助理 Antigravity 來協助處理,發現這是一個非常高效的工作流,特別是針對舊式 Shapefile 資料結構的梳理。 以下分享這次的實作筆記,以及一個關鍵的發現:河川代碼 CSV 的重要性。 1. 任務目標 從全台的 GIS 圖資中,提取出 濁水溪流域 的完整資料,並轉換成 Google Earth 可用的 KMZ 格式。需求包含: 流域範圍:濁水溪集水區的面資料 (Polygon)。 河道水系:包含主流與所有支流的線資料 (Line)。 層級結構:需區分主流、一級支流(如陳有蘭溪)、二級支流(如和社溪),並以不同顏色與資料夾呈現。 2. 關鍵資料解析 在專案目錄中,主要的幾何資料位於 1-流域水文地理環境 下的 RIVERL.shp(全台中央管河川)。原本以為只要用 SQL 篩選 BASIN_NAME = '濁水溪' 即可,但 AI 分析後發現了一個隱藏的寶藏檔案: 📂 檔案位置: 河川整理資料 - 河川代碼主從 這份 CSV 檔案是解析河川「拓撲關係(Topology)」的關鍵,沒有它,GIS 圖資就只是一堆沒有從屬關係的線條。所以也很容易做出下圖 為什麼這份 CSV 很重要? Shapefile 本身雖然有 RV_NO (河川代碼),但要從代碼反推「誰是誰的上游」需要複雜的解碼邏輯。而這份 CSV 直接建立了樹狀結構: 欄位 說明 範例 (陳有蘭溪) river_id 河川唯一碼 151010 river_name 中文名稱 陳有蘭溪 in_id 注入的河川 ID (Parent) 151000 (注入濁水溪) river_link 全路徑字串 0@151000@151010 AI 應用的邏輯技巧 透過 Antigravity,我們利用 river_link 欄位快速算出了河川的「層級 (Stream Order)」,邏輯出奇簡單: ...

2026-01-11 · 2 min · 237 words · Wuulong

實作筆記:從 Deep Research 到 WalkGIS 自動地圖生成 - 以濁水溪流域為例

引言:打造「百科全書式」的流域地圖 一直以來,我對於製作「有深度」的地圖充滿熱情。一張好的地圖,不應該只是標記與導航,它應該能承載歷史的厚度、文化的溫度,以及地理空間的邏輯。 這次,我以台灣的母親河——濁水溪為範圍,嘗試進行了一次「百科全書式」的探索與實作。我的目標是將這條河流從合歡山源頭到麥寮出海口,涵蓋自然地景、水利設施、人文史蹟、交通設施、災害環境五大維度的知識,轉化為可互動、可導航的數位資產。 這篇文章記錄了我如何利用 AI Agent 與自動化腳本,將大量且發散的研究資料,快速收斂為 WalkGIS 系統中的標準化地圖。 實作流程解析 我的工作流主要分為三個階段:Deep Research (發散) -> 結構化萃取 (收斂) -> 自動化生成 (Agent Task)。 階段一:Deep Research 與維度定義 首先,我並不是直接開始畫地圖,而是先進行研究。我定義了濁水溪流域的五個觀察維度: 自然 (Nature): 包含源頭的合歡山、地質敏感的金門峒斷崖、以及河口的濕地生態。 水利 (Water Infrastructure): 這是濁水溪的靈魂。從上游的霧社水庫、武界壩,中游的集集攔河堰,到下游滋養彰雲平原的八堡圳與濁幹線。 人文 (Culture/History): 包含原住民部落(曲冰、武界)、客家文化(詔安)、以及漢人聚落(西螺、北斗)。 交通 (Transport): 見證歷史的西螺大橋、集集車站,以及現代的國道橋樑。 災害 (Disaster/Env): 誠實面對環境課題,如車籠埔斷層保存園區、地層下陷區。 我利用 AI 工具(如 Gemini)針對這些維度進行深度搜尋,挖掘出最具代表性的關鍵字與地點。 階段二:萃取清單 (The List) 研究之後,我將這些發散的資訊收斂為一份結構化的景點清單 (List of Locations)。這份清單不需要包含座標或詳細敘述,只需要準確的「名稱」與「分類」。 例如: 水利:八堡一圳、林內分水工 交通:西螺大橋、溪州大橋 人文:林先生廟、麥寮拱範宮 這份清單,就是餵給 AI Agent 的「種子」。 階段三:Run Task - 自動化生成的魔法 這一步是效率爆發的關鍵。我定義了一個名為 create-walkgis-map-from-list 的 Agent Task,讓 AI 代理人幫我完成那些繁瑣的 GIS 建置工作。 ...

2026-01-11 · 1 min · 192 words · Wuulong

Python 與 ATAK 的通訊實戰:如何用 TCP 發送動態 CoT 標點

在開發 AI Field Scout (AI 偵查員) 系統的過程中,我們的一個核心需求是:讓 AI Agent 能即時把發現的資訊(例如:附近的便利商店、危險地形、或是沿著路徑移動的隊友)投放到使用者的 ATAK 地圖上。 ATAK (Android Team Awareness Kit) 是一個非常強大的戰術地圖軟體,它使用 CoT (Cursor on Target) 這種 XML 格式來交換訊息。網路上大部分的教學都推薦使用 UDP Multicast,但在實際的開發環境(特別是 Mac 電腦連接 iPhone 熱點,或是複雜的內網環境)中,UDP 經常因為路由、防火牆或廣播限制而撞牆。 經過了一番「通訊地獄」的除錯後,我們總結出了一套最穩定的解決方案:使用 TCP 直連。 這篇筆記將分享如何用 Python 建立一個穩定的 CoT 發送器,讓你的程式碼能直接控制 ATAK 地圖上的標記。 為什麼選擇 TCP 而不是 UDP? 雖然 CoT 的原生設計大量依賴 UDP Multicast 來達到「即插即用」的群組廣播效果,但在點對點(Point-to-Point)的開發測試中,UDP 有幾個痛點: 網路不可靠:在手機熱點或某些 Wi-Fi 設定下,Multicast 封包常被丟棄或過濾。 除錯困難:UDP 是「射後不理 (Fire and Forget)」,程式碼送出去了,你完全不知道對方收到了沒。 路由黑洞:作業系統(特別是 macOS)在多重網路介面下,UDP 出站路由容易走錯路(No route to host)。 相對的,TCP (Transmission Control Protocol) 提供了一個非常明確的機制: ...

2026-01-10 · 3 min · 456 words · Wuulong

WalkGIS 實戰:ATAK 碎裂軌跡合併與 Google My Maps 輕量化指南

在進行長距離的河川探索(如大甲溪、濁水溪)時,我們依賴 ATAK (Android Team Awareness Kit) 作為主要的軌跡記錄工具。然而,在實際作業中遇到了一個痛點: ATAK 為了效能或訊號不穩,常會將一整天的行程自動切分成多個軌跡檔案 (GPX/KML)。 這造成兩個後續應用的問題: 管理困難:一天產生 3-4 個檔案,Day 4 就有三個 GPX (01:31, 04:47, 06:12)。 Data Package 限制:ATAK 的 Data Package 雖然好用,但主要針對靜態圖層 (Points, Shapes),對於「動態軌跡」的打包支援較弱,往往需要手動匯出 GPX。 Google My Maps 拒收:當我們想把這些高精度的原始軌跡整合到 Google My Maps 分享時,會因為點數過多 (Over 2000 points) 而導致上傳失敗或顯示不全。 🛠️ 解決方案:Python 自動化合併與抽稀 為了不僅將檔案「接起來」,還要能「瘦身」給 Google 吃,我開發了一個 Python 腳本來處理這個標準作業程序。 步驟一:處理 Namespace 陷阱 ATAK 輸出的 GPX 檔案,其 XML Namespace 有時會帶有尾端斜線(.../GPX/1/1/),這會導致標準的 Python xml.etree.ElementTree 解析失敗。 解法:寫一個 Helper Function strip_ns(),不管 Namespace 長怎樣,只認標籤名稱(如 trkpt),這樣最穩健。 ...

2026-01-09 · 1 min · 184 words · Wuulong

WalkGIS 實戰:如何製作「有廁所的便利商店」地圖 (Google My Maps + ATAK)

在規劃「2026 台灣河流探索」的過程中,除了路線本身的挑戰,最實際的問題往往是:「哪裡可以補給?」以及更重要的——「哪裡有廁所?」。 雖然 Google Maps 很強大,但要一眼在地圖上看出「哪一家超商有廁所」並不容易。於是,我決定自己動手做一張專屬的地圖,並將其整合到我的主力導航工具 Google My Maps 與 ATAK 中。 🚀 任務目標 取得全台灣便利商店的資料。 篩選出標記為「有廁所」的店家。 製作成 Google My Maps 可以吃的 KML 檔。 打包成 ATAK 可以用的 Data Package。 🛠️ Step 1: 資料來源 - OpenStreetMap (OSM) 相較於政府資料只有地址,OpenStreetMap (OSM) 社群維護的資料包含了更多屬性(如廁所、ATM、品牌)。我使用 Overpass API 來抓取資料。 Python 抓取腳本 (核心邏輯) 我們不需要下載整個台灣的圖資,只需針對 shop=convenience 進行查詢: overpass_query = """ [out:json][timeout:60]; area["name:en"="Taiwan"]->.searchArea; ( node["shop"="convenience"](area.searchArea); way["shop"="convenience"](area.searchArea); ); out center; """ 這段腳本會抓下全台約 13,000+ 筆超商資料。 🧹 Step 2: 現實的殘酷 - 資料篩選 抓下來後,我原本期待能有滿滿的廁所清單,結果進行統計後發現: Total Stores: 13,000+ Toilets = Yes: ~550 Toilets = No: ~150 Toilets = Unknown: 12,000+ 顯然 OSM 上關於廁所的標記還很不普及(填寫率不到 5%)。但換個角度想,這 550 間 是經過熱心網友確認「一定有」廁所的精華名單,對於急需的人來說,這就是最可靠的綠洲。 ...

2026-01-09 · 2 min · 221 words · Wuulong

WalkGIS 實戰:為 ATAK 打造專屬的「河川探索」戰術圖示包

在 上一篇 我們搞定了「有廁所的便利商店」地圖資料。然而,當我們真正走入濁水溪或曾文溪的荒野時,地圖上需要的資訊遠不止這些。 我們需要知道哪裡有攔沙壩 (Weir) 可以觀察水流,哪裡有 吊橋 (Suspension Bridge) 可以跨越峽谷,哪裡有 土地公廟 (Earth God Temple) 可以補給休息。 ATAK 內建的軍規符號太過複雜且抽象,網路上抓的圖示又風格不一。於是,我決定自己動手做一套**「WalkGIS 河川探索專用圖示包」**。 🎯 設計理念:直覺至上 在地圖上(尤其是戶外強光下的手機螢幕),辨識度是第一要務。經過幾次嘗試(從下載 icon 到失敗的 fallback),我發現最有效的方法竟然最簡單: 「直接把字寫在圓圈裡。」 看圖示猜半天這是廟還是房子?不如直接寫個**「廟」**。 這是水壩還是水管?直接寫個**「壩」**。 我將需求分為四大類色系,建立了一套視覺語言: 💚 生存 (Survival) - 綠色:廁、店 (雜貨)、水 (水源)、車 (車宿點) 💙 水利 (Hydro) - 藍色:壩、橋、閘 (水門)、生 (生態點)、景 (觀景) 🧡 人文 (Culture) - 橙/棕:廟 (土地公)、跡 (遺跡)、訊 (解說牌)、村 (部落) ❤️ 危險 (Danger) - 紅色:危 🛠️ 技術實作:Python Pillow 自動繪圖 我寫了一個 Python 腳本 (generate_chinese_icons.py),完全不依賴外部圖片素材,直接用程式碼「畫」出這些圖示。 核心邏輯 定義設定檔:用一個 List 管理所有圖示的名稱、顯示文字與顏色。 字體偵測:自動抓取 macOS 系統內的 PingFang.ttc 或 STHeiti 中文字體。 畫布生成: 建立 64x64 的透明底圖。 畫一個實心圓圈(帶白邊),顏色由設定檔決定。 將中文字置中寫在圓圈上。 ATAK 打包:生成 iconset.xml 並將所有 PNG 壓成 ZIP 檔。 程式碼與成果 # 部分程式碼片段 def create_text_icon(item): # ... 畫圓與寫字 ... draw.ellipse([4, 4, 60, 60], fill=item['color'], outline='white', width=3) draw.text((x, y), item['label'], font=font, fill='white') # ... 存檔 ... 執行後,我得到了一個 River_Exploration_Icons_Text.zip。 ...

2026-01-09 · 1 min · 146 words · Wuulong

WalkGIS 資料治理實戰:從「差不多準」到「精確定位」的 GPS 校正之旅

在 WalkGIS 2.0 的開發過程中,我發現早期的地圖資料存在嚴重的 GPS 誤差。本文記錄了如何利用 Google Maps API 進行批次自動化校正,並解決了「台灣中心點」歸零問題、路徑檔被誤改以及資料一致性維護的技術挑戰。

2026-01-05 · 1 min · 143 words · Wuulong

Gemini Dynamic View 實戰:一句話把萬字研究報告變成視覺化簡報

在將 Deep Research 應用於 WalkGIS 的過程中,我意外發現了 Gemini ‘Dynamic View’ 的強大之處。透過幾個簡單的 Prompt,一份幾萬字的枯燥水利工程報告,瞬間被轉化為精美的時間軸、比較表與行程卡片。這不僅是視覺化工具,更是新一代的知識策展神器。

2026-01-04 · 1 min · 78 words · Wuulong