
简介本资源为江苏省134个地表水水质国控断面的标准化GIS空间数据集面向环境科学、水资源管理、地理信息及生态规划领域的研究人员、高校师生与环保从业人员用于支撑水质空间分析、污染溯源建模、流域监管评估等实际工作。压缩包共8个文件9KB包含.shp主矢量文件存储断面几何位置、.dbf属性表含省、市、流域、河流、断面名称及经纬度、.prj投影定义、.shx索引及.cpg编码文件等标准Shapefile组件开箱即用兼容ArcGIS、QGIS等主流平台。已有1657人学习下载数据源自国家水质监测体系权威性强、定位精准可直接用于地图可视化、缓冲区分析、断面空间分布统计及与遥感/水质参数数据的叠加分析显著降低GIS数据准备门槛。 最近我在整理一份江苏省地表水水质国控断面坐标数据总共134个水质断面每个断面都带经纬度坐标。乍一看这就是个普通的数据表但真正用起来才发现协调好点位、编码、坐标、关联监测数据背后有一套完整的逻辑。如果你正准备做水质监测点位可视化、环境数据分析或者只是想快速把这类国控断面坐标落地成一张可用地图这篇文章可以帮你少走不少弯路。这份数据核心用途很明确把134个国控水质断面的空间位置准确落到地图上再与水质监测结果对接形成“哪个断面、在哪条河、水质怎么样”的直观认识。适合环境专业学生、第三方检测机构、做GIS数据分析的工程师以及需要快速理解省级地表水监测网络的朋友。下面我把整个数据拆解、清洗、应用过程和踩过的坑一并写出来。1. 项目背景与数据整体解读1.1 国控断面是什么为什么是134个国控断面是国家地表水环境质量监测网络里的考核断面名字里带“国控”核心作用就是用来评价一个地区地表水环境质量是否达标。和水站的自动监测不同国控断面很多是人工采样加实验室分析但点位设定和考核目标都是国家层面统一确定的数据代表性很强。江苏这134个断面并不是随手划出来的。江苏地处长江、淮河、太湖等多个流域河网密度全国顶级还有大运河贯穿南北水域情况非常复杂。要把全省的地表水环境质量讲清楚就必须在这些重点河流、湖库的特定位置布设监测点。134个断面的布局基本覆盖了长江干流及主要支流、淮河流域、太湖及入湖河道、洪泽湖、大运河以及城市重要水源地等。我看过较早版本的公开资料不同年份的断面数量会有微调比如“十三五”期间是104个进入“十四五”后调整到134个左右。所以拿到一份“134个断面”的数据首先要确认版本年份。如果对应的是最新考核名录那定位省级水环境质量空间分布、做专题图都是比较靠谱的如果拿的是旧版本后面做趋势对比时就要特别谨慎。1.2 坐标数据的形态与字段这类坐标数据最常见的格式是Excel或CSV有代表性的字段包括断面名称如“大运河-某某大桥”“太湖-某湖心”“长江-某取水口”等名称通常包含水体名和具体位置描述。断面代码每个国控断面都有唯一编码一般是一串数字或字母数字组合这是关联水质监测数据的键值。经度、纬度核心坐标字段通常以十进制度数表示比如“118.8447, 32.0825”。所在行政区地级市或县区级别便于分区统计。所在水体河流、湖库名称用于分类筛选。控制级别/属性如“国控”“省控”等有的表格还会标注断面属性是“河流”还是“湖库”。拿到手之后第一件事不是急着画图而是先检查表结构尤其要确认坐标字段的格式。有些表会把经纬度写成“118°50′41″”这种度分秒格式有些则是小数度还有的会用文本格式存储数字带前后空格。这些细节不处理干净后面合并数据或者做空间连接时会非常痛苦。1.3 数据质量初判与版本核对拿到数据后我习惯先做一轮“肉眼加工具”的质量初判。方法很简单看数量是不是134个有没有重复行。看坐标范围是否符合江苏的地理范围。江苏的经度范围大约在116.3°E到121.9°E之间纬度范围大约在30.7°N到35.1°N之间如果出现明显越界说明可能有异常点或坐标单位搞错。和官方公开的断面名录比对断面名称看看是否有疑似缺失或多余的点位。用地图做一次快速落点把坐标点叠加到底图上看看点位是否落在河道内或水体附近。我在这轮经常发现的问题一是“缺胳膊少腿”比如某个断面只有经度没有纬度二是“张冠李戴”断面名称和坐标对应错了位置三是“坐标打架”两个断面坐标极其接近实际可能是重复项。这些问题不解决后面说啥都是白搭。2. 坐标数据处理与清洗实操2.1 用Python读取原始数据并做字段检查我个人比较习惯用Python做这类数据清洗因为可重复性高改一个参数重新跑一遍就行。如果数据量不大用Excel也能做但编码处理和坐标转换还是Python更方便。假设你的原始数据是Excel文件第一行是表头有“断面名称”“断面代码”“经度”“纬度”“所在水体”等列。用pandas读取时有一个高频坑Excel文件里可能有合并单元格、空行、列名前后的空格读出来之后字段名会自动变成“断面名称 ”这种带空格的样子。所以读取之后我一般会先对列名做一次stripimport pandas as pd df pd.read_excel(jiangsu_134_water_quality.xlsx) df.columns [str(col).strip() for col in df.columns] print(df.shape) print(df.head()) print(df.dtypes)看到shape是(134, n)基本说明行数没问题。接着检查经纬度字段是不是数值类型。如果是对象类型大概率里面混了文本或者“-”之类占位符。df[经度] pd.to_numeric(df[经度], errorscoerce) df[纬度] pd.to_numeric(df[纬度], errorscoerce) print(df[df[经度].isnull() | df[纬度].isnull()])用errorscoerce把非数字转成NaN然后筛出来看。如果某个断面经纬度缺失就需要回原表补或者根据断面名称所属河流和行政区大致推断一个参考坐标但必须给这个点位打上“待核”标记不能用推测值直接当实测值用。2.2 去重和坐标范围校验重复是这类数据很常见的问题。同一个断面可能在多次更新后被重复采集名称相同但坐标略有差异也可能坐标完全相同但断面代码不同。我倾向于先用断面代码去重因为代码唯一性更高如果代码缺失就按“断面名称水体行政区”联合去重。df df.drop_duplicates(subset[断面代码], keepfirst)去重之后再做坐标范围校验。江苏经度范围116.3到121.9纬度30.7到35.1直接写条件筛选df_valid df[ (df[经度] 116) (df[经度] 122) (df[纬度] 30) (df[纬度] 36) ]有些数据可能用6度带投影坐标比如X坐标是7位数、Y坐标是3位数这种不是经纬度需要先识别。如果坐标值范围在几百到几千那很可能是投影坐标系得问清楚数据源用的什么投影。大部分公开发布的水质断面坐标都采用经纬度但也不排除有人给过“近似米”的坐标。2.3 坐标转换WGS84还是CGCS2000国内公开的地表水断面坐标早期很多是基于GPS采集的WGS84经纬度后期官方发布的地理空间数据则逐步统一到CGCS2000国家大地坐标系2000。WGS84和CGCS2000在普通精度应用下差异很小平面位置差一般在几十厘米到一两米左右。如果只是做展示和分析基本可以忽略但如果要跟高精度国土数据做空间叠置建议进行转换。用Python实现WGS84到CGCS2000的转换可以用pyprojfrom pyproj import Transformer transformer Transformer.from_crs(EPSG:4326, EPSG:4490, always_xyTrue) lon_cgcs, lat_cgcs transformer.transform(df[经度].values, df[纬度].values)EPSG:4326是WGS84经纬度EPSG:4490是CGCS2000经纬度。严格来说两者都是地理坐标系转换过程并不改变经纬度数值只是做基准面平移。如果你要把数据投到“高斯-克吕格投影”之类的平面坐标系里还会涉及投影变换这时要格外注意所在分带。2.4 断面编码与名称标准化国控断面编码是后续关联水质监测数据的核心。同一份水质监测月报里可能用“断面代码”关联也可能用“断面名称”关联而不同来源的断面名称写法经常不一致“长江南京段”和“南京长江”在字面上不一样实际是同一个点。我拿到数据后会把断面名称统一成“水体具体位置”的格式比如“太湖西部湖区”“京杭运河苏州段”等。同时给每个断面建一个“关键字表”把可能的别名、简称都列进去方便后面匹配。如果断面名称里包含明显的行政区名字我还会提取行政区字段方便按市分区统计。这里有一个小技巧用行政区划代码前四位加断面代码拼接一个“内部唯一键”这样即使原始代码有重复也不影响后续关联。3. 核心应用场景与实操实现3.1 用QGIS把134个断面落成地图把清洗好的坐标数据做成地图是这套数据最直观的应用。新手我也推荐直接使用QGIS免费且跨平台不用纠结授权问题。操作步骤大致如下将CSV导入QGIS选择“Layer Add Layer Add Delimited Text Layer”。在“Geometry Definition”里选“Point coordinates”X字段选经度Y字段选纬度坐标系选WGS84EPSG:4326。加载后如果点不显示检查是不是经纬度选反了国内数据一般经度在前纬度在后。添加在线底图比如“XYZ Tiles”里的OpenStreetMap或者天地图底图坐标系通常是Web墨卡托QGIS会自动做在线投影转换。如果点位明显偏移不要怀疑是QGIS的问题先回去查坐标字段是否干净以及坐标系设置是否正确。这134个点位落到地图后一眼就能看出江苏水网的大致格局长江沿线点位密集太湖周边围了一圈洪泽湖周边也有不少淮河和沂沭泗水系主要集中在苏北。这种空间直觉是纯看表格完全感受不到的。3.2 关联水质监测数据做等级渲染坐标数据只是骨架真正有分析价值的是把坐标和水质监测结果关联起来。常见的做法是用断面代码做主键join月度“地表水考核断面水质状况表”。比如拿到的监测数据里有“pH、溶解氧、高锰酸盐指数、氨氮、总磷、总氮”等指标先按国家《地表水环境质量标准》的限值给每项打分定类再综合得出该断面是Ⅰ类、Ⅱ类还是Ⅲ类水。把这些类别挂到坐标点上就能用QGIS的“Categorized”符号渲染按水质类别分别显示成蓝色、绿色、黄色等不同颜色。实际操作中有一个坑监测数据的断面代码和坐标表里的断面代码可能不是同一套编码。此时必须先把两边的断面名称做一次模糊匹配我建议先在Excel里做一次人工映射再写代码匹配。# 示例用pandas合并断面坐标和水质类别 data_merged df_coord.merge(df_water_quality, on断面代码, howleft)关联完成后可以按行政区统计各市断面的“优Ⅲ比例”达到Ⅲ类及以上水质断面的占比。比如统计结果能发现苏南某些城市的断面优Ⅲ比例低于苏北这种结论可以直接写成分析简报非常直观。3.3 计算断面间距和上下游关系有了坐标和流向信息就可以进一步做空间关系的分析。比如在多条河流连续布设断面时可以通过坐标计算相邻断面的大致距离。不过要注意直接用经纬度计算球面距离时不能简单套用欧式距离需要用Haversine公式。如果只在省内小范围分析精度也够import math def haversine(lon1, lat1, lon2, lat2): R 6371.0088 phi1, phi2 math.radians(lat1), math.radians(lat2) dphi math.radians(lat2 - lat1) dlambda math.radians(lon2 - lon1) a math.sin(dphi / 2) ** 2 math.cos(phi1) * math.cos(phi2) * math.sin(dlambda / 2) ** 2 return 2 * R * math.asin(math.sqrt(a))再用河流编码或水体名称进行分组就能知道同一河流上断面之间的上下游距离。结合监测数据看某个断面氨氮突然超标时可以快速定位上游最近断面是否也有类似情况辅助判断是局地排污还是上游来水影响。4. 踩坑记录与排查实操4.1 底图偏移国内地图和WGS84的恩怨很多新手把WGS84坐标点导入高德地图或者某些在线地图时发现点位整体往东南方向偏了几百米这就是“火星坐标”GCJ-02的锅。国内大多数商业地图服务高德、腾讯、百度对外提供的在线底图都经过偏移加密直接把WGS84经纬度叠上去必然对不上。解决办法有两个方向一是不要用商业地图底图改用天地图。天地图有国家官方发布的服务提供CGCS2000坐标系底图如果数据也统一到CGCS2000叠加效果最好。二是必须用高德、腾讯底图时先对点位做坐标纠偏把WGS84转GCJ-02。这个转换算法是公开的但注意它只用于民间使用不是严格测绘级转换精度到米级可以接受做不到厘米级。贴一段常用的WGS84转GCJ-02核心代码需要的话可以直接用import math def out_of_china(lng, lat): return not (73.66 lng 135.05 and 3.86 lat 53.55) def transform_lat(x, y): ret -100.0 2.0 * x 3.0 * y 0.2 * y * y 0.1 * x * y 0.2 * math.sqrt(abs(x)) ret (20.0 * math.sin(6.0 * x * math.pi) 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0 ret (20.0 * math.sin(y * math.pi) 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0 ret (160.0 * math.sin(y / 12.0 * math.pi) 320 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0 return ret def transform_lng(x, y): ret 300.0 x 2.0 * y 0.1 * x * x 0.1 * x * y 0.1 * math.sqrt(abs(x)) ret (20.0 * math.sin(6.0 * x * math.pi) 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0 ret (20.0 * math.sin(x * math.pi) 40.0 * math.sin(x / 3.0 * math.pi)) * 2.0 / 3.0 ret (150.0 * math.sin(x / 12.0 * math.pi) 300.0 * math.sin(x / 30.0 * math.pi)) * 2.0 / 3.0 return ret def wgs84_to_gcj02(lng, lat): if out_of_china(lng, lat): return lng, lat a 6378245.0 ee 0.00669342162296594323 dlat transform_lat(lng - 105.0, lat - 35.0) dlng transform_lng(lng - 105.0, lat - 35.0) radlat lat / 180.0 * math.pi magic math.sin(radlat) magic 1 - ee * magic * magic sqrtmagic math.sqrt(magic) dlat (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * math.pi) dlng (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * math.pi) return lng dlng, lat dlat要注意这个转换在线底图可以用但如果做正式出版地图或者要求严格的地理匹配还是要以官方发布的CGCS2000数据和天地图为基准不要用商业地图做数据生产。4.2 断面点位落不到河道上的处理坐标数据里有一部分断面位置是在河流旁边而不是河道中心。原因可能是现场采样点设在桥下、岸边、取水口附近或者原始坐标是在室内地图上点选的存在偏差。我在核对时发现像“淮河-某断面”这种点如果直接落图有的点在堤防上有的点偏离河道几百米。要修正的话建议用QGIS加载高分辨率影像底图配合“Vertex Tool”手动移动点位到河道中泓线位置。但修完一定要记录“坐标修正说明”因为这不是原始采样坐标了后面如果要做严格的监测数据空间分析必须知道哪个点是人工修正过的。判断断面是否应落到河道中心有一个简单原则河流断面监测时采样垂线一般设在河道中心或水流主流位置所以地图上偏离河道中心太远的点大概率是坐标录入误差。如果多个断面都集中在同一处可能是该处河流改道导致的。4.3 编码混乱导致的数据关联失败水质监测数据和断面坐标数据最常遇到的问题是两边的断面编码根本对不上。有些监测报表用“断面代码监测时间”作为唯一标识有些则只写了断面名称缩写。比如“刁铺”“三江营”“小湾”这种地表水考核断面名称在不同报表里可能写成“泰州刁铺”“扬州三江营”“无锡小湾”。我的处理办法分三步第一步用断面代码精确匹配能匹配多少算多少第二步用断面名称的缩写去匹配比如去掉省、市前缀只留“水体具体地名”第三步剩余没法匹配的人工对着地图和名录核对在映射表里手动补上对应关系。这种繁琐的匹配工作看起来不起眼但如果不做后面所有的统计结果都有bug根基。我现在宁可花一小时把映射表做扎实也不想后面返工。4.4 工具脚本常见报错汇总踩过不少次工具脚本的坑这里把最常见的几个列一下报错/现象原因解决办法pandas读CSV出现乱码文件编码不是UTF-8可能是GBK/GB2312用encodingutf-8-sig或encodinggbk读取QGIS提示“无有效几何”CSV经纬度列名与配置不一致或列中有非数值检查X/Y字段选择先清洗成浮点数坐标点整体飞到国外经纬度列反了或坐标系选成投影坐标交换经度纬度字段重新指定EPSG:4326点位和底图对不齐底图是GCJ-02或Web墨卡托数据是WGS84底图换天地图或对点位做坐标纠偏merge后数据行数暴增两个表有重复键连接时产生笛卡尔积先drop_duplicates再merge5. 扩展应用与个人体会5.1 从134个断面到流域水环境管理小工具当点位稳定、数据关联顺畅之后134个断面就不是零散坐标点了而是一套流域水环境状态的空间骨架。我后来基于这份坐标数据做了一张“江苏省国控断面水质启视卡”把每月最新公布的断面水质类别、超标因子、所在流域都挂到地图上点一个断面就能看到历史变化趋势。说实话这种工具的价值不在于多高深的算法而在于把分散在Excel里的信息整合到一个可交互的空间界面上让不懂数据的领导也能一眼看懂问题。你完全可以按同样思路做自己的版本用Leaflet加载一份GeoJSON把134个断面坐标和最新监测数据一起打包发布成网页。这样无论做内部汇报还是外部展示都很方便。5.2 个人实操心得经过几轮整理我总结出三条经验第一坐标数据一定要从源头约定清楚坐标系。哪怕数据说明里只写了“经纬度”也要追问一句“是WGS84还是CGCS2000”。不要怕显得外行这个问题在行业内真的很常见。第二可视化是坐标数据最好的质检方式。我几乎不会只看表格判断点位是否正常一定会把点位全部落到地图上看一眼。有时候一屏幕就能发现表格里很难注意到的异常。第三做好版本管理。同一套134个坐标可能因为监测方案微调而发生变化。每次拿到新数据我都建议单独存一个带发布日期或来源标签的文件夹防止几个月后分不清哪个是最新版。5.3 后面还想扩展什么如果这份数据后续继续完善我会补充两个方向一是把断面所在河流的流向和水系拓扑关系整理出来这样就能做上下游关联分析二是接入自动监测站的小时级数据生成实时水质空间分布动态图。到那时134个断面就不再是“静态坐标点”而是一个“全省水环境态势感知网络”的基础节点。最后再分享一个小技巧无论做什么坐标数据分析都建议用QGIS把点位“符号化”后导出为GeoJSON或者Shapefile在之后的网页开发、Python空间分析、甚至与第三方地图系统对接时通用性都会强很多。保留一份“原始CSV”和一份“GIS图层文件”是保证后续项目不乱的底线。本文还有配套的精品资源点击获取