ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

全国风机点位数据GIS处理全攻略:坐标、清洗与分析实战

全国风机点位数据GIS处理全攻略:坐标、清洗与分析实战 简介这份全国风机点位数据源自OpenStreetMap以Shapefile格式存储涵盖2026年5月1日全国范围内共计158061个风机点位可广泛应用于GIS空间分析、风电资源评估、环保选址等场景也适合作为地理信息教学与实际项目中的基础底图。压缩包体积仅为7.5MB解压后约400MB共包含9个文件其中.shp负责点几何存储.shx、.dbf分别承担索引与属性记录.prj定义投影坐标另有.qmd、.cpg等辅助文件可直接加载到ArcGIS、QGIS等主流平台省去格式转换环节。每个点位都带有经纬度坐标便于进行密度制图、核密度分析、缓冲区分析及多源数据叠加。该数据集目前已有31人学习下载为需要全国风机点位底图的开发者、研究者和学生提供了省时省力的离线数据源尤其适合开展批量统计与可视化工作。1. 全国风机点位数据放进 GIS 之前先过坐标、格式和口径三关拿到“20260501全国风机点位数据”这份资源第一反应是赶紧拉进 GIS 里出图。在风电相关工作里这份全国风机点位能做的事不少风电场开发前期的选址评估、与生态红线和居民点叠合做合规性初查、已建成机组的分布统计、以及老旧风场改造时的资源复核。但作为长期和点位数据打交道的人我会先做三件事确认坐标系、检查字段口径、排查重复点位。这三件事不做后面所有分析都是白做因为点位数据看起来只是“一个点”但“点在哪儿、点代表什么、点有多少个”直接决定分析结论是否成立。这篇文章把它拆开讲从数据格式一路讲到 QGIS、GeoPandas 里的实操最后落到五个常见坑和一套进阶用法。2. 认识这份点位资源字段口径、坐标基准和文件格式是分析前提2.1 点位数据里的字段长什么样全国风机点位数据通常不是一张已经渲染好的地图成果而是一份带属性表的矢量文件或表格文件。常见的落地格式有这么几种CSV 或 Excel 表格、Shapefile、GeoJSON。其中 CSV/Excel 最常见因为采集端出于体积和兼容性考虑习惯用点表存经纬度GIS 分析端再根据经纬度生成空间图层。拿到手先打开字段看别急着导入。常见的字段名和业务含义大致如下字段名常见英文名示例值用途说明风机编号turbine_id / fan_codeTJ-2026-0101单机唯一标识用于去重和回溯经度lon / lng / x116.4074十进制度WGS84 或 GCJ02 取决于来源纬度lat / y39.9042十进制度与经度配套海拔elevation / alt1280.5影响实际风资源评估轮毂高度hub_height100风机轮毂离地高度单位米单机容量rated_power / capacity3.0单台风机的额定功率单位 MW装机台数unit_count / turbine_count50风电场内机组数所属电场wind_farm_nameXX风电场多台机组归属同一场区投运年份commission_year2024判断新旧机组用于改造评估这里有一个口径问题经常被忽略同样是“风机点位数据”有的资源存的是“单台风机点位”一条记录对应一台风机有的存的是“风电场中心点”一条记录对应整个场区。区别非常大。单机点位做缓冲区和密度分析才有意义场区中心点只能做宏观分布。判断方法很简单看有没有“单机容量”这类单台属性以及同名称电场出现多条记录还是单条记录。建议收到资源后先做一次字段盘点把每个字段的类型和取值区间列出来。比如经度范围应该在 73~135 之间纬度在 18~54 之间超出这个范围的点基本可以判定为异常坐标。这一步虽然基础但能省掉后续大量排错时间。2.2 坐标系与投影先判断数据是不是 WGS84风机点位数据的坐标系是整个分析里最不该出问题、却最容易出问题的地方。国内能接触到的点位来源无非几个渠道GPS 采集、测绘成果、互联网地图服务导出、以及设备台账整理。不同渠道的坐标基准不一样。GPS 原始采集和大多数专业 GIS 软件默认的是 WGS84 坐标系即 EPSG:4326经纬度直接用十进制度表示。互联网地图平台导出的数据则很可能是 GCJ02火星坐标系经度和纬度都做了非线性偏移偏移量通常在 100 米到几百米不等。测绘成果可能是 CGCS2000 或西安 80、北京 54 投影坐标这时文件里的字段不再是经纬度而是 Y、X 或带带号的高斯平面坐标。快速判断数据坐标系的土办法有两个。第一把点叠到省市边界上如果所有点位整体偏移且偏移方向一致、距离在百米量级基本是 GCJ02 和 WGS84 的差异第二看字段的取值范围经纬度如果出现 Y 值为 400000 左右的字段那根本不是经纬度而是高斯投影的平面坐标。全国尺度的风机点位分析我习惯统一到 WGS84 经纬度保存原始数据分析时再按需投影。为什么不用 GCJ02因为它是加迷算法虽然在国内底图上显示位置准但做空间计算缓冲区、面积、距离时没有标准的投影参数而且 GeoPandas、PostGIS 这些工具处理 GCJ02 的投影定义很别扭。统一到 WGS84 之后底图选 OpenStreetMap、天地图或自然资源标准地图都能对齐。如果是 Shapefile 或 GeoJSON通常带 .prj 文件或坐标声明可以直接读。但 CSV 里只有经度纬度两列没有坐标系声明必须自己确认来源。我的习惯是先抽取 200 个点在 QGIS 里叠合官方省市界验证确定坐标系后再做全量转换。这一步花 10 分钟能避免后面所有分析结论因为底图套合不准而翻车。3. 把点位灌进 GIS用 Python 读取、清洗、做空间连接3.1 从 CSV 变成真正的空间图层拿到 CSV 格式的风机点位第一步是转成空间数据。这里用 Python 的 geoandas 库读取、转格式、导出一次完成。代码和说明如下import pandas as pd import geopandas as gpd from shapely.geometry import Point # 读取原始表格注意指定编码很多资源是 UTF-8 或 GBK raw_df pd.read_csv(wind_turbines_20260501.csv, encodingutf-8) # 把经纬度两列转成 Point 对象 geometry [Point(x, y) for x, y in zip(raw_df[lon], raw_df[lat])] # 创建 GeoDataFrame明确指定坐标系为 WGS84EPSG:4326 gdf gpd.GeoDataFrame(raw_df, geometrygeometry, crsEPSG:4326) # 删除经纬度为空或明显越界的记录 gdf gdf.dropna(subset[lon, lat]) gdf gdf[(gdf[lon] 73) (gdf[lon] 135) (gdf[lat] 18) (gdf[lat] 54)] # 导出为 GeoJSON方便在 QGIS 和 ArcGIS 里直接打开 gdf.to_file(wind_turbines_20260501.geojson, driverGeoJSON)这段代码做了三件事把经纬度转成几何点、声明坐标系、过滤异常范围。其中crsEPSG:4326是关键如果不声明坐标系后面所有投影转换都会报错或得到错误结果。过滤经纬度范围是必要的原始数据经常混入零值或乱码导致的异常点比如经纬度为 0,0 的记录会跑到非洲几内亚湾去。导出 GeoJSON 而不是 Shapefile 的原因是GeoJSON 是纯文本格式字段名不会像 Shapefile 那样被截断成 10 个字符中文属性名也能完整保留。如果要交给同事用 ArcGIS 处理可以先导出 GeoJSON 再在 ArcGIS 里转换。3.2 清洗流程去重、去孤立点点位数据最常见的质量问题是重复。同一个风机在台账里录了两次或者移交数据时把历史版本和当前版本合并了。重复点对缓冲区分析的影响不大但对密度分析和数量统计影响很大——数量多算一倍热力图会出现异常的集中斑块。# 按风机编号去重保留第一条 gdf_dedup gdf.drop_duplicates(subset[turbine_id], keepfirst) # 如果没有风机编号按经纬度去重保留精度为小数点后 6 位 gdf_dedup gdf.drop_duplicates( subset[lon, lat], keepfirst ) # 检查去重前后数量差异判断数据重叠程度 print(f原始记录数: {len(gdf)}) print(f去重后记录数: {len(gdf_dedup)})优先用turbine_id去重因为不同风机的经纬度可能因为坐标采集精度问题出现小数点后第三位相同的情况直接按经纬度去重会误伤。如果数据里没有风机编号再退而求其次用经纬度去重同时设定tolerance思路先把经纬度四舍五入到小数点后 5 位约 1 米精度再按舍入后的值去重。至于孤立点指的是那些离最近风机几百公里的记录通常是采集设备异常或人工录入错误。判断方法用空间临近度对每个点找它最近邻的距离超过 100 公里的记录直接剔除。风电场不会建在孤立区域至少周围会有配套道路和升压站不太可能出现单机孤悬的情况。3.3 按行政区统计风机数量和装机容量很多分析需求是“某省/某市有多少风机、总容量是多少”。这个操作在 GIS 术语里叫空间连接核心是判断点落在哪个面里。用 GeoPandas 实现方式如下# 读取全国省市边界数据同样坐标系 WGS84 province_gdf gpd.read_file(province_boundary.geojson) # 空间连接点落在哪个省就给这个点打上省的标签 joined gpd.sjoin( gdf_dedup, province_gdf, howleft, predicatewithin ) # 按省统计风机数量和总装机容量 stat_result joined.groupby(province_name).agg( turbine_count(turbine_id, count), total_capacity(rated_power, sum) ).reset_index() # 结果按装机容量降序排列方便看头部省份 stat_result stat_result.sort_values(total_capacity, ascendingFalse) print(stat_result.head(20))sjoin函数里的predicatewithin表示“点必须完全落在面内部”但这里有个边界问题处于省界线上的点因为边界精度问题可能匹配不到任何省结果是 NaN。更稳妥的做法是把predicate改成intersects并且先对边界做 10 米缓冲区把边界精度容差放进去。聚合统计时注意rated_power字段可能是字符串类型如果 CSV 里某些行写成了“3 MW”这种带单位的值pandas 的sum会直接报错或按字符串拼接。先执行pd.to_numeric转换遇到无法转换的值填 0是这类任务里最常见的补救操作。4. 做能拿去汇报的分析缓冲区、敏感目标判定与热力渲染4.1 500 米缓冲区风机与敏感目标的距离判定风机点位数据最核心的应用场景之一是合规性检查。自然保护区边界、居民点、水源保护区都是常见敏感目标风机与这些目标的距离是风电项目审批的关键指标。不同省份对缓冲区半径要求不一样有的要求距离居民点 300 米有的要求 500 米水利设施附近可能要求更严格。缓冲区分析的思路是以风机点位为中心生成指定半径的圆面再与敏感目标求交集统计“哪些敏感目标在风机周边多少米范围内”。# 必须投影到米制坐标系缓冲区半径单位才准确 # 用 Albers 等积投影 EPSG:102023覆盖全国且面积变形较小 gdf_proj gdf_dedup.to_crs(EPSG:102023) # 生成 500 米缓冲区 buffer_500 gdf_proj.buffer(500) # 把缓冲区结果存到一个新的 GeoDataFrame buffer_gdf gpd.GeoDataFrame( gdf_proj.drop(columns[geometry]), geometrybuffer_500, crsgdf_proj.crs ) # 读取居民点数据并与缓冲区求交集 residential_gdf gpd.read_file(residential_points.geojson).to_crs(EPSG:102023) conflict gpd.sjoin( residential_gdf, buffer_gdf, howinner, predicateintersects ) # 统计每个风机引发的冲突点数量 conflict_stat conflict.groupby(turbine_id).size().reset_index(nameconflict_count)注意这段代码里的一个关键动作先投影再缓冲区。在 EPSG:4326 经纬度坐标系里直接做缓冲区半径单位是度500 米的含义完全不成立得到的是一个异常粗糙的结果。投影到等积投影后缓冲区单位变成米这才是真正的空间距离。选 EPSG:102023Albers 等积圆锥投影而不是 UTM 分带的原因是全国尺度下UTM 需要按 6 度带切成多个分区跨带拼接很麻烦Albers 是双标准纬线等积投影全国范围一套参数跑完虽然在高纬度区域行政区域边界可能稍有扭曲但缓冲区面积计算精度足够。如果是做省域范围内的精细化分析我一般会换成更贴近本省的 CMVF 投影或自定义中央经线的高斯投影。4.2 核密度图风机分布热力渲染的带宽玄学风机分布热力图是汇报材料里的常客。它不统计具体数量而是通过核密度估计描述“哪片区域风机最密集”。这个工具的坑在带宽参数上同样的数据带宽设成 5 公里和设成 50 公里出来的热力图完全两个故事。核密度的核心参数是bandwidth带宽它决定了每个点的影响半径。带宽太小图面全是孤立的高亮点带宽太大全国变成一个平滑的渐变面看不出局部集聚。实用经验是看风机分布的尺度。如果分析目标是全国布局建议带宽 20~50 公里能看出风电基地的集群效应如果分析目标是省级布局建议带宽 5~10 公里能对比省内各区域的密度差异。# 用 PySAL 的核密度估计做二维密度分析 import numpy as np import pandas as pd coords np.array([ gdf_dedup[lon].values, gdf_dedup[lat].values ]).T # 带宽根据分析尺度调整这里设 10 公里转换为度约 0.1 from scipy.stats import gaussian_kde kde gaussian_kde(coords.T, bw_method0.08) # 生成全国网格并计算密度值 grid_x np.linspace(73, 135, 500) grid_y np.linspace(18, 54, 500) xx, yy np.meshgrid(grid_x, grid_y) positions np.vstack([xx.ravel(), yy.ravel()]) density kde(positions).reshape(xx.shape) density density / density.max() * 100 # 归一化到 0-100 # 导出为栅格 TIFF方便在 QGIS 里做分层渲染 from osgeo import gdal driver gdal.GetDriverByName(GTiff) out_raster driver.Create(wind_density.tif, 500, 500, 1, gdal.GDT_Float32) out_raster.GetRasterBand(1).WriteArray(density) out_raster.GetGeoTransform()bw_method的取值直接决定热力图是“只看到三大风区”还是“能看到每台风机”。0.08 这个值是经验值对应全国尺度下大约 10 到 15 公里的空间影响半径。如果数据覆盖范围只有几个省这个值要调小到 0.02 左右否则热力图会糊成一片。热力图渲染还有一个常见误用直接按密度值的大小用红色到蓝色渐变看起来好看但图例没有数量含义。我更建议把密度值归一化成“每百平方公里风机台数”或者至少在图例里标注清楚使用的是相对密度还是绝对密度避免汇报时被问“这个红色代表多少台”答不上来。5. 常见问题与避坑五个会实际踩到的坑5.1 整批点位偏移到隔壁县现象把点位加载进 QGIS 后所有风机点整体偏移到省界另一侧偏移距离在几十米到几百米不等而且距离越往北偏移越大。原因原始数据是 GCJ02 坐标系但导入时被当成 WGS84 使用了或者反过来WGS84 数据叠到了 GCJ02 底图上。GCJ02 对 WGS84 的偏移不是简单平移而是一个随经纬度变化的非线性变换所以表现出“越往北偏得越远”的特征。解决判断好来源后做坐标转换。GCJ02 转 WGS84 用第三方库如 coord_convert 包或已知的偏移修正算法注意不要用固定常量偏移那种做法只能解决一个点解决不了一张图。转换后再随机抽 20 个点位叠到高精度影像上验证。5.2 重复点位导致统计数虚高现象按省统计风机台数统计结果比实际投产数据多出 30% 以上且某些风电场同一坐标出现多条完全一致的记录。原因数据合并时不同来源的台账没有按唯一标识去重。常见场景是风电场扩建后老台账和新台账叠加同一台机组的坐标和编号出现两次。解决先按turbine_id去重没有 ID 的按“经纬度精确到小数点后 5 位 单机容量”组合去重。去重前后要打印数量对比如果差异超过 10%大概率数据源本身有重复这也是一个值得写进数据说明文档的发现。5.3 CSV 乱码与字段类型错乱现象CSV 文件在 QGIS 里加载后坐标列是空的但 Excel 打开明明有数据或者属性表里的中文显示成一串问号。原因CSV 编码不一致。有的文件是 UTF-8 带 BOM有的是 UTF-8 无 BOM还有的是 GBK。QGIS 默认猜测编码经常猜错Excel 对 UTF-8 无 BOM 文件的中文兼容性也差。解决用 VSCode 或 Notepad 批量检测编码并转成 UTF-8 带 BOM。实测 QGIS 对 UTF-8 带 BOM 的识别最稳定。读取后立即检查经纬度列类型pandas.read_csv时显式指定dtype{lon: float, lat: float}防止前几个值看起来像整数导致整列被解析成整数。5.4 点位与国界省界对不齐现象风机点位在沿海省份出现一部分落在海里或者在国境线附近跑到境外。原因数据在人工编辑阶段使用了不同的底图边缘部分点位是手绘或采集精度低另一种原因是数据未经投影直接按经纬度渲染而底图在投影转换后有一定形变。解决先用行政区边界做反空间连接把落在省委以外的点提取出来人工检查。对沿海风机保留距离海岸 500 米缓冲区内的点远海孤点按异常值剔除。这一步本质上不是精度问题而是数据可信度的备案建议把异常点的剔除原因记入元数据。6. 进阶用法用字段属性做风机分档与资源粗筛6.1 按单机容量和轮毂高度分档渲染点位数据不只是画点把属性字段用起来能大幅提升分析价值。按单机容量把风机分成三档小于 1.5MW 的早期机组、1.5 到 3MW 的过渡期机组、3MW 以上的大容量机组。分档后用不同符号大小和颜色渲染一眼就能看出哪些区域是老旧机组集中的区域这对风电改造和“以大代小”项目很有参考价值。# 分档函数 def classify_capacity(cap): if cap 1.5: return early_lt_1.5MW elif cap 3.0: return mid_1.5_3MW else: return large_gt_3MW gdf_dedup[cap_class] gdf_dedup[rated_power].apply(classify_capacity)6.2 与风资源数据叠合做选址粗筛更进阶的用途是把风机点位与平均风速数据叠合。全国风资源网格数据通常是 250 米分辨率的 GeoTIFF用 GeoPandas 做点采样# 从风资源栅格中提取点位处的年平均风速 import rasterio from rasterio.sample import sample_gen with rasterio.open(annual_wind_speed.tif) as src: coords_list [(x, y) for x, y in zip(gdf_dedup.geometry.x, gdf_dedup.geometry.y)] sampled list(src.sample(coords_list)) gdf_dedup[wind_speed_avg] [s[0] for s in sampled]然后绘制风速与装机台数的交叉表能看到“高风速区的风机建得不多低风速区反而密布”的反常结果这种反常识数据往往意味着限电或地形限制值得深入追查。从那以后我每次拿到点位数据都强制走一遍“坐标验证、去重、投影转换、字段检查”四步流程跑完才敢把结果发出去希望帮到你。本文还有配套的精品资源点击获取
返回列表