
簡介這份國家基礎地理信息系統(tǒng)數(shù)據(jù)包以矢量格式為核心覆蓋中國主要公路、鐵路、河流、湖泊、國界、省界、縣界及城市駐地等基礎地理要素適合GIS學習者、城鄉(xiāng)規(guī)劃、交通和環(huán)保從業(yè)者用作空間分析與專題制圖的基礎數(shù)據(jù)源。壓縮包共93個文件主要類型包括矢量圖形、屬性表、空間索引、投影定義等對應SHP、DBF、SHX、PRJ等常見GIS格式體積僅10.63MB輕量易用其中屬性表詳細記錄了各地物的分類、等級等關鍵信息便于篩選統(tǒng)計。資源已有1940人學習下載。包內還融入森林覆蓋圖層及全國縣級統(tǒng)計數(shù)據(jù)可支撐森林資源評估、交通可達性分析、行政區(qū)劃對比等公路圖層可提取道路等級以優(yōu)化物流路徑縣級統(tǒng)計數(shù)據(jù)可與行政邊界關聯(lián)實現(xiàn)人口、經濟指標空間化。配合專業(yè)GIS平臺可完成地圖配圖、疊加查詢、緩沖區(qū)分析與統(tǒng)計出圖是搭建區(qū)域地理空間工作底圖的實用素材。1. 一個zip壓縮包裝的是能直接進GIS的矢量底圖如果你拿到一個名字里同時出現(xiàn)“國家基礎地理信息系統(tǒng)數(shù)據(jù).zip”“foreste75_shp”“主要公路shp”的壓縮包先別急著雙擊加載。這個zip不是普通文檔包而是一套按基礎地理信息數(shù)據(jù)組織習慣整理好的矢量數(shù)據(jù)集森林或植被覆蓋圖斑文件名里的foreste75通常是分類代碼或年份標識和主要公路分屬不同圖層可能還帶著坐標參考、字段編碼和元數(shù)據(jù)說明。本文要解決的問題就是如何把這個zip安全地變成ArcGIS Pro或QGIS里真正能打開、能疊加、能算面積和長度的shp同時繞過解壓亂碼、坐標漂移、屬性表打不開這一串常見故障。適合剛接手地理信息系統(tǒng)數(shù)據(jù)的工程師也適合正在做道路網與地表覆蓋疊加分析、但被shp細節(jié)折磨過的人。2. 拆包之前先搞懂shp的“多文件結構”和zip完整性2.1 shp不是單個文件至少三個伴隨文件才能打開很多人從zip里解壓出“主要公路.shp”就雙擊結果彈“無法打開”或“要素類無效”。因為ESRI Shapefile本身是分布式存儲的集合文件真正能稱為一個完整圖層的必須同時包含以下核心文件后綴作用缺失后果.shp存儲要素幾何位置沒有任何幾何.shx存儲幾何位置索引能打開但效率低部分工具報錯.dbf存儲屬性字段值屬性表為空或無法打開.prj存儲坐標系定義WKT文本坐標系未知疊加時位置錯誤.cpg存儲dbf字符編碼標識中文屬性亂碼除了這幾個有時還會看到.sbn、.sbx、.ain、.aih這些是ArcGIS生成的空間索引和屬性索引文件缺失時ArcGIS會重建不影響讀取。真正影響加載的是前三件套尤其是.dbf——如果缺失ArcGIS會直接提示“沒有可用的屬性表”。2.2 為什么從zip直接雙擊shp經常會報錯用Windows資源管理器直接在zip內雙擊shp系統(tǒng)會先把臨時副本解壓到%Temp%目錄再交給ArcGIS讀取。問題有兩個一是資源管理器的zip預覽和ArcGIS同時搶占文件句柄容易報“文件被占用”二是zip包內路徑如果帶中文或空格臨時目錄里的文件名可能被截斷或轉碼失敗。所以我的建議是永遠不要“就地打開”一定先完整解壓到純英文目錄比如D:\gisdata\national。2.3 解壓前先做三件事校驗、看列表、看壓縮方式在命令行CMD或PowerShell以及Git Bash下這三條命令最實用unzip -l NationalData.zip unzip -t NationalData.zip unzip -O gbk NationalData.zip -d D:/gisdata/national第一條unzip -l列出壓縮包內所有文件你可以立即核對是否存在主要公路.shp、主要公路.dbf、foreste75.shp、foreste75.prj等必要組件。第二條unzip -t測試zip完整性如果輸出bad CRC或mismatch說明壓縮包在傳輸或存儲中損壞了不要繼續(xù)解壓。第三條unzip -O gbk強制按GBK編碼解壓能避免中文文件名變成_或亂碼。如果你的操作系統(tǒng)沒有unzip -O參數(shù)macOS上默認沒有可以用Python的zipfile模塊配合shutil重命名import zipfile, os zip_path NationalData.zip out_dir D:/gisdata/national os.makedirs(out_dir, exist_okTrue) with zipfile.ZipFile(zip_path, r) as zf: for info in zf.infolist(): # 用cp437解碼再轉gbk解決中文文件名亂碼 raw_name info.filename.encode(cp437).decode(gbk, errorsignore) target os.path.join(out_dir, raw_name) if info.is_dir(): os.makedirs(target, exist_okTrue) else: os.makedirs(os.path.dirname(target), exist_okTrue) with zf.open(info) as src, open(target, wb) as dst: dst.write(src.read()) print(done)這段腳本的關鍵點是info.filename.encode(cp437).decode(gbk)zipfile默認把文件名當成cp437編碼但你的數(shù)據(jù)包來自中文環(huán)境實際是GBK編碼這一轉就能還原出正確中文名。如果你在Linux下處理也可以直接用7z x NationalData.zip它通常能自動識別包內編碼。2.4 zip損壞的應急處理與密碼工具的誤區(qū)unzip -t一旦報錯不要急著用網上的“zip壓縮包密碼破解工具”或“zip密碼移除軟件”。這些工具絕大多數(shù)只能處理你自己忘了密碼且加密方式已知的情況對損壞的zip毫無幫助更危險的是很多所謂破解工具會捆綁惡意程序。真正的修復原則損壞的zip只有從源頭重新下載才是可靠方案。如果你只是需要恢復其中某個shp可以嘗試zip -F或zip -FF修復自解壓文件但成功率很低。對于加密zip合規(guī)的做法是聯(lián)系數(shù)據(jù)提供方獲取授權而不是暴力破解。數(shù)據(jù)管理中有一個重要習慣zip包旁邊一定要保留MD5或SHA256校驗文件下載后先核對哈希再解壓。3. 把主要公路shp和foreste75接入GIS從環(huán)境到屬性編碼3.1 ArcGIS運行要求與數(shù)據(jù)加載處理全國級shp時ArcGIS Pro和ArcMap仍是主流但它們不是解壓就能跑。先說運行要求64位操作系統(tǒng)、16GB內存是推薦起點硬盤建議SSD因為shp疊加分析會產生大量臨時緩存圖形顯卡不需要多貴但驅動必須更新到支持OpenGL 4.0以上。如果你拿到的zip里有幾個GB的shp第一次加載會卡這是正常的別急著殺進程。打開ArcGIS Pro后通過“添加數(shù)據(jù)”按鈕選擇解壓目錄里的主要公路.shp。如果文件列表里看不見shp檢查是否誤設了過濾器如果能看見但加載不上檢查同目錄是否存在.shx和.dbf。一個常見低級錯誤是從zip里拖出時只拖了.shp其他伴隨文件留在原目錄導致shp孤立。3.2 坐標系檢查prj文件決定數(shù)據(jù)落在哪里在圖層屬性-源里查看坐標系這是所有分析前必做的一步。國家基礎地理信息系統(tǒng)數(shù)據(jù)通常有兩種可能一種是經緯度地理坐標系GCS_WGS_1984或GCS_China_2000另一種是投影坐標系CGCS2000 / 高斯克呂格帶分帶。如果shp缺少.prj文件GIS會把坐標系識別為Unknown疊加到其他圖層時要素可能全部落在(0,0)附近。常見做法是先用“定義投影”工具Define Projection補上坐標系而不是直接用“投影”工具。區(qū)別在于定義投影只修改元數(shù)據(jù)不改變坐標值投影工具則會做數(shù)學換算改變坐標值。如果你把原本是WGS84經緯度的數(shù)據(jù)誤定義成CGCS2000高斯投影幾何坐標會被當作米來處理后續(xù)分析結果完全錯誤。可以用一個小腳本快速查看所有shp的坐標系ogrinfo -so D:/gisdata/national/主要公路.shp 主要公路 | grep -E Geometry|EXTENT如果系統(tǒng)沒有ogrinfo安裝GDAL即可。這個命令只讀元數(shù)據(jù)不會修改原文件。3.3 dbf屬性亂碼cpg文件的作用屬性表中文亂碼是這類zip的高頻問題。dbf文件的編碼取決于創(chuàng)建軟件常見的是GBK或UTF-8。ArcGIS讀取dbf時優(yōu)先讀取同目錄下的.cpg文件沒有.cpg時按系統(tǒng)區(qū)域設置猜測編碼這就很容易在中文Windows上誤判為ANSI。處理辦法很簡單在shp同目錄下新建或修改一個.cpg文件內容只寫UTF-8或GBK保存為無BOM文本。改完重啟ArcGIS就能正確顯示。如果你不確定原編碼用QGIS打開屬性表試一遍QGIS在加載dbf時會枚舉常見編碼選擇GB2312或GB18030預覽正常后再另存為UTF-8的shp。3.4 Python批處理一次性修復圖層編碼和坐標系當zip里不止兩個shp而是幾十個時手動改cpg和定義投影太慢。我一般用這個ArcPy腳本批量處理import arcpy, os, codecs src_dir rD:\gisdata\national out_dir rD:\gisdata\national_utf8 target_sr arcpy.SpatialReference(CGCS2000_3_Degree_GK_CM_114E) if not os.path.exists(out_dir): os.makedirs(out_dir) for file in os.listdir(src_dir): if file.lower().endswith(.shp): src os.path.join(src_dir, file) name os.path.splitext(file)[0] out os.path.join(out_dir, file) desc arcpy.Describe(src) if desc.spatialReference.name Unknown: arcpy.management.DefineProjection(src, target_sr) arcpy.management.CopyFeatures(src, out) with codecs.open(os.path.join(out_dir, name .cpg), w, utf-8) as f: f.write(UTF-8) print(batch done)說明腳本先遍歷目錄中所有.shp對坐標系未知的圖層執(zhí)行DefineProjection強制定義為CGCS2000高斯投影然后用CopyFeatures復制到新目錄同時寫入UTF-8的.cpg文件。這里有一個關鍵假設所有圖層的原始幾何都符合CGCS2000高斯克呂格投影否則會改錯。實際使用時應該先抽取一個圖層在ArcGIS里目視檢查其范圍和單位再決定target_sr是地理坐標還是投影坐標。更穩(wěn)妥的做法是把target_sr換成一個常量字典按文件名前綴分別指定。3.5 加載后必須做的范圍驗證數(shù)據(jù)加載后不要急著做分析。先把圖層屬性-源里的“范圍”調出來看如果顯示經度范圍在110~120度、緯度在30~40度說明是經緯度坐標如果顯示的范圍是幾百萬米量級例如X: 39400000說明數(shù)據(jù)帶帶號且是投影坐標疊加時要考慮中央經線是否一致。4. 公路shp與森林shp疊加分析時避不開的三個坑4.1 空間參考不一致導致疊加結果為空假設主要公路.shp是WGS84經緯度而foreste75.shp是CGCS2000高斯投影。在ArcGIS地圖上疊加時由于動態(tài)投影的作用兩者看起來是重合的但如果直接執(zhí)行“相交”或“裁剪”工具工具會要求所有輸入處于同一坐標系否則要么報錯要么輸出一個空要素類。原因是地理處理工具默認在輸出坐標系下做幾何計算混合坐標系會造成精度損失或計算失敗。正確做法是在分析前用“投影”工具統(tǒng)一坐標系。我建議把兩個圖層都轉到CGCS2000 3度帶高斯投影因為面積計算和長度計算在投影坐標下才接近真實值arcpy.management.Project( in_datasetrD:\gisdata\national_utf8\主要公路.shp, out_datasetrD:\gisdata\project\road_gk.shp, out_coor_systemarcpy.SpatialReference(CGCS2000_3_Degree_GK_CM_114E) )參數(shù)注意in_dataset必須是已經定義過投影的shp不能是Unknown否則Project會報錯020002。觀察out_coor_system里的字符串其中的CM_114E表示中央經線114°E你的數(shù)據(jù)如果覆蓋不同經度帶應改成對應的帶號。4.2 字段類型與空值讓屬性連接失敗公路shp和森林shp經常需要通過行政區(qū)代碼或路段編號連接屬性。這時候最常見的問題是一邊字段類型是文本String另一邊是雙精度Double導致連接時找不到匹配記錄。另一個問題是.dbf中的空值被表示為NULL或空字符串ArcGIS的Join工具對空值的處理邏輯不一致可能產生重復記錄或丟失記錄。執(zhí)行連接前先用Python檢查兩邊字段類型import arcpy road rD:\gisdata\national_utf8\主要公路.shp forest rD:\gisdata\national_utf8\foreste75.shp for fc in [road, forest]: desc arcpy.Describe(fc) print(Fields in, os.path.basename(fc)) for field in desc.fields: print(field.name, field.type)確認公共字段類型一致后再用JoinFieldarcpy.analysis.JoinField( target_featuresroad, in_fieldAD_CODE, join_featuresforest, join_fieldAD_CODE, fields[COVER_TYPE, AREA_KM2] )這段代碼的fields參數(shù)指定從被連接表復制哪些字段。如果公共字段一個是文本型一個是數(shù)值型先用“新建字段”“計算字段”轉換類型不要偷懶直接Join。4.3 拓撲錯誤與shapechecker修復shp步驟野外采集或自動化簡處理過的shp常存在自相交、重復節(jié)點、懸空線等拓撲錯誤。這些錯誤在顯示時看著沒問題但執(zhí)行“緩沖”、“疊加”時會報錯或不產生結果。ArcGIS內置的“修復幾何”工具能處理大部分情況在ArcGIS Pro中運行菜單Path數(shù)據(jù)管理工具 → 要素 → 修復幾何。也可以用命令行arcpy.management.RepairGeometry(rD:\gisdata\national_utf8\主要公路.shp)如果修復后還有錯誤或者想要更多檢查項很多人會用到ShapeChecker這個外部工具。它的典型修復步驟是打開ShapeChecker選擇需要處理的shp文件。點擊“檢查”得到錯誤列表比如Self-Intersection、Invalid Ring。勾選“自動修復”項并確認輸出路徑執(zhí)行修復。修復完成后在GIS中重新加載檢查要素數(shù)量是否變化。注意ShapeChecker不是ESRI官方工具版本較多部分版本只支持Shapefile而不支持File Geodatabase。另外它修復后會生成新的shp強烈建議保留原始文件不要覆蓋。4.4 一個更穩(wěn)的疊加操作順序我處理這類森林道路疊加時操作順序是固定的先修復幾何再統(tǒng)一投影再做屬性連接最后用相交或裁剪。如果順序顛倒比如先投影再修復幾何被懸空線影響的幾何可能在投影過程中被放大錯誤。而且修復幾何一定要在投影前因為投影坐標系下的容差與地理坐標系不同修復算法計算出的誤差半徑不一樣。5. 把shp轉成txt或其他格式之前先做這三步驗證5.1 shp轉txt的正確姿勢很多人搜索“shp轉txt”其實想要的只是“導出屬性表”。ArcGIS里沒有直接的“shp轉txt”常見做法是轉成CSV再用Excel或文本編輯器打開arcpy.conversion.TableToTable( in_rowsrD:\gisdata\project\road_gk.shp, out_pathrD:\gisdata\export, out_nameroad.txt )注意這樣導出的txt只包含dbf屬性不包含坐標。如果需要導出每個要素的坐標比如線的起點和終點必須先添加幾何屬性arcpy.management.AddGeometryAttributes( in_featuresrD:\gisdata\project\road_gk.shp, geometry_propertyLINE_START_MID_END, coordinate_systemarcpy.SpatialReference(WGS_1984) )LINE_START_MID_END會生成StartX、StartY、MidX、MidY、EndX、EndY六個字段分別對應線要素的起點、中點和終點坐標。然后再執(zhí)行TableToTable導出。對于面要素如foreste75可以用POINT_X_Y_Z_M生成質心坐標但要注意質心不一定落在面內部如果做標注需額外檢查。5.2 壓縮與清理只保留必要文件shp要歸檔或發(fā)給別人時不要直接把整個文件夾拖進zip因為目錄里可能殘留ArcGIS運行時產生的.lock文件、臨時緩存甚至還有損壞的.sbn索引。自定義壓縮前建議只保留.shp、.shx、.dbf、.prj、.cpg五個文件。如果空間允許也可以包含.xml元數(shù)據(jù)如果有。用7-Zip選擇“極限壓縮”可能對shp這種混合內容幾何DBF沒有明顯體積優(yōu)勢建議選“正常”壓縮即可。5.3 用一行屬性表快速驗收數(shù)據(jù)每次做轉換前我會用下面這個腳本生成一張驗收清單確保數(shù)據(jù)沒有在中間環(huán)節(jié)被改壞import arcpy fc rD:\gisdata\project\road_gk.shp desc arcpy.Describe(fc) print(ShapeType:, desc.shapeType) print(Extent:, desc.extent.XMin, desc.extent.YMin, desc.extent.XMax, desc.extent.YMax) print(SR:, desc.spatialReference.name) with arcpy.da.SearchCursor(fc, [OID]) as cur: count sum(1 for _ in cur) print(FeatureCount:, count)這段腳本輸出要素類型、空間范圍、坐標系和要素數(shù)量。如果要素數(shù)量為0先回頭檢查坐標系定義和幾何修復不要繼續(xù)做shp轉txt或任何統(tǒng)計。把這份輸出連同原始zip的MD5保存在一起下次排查問題時就能直接對照。這些驗證步驟雖然瑣碎但能讓你在下一次打開這個zip時不再從頭踩坑。本文還有配套的精品資源點擊獲取