現(xiàn)SHP轉(zhuǎn)VCT:字段映射與坐標(biāo)轉(zhuǎn)換全流程解析)
簡(jiǎn)介面向GIS開(kāi)發(fā)與數(shù)據(jù)管理場(chǎng)景這份壓縮包提供了一套將ShapefileSHP轉(zhuǎn)換為矢量瓦片VCT的完整工具主要解決ArcGIS環(huán)境下海量矢量數(shù)據(jù)難以高效網(wǎng)絡(luò)發(fā)布的問(wèn)題適合需要在WebGIS或移動(dòng)端展示地理數(shù)據(jù)的開(kāi)發(fā)者和數(shù)據(jù)處理人員。包內(nèi)共92個(gè)文件約6.1MB包含C源碼.cpp、.h、ArcGIS工程文件.dsw、.vcproj、.rc以及已編譯好的可執(zhí)行程序.exe和調(diào)試輔助文件.pdb、.ilk既可直接運(yùn)行也便于二次開(kāi)發(fā)與學(xué)習(xí)底層轉(zhuǎn)換邏輯。目前已有3821人學(xué)習(xí)下載。從文件結(jié)構(gòu)看工具實(shí)現(xiàn)了SHP讀取、要素解析、瓦片切割、MVT編碼等關(guān)鍵模塊并提供ArcGIS環(huán)境下的對(duì)話框交互界面。借助該工具可以快速將本地SHP數(shù)據(jù)轉(zhuǎn)換為適合Web端加載的VCT格式免去自行編寫(xiě)轉(zhuǎn)換代碼的時(shí)間成本同時(shí)還能參考其工程組織方式理解SHP與VCT之間的數(shù)據(jù)轉(zhuǎn)換流程。1. SHP轉(zhuǎn)VCT工具為什么不能靠“另存為”解決做自然資源數(shù)據(jù)匯交的人多半都有過(guò)這種經(jīng)歷ArcGIS里把shapefile整理得干干凈凈圖斑邊界、屬性字段都沒(méi)問(wèn)題結(jié)果提交數(shù)據(jù)時(shí)對(duì)方來(lái)一句“要VCT格式不是SHP”。打開(kāi)ArcGIS的導(dǎo)出對(duì)話框找遍格式列表也沒(méi)有VCT這個(gè)選項(xiàng)因?yàn)閂CT是國(guó)土行業(yè)自定義的文本交換格式不是通用格式。ARCGIS shp轉(zhuǎn)VCT這個(gè)需求幾乎都出現(xiàn)在這類場(chǎng)景里某縣的土地報(bào)批、三調(diào)外業(yè)核查、年度變更調(diào)查或者給某規(guī)劃院交底圖數(shù)據(jù)。這份工具本質(zhì)是一套基于ArcGIS Python環(huán)境的轉(zhuǎn)換腳本加配置模板解決的是“SHP怎么變成符合國(guó)標(biāo)結(jié)構(gòu)的VCT”這件事適合測(cè)繪數(shù)據(jù)生產(chǎn)、GIS數(shù)據(jù)處理、自然資源相關(guān)行業(yè)的從業(yè)者。明白了這個(gè)邊界接下來(lái)看它具體怎么做。2. VCT格式與工具選型先搞懂交換格式的數(shù)據(jù)約束2.1 VCT不是另一種ShapefileVCT全稱是矢量數(shù)據(jù)交換格式它和shapefile的最大區(qū)別在于VCT有明確的圖層組織約定和屬性字段約束而shapefile只是“要素類屬性表”的通用容器。以土地利用相關(guān)的VCT為例圖斑層、線狀地物層、零星地物層必須寫(xiě)到固定段里每一層的字段名、字段順序都有參照標(biāo)準(zhǔn)坐標(biāo)單位通常要求為十進(jìn)制度文本編碼要求GBK或GB2312不是ArcGIS默認(rèn)的UTF-8。這意味著轉(zhuǎn)換不能只是“換個(gè)格式名”而要做三件事字段名映射、坐標(biāo)單位轉(zhuǎn)換、編碼轉(zhuǎn)換。字段名映射是最容易翻車的——SHP里字段可以叫“DLBM”“DKMJ”但VCT模板里可能要求“地類編碼”“圖斑面積”或某種簡(jiǎn)寫(xiě)兩者對(duì)不上后面的解析程序直接報(bào)錯(cuò)。編碼問(wèn)題更隱蔽SHP的屬性值在ArcGIS里顯示正常是因?yàn)锳rcGIS自己處理了編碼而VCT是以文本文件落盤(pán)的編碼不對(duì)對(duì)方用國(guó)標(biāo)解析器打開(kāi)就是亂碼。2.2 工具鏈怎么選腳本方案與商用工具的取舍處理SHP轉(zhuǎn)VCT業(yè)內(nèi)常見(jiàn)做法有三條路一是用ArcGIS自帶工具手工整理再導(dǎo)出二是用商用的數(shù)據(jù)轉(zhuǎn)換平臺(tái)三是寫(xiě)Python腳本配合arcpy實(shí)現(xiàn)批處理。這里給出的工具包走的是第三條路。它由一個(gè)主轉(zhuǎn)換腳本、一個(gè)字段映射配置文件和若干數(shù)據(jù)檢查腳本組成設(shè)計(jì)目標(biāo)是讓同一個(gè)工作流可以重復(fù)使用。三條路的差異用一個(gè)表說(shuō)清楚方案適用場(chǎng)景優(yōu)點(diǎn)缺點(diǎn)手工整理ArcGIS導(dǎo)出單文件、字段簡(jiǎn)單不需要寫(xiě)代碼字段映射全靠手敲容易漏批量時(shí)效率極低商用轉(zhuǎn)換平臺(tái)預(yù)算充足、有正版授權(quán)界面操作支持多格式自定義國(guó)標(biāo)模板需要額外配置成本高Python腳本arcpy有Python基礎(chǔ)、需要批量可復(fù)用、可版本控制、可加入檢查邏輯環(huán)境依賴需要配好調(diào)試有門(mén)檻這個(gè)工具包選擇了腳本方案核心原因是VCT模板每個(gè)項(xiàng)目都會(huì)微調(diào)腳本把映射邏輯集中在配置文件里項(xiàng)目變的時(shí)候只改一處不用重新走一遍界面操作。下面兩節(jié)就從這個(gè)思路出發(fā)把轉(zhuǎn)換前的準(zhǔn)備和轉(zhuǎn)換中的要點(diǎn)拆開(kāi)講。3. 轉(zhuǎn)換前體檢SHP數(shù)據(jù)的坐標(biāo)系統(tǒng)、編碼與字段檢查3.1 坐標(biāo)系統(tǒng)體檢投影坐標(biāo)必須轉(zhuǎn)成地理坐標(biāo)拿到一份SHP第一步先看坐標(biāo)系。很多SHP是從地方坐標(biāo)系或者高斯投影里出來(lái)的平面坐標(biāo)的數(shù)值范圍是幾十萬(wàn)到幾百萬(wàn)而VCT要求十進(jìn)制度不轉(zhuǎn)換的話圖斑坐標(biāo)會(huì)變成一串天文數(shù)字圖形直接飛出地球。檢查坐標(biāo)系用Describe就能完成。import arcpy shp_path rD:\data\taoban.shp desc arcpy.Describe(shp_path) sr desc.spatialReference print(坐標(biāo)系名, sr.name) print(投影類型, sr.type) # 如果不是地理坐標(biāo)系執(zhí)行投影轉(zhuǎn)換 if sr.type ! Geographic: output rD:\data\taoban_geo.shp arcpy.Project_management(shp_path, output, arcpy.SpatialReference(4326)) print(已轉(zhuǎn)換為 WGS84 地理坐標(biāo)系) else: print(已經(jīng)是地理坐標(biāo)系可直接使用)邏輯說(shuō)明先用Describe讀取空間參考對(duì)象sr.type可以區(qū)分是地理坐標(biāo)Geographic還是投影坐標(biāo)Projected。判定為投影坐標(biāo)時(shí)用Project_management轉(zhuǎn)換到WGS84經(jīng)緯度。參數(shù)說(shuō)明arcpy.SpatialReference(4326)是WGS84的EPSG代碼如果你的數(shù)據(jù)是CGCS2000坐標(biāo)系需要把4326換成4490即CGCS2000地理坐標(biāo)系?,F(xiàn)實(shí)中不少地方要求交CGCS2000的VCT所以這個(gè)參數(shù)要看項(xiàng)目要求不能固定寫(xiě)死。3.2 屬性表體檢字段類型和長(zhǎng)度是隱藏地雷坐標(biāo)系統(tǒng)對(duì)了接著看屬性表。VCT標(biāo)準(zhǔn)對(duì)字段長(zhǎng)度敏感比如地類代碼字段長(zhǎng)度如果是6SHP里卻建成了10轉(zhuǎn)換后解析時(shí)高位的空格會(huì)被帶進(jìn)去值匹配直接失敗。用ListFields把所有字段的類型和長(zhǎng)度拉出來(lái)和VCT模板逐個(gè)對(duì)。import arcpy shp_path rD:\data\taoban_geo.shp fields arcpy.ListFields(shp_path) for f in fields: print(f.name, f.type, f.length) # 對(duì)照模板檢查關(guān)鍵字段 target_fields { DLBM: {type: String, length: 6}, TBMJ: {type: Double, length: 18}, XZQDM: {type: String, length: 12}, } for name, spec in target_fields.items(): field [f for f in fields if f.name name] if not field: print(f[缺少字段] {name}) else: f field[0] if f.type ! spec[type] or f.length spec[length]: print(f[字段不符] {name} 實(shí)際類型{f.type} 長(zhǎng)度{f.length})邏輯說(shuō)明這個(gè)腳本不修改數(shù)據(jù)只做體檢。target_fields字典是從VCT模板里抽出來(lái)的關(guān)鍵字段約束類型和長(zhǎng)度就是對(duì)照標(biāo)準(zhǔn)。參數(shù)說(shuō)明字段名DLBM、TBMJ、XZQDM是常見(jiàn)的國(guó)標(biāo)縮寫(xiě)實(shí)際項(xiàng)目里如果模板用的中文名把字典的鍵改成模板里的中文即可。體檢結(jié)果如果有缺少或類型不符的字段先回ArcGIS里改字段結(jié)構(gòu)不要在轉(zhuǎn)換腳本里硬編碼處理否則每跑一次都要改腳本。3.3 數(shù)據(jù)清洗空值與重復(fù)要素會(huì)影響圖斑編號(hào)字段結(jié)構(gòu)對(duì)了還要處理數(shù)據(jù)內(nèi)容。最常見(jiàn)的問(wèn)題是空值某個(gè)圖斑的地類代碼是空的VCT解析時(shí)會(huì)把空字符串寫(xiě)入記錄對(duì)方的程序未必能處理。另一個(gè)問(wèn)題是重復(fù)幾何完全重疊的圖斑會(huì)導(dǎo)致弧段編號(hào)生成失敗因?yàn)閂CT里的面狀要素是靠弧段拓?fù)浔磉_(dá)邊界的兩個(gè)圖斑共用同一個(gè)邊界時(shí)弧段只能登記一次。import arcpy shp_path rD:\data\taoban_geo.shp with arcpy.da.UpdateCursor(shp_path, [DLBM, TBMJ]) as cursor: for row in cursor: # 地類代碼為空時(shí)填為99999代表“未調(diào)查” if row[0] is None or str(row[0]).strip() : row[0] 99999 cursor.updateRow(row) print(補(bǔ)充默認(rèn)地類代碼:, row[0]) # 面積字段為負(fù)值時(shí)取絕對(duì)值 if row[1] is not None and row[1] 0: row[1] abs(row[1]) cursor.updateRow(row) print(面積負(fù)數(shù)已糾正:, row[1])邏輯說(shuō)明UpdateCursor可以逐行修改要素屬性這里處理兩個(gè)高頻問(wèn)題空地類代碼補(bǔ)默認(rèn)值負(fù)面積取絕對(duì)值。參數(shù)說(shuō)明默認(rèn)值99999在部分項(xiàng)目里是“未調(diào)查地類”的約定寫(xiě)法換項(xiàng)目時(shí)改成對(duì)方模板里規(guī)定的默認(rèn)碼不要讓腳本自己發(fā)明。重復(fù)幾何的刪除要復(fù)雜一些一般先跑ArcGIS的Delete Identical工具再用Select Layer By Location配合拓?fù)錂z查腳本去重這一步不能省后面積弧段生成階段報(bào)錯(cuò)時(shí)再回頭查重復(fù)就會(huì)很被動(dòng)。4. 屬性映射與VCT生成arcpy腳本的完整轉(zhuǎn)換流程4.1 字段映射配置把SHP字段名翻譯成VCT字段名字段映射是轉(zhuǎn)換腳本的核心。SHP里的字段名通常只有我們自己看得懂VCT模板里的字段名則是國(guó)標(biāo)規(guī)定的。這個(gè)工具包的做法是把映射關(guān)系單獨(dú)放到一個(gè)JSON或者字典里轉(zhuǎn)換腳本只讀配置不寫(xiě)死任何字段名。# field_mapping.json { layer: taoban, fields: [ {shp_field: DLBM, vct_field: 地類編碼}, {shp_field: TBMJ, vct_field: 圖斑面積}, {shp_field: XZQDM, vct_field: 行政區(qū)代碼}, {shp_field: XZQMC, vct_field: 行政區(qū)名稱} ], geometry: Polygon, encoding: GBK }邏輯說(shuō)明json文件分為三部分layer聲明圖層名fields數(shù)組是一一對(duì)應(yīng)的映射關(guān)系geometry聲明幾何類型encoding聲明輸出編碼。參數(shù)說(shuō)明shp_field必須是SHP里真實(shí)存在的字段名vct_field必須是VCT模板里官方規(guī)定的字段名兩個(gè)都從模板復(fù)制不要手打。這個(gè)配置的好處是項(xiàng)目換模板時(shí)只改json不碰腳本。4.2 要素遍歷與弧段ID生成面狀數(shù)據(jù)的核心邊界面狀要素轉(zhuǎn)VCT時(shí)一個(gè)容易卡住的概念是“弧段”。VCT里多邊形不是直接存整個(gè)環(huán)的坐標(biāo)而是拆成弧段兩個(gè)圖斑共邊時(shí)共用一條弧段。這意味著轉(zhuǎn)換時(shí)要做兩個(gè)動(dòng)作一是給每條唯一邊界生成弧段ID二是把圖斑要素與弧段ID關(guān)聯(lián)起來(lái)。import arcpy from collections import OrderedDict shp_path rD:\data\taoban_geo.shp # 弧段字典key為邊界坐標(biāo)序列的指紋value為弧段ID arc_dict OrderedDict() arc_id 0 with arcpy.da.SearchCursor(shp_path, [OID, SHAPE]) as cursor: for oid, shape in cursor: rings shape.getPart() for part in rings: # 取ring的坐標(biāo)序列生成指紋 coords [] for point in part: coords.append((round(point.X, 6), round(point.Y, 6))) fingerprint str(coords) if fingerprint not in arc_dict: arc_dict[fingerprint] fARC_{arc_id:06d} arc_id 1 print(共生成弧段數(shù), len(arc_dict)) for k, v in list(arc_dict.items())[:5]: print(v, k[:80])邏輯說(shuō)明這段代碼先遍歷所有圖斑的幾何邊界把每個(gè)ring的坐標(biāo)序列四舍五入到6位小數(shù)后做成字符串指紋指紋相同的說(shuō)明是共邊弧段只登記一次。參數(shù)說(shuō)明round(point.X, 6)這個(gè)6位小數(shù)是為了消除浮點(diǎn)誤差如果兩個(gè)SHP的邊界點(diǎn)坐標(biāo)在小數(shù)點(diǎn)后第7位有輕微差異6位精度能容忍這種建模誤差但如果數(shù)據(jù)本身是從低精度來(lái)源轉(zhuǎn)出來(lái)的可能要放寬到5位否則明明是共邊卻被當(dāng)成不同的弧段。4.3 VCT文件寫(xiě)入文件頭、屬性表段與圖形數(shù)據(jù)段VCT文件本質(zhì)是分段結(jié)構(gòu)的文本文件常見(jiàn)實(shí)現(xiàn)包含文件頭、屬性表定義段、圖形數(shù)據(jù)段三部分。文件頭記錄版本號(hào)和坐標(biāo)系信息屬性表段定義每個(gè)圖層有哪些字段圖形數(shù)據(jù)段按要素寫(xiě)入坐標(biāo)和屬性值。import io vct_path rD:\data\output\taoban.vct encoding GBK with io.open(vct_path, w, encodingencoding, newline\r\n) as f: # 文件頭 f.write(HEADER BEGIN\n) f.write(VERSION: 1.0\n) f.write(COORDINATE_UNIT: DEGREE\n) f.write(COORDINATE_SYSTEM: CGCS2000\n) f.write(HEADER END\n) # 屬性表定義段 f.write(TABLE BEGIN\n) f.write(TABLE_NAME: taoban\n) f.write(FIELD: 地類編碼,C,6\n) f.write(FIELD: 圖斑面積,N,18,2\n) f.write(FIELD: 行政區(qū)代碼,C,12\n) f.write(TABLE END\n) # 圖形數(shù)據(jù)段示例要素 f.write(FEATURE BEGIN\n) f.write(FEATURE_ID: 1\n) f.write(GEOMETRY_TYPE: POLYGON\n) f.write(ARC_IDS: ARC_000000 ARC_000001\n) f.write(ATTRIBUTES: 010101,12345.67,110000\n) f.write(FEATURE END\n) print(VCT文件已生成)邏輯說(shuō)明這個(gè)寫(xiě)入腳本把VCT文件當(dāng)作文本按行寫(xiě)入字段定義和屬性值之間用逗號(hào)分隔。文件頭里COORDINATE_UNIT必須和前面坐標(biāo)轉(zhuǎn)換的結(jié)果一致如果第3節(jié)沒(méi)做投影轉(zhuǎn)換這里就已經(jīng)錯(cuò)了。參數(shù)說(shuō)明FIELD行的格式是“字段名,類型,長(zhǎng)度”C代表字符型N代表數(shù)值型N后面還可以帶小數(shù)位數(shù)ATTRIBUTES行必須和TABLE里定義字段的順序完全一致這是VCT解析器的硬性要求順序錯(cuò)了不會(huì)報(bào)錯(cuò)但后面的值會(huì)全部錯(cuò)位。5. 避坑與常見(jiàn)問(wèn)題五個(gè)最容易翻車的轉(zhuǎn)換細(xì)節(jié)5.1 屬性值變成亂碼編碼聲明與寫(xiě)入編碼不一致現(xiàn)象VCT文件用文本編輯器打開(kāi)中文屬性值顯示成“錕斤拷”之類的亂碼。原因ArcGIS的SHP屬性本身可能是UTF-8編碼而VCT解析器按GBK讀取或者腳本寫(xiě)入時(shí)用的編碼是UTF-8但文件頭聲明的編碼是GBK。兩處不一致就出現(xiàn)亂碼。解決統(tǒng)一用GBK寫(xiě)文件同時(shí)在文件頭聲明編碼為GBK。這里有個(gè)細(xì)節(jié)ArcGIS的SHP屬性編碼有時(shí)是系統(tǒng)默認(rèn)編碼win系統(tǒng)下可能是ANSI也可能是UTF-8先看屬性表確定實(shí)際編碼再?zèng)Q定腳本的寫(xiě)入方向。如果是UTF-8的SHP先在ArcGIS里導(dǎo)出為GBK編碼的dbf再用腳本讀。5.2 解析器報(bào)“字段順序錯(cuò)誤”映射順序沒(méi)對(duì)齊現(xiàn)象VCT文件生成成功但對(duì)方的解析程序報(bào)字段缺失或類型錯(cuò)誤實(shí)際字段都在。原因VCT的TABLE段里定義了字段順序而FEATURE段里ATTRIBUTES行的值順序必須和TABLE段一致。如果腳本里屬性值拼接時(shí)用的是SHP的字段順序而TABLE段用的是VCT模板的字段順序兩者一旦不一致解析器按聲明順序取數(shù)第一個(gè)字段就錯(cuò)位了。解決在配置json里明確vct_field的順序腳本讀取時(shí)按這個(gè)順序組成屬性值字符串不要用shp_field的原始順序。轉(zhuǎn)換完成后人工抽查前三條要素的ATTRIBUTES行和TABLE段逐列對(duì)照。5.3 圖斑共邊處理后面積對(duì)不上現(xiàn)象轉(zhuǎn)換后的VCT在目標(biāo)軟件里打開(kāi)圖斑面積和圖斑形狀看著是對(duì)的但屬性里的面積字段和軟件重新計(jì)算的面積差幾平方米。原因VCT的面積字段是從圖斑屬性里讀取的不重新計(jì)算。SHP里面積字段可能保留了投影坐標(biāo)系下的平方米值而VCT要求的是經(jīng)緯度坐標(biāo)下的面積或者要求橢球面積。直接用原值寫(xiě)入就會(huì)和實(shí)際圖形面積不一致。解決轉(zhuǎn)換前在SHP里用Calculate Geometry重新計(jì)算面積坐標(biāo)系設(shè)為CGCS2000地理坐標(biāo)系輸出單位選平方米橢球面積。腳本里不要做任何面積計(jì)算只做屬性搬運(yùn)計(jì)算交給ArcGIS或原始數(shù)據(jù)生產(chǎn)環(huán)節(jié)。5.4 弧段生成失敗幾何拓?fù)洳婚]合現(xiàn)象轉(zhuǎn)換腳本跑到一半報(bào)“ring not closed”或弧段鏈表斷裂退出。原因SHP里部分圖斑的邊界沒(méi)有完全閉合頂點(diǎn)首尾坐標(biāo)不一致。這類臟數(shù)據(jù)在ArcGIS里可視化時(shí)看不出問(wèn)題但VCT要求弧段首尾閉合否則無(wú)法表達(dá)完整多邊形。解決轉(zhuǎn)換前先跑ArcGIS的Repair Geometry工具修完后用Feature to Polygon重建一次。注意Repair Geometry不報(bào)錯(cuò)的要素也可能是頂點(diǎn)順序問(wèn)題重建后要再跑一遍第3節(jié)的體檢腳本確認(rèn)幾何類型沒(méi)變。5.5 空值字段導(dǎo)致解析中斷現(xiàn)象VCT文件在ArcGIS里能打開(kāi)但用對(duì)方的質(zhì)檢軟件檢查時(shí)報(bào)空值錯(cuò)誤要素被跳過(guò)。原因SHP屬性里的NULL值直接寫(xiě)進(jìn)VCT的ATTRIBUTES行解析器讀到空字符串按類型轉(zhuǎn)換時(shí)報(bào)錯(cuò)。字符型還好處理數(shù)值型字段空值直接導(dǎo)致解析中斷。解決在寫(xiě)入屬性值之前對(duì)每個(gè)字段做空值判斷字符型填入默認(rèn)值數(shù)值型填入0或者模板允許的特殊值。這個(gè)邏輯不能放在最后的寫(xiě)入腳本里應(yīng)該放在第3.3節(jié)的數(shù)據(jù)清洗步驟中保證進(jìn)入VCT腳本的數(shù)據(jù)已經(jīng)是干凈的。6. 批量轉(zhuǎn)換與結(jié)果驗(yàn)證讓工具鏈跑得穩(wěn)一點(diǎn)6.1 批量處理的循環(huán)腳本一次處理整個(gè)目錄的SHP實(shí)際項(xiàng)目里不可能只有一個(gè)SHP一個(gè)村可能有十幾個(gè)圖層圖斑、線狀地物、零星地物等。把單文件轉(zhuǎn)換腳本套到一個(gè)循環(huán)里批量處理目錄下的所有SHP。import arcpy import os import json src_dir rD:\data\origin out_dir rD:\data\vct_output config_path rD:\data\field_mapping.json with open(config_path, r, encodingutf-8) as fp: config json.load(fp) layer_cfg {item[layer]: item for item in config[layers]} for root, dirs, files in os.walk(src_dir): for fn in files: if fn.endswith(.shp): shp_path os.path.join(root, fn) layer_name os.path.splitext(fn)[0] if layer_name not in layer_cfg: print(f[跳過(guò)未配置圖層] {fn}) continue vct_name f{layer_name}.vct vct_path os.path.join(out_dir, vct_name) print(f正在轉(zhuǎn)換{fn} - {vct_name}) # 真正的轉(zhuǎn)換函數(shù)略前面兩節(jié)已拆解 convert_shp_to_vct(shp_path, vct_path, layer_cfg[layer_name]) print(批量轉(zhuǎn)換完成)邏輯說(shuō)明這段代碼先讀取映射配置把圖層名和配置對(duì)應(yīng)關(guān)系建立成一個(gè)字典再遍歷源目錄只處理在配置里出現(xiàn)過(guò)的SHP未配置的圖層直接跳過(guò)并打印日志。參數(shù)說(shuō)明os.walk是遞歸遍歷如果你的目錄層級(jí)很深且只有一層SHP也可以換成os.listdir減少不必要的遍歷時(shí)間。convert_shp_to_vct是實(shí)際調(diào)用的轉(zhuǎn)換函數(shù)在實(shí)際工具包里已經(jīng)封裝到位這里的關(guān)鍵是圖層名與配置的對(duì)應(yīng)邏輯。6.2 結(jié)果驗(yàn)證三類檢查一個(gè)都不能少批量轉(zhuǎn)換完別急著提交花十分鐘做驗(yàn)證。我一般做三類檢查第一類是文件頭檢查用文本編輯器打開(kāi)VCT文件確認(rèn)文件頭里COORDINATE_UNIT是DEGREE、坐標(biāo)系是CGCS2000或WGS84跟項(xiàng)目要求一致。第二類是屬性抽查用表格比較工具或者寫(xiě)個(gè)小腳本把VCT的ATTRIBUTES行和SHP的屬性表逐條對(duì)比重點(diǎn)看字段錯(cuò)位和數(shù)據(jù)丟失。第三類是圖形驗(yàn)證把VCT文件用支持該格式的軟件打開(kāi)和原始SHP疊加看圖形是否完全重合。檢查項(xiàng)判定標(biāo)準(zhǔn)問(wèn)題處理文件頭坐標(biāo)系、單位、編碼與模板一致不一致則回第3節(jié)重轉(zhuǎn)屬性值抽查要素與SHP一致無(wú)錯(cuò)位錯(cuò)位則檢查field_mapping.json圖形疊加與SHP完全重合無(wú)移位、無(wú)缺失有缺失則回查弧段ID生成步驟這套驗(yàn)證邏輯不是可有可無(wú)有一次我跳過(guò)屬性抽查結(jié)果對(duì)方收到文件后反饋“所有圖斑的地類編碼都多了一個(gè)空格”問(wèn)題就出在長(zhǎng)度檢查漏了——SHP里字段長(zhǎng)度是8VCT模板要求6轉(zhuǎn)換腳本把值寫(xiě)進(jìn)去時(shí)補(bǔ)了空格。從那以后每次轉(zhuǎn)換完成我都要強(qiáng)制走一遍三連檢查文件頭、屬性、圖形一個(gè)不落。這個(gè)習(xí)慣幫我擋掉過(guò)好幾回“數(shù)據(jù)退回”的窘境希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取