矢量地圖SHP處理指南:從RAR解壓到坐標(biāo)糾偏與發(fā)布)
簡(jiǎn)介全國(guó)矢量地圖shp格式壓縮包面向GIS數(shù)據(jù)分析、城市規(guī)劃、環(huán)境研究與交通管理等人員提供了一套覆蓋全國(guó)范圍的基礎(chǔ)地理數(shù)據(jù)可滿足行政區(qū)劃、道路網(wǎng)絡(luò)、水系、地貌及興趣點(diǎn)等多種空間分析需求。包內(nèi)共85個(gè)文件以shp幾何文件、dbf屬性文件、shx索引文件和xml元數(shù)據(jù)為主整體大小34.27MB數(shù)據(jù)組織較為規(guī)范便于在ArcGIS、QGIS等常用GIS軟件中直接加載和編輯。目前已有543人學(xué)習(xí)下載。資源內(nèi)容包含省級(jí)、市級(jí)等不同行政層級(jí)邊界以及道路、河流、建筑、機(jī)場(chǎng)車站等點(diǎn)線面要素用戶可以直接用于地圖制圖、緩沖區(qū)分析、疊加統(tǒng)計(jì)和路徑規(guī)劃等實(shí)際操作對(duì)于需要建立全國(guó)底圖或開(kāi)展區(qū)域研究的讀者來(lái)說(shuō)是一套基礎(chǔ)且實(shí)用的數(shù)據(jù)素材。使用時(shí)注意根據(jù)項(xiàng)目需求核對(duì)數(shù)據(jù)精度與更新日期以提高分析結(jié)果的可靠性。1. 拿到“全國(guó)矢量地圖shp格式.rar”先把坐標(biāo)、來(lái)源和邊界范圍三件事問(wèn)清楚很多做GIS的人電腦里都有這樣一個(gè)壓縮包幾個(gè)GB的RAR文件名寫(xiě)著“全國(guó)矢量地圖shp格式”解壓出來(lái)是省界、市界、區(qū)縣界、鐵路、河流、居民地年份不明坐標(biāo)系不明。它的價(jià)值很直接——不用從零矢量化全國(guó)也不用反復(fù)搜“中國(guó)行政區(qū)劃shp怎么下載”項(xiàng)目底圖、出圖、空間分析都能靠它起步。但同樣叫“全國(guó)矢量地圖”的包坐標(biāo)系可能是CGCS2000也可能是GCJ-02一份省界文件可能叫“省1”另一份叫“省2”在ArcGIS里打開(kāi)可能是一片空白屬性表全是亂碼。這些都是真實(shí)發(fā)生的現(xiàn)象不是版本玄學(xué)。這篇從拿到RAR開(kāi)始按拆包、轉(zhuǎn)格式、日常加工、排錯(cuò)、發(fā)布五個(gè)環(huán)節(jié)講一遍爭(zhēng)取讓你當(dāng)天就把數(shù)據(jù)跑起來(lái)。2. RAR里的全國(guó)SHP拆包坐標(biāo)系陷阱、圖層命名差異與GB級(jí)數(shù)據(jù)的資源賬2.1 坐標(biāo)系陷阱CGCS2000與GCJ-02的偏差會(huì)讓邊界看起來(lái)“錯(cuò)位”300米打開(kāi)壓縮包以后我第一件事不是急著拖進(jìn)ArcGIS而是先查坐標(biāo)系。全國(guó)范圍的shp文件最常見(jiàn)的是CGCS2000EPSG:4490這是當(dāng)前國(guó)內(nèi)測(cè)繪成果的標(biāo)準(zhǔn)坐標(biāo)系。另一個(gè)常見(jiàn)的坐標(biāo)是WGS84和CGCS2000在普通制圖尺度下差別很小。真正讓你翻車的是GCJ-02也就是高德、騰訊這些互聯(lián)網(wǎng)地圖用到的加密坐標(biāo)系。高德地圖矢量爬取下來(lái)的一堆邊界、道路數(shù)據(jù)幾乎都落在GCJ-02里。它和標(biāo)準(zhǔn)SHP疊在一起視覺(jué)上會(huì)整體偏移幾百米城市里尤其明顯——路網(wǎng)和底圖錯(cuò)開(kāi)一條街。這種偏移不是用“平移”能解決的因?yàn)镚CJ-02是對(duì)WGS84做非線性加密后的結(jié)果不同區(qū)域偏移量不一樣。我之前接過(guò)一個(gè)項(xiàng)目甲方拿“高德爬取的行政邊界”當(dāng)正式界址用疊到1:2000的地形圖上差了半條路最后全部返工。現(xiàn)在我的原則是凡是涉及面積計(jì)算、界址比對(duì)、審批出圖一律不用爬取類矢量做分析底圖頂多當(dāng)展示用。判斷坐標(biāo)系的方法很簡(jiǎn)單用GDAL自帶的ogrinfo看一眼.prj信息ogrinfo -so 全國(guó)_district.shp 全國(guó)_district命令最后的參數(shù)是圖層名通常和shp主文件名一致。輸出里會(huì)有一段Layer SRS WKT看到GCS_China_Geodetic_Coordinate_System_2000就是CGCS2000看到GCS_WGS_1984就是WGS84。GCJ-02的prj文件在標(biāo)準(zhǔn)工具里經(jīng)常顯示為自定義字符串甚至缺失。更保險(xiǎn)的辦法是打開(kāi)shp的.prj文件用記事本看里面寫(xiě)的坐標(biāo)系名稱。如果寫(xiě)的是“GCJ-02”這類非標(biāo)準(zhǔn)名稱那這份數(shù)據(jù)就屬于商業(yè)地圖坐標(biāo)系不能用國(guó)土、規(guī)劃項(xiàng)目里慣用的CGCS2000去套。拿到北京 shp這類城市級(jí)數(shù)據(jù)也一樣直接看prj而不是猜后綴。2.2 圖層命名與字段差異同樣叫“省界”為什么會(huì)有省1和省2兩份文件解壓出來(lái)的文件夾里經(jīng)常能看到一套命名的數(shù)據(jù)省界、市界、區(qū)縣界、鄉(xiāng)鎮(zhèn)界、鐵路、河流、居民地。用詞不統(tǒng)一但結(jié)構(gòu)基本是這個(gè)套路。真正讓人困惑的是有時(shí)同一個(gè)圖層會(huì)出現(xiàn)兩份比如“省界線文件省1和省2的shp文件有什么區(qū)別”這個(gè)問(wèn)題我?guī)缀趺恐芏寄茉陧?xiàng)目群里看到。常見(jiàn)情況有兩種。第一種是同一份邊界的不同版本一個(gè)含沿海島嶼、飛地另一個(gè)做了簡(jiǎn)化去掉了圖斑面積特別小的小島。第二種是數(shù)據(jù)來(lái)源不同省1來(lái)自國(guó)家基礎(chǔ)地理信息數(shù)據(jù)省2來(lái)自某個(gè)行業(yè)專項(xiàng)采集屬性表字段都不一樣。判斷方法是分別跑一次ogrinfo看要素?cái)?shù)和字段名ogrinfo -so 省1.shp 省1 ogrinfo -so 省2.shp 省2 ogrinfo -al -so 省1.shp | head -40ogrinfo -al -so會(huì)列出所有屬性字段和類型。對(duì)比兩份文件的要素?cái)?shù)、字段名集合再看是否有省代碼字段。通常一份帶6位或12位行政區(qū)劃代碼另一份只有名稱這種優(yōu)先選用帶官方行政區(qū)劃代碼的版本后面做屬性關(guān)聯(lián)會(huì)省很多事。字段命名也要留意。有的包用英文AREA、PERIMETER、PRV_NAME、PRV_CODE這些寫(xiě)法很老派有的直接用中文屬性名比如“省名稱”“省代碼”。中文屬性對(duì)出圖友好但轉(zhuǎn)KML、GeoJSON時(shí)容易因?yàn)榫幋a出問(wèn)題這部分在第5章展開(kāi)。無(wú)論什么命名我先記住一點(diǎn)把“省代碼”“PAC”“ADCODE”這類鍵字段找出來(lái)它是后續(xù)關(guān)聯(lián)統(tǒng)計(jì)數(shù)據(jù)的鑰匙比名稱可靠得多。2.3 要素?cái)?shù)量與硬件預(yù)算先算資源賬再?zèng)Q定用QGIS還是ArcGIS全國(guó)級(jí)別的shp包解壓后大小往往以GB計(jì)算。雖然文件大小不直接等于加載速度但要素?cái)?shù)量會(huì)實(shí)實(shí)在在影響軟件表現(xiàn)。以區(qū)縣級(jí)邊界為例全國(guó)有幾千個(gè)縣級(jí)區(qū)劃光是一個(gè)區(qū)縣面圖層加屬性表就有上萬(wàn)條記錄如果還帶了鄉(xiāng)鎮(zhèn)界、村級(jí)點(diǎn)、地名注記要素量輕松到幾十萬(wàn)甚至百萬(wàn)級(jí)。在這樣的數(shù)據(jù)量下老版本ArcMap打開(kāi)大shp經(jīng)常轉(zhuǎn)圈卡死尤其是啟動(dòng)時(shí)就自動(dòng)識(shí)別字段類型的那一下可能等幾分鐘沒(méi)反應(yīng)。我現(xiàn)在的習(xí)慣是優(yōu)先用QGIS 3.x打開(kāi)全國(guó)包做瀏覽和檢查。QGIS對(duì)大數(shù)據(jù)量shapefile的列表加載更利索內(nèi)存管理也相對(duì)穩(wěn)定。如果項(xiàng)目規(guī)范必須用ArcGIS那建議在ArcGIS Pro里操作Pro的64位架構(gòu)處理大文件比傳統(tǒng)ArcMap好不少。另一個(gè)容易忽略的點(diǎn)是DBF屬性表的限制。shapefile的屬性存于.dbf老式dbf單文件上限約2GB字段數(shù)上限255個(gè)。全國(guó)包如果屬性字段特別多或者要素總量過(guò)大寫(xiě)入時(shí)會(huì)報(bào)錯(cuò)。遇到這種情況我會(huì)把數(shù)據(jù)轉(zhuǎn)成GeoPackage.gpkg作為工作格式減少DBF帶來(lái)的邊界問(wèn)題。GeoPackage在QGIS和ArcGIS Pro里都能直接讀字段類型也更寬松。資源賬的另一部分是坐標(biāo)投影。全國(guó)矢量shp通常是經(jīng)緯度坐標(biāo)做長(zhǎng)度、面積計(jì)算時(shí)必須投影到適合所在區(qū)域的地圖投影坐標(biāo)系。比如只算北京市的面積范圍就用適合北京的投影參數(shù)算全國(guó)面積推薦Albers等積投影。很多人拿著WGS84的經(jīng)緯度shp直接算面積結(jié)果單位變成平方度數(shù)值小得不正常然后跑來(lái)問(wèn)數(shù)據(jù)是不是壞了。數(shù)據(jù)沒(méi)壞是投影沒(méi)設(shè)置。3. 解壓、校驗(yàn)與格式轉(zhuǎn)換從RAR到SHP再到KML與GeoJSON/3D Tiles3.1 用7-Zip命令行解壓RAR并逐文件核驗(yàn)SHP三件套不少人解壓RAR習(xí)慣雙擊用WinRAR的界面點(diǎn)“解壓到”這對(duì)單文件沒(méi)問(wèn)題但遇到幾十個(gè)分卷、帶路徑的壓縮包我建議用7-Zip命令行命令簡(jiǎn)單還能保留目錄結(jié)構(gòu)、避免文件名編碼錯(cuò)亂7z l 全國(guó)矢量地圖shp格式.rar 7z x 全國(guó)矢量地圖shp格式.rar -oD:\gis_data -y第一條命令l是列出壓縮包內(nèi)容先確認(rèn)里面是單個(gè)文件夾還是一片散文件能提前看到有沒(méi)有分卷、有沒(méi)有說(shuō)明文本。第二條命令x是完整解壓-o指定輸出目錄-y遇到覆蓋詢問(wèn)直接確認(rèn)。如果壓縮包設(shè)了密碼可以在命令里加-p密碼但我一般先不加等它提示時(shí)再輸入避免密碼帶特殊符號(hào)時(shí)命令行解析出錯(cuò)。解壓之后不要急著打開(kāi)先做三件套校驗(yàn)。shapefile不是單個(gè)文件一個(gè)完整圖層至少包含三個(gè)文件文件后綴作用缺失后果.shp幾何要素本身打開(kāi)直接報(bào)“文件不存在”.shx幾何索引能打開(kāi)但可能要素殘缺或顯示空白.dbf屬性表要素能顯示但沒(méi)有屬性字段.prj坐標(biāo)系統(tǒng)定義軟件按默認(rèn)坐標(biāo)讀坐標(biāo)可能偏移.cpg屬性編碼聲明中文屬性易亂碼.dbf缺失是最隱蔽的ArcGIS可能照常顯示圖形但屬性表打開(kāi)是空的等你要用字段做符號(hào)化才發(fā)現(xiàn)問(wèn)題。我習(xí)慣先執(zhí)行一次目錄清單檢查ls -l D:\gis_data\*.shp D:\gis_data\*.shx D:\gis_data\*.dbf看到每類文件數(shù)量一致還不夠文件名必須完全匹配。province.shp對(duì)應(yīng)province.shx和province.dbf如果壓縮包里有province.shx.bak這種奇怪后綴多半是別人手工修復(fù)過(guò)的殘留得小心對(duì)待。3.2 SHP轉(zhuǎn)KMLogr2ogr最小命令和ArcGIS的另存路線把全國(guó)或某個(gè)省份的shp轉(zhuǎn)成KML用于谷歌地球、奧維、無(wú)人機(jī)地面站這類場(chǎng)景是出現(xiàn)頻率很高的需求。網(wǎng)上常搜“arcgis shp轉(zhuǎn)kml”ArcGIS里確實(shí)有專門(mén)的工具ArcToolbox里的“圖層轉(zhuǎn)KML”勾選“將要素限制為感興趣區(qū)域”可以控制輸出范圍。但在沒(méi)有ArcGIS的環(huán)境中GDAL的ogr2ogr是最省事的手段ogr2ogr -f KML -dsco NameFieldNAME 全國(guó)_省份.kml 全國(guó)_省份.shp-f KML指定輸出格式-dsco NameFieldNAME把屬性表里的NAME字段作為KML的標(biāo)注名稱這樣到了谷歌地球里圖斑顯示的是省名而不是一串ID。如果不寫(xiě)這個(gè)參數(shù)KML里的Placemark名字會(huì)變成數(shù)字型要素ID顯示效果很差。轉(zhuǎn)出來(lái)之后KML文件默認(rèn)是WGS84經(jīng)緯度坐標(biāo)這符合KML規(guī)范。如果原始SHP是CGCS2000ogr2ogr在轉(zhuǎn)KML時(shí)會(huì)自動(dòng)做坐標(biāo)系變換不需要手動(dòng)加參。要注意的是全國(guó)級(jí)別的KML生成后體積動(dòng)輒幾十MB以上谷歌地球加載會(huì)明顯卡頓。我建議按省級(jí)或地市級(jí)范圍導(dǎo)出不要一次性輸出全國(guó)。反過(guò)來(lái)做kml轉(zhuǎn)shp也一樣ogr2ogr -f ESRI Shapefile 輸出目錄/轉(zhuǎn)換結(jié)果.shp 輸入文件.kmlKML轉(zhuǎn)shp后最好用ogrinfo復(fù)查一次幾何類型KML里一個(gè)要素可能被讀成Point或Polygon混合一個(gè)shapefile圖層不能同時(shí)容納兩種幾何類型這種情況下GDAL會(huì)報(bào)錯(cuò)需要把點(diǎn)、線、面拆開(kāi)分別導(dǎo)出。3.3 SHP轉(zhuǎn)GeoJSON與3D Tiles做Web預(yù)覽與三維展示的取舍Web端做可視化GeoJSON是最通用的格式。轉(zhuǎn)GeoJSON的關(guān)鍵是輸出坐標(biāo)系必須是EPSG:4326不然Leaflet、Mapbox等前端庫(kù)不認(rèn)ogr2ogr -f GeoJSON -t_srs EPSG:4326 全國(guó)_省份.geojson 全國(guó)_省份.shp-t_srs是重投影參數(shù)把源數(shù)據(jù)從CGCS2000或Web墨卡托轉(zhuǎn)換到4326。如果源SHP本身就是4326這個(gè)參數(shù)寫(xiě)了也不影響結(jié)果但統(tǒng)一寫(xiě)明更安全。GeoJSON字段名用英文最省事中文字段名在部分前端庫(kù)和壓縮傳輸環(huán)節(jié)會(huì)出問(wèn)題。所以我在轉(zhuǎn)之前會(huì)先在QGIS里把屬性字段重命名一遍?,F(xiàn)在還有人問(wèn)“json轉(zhuǎn)shp網(wǎng)站”常見(jiàn)做法是在瀏覽器用geojson.io這類在線頁(yè)面工具做檢查和編輯但全國(guó)級(jí)別的GeoJSON動(dòng)輒幾百M(fèi)B上傳網(wǎng)站既不安全也不現(xiàn)實(shí)。我一般做小范圍數(shù)據(jù)核查才用在線工具大批量轉(zhuǎn)換一律本地ogr2ogr解決數(shù)據(jù)不用離開(kāi)自己的機(jī)器。“shp轉(zhuǎn)3dtiles”是另一個(gè)被問(wèn)很多的方向。把全國(guó)矢量轉(zhuǎn)3D Tiles用于Cesium場(chǎng)景這個(gè)思路沒(méi)問(wèn)題但要注意全國(guó)級(jí)別的數(shù)據(jù)直接轉(zhuǎn)3D Tiles會(huì)生成一個(gè)巨大的數(shù)據(jù)集根節(jié)點(diǎn)加載慢客戶端也扛不住。正確做法是先分層省界單獨(dú)一層道路單獨(dú)一層建筑單獨(dú)一層然后按瓦片范圍分批轉(zhuǎn)換。Cesium離子平臺(tái)可以直接吃GeoJSON/glTF生成3D Tiles本地也可以用py3dtiles這樣的庫(kù)跑。無(wú)論用哪條路原則是“大切片小粒度”先做輕量化精簡(jiǎn)要素再轉(zhuǎn)三維格式。4. 日常加工需求DWG轉(zhuǎn)SHP、Excel點(diǎn)數(shù)據(jù)轉(zhuǎn)SHP與漁網(wǎng)分割實(shí)戰(zhàn)4.1 DWG轉(zhuǎn)SHP圖層篩選、坐標(biāo)重投影與邊界閉合檢查國(guó)土、規(guī)劃行業(yè)經(jīng)常拿到DWG格式的地塊邊界或道路中線要轉(zhuǎn)成SHP和全國(guó)底圖疊在一起。最常見(jiàn)的問(wèn)題不是“轉(zhuǎn)不了”而是轉(zhuǎn)完以后坐標(biāo)系完全不對(duì)位。DWG文件很多是設(shè)計(jì)院自定義的平面坐標(biāo)系原點(diǎn)、單位都不標(biāo)準(zhǔn)直接轉(zhuǎn)SHP后圖形可能出現(xiàn)在完全錯(cuò)誤的方位。如果DWG是AutoCAD標(biāo)準(zhǔn)文件先另存為DXF再轉(zhuǎn)換GDAL對(duì)DXF的支持比內(nèi)建DWG驅(qū)動(dòng)成熟得多。然后用ogr2ogr做轉(zhuǎn)換ogr2ogr -f ESRI Shapefile 轉(zhuǎn)換結(jié)果.shp 規(guī)劃地塊.dxf -skipfailures-skipfailures很重要源文件里有些實(shí)體類型GDAL不認(rèn)加了這個(gè)參數(shù)就能跳過(guò)不至于中途中斷。如果不加可能轉(zhuǎn)了30%就報(bào)錯(cuò)停掉。轉(zhuǎn)換后用QGIS加載先查看要素的屬性表確認(rèn)圖層的幾何類型DWG里的閉合多段線轉(zhuǎn)進(jìn)SHP后通常成了Polygon但有很多看起來(lái)閉合卻實(shí)際沒(méi)閉合拓?fù)渖辖小拔撮]合線”后續(xù)做面積計(jì)算時(shí)會(huì)得到0或報(bào)錯(cuò)。遇到這種情況我的處理是在QGIS里跑一遍“修復(fù)幾何”工具或者用PostGIS的ST_MakeValid批量修復(fù)。更關(guān)鍵的步驟是坐標(biāo)重投影DWG里如果有控制點(diǎn)坐標(biāo)用“移動(dòng)到圖層”工具做仿射變換把整個(gè)圖形搬到正確位置。單純?cè)趕hp里修改prj文件是自欺欺人prj只改變顯示坐標(biāo)不改變幾何數(shù)值圖形該在哪還在哪。4.2 Excel坐標(biāo)點(diǎn)轉(zhuǎn)SHPpandas geopandas批量生成野外調(diào)查、管網(wǎng)普查的數(shù)據(jù)經(jīng)常是Excel表格里面只有點(diǎn)號(hào)、經(jīng)度、緯度要落成SHP疊加到全國(guó)底圖上。這種情況我用Python的pandas加geopandas幾分鐘搞定幾千個(gè)點(diǎn)import pandas as pd import geopandas as gpd from shapely.geometry import Point df pd.read_excel(井位坐標(biāo).xlsx, dtype{點(diǎn)號(hào): str}) df[geometry] df.apply(lambda r: Point(r[經(jīng)度], r[緯度]), axis1) gdf gpd.GeoDataFrame(df, geometrygeometry, crsEPSG:4326) gdf.to_file(井位.shp, encodingutf-8, driverESRI Shapefile)dtype參數(shù)把“點(diǎn)號(hào)”列強(qiáng)制轉(zhuǎn)成字符串避免點(diǎn)號(hào)以0開(kāi)頭時(shí)被Excel識(shí)別成數(shù)值丟掉前導(dǎo)零。crsEPSG:4326是聲明坐標(biāo)是WGS84經(jīng)緯度如果你的Excel坐標(biāo)來(lái)自實(shí)測(cè)CGCS2000就改成EPSG:4490。聲明錯(cuò)誤是最常見(jiàn)的坑坐標(biāo)數(shù)值完全一樣但聲明成不同坐標(biāo)系疊圖時(shí)就差出一大截。如果坐標(biāo)是從高德地圖或者手機(jī)App里拿的多半是GCJ-02直接轉(zhuǎn)4326的SHP和標(biāo)準(zhǔn)底圖疊不上。這類數(shù)據(jù)必須先通過(guò)坐標(biāo)糾偏工具把GCJ-02轉(zhuǎn)回WGS84再進(jìn)入后續(xù)流程。我的經(jīng)驗(yàn)是不要指望在shp里做糾偏要在進(jìn)入SHP之前就把原始Excel坐標(biāo)處理好。點(diǎn)數(shù)據(jù)分散在幾十個(gè)Excel表時(shí)可以先用glob把文件全部讀進(jìn)來(lái)合并pandas.concat成一個(gè)DataFrame再統(tǒng)一生成SHPimport glob frames [] for f in glob.glob(點(diǎn)位數(shù)據(jù)/*.xlsx): df pd.read_excel(f) frames.append(df) df_all pd.concat(frames, ignore_indexTrue) df_all.to_excel(合并點(diǎn)位.xlsx, indexFalse)合并后先檢查有沒(méi)有重復(fù)點(diǎn)號(hào)、空坐標(biāo)行再做SHP轉(zhuǎn)換。Excel里空坐標(biāo)在轉(zhuǎn)Point時(shí)是致命的會(huì)直接拋異常。4.3 漁網(wǎng)分割SHPQGIS網(wǎng)格創(chuàng)建、按位置裁剪與批量輸出把全國(guó)或者大流域的矢量范圍按規(guī)則網(wǎng)格切開(kāi)是生態(tài)、氣象、自然資源調(diào)查里常見(jiàn)的操作。比如手頭有塔里木河流域邊界shp想按1公里網(wǎng)格統(tǒng)計(jì)植被指數(shù)就需要先生成漁網(wǎng)再用它裁剪邊界。在QGIS里路徑是“矢量 → 研究工具 → 創(chuàng)建漁網(wǎng)”。關(guān)鍵參數(shù)有三個(gè)網(wǎng)格間距、網(wǎng)格范圍、輸出類型。網(wǎng)格間距按“米”還是“度”取決于你的坐標(biāo)系投影坐標(biāo)系里填“1000米”經(jīng)緯度坐標(biāo)系里填度比如0.01度約等于1公里。網(wǎng)格范圍可以直接引用另一個(gè)圖層比如“塔里木河流域邊界shp”的范圍這樣漁網(wǎng)就只覆蓋流域區(qū)域不會(huì)生成一大片空白網(wǎng)格。生成漁網(wǎng)后把漁網(wǎng)圖層和流域邊界做“按位置裁剪”保留邊界內(nèi)部的網(wǎng)格單元再對(duì)每個(gè)網(wǎng)格單元賦值流域?qū)傩浴E枯敵鰰r(shí)QGIS處理工具箱里的“按位置選擇”和“分割矢量圖層”是配合使用的先用分割工具按網(wǎng)格字段拆開(kāi)再逐格導(dǎo)出。要注意的是裁剪后的網(wǎng)格單元數(shù)可能上萬(wàn)個(gè)導(dǎo)出文件時(shí)文件命名必須用字段值而不是FID不然順序一亂全對(duì)不上。如果想用代碼實(shí)現(xiàn)漁網(wǎng)分割可以用geopandas生成網(wǎng)格矩形并做空間連接但代碼量會(huì)大不少。QGIS界面操作對(duì)多數(shù)人更快建議優(yōu)先走GUI路線除非網(wǎng)格數(shù)超過(guò)幾萬(wàn)個(gè)再考慮腳本。順帶說(shuō)一個(gè)相關(guān)高頻問(wèn)題“如何在shp圖中去掉一部分矢量”。例如想把南盤(pán)江流域邊界中某個(gè)小支流范圍去掉用“矢量 → 地理處理 → 擦除”即可。擦除失敗最常見(jiàn)的原因是邊界圖層有拓?fù)溴e(cuò)誤工具結(jié)果為空第5章會(huì)講排查方法。5. SHP打開(kāi)失敗與屬性異常排查shapechk修復(fù)、RAR密碼與編碼亂碼5.1 圖層打開(kāi)為空或要素殘缺shapechk檢測(cè)與修復(fù)流程現(xiàn)象在ArcGIS或QGIS里打開(kāi)某個(gè)shp圖層界面完全空白或者只有一部分要素顯示屬性表行數(shù)也少了一截。這種大概率不是數(shù)據(jù)源坐標(biāo)問(wèn)題而是shapefile內(nèi)部結(jié)構(gòu)壞了最常見(jiàn)的是.shx索引與實(shí)際.shp記錄數(shù)不一致。檢查工具我用shapechk。shapechk是專門(mén)用來(lái)掃描shp文件完整性的工具打開(kāi)后選擇要檢測(cè)的shp它逐條讀取記錄并報(bào)告錯(cuò)誤類型。使用方法是選擇shp文件點(diǎn)擊“開(kāi)始”等待掃描結(jié)果。常見(jiàn)提示包括“索引文件記錄數(shù)與幾何記錄數(shù)不一致”“幾何類型非法”“shp文件頭描述的文件大小與實(shí)際不符”。掃描發(fā)現(xiàn)問(wèn)題后修復(fù)辦法我用GDAL重寫(xiě)ogr2ogr -f ESRI Shapefile 修復(fù)后.shp 損壞.shp -skipfailures這條命令會(huì)從損壞文件里把能讀的要素全部讀出再重新生成一套完整的三件套。-skipfailures決定了一個(gè)重要行為跳過(guò)那些讀不出來(lái)的要素。如果沒(méi)有這個(gè)參數(shù)遇到第一個(gè)壞要素就停掉修復(fù)文件可能一個(gè)要素都沒(méi)有。修復(fù)完成后再跑一次shapechk確認(rèn)沒(méi)有錯(cuò)誤報(bào)告才進(jìn)入下一步使用。5.2 屬性表中文亂碼CP936、UTF-8與.cpg文件的關(guān)系現(xiàn)象SHP能正常顯示圖形但打開(kāi)屬性表中文全是“錕斤拷”“燙燙燙”一類的亂碼。這在從網(wǎng)上下載的全國(guó)矢量包里太常見(jiàn)了尤其是一些老版本數(shù)據(jù)。原因在于dbf屬性文件的編碼聲明與實(shí)際編碼不一致字段值實(shí)際是GBK/CP936編碼但.cpg文件寫(xiě)成了UTF-8或者根本沒(méi)有.cpg文件ArcGIS按默認(rèn)規(guī)則讀成了UTF-8。檢查思路是用記事本打開(kāi).cpg文件看內(nèi)容里面是“UTF-8”就是聲明為UTF-8如果是“CP936”或“GBK”那是聲明為中文編碼。然后對(duì)比屬性表顯示如果聲明UTF-8但亂碼說(shuō)明源數(shù)據(jù)實(shí)際不是UTF-8。修復(fù)方法有個(gè)偷懶但有效的做法用geopandas重新指定編碼讀取并轉(zhuǎn)存import geopandas as gpd gdf gpd.read_file(亂碼.shp, encodingGBK) gdf.to_file(修復(fù)編碼.shp, encodingUTF-8, driverESRI Shapefile)encodingGBK保證按正確編碼讀出屬性轉(zhuǎn)存時(shí)寫(xiě)成UTF-8并讓工具重新生成.cpg文件。轉(zhuǎn)換后用QGIS復(fù)核屬性表字段值正常再歸檔。如果源實(shí)測(cè)是其他編碼比如CP936實(shí)際等于GBK絕大多數(shù)情況下GBK能覆蓋。還有少數(shù)數(shù)據(jù)是Big5或者Shift-JIS那就不能用GBK硬讀先試著讀出正常屬性再轉(zhuǎn)。5.3 RAR壓縮包帶密碼先找來(lái)源別急著用破解工具現(xiàn)象雙擊“全國(guó)矢量地圖shp格式.rar”彈窗要求輸入密碼輸不對(duì)即使能列出目錄也解不出文件。這種情況第一時(shí)間想到“rar密碼移除”“advanced rar password recovery”這類破解工具的人不在少數(shù)但我建議先停一下。多數(shù)帶密碼的國(guó)土資源類壓縮包密碼不是隨機(jī)加密而是發(fā)布者設(shè)置的簡(jiǎn)單口令一個(gè)網(wǎng)址、一串?dāng)?shù)字、或者“1234”。我的處理順序是先返回下載頁(yè)面或來(lái)源頁(yè)面找密碼說(shuō)明很多包在網(wǎng)盤(pán)的描述文字里就寫(xiě)著“解壓密碼www.xxx.com”。如果找不到試試壓縮包里的說(shuō)明文檔或文件名本身文件名中用點(diǎn)或橫線分隔的單詞往往就是線索。驗(yàn)證密碼是否正確的命令是7z t 全國(guó)矢量地圖shp格式.rar -p你的密碼t是測(cè)試壓縮包完整性密碼正確且壓縮包結(jié)構(gòu)完整時(shí)會(huì)顯示“全部正常”同時(shí)也能順便驗(yàn)證壓縮包本身有沒(méi)有損壞。如果確認(rèn)密碼錯(cuò)誤再考慮聯(lián)系方式。網(wǎng)上所謂的“rar password recovery”方案對(duì)老版本RAR的加密有可能奏效但遇到RAR5默認(rèn)的AES-256加密普通電腦跑暴力破解的內(nèi)存和時(shí)間成本極高幾天幾夜也未必出結(jié)果。更實(shí)際的是回來(lái)源渠道找回密碼。還有一點(diǎn)要警惕下載所謂“破解版”恢復(fù)工具時(shí)安裝包經(jīng)常捆綁加載廣告的子程序甚至篡改瀏覽器設(shè)置。我在這上面吃過(guò)虧現(xiàn)在寧可不解壓也不碰來(lái)源不明的破解工具。5.4 拓?fù)溴e(cuò)誤導(dǎo)致裁剪失敗幾何修復(fù)與有效性質(zhì)檢現(xiàn)象用某個(gè)SHP做擦除或裁剪時(shí)工具提示“處理失敗”或輸出為空。這種情況常見(jiàn)于邊界不完整的流域shp比如淮河shp文件可能是人工從紙質(zhì)圖矢量化出來(lái)的存在自相交、重復(fù)頂點(diǎn)、縫隙等問(wèn)題。在QGIS里先檢查“矢量 → 幾何工具 → 檢查有效性”它會(huì)把無(wú)效要素逐條列出來(lái)錯(cuò)誤類型通常包括“自相交”“環(huán)方向錯(cuò)誤”“重復(fù)節(jié)點(diǎn)”。拿到檢查結(jié)果后用“修復(fù)幾何”工具批量處理。修復(fù)算法會(huì)把非法的多邊形重新組織成有效多邊形。我在代碼里修復(fù)時(shí)用shapely的make_validfrom shapely.validation import make_valid import geopandas as gpd gdf gpd.read_file(流域邊界.shp) gdf[geometry] gdf[geometry].apply(make_valid) gdf.to_file(流域邊界_修復(fù).shp, encodingutf-8)修復(fù)后注意幾何類型可能變化一個(gè)Polygon可能變成MultiPolygon極少數(shù)情況下還會(huì)生成LineString。線要素不能和面要素放在同一個(gè)shapefile圖層里所以導(dǎo)出前要檢查geometry類型分布如果有線單獨(dú)分離出去或者丟棄。修復(fù)后的SHP再做擦除、裁剪、拓?fù)涮缀匣静粫?huì)再翻車。6. 把全國(guó)SHP用起來(lái)行政區(qū)劃代碼關(guān)聯(lián)統(tǒng)計(jì)表與最小切片發(fā)布6.1 用區(qū)劃代碼做連接主鍵避免地名文字匹配拿到一份全國(guó)區(qū)縣SHP下一步往往是和統(tǒng)計(jì)年鑒、經(jīng)濟(jì)普查數(shù)據(jù)做關(guān)聯(lián)。按名稱匹配是新手最愛(ài)干的事但“城區(qū)”“郊區(qū)”這種名稱在多個(gè)地市重復(fù)出現(xiàn)按名稱連會(huì)串行。正確做法是用行政區(qū)劃代碼做連接主鍵import pandas as pd import geopandas as gpd gdf gpd.read_file(全國(guó)_區(qū)縣.shp, encodingutf-8) stat pd.read_csv(2024年各縣GDP.csv, dtype{區(qū)劃代碼: str}) merged gdf.merge(stat, left_onPAC, right_on區(qū)劃代碼, howleft) merged.to_file(全國(guó)_區(qū)縣_帶經(jīng)濟(jì)數(shù)據(jù).shp, encodingutf-8, driverESRI Shapefile)dtype{區(qū)劃代碼: str}是必須的12位行政區(qū)劃代碼以數(shù)字形式存在Excel里會(huì)被讀成int前導(dǎo)的0會(huì)消失與SHP的PAC字段類型不一致導(dǎo)致匹配失敗。howleft保留所有SHP面要素統(tǒng)計(jì)表里沒(méi)有的可以留空。6.2 設(shè)置縣級(jí)最小顯示粒度把全國(guó)包發(fā)布成XYZ Tiles最后說(shuō)發(fā)布。把全國(guó)SHP發(fā)布成切片底圖時(shí)最容易犯的錯(cuò)是一個(gè)圖層從頭到尾只配一種顯示比例。全國(guó)范圍在小比例尺下只看省界放大到城市級(jí)別才需要區(qū)縣界全部要素?zé)o差別輸出會(huì)讓切片進(jìn)程卡死生成的文件也巨大。我現(xiàn)在用GeoServer或QGIS Server做切片預(yù)覽一般分三層省界圖層從第2級(jí)顯示到第8級(jí)市界從第6級(jí)顯示到第12級(jí)區(qū)縣界從第10級(jí)往下顯示。QGIS里“瓦片生成”工具可以設(shè)置“最小縮放級(jí)別”和“最大縮放級(jí)別”直接把全國(guó)區(qū)縣包切到適合Web地圖使用的XYZ目錄。輸出前先做一次ogr2ogr簡(jiǎn)化邊界保留精度在0.001度左右文件名加_simplify后綴用來(lái)發(fā)布原始SHP留作分析。去年做的一個(gè)省級(jí)項(xiàng)目就是把全省邊界包按這個(gè)方式拆了三層發(fā)布后加載速度終于不用等十幾秒轉(zhuǎn)圈。從那以后我拿到新的全國(guó)矢量包第一件事固定是ogrinfo查坐標(biāo)和字段第二件事是7z t驗(yàn)證壓縮包完整然后再考慮怎么加工。數(shù)據(jù)不是越全越好而是越貼合使用場(chǎng)景越好。希望我的這些踩坑經(jīng)驗(yàn)?zāi)軒偷侥恪1疚倪€有配套的精品資源點(diǎn)擊獲取