GIS數(shù)據(jù)包:從Shapefile清洗到可視化的完整指南)
簡介中國七大地理分區(qū)標(biāo)準(zhǔn)GIS矢量數(shù)據(jù)包完整覆蓋華北、東北、華中、華東、西北、西南、華南七個(gè)常用地理單元每個(gè)分區(qū)均提供獨(dú)立Shapefile文件同時(shí)附帶整合后的全國七區(qū)合并版本。面向GIS數(shù)據(jù)分析、區(qū)域研究及制圖人員適用于區(qū)域裁剪、空間疊加、統(tǒng)計(jì)匯總和專題出圖等中尺度場景。壓縮包共68個(gè)文件約1.26MB包含shp幾何文件、dbf屬性表、prj投影定義、shx索引、cpg編碼文件等保證各文件坐標(biāo)系與屬性結(jié)構(gòu)統(tǒng)一可在ArcGIS、QGIS及Python的geopandas/shapely環(huán)境中直接加載使用。目前已有151人學(xué)習(xí)下載。數(shù)據(jù)包內(nèi)各區(qū)域采用標(biāo)準(zhǔn)化邊界字段含區(qū)劃名稱、編號等信息便于快速框選目標(biāo)區(qū)域開展人口密度分析、生態(tài)功能區(qū)評估或資源稟賦橫向比較還可直接使用合并文件快速生成全國分區(qū)底圖進(jìn)一步疊加社會(huì)經(jīng)濟(jì)數(shù)據(jù)開展區(qū)域差異對比研究。1. 七大地理分區(qū) GIS 數(shù)據(jù)包拿到手先別急著畫圖先搞懂分區(qū)和字段再說做地圖可視化或區(qū)域統(tǒng)計(jì)分析時(shí)最常踩的一個(gè)坑不是數(shù)據(jù)量太大而是手里缺一套干凈、統(tǒng)一、可直接合并的行政區(qū)劃矢量邊界。網(wǎng)上零散下載的省界、市界文件坐標(biāo)系五花八門屬性表字段名對不上邊界線還有縫隙光清洗數(shù)據(jù)就能耗掉半天。這份「中國七大地理分區(qū)標(biāo)準(zhǔn) GIS 數(shù)據(jù)包」解決的就是這個(gè)痛點(diǎn)把全國省級行政邊界按華北、東北、華東、華中、西北、西南、華南七大地理區(qū)劃整理成標(biāo)準(zhǔn) Shapefile每個(gè)分區(qū)單獨(dú)成包另附一個(gè)合并版直接用 QGIS 或 ArcGIS 打開就能出圖省去從零拼接和對字段的功夫。適合做數(shù)據(jù)可視化、區(qū)域經(jīng)濟(jì)分析、GIS 課程設(shè)計(jì)或地圖開發(fā)前期的邊界底圖工作新手能直接上手熟手可以跳過清洗環(huán)節(jié)直接做業(yè)務(wù)疊加。2. Shapefile 結(jié)構(gòu)與非空間屬性讀不懂這三個(gè)文件加載必翻車2.1 Shapefile 不是單個(gè)文件而是一組文件的集合很多第一次接觸 GIS 數(shù)據(jù)的開發(fā)者拿到.shp之后習(xí)慣性地雙擊結(jié)果發(fā)現(xiàn)打不開或提示缺文件。原因很簡單Shapefile 是一組文件的集合.shp只是其中存放幾何坐標(biāo)的主文件光有它成不了完整的矢量數(shù)據(jù)。一份合格的 Shapefile 至少包含以下三個(gè)基礎(chǔ)文件擴(kuò)展名作用缺失后果.shp幾何信息點(diǎn)、線、面坐標(biāo)沒這個(gè)文件啥都加載不了.shx幾何索引配合.shp快速定位要素只有.shp時(shí)某些軟件會(huì)報(bào)錯(cuò)或極慢.dbf屬性表數(shù)據(jù)省名、編碼、面積等字段在這里地圖能顯示但屬性表全空此外還有.prj文件它記錄坐標(biāo)系統(tǒng)影響范圍從「疊加時(shí)位置對不上」到「整個(gè)圖層偏移到海里」后面單獨(dú)展開說。這個(gè)數(shù)據(jù)包里每個(gè)分區(qū)文件夾下都完整包含上述文件拿到壓縮包后先解壓不要直接在壓縮包里雙擊加載很多 GIS 軟件在壓縮狀態(tài)下讀取.shp會(huì)解包失敗或丟失投影信息。2.2 七大分區(qū)的劃分規(guī)則與字段設(shè)計(jì)數(shù)據(jù)包的分類依據(jù)是常見的七大地理分區(qū)口徑華北、東北、華東、華中、西北、西南、華南。這種劃分并非單純按直線省界切塊而是結(jié)合了地理方位、行政區(qū)劃完整性和經(jīng)濟(jì)區(qū)域慣例比如華東包含了多個(gè)沿海省份西南包含云貴川渝和西藏華中則落在中部地帶。每個(gè)分區(qū)的.dbf屬性表里通常包含以下核心字段NAME省級行政區(qū)名稱即省、直轄市、自治區(qū)名稱PYNAME拼音縮寫或全拼便于寫代碼時(shí)按名稱做匹配CODE省級行政區(qū)劃代碼六位數(shù)字例如某省為 110000 這樣的格式AREA要素面積單位一般為平方米或平方千米REGION所屬大區(qū)名稱合并版里這個(gè)字段就是華北、華東這樣的大區(qū)標(biāo)簽做一個(gè)按大區(qū)匯總的統(tǒng)計(jì)圖時(shí)直接按REGION字段做 group by 即可不需要維護(hù)一份大區(qū)到省份的映射字典。這個(gè)細(xì)節(jié)看似不起眼實(shí)際能省掉不少代碼行也避免了自己手寫字典把某個(gè)省歸錯(cuò)區(qū)域。提示不同數(shù)據(jù)源對西南、華中包含的省份口徑略有差異拿到數(shù)據(jù)后先打開屬性表確認(rèn)每個(gè)大區(qū)下包含的省級單位數(shù)量再開始做業(yè)務(wù)分析。2.3 坐標(biāo)系和投影為什么你的圖層和底圖對不上打開數(shù)據(jù)包里的.prj文件會(huì)看到類似GEOGCS[GCS_WGS_1984或PROJCS[CGCS2000的文本。如果底圖用的是 Web 墨卡托而數(shù)據(jù)包是 WGS84 經(jīng)緯度加載之后會(huì)出現(xiàn)位置偏移或在某些投影下拉伸變形。常見做法是先將數(shù)據(jù)包的坐標(biāo)系確認(rèn)清楚再按項(xiàng)目需要?jiǎng)討B(tài)轉(zhuǎn)換投影。在 QGIS 里可以通過右鍵圖層 → 設(shè)置圖層坐標(biāo)參考系來查看在 ArcGIS 里則放在圖層屬性 → 源的坐標(biāo)系統(tǒng)選項(xiàng)卡。這里有個(gè)容易混淆的點(diǎn)QGis 的狀態(tài)欄右下角「啟用實(shí)時(shí)投影變換」只是臨時(shí)顯示變換不改變數(shù)據(jù)本身的坐標(biāo)系導(dǎo)出時(shí)仍然以原始坐標(biāo)為準(zhǔn)除非專門使用「導(dǎo)出 → 另存為」并指定新的 CRS。3. 加載與合并實(shí)操Q(mào)GIS 加載分區(qū)分包與 Python 合并完整流程3.1 QGIS 中加載單分區(qū)并做基礎(chǔ)樣式配置把壓縮包解壓后啟動(dòng) QGIS通過圖層菜單添加矢量圖層選中某一個(gè)分區(qū)文件夾下的.shp文件。添加成功后會(huì)看到邊界圖層自動(dòng)賦了一個(gè)隨機(jī)顏色這對業(yè)務(wù)分析不夠友好??梢园闯R?guī)做法給不同的省設(shè)置不同配色具體操作是雙擊圖層打開圖層屬性在符號化選項(xiàng)卡里選擇「分類」分類值選擇NAME字段配色方案選擇一個(gè)漸變色系點(diǎn)擊分類后確定。如果想突出顯示大區(qū)邊界可以對該圖層做一次「按 REGION 融合」的復(fù)制操作方法是使用處理工具箱里的「融合」算法融合字段選擇REGION生成的融合圖層只有七條大區(qū)邊界線比直接用原始省界圖層勾大區(qū)輪廓更干凈也便于輸出專題圖。3.2 Python 解析 Shapefile用 geopandas 讀取分區(qū)數(shù)據(jù)除了桌面 GIS很多自動(dòng)化的數(shù)據(jù)處理流程需要用 Python 完成。常見做法是使用geopandas讀取數(shù)據(jù)包中的數(shù)據(jù)做屬性篩選或直接合并全部分區(qū)。import geopandas as gpd # 讀取華北分區(qū)數(shù)據(jù) hb gpd.read_file(data/華北/華北.shp, encodingutf-8) print(hb.columns.tolist()) print(hb[NAME].tolist()) # 讀取全部七個(gè)分區(qū)并合并 import glob files glob.glob(data/*/*.shp) frames [] for f in files: gdf gpd.read_file(f, encodingutf-8) frames.append(gdf) merged gpd.pd.concat(frames, ignore_indexTrue) merged.to_file(data/全國七大分區(qū)合并.shp, encodingutf-8)邏輯說明read_file會(huì)自動(dòng)讀取同目錄下的.shx和.dbf構(gòu)成完整的 GeoDataFrameglob在這里負(fù)責(zé)匹配路徑下所有分區(qū)文件夾里的.shp文件比手工逐個(gè)子目錄讀取更可靠。參數(shù)說明encoding參數(shù)要按數(shù)據(jù)包實(shí)際的屬性編碼來設(shè)如果讀取后NAME亂碼可嘗試gbk或utf-8。合并完成后用to_file導(dǎo)出導(dǎo)出的合并文件同樣包含.shp、.shx、.dbf和自動(dòng)生成的.prj。這里需要注意的是合并前先檢查各分區(qū)之間的邊界要素在拓?fù)渖鲜欠裢耆呛稀H绻硞€(gè)省界在數(shù)據(jù)包里被畫到相鄰分區(qū)合并后的邊界可能出現(xiàn)重疊或縫隙后面第四章專門講這個(gè)坑。3.3 合并版的屬性一致性合并前先統(tǒng)一字段結(jié)構(gòu)合并多個(gè)分區(qū)時(shí)最容易翻車的點(diǎn)在于字段名和字段類型不一致。比如華北分區(qū)的屬性表叫NAME某另一個(gè)分區(qū)的屬性表叫省名稱concat之后會(huì)變成兩列字段后續(xù)畫圖按名稱分類時(shí)就會(huì)出現(xiàn)大量「空值」。我一般會(huì)在循環(huán)讀取時(shí)分兩步處理第一步先打印每個(gè)文件的列名第二步把所有分區(qū)的列名統(tǒng)一重命名為同一套規(guī)范再進(jìn)入合并流程。這個(gè)檢查放進(jìn)腳本里只需要幾行代碼但能避免合并后才發(fā)現(xiàn)問題又得回去重讀的尷尬。4. 避坑與排查屬性亂碼、幾何類型不一致、邊界縫隙4.1 現(xiàn)象打開屬性表后中文名稱全部亂碼用 QGIS 加載 Shapefile 后打開屬性表發(fā)現(xiàn)NAME字段顯示為「錕斤拷」一類亂碼地圖上還能正常顯示圖形但查不了哪個(gè)面是哪個(gè)省。原因通常是.dbf屬性表文件使用的是 GBK 編碼而 QGIS 默認(rèn)按 UTF-8 讀取。解決方法是重新加載圖層時(shí)手動(dòng)指定編碼方式在 QGIS 數(shù)據(jù)源管理器中選擇該 Shapefile 后可在編碼下拉框中選擇GBK或GB2312再點(diǎn)擊添加。若是用 Python 的geopandas讀取讀取命令指定encodinggbk即可。4.2 現(xiàn)象加載報(bào)錯(cuò)「Invalid shapefile」或要素丟失報(bào)錯(cuò)提示數(shù)據(jù)有問題或在圖層上看到部分省份缺失只剩下零星幾個(gè)面。原因多半是.shp文件與.shx索引對不上例如壓縮包解壓不完整、文件被下載工具截?cái)嗷蛑苯釉趬嚎s包內(nèi)讀取時(shí)索引路徑錯(cuò)誤。解決方法是重新從原始壓縮包解壓確認(rèn).shp、.shx、.dbf三個(gè)文件在同一目錄且文件名完全一致不區(qū)分大小寫但拼寫要完全匹配。4.3 現(xiàn)象合并后相鄰省份邊界出現(xiàn)細(xì)線縫隙或微小重疊做融合或疊加分析時(shí)相鄰省界的縫隙雖然肉眼幾乎看不到但執(zhí)行面積統(tǒng)計(jì)或拓?fù)洳僮鲿r(shí)會(huì)報(bào)拓?fù)溴e(cuò)誤。原因在于不同分區(qū)在制作時(shí)的數(shù)據(jù)源精度不一致或者相鄰省級要素的公共邊不是完全相同的坐標(biāo)串只是一個(gè)視覺上重合的近似值。解決方法是先不要逐分區(qū)合并先把七個(gè)分區(qū)全部讀入后執(zhí)行g(shù)pd.overlay做一次幾何修復(fù)或用snap工具把邊界捕捉到同一容差范圍。常用參數(shù)容差設(shè)為 0.01 度約 1 公里或者按投影坐標(biāo)系設(shè) 100 米量級具體以數(shù)據(jù)實(shí)際精度為準(zhǔn)。4.4 現(xiàn)象幾何類型不統(tǒng)一有的要素是面、有的是多面用 Python 檢查時(shí)發(fā)現(xiàn)geometry列中同時(shí)存在Polygon和MultiPolygon某些統(tǒng)計(jì)函數(shù)直接報(bào)錯(cuò)。原因同樣是數(shù)據(jù)源精度或制圖方式造成。解決方法是統(tǒng)一轉(zhuǎn)換在 geopandas 中執(zhí)行g(shù)df[geometry] gdf[geometry].apply(lambda g: g.buffer(0))這個(gè)常用操作能自動(dòng)把Polygon轉(zhuǎn)為MultiPolygon同時(shí)消除部分無效的幾何自相交問題不改變實(shí)際邊界形狀。轉(zhuǎn)換后再做一次is_valid檢查確認(rèn)全部為 True 再繼續(xù)處理。5. 業(yè)務(wù)落地利用REGION字段做七大區(qū)劃匯總統(tǒng)計(jì)與可視化5.1 按大區(qū)聚合從省界到區(qū)域統(tǒng)計(jì)圖拿到合并版數(shù)據(jù)后最常見的一個(gè)業(yè)務(wù)做法是按大區(qū)做指標(biāo)匯總。比如你有一張省級的年度銷售數(shù)據(jù)表字段包含省份和銷售額希望通過地圖展示各大區(qū)的匯總結(jié)果。常規(guī)思路是先用 pandas 把銷售表按省合并再與 GIS 數(shù)據(jù)的屬性表按省份名稱關(guān)聯(lián)。這里直接使用REGION字段做分組聚合即可因?yàn)榇髤^(qū)字段已經(jīng)人工校對過不需要再用省名去匹配大區(qū)字典。import pandas as pd import geopandas as gpd # 模擬省銷售額數(shù)據(jù) sales pd.DataFrame({ NAME: [某省A, 某省B, 某省C], sales: [120, 200, 150] }) gdf gpd.read_file(data/七大分區(qū)合并.shp, encodingutf-8) merged_df gdf.merge(sales, onNAME, howleft) # 按大區(qū)匯總銷售額 region_sum merged_df.groupby(REGION)[sales].sum() print(region_sum)邏輯說明先把省級銷售表關(guān)聯(lián)到合并版矢量數(shù)據(jù)的屬性表上merge的關(guān)聯(lián)鍵是省級名稱。之后按REGION字段分組求和得到的聚合結(jié)果直接落到省級要素的REGION字段分組下。參數(shù)說明howleft保留所有省級要素即使某個(gè)省份沒有銷售數(shù)據(jù)也不會(huì)丟失邊界groupby(REGION)會(huì)按七個(gè)大區(qū)自動(dòng)匯總。但如果屬性表里的省份名稱和銷售表里的名稱寫法不一致比如「某省A」寫成「A省」關(guān)聯(lián)后會(huì)出現(xiàn)空值。常見做法是先統(tǒng)一名稱格式或在merge之前做一個(gè)標(biāo)準(zhǔn)化函數(shù)將兩地名都映射到同一套編碼上。5.2 出大區(qū)專題圖前的最后一步區(qū)劃色帶與標(biāo)注在 QGIS 中基于合并版做七區(qū)專題圖時(shí)建議直接按REGION字段做分類符號七種顏色分別代表七大地理區(qū)劃并在圖例中顯示大區(qū)中文名。做法是雙擊合并圖層符號化選項(xiàng)卡選擇「分類」列選擇REGION色帶選擇一個(gè)色差明顯的方案比如從暖到冷漸變再點(diǎn)擊「分類」生成七類。標(biāo)注設(shè)置選擇顯示REGION字段值字號設(shè)置在 10 到 12 之間放在面的中央。如果想輸出高清圖常規(guī)做法是使用打印布局導(dǎo)出分辨率設(shè)置 300 DPI這樣輸出的大區(qū)專題圖能直接用于演示或報(bào)告。5.3 坐標(biāo)系轉(zhuǎn)換從 WGS84 經(jīng)緯度到投影坐標(biāo)做面積計(jì)算時(shí)需特別注意當(dāng)前坐標(biāo)系的單位。若數(shù)據(jù)包是 WGS84 經(jīng)緯度geopandas中直接.area計(jì)算的是度單位的面積幾乎無實(shí)際意義。正確做法是先投影到適合全國范圍的等積投影常見選擇是 Albers 等積圓錐投影或使用省級范圍的 UTM 投影。然后在 geopandas 中執(zhí)行坐標(biāo)轉(zhuǎn)換# 將經(jīng)緯度坐標(biāo)系轉(zhuǎn)換為投影坐標(biāo)系 gdf_proj gdf.to_crs(EPSG:3857) gdf_proj[area_m2] gdf_proj.geometry.area參數(shù)說明EPSG:3857是 Web 墨卡托投影適合范圍較小的面積比較并非嚴(yán)格等積投影準(zhǔn)確的面積統(tǒng)計(jì)更推薦使用EPSG:102025或 Albers 等積投影具體取決于數(shù)據(jù)覆蓋范圍。這里用3857僅為展示代碼寫法業(yè)務(wù)中需要按實(shí)際數(shù)據(jù)范圍選擇。6. 用邊界質(zhì)量檢查腳本做數(shù)據(jù)交付前的最后驗(yàn)證矢量數(shù)據(jù)能不能進(jìn)生產(chǎn)流程不只是「地圖上能顯示」這么簡單。拿到合并版后我通常還會(huì)跑一組簡單的質(zhì)量檢查腳本用程序去驗(yàn)證幾何有效性和屬性完整性確認(rèn)這底層數(shù)據(jù)不會(huì)成為后續(xù)業(yè)務(wù)分析的黑匣子。import geopandas as gpd gdf gpd.read_file(data/七大分區(qū)合并.shp, encodingutf-8) print(要素總數(shù):, len(gdf)) print(大區(qū)列表:, gdf[REGION].unique().tolist()) print(各省數(shù)量:, gdf[NAME].nunique()) print(邊界有效期檢查:, gdf.geometry.is_valid.all()) # 檢查是否有空幾何 print(空幾何數(shù)量:, gdf.geometry.isna().sum())這段腳本解決了三個(gè)核心問題要素是否齊全、大區(qū)分類是否正確、邊界幾何是否全部有效。is_valid是 GeoPandas 對每個(gè)幾何要素執(zhí)行拓?fù)湫r?yàn)返回False就代表存在自相交或拓?fù)渫嘶瘑栴}空幾何數(shù)量超過 0 說明某些省份邊界丟失或?qū)傩员黻P(guān)聯(lián)出錯(cuò)。除了這個(gè)檢查我最終會(huì)把這個(gè)腳本得出的檢查結(jié)果和數(shù)據(jù)包放在一起輸出一份簡潔的 txt 記錄作為數(shù)據(jù)交付的「體檢單」。從那以后每次拿到底層邊界數(shù)據(jù)我都會(huì)強(qiáng)制走一遍這個(gè)驗(yàn)證流程處理完數(shù)據(jù)先跑腳本再進(jìn)入業(yè)務(wù)邏輯不跳過。這些年因?yàn)槎鄨?zhí)行這一步少返工了不少項(xiàng)目希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取