资讯详情

资讯详情

ArcGIS创建渔网:参数计算、批量脚本与不显示排查

渔网Fishnet这个工具我在 ArcGIS 里用了快十年被同事追问的频率也差不多有十年。问题几乎永远是同一句“ArcGIS 如何创建渔网我建完了渔网不见了。”前半句是操作问题后半句是显示问题两个问题卡在同一句话里其实正好说明了一件事渔网的参数逻辑和 ArcGIS 的图层显示逻辑是两套独立的东西任何一套没理顺你都会觉得“东西没生成”。这篇就把这两件事彻底拆开讲参数怎么填、数字怎么算、脚本怎么写以及渔网建完之后躺在内容列表里却看不见的六种真实原因。适合刚上手 ArcGIS 的新人也适合天天做格网统计、分幅出图、样方抽样的老手——后面几节的字段扩展和批量脚本是我自己在项目里沉淀下来的写法能直接拿去改。1. 先搞清楚渔网到底是什么再谈怎么建1.1 渔网的本质是一套规则化的矢量格网很多人把渔网想成“地图上画的格子”这个理解不太准确。渔网在 ArcGIS 里是实打实的矢量要素类落到地理数据库里就是一堆面或者一堆线每个格子有自己的 FID、有自己的几何、有自己的属性表记录。它跟你在布局视图里加的参考格网完全是两回事——后者是制图装饰前者是能用 Select by Attributes 筛、能做空间连接、能参与分区统计的数据。理解这一点非常关键因为它直接决定了两件事。第一渔网的格网数量是有代价的一万个面还好一百万个面会让符号化和属性表操作明显变慢因为每一个格子都是一条独立记录。第二渔网生成之后“看不见”绝大概率不是数据没生成而是图层渲染、坐标系或者视图范围出了问题——数据在硬盘上好好的只是没画出来。我见过太多人反复点工具、反复重跑最后发现要素类已经生成了七八个全堆在默认数据库里。渔网的规则性体现在三个参数上原点、方向、步长。原点确定左下角那颗钉子的位置方向由 Y 轴坐标点确定默认正北步长就是每个格子的宽和高。行数和列数决定了往东、往北各铺多少格。四个东西凑齐整个格网就唯一确定了没有任何随机性。这也是为什么渔网特别适合做标准化流程——同样的参数跑一百遍结果完全一致。1.2 三种常见用法与工具选型判断同样是“画格子”ArcGIS 里其实有三四个不同的工具选错了就会出现“建完找不到”的尴尬。我在下面这张表里把最容易混淆的几个列清楚你对着自己的目的挑就行。工具产出物类型典型用途会不会出现在地图视图里创建渔网 Create Fishnet矢量要素类面或线格网统计、样方抽样、分幅索引会需要手动加图层格网索引要素 Grid Index Features矢量面要素类分幅出图、图幅索引表会自带页码和比例字段生成格网 Generate Grid布局元素出图时压在地图框上的参考网不会只在布局视图可见创建规则渔网栅格化思路栅格大范围快速分区会但已经是栅格表格里第三行是重灾区。不少人搜“ArcGIS 创建渔网”出来的第一个结果是布局用的格网工具点进去生成完数据视图里空空如也于是就有了“渔网不见了”这个疑问。记住一条判断标准如果你要拿格网去做统计、做连接、做筛选那必须是矢量要素类用创建渔网或者格网索引要素如果只是想让打印出来的图上有经纬度线或者方里网那才用布局格网。至于创建渔网和格网索引要素怎么选我的经验是看下游需求。单纯要一堆规则的面去做分区统计创建渔网足够了参数少、逻辑干净如果后面要批量出图、每个格子对应一张图、还要在属性表里看到“第几行第几列、比例尺多少”那格网索引要素省事得多它自带 PageName、RowLabel、ColLabel 这些字段接地图系列的时候几乎不用二次处理。2. 参数准备九成的“不见了”都埋在这一步2.1 坐标系选错格子会小到肉眼看不见这是我见过最高频的翻车点没有之一。创建渔网工具本身不强制你选坐标系它跟着输出位置走很多人直接把输出丢进默认地理数据库而默认数据库的要素类往往是地理坐标系比如常见的经纬度。这时候“像元宽度”这个参数的单位就变成了度不是米。一度在赤道附近大约一百一十一公里你按平时的习惯填个 100以为是一百米实际上是绕地球跑了两圈半工具要么跑很久要么直接给你一个覆盖大半个中国的巨网。反过来有人意识到单位不对改填 0.001那就是一百多米听着挺合理但如果你的地图视图当前缩放到几千公里范围这个格子只有零点几个像素屏幕上当然什么都没有。数据是真生成了要素数也是对的只是你 zoom 到那一层才看得见。所以正确的做法是先建一个投影坐标系的要素类或者要素数据集把渔网输出到那里让像元宽高的单位明确是米。判断方法很简单打开渔网的属性看空间参考那一栏写的是不是“投影坐标系”。如果不放心用测量工具在地图上量一下某个格子的实际边长跟参数对得上就说明单位没问题。注意如果输出位置已经是地理坐标系工具不会报错也不会提醒你单位问题它只会安安静静地生成一个尺度完全不对的结果。这个坑没有报错信息兜底只能靠事前检查。2.2 范围、行列数与像元大小的换算关系渔网的四个核心参数之间有硬约束范围决定总跨度像元大小决定单格尺寸行数乘列数决定总格数。三者必须自洽否则要么渔网超出研究区一大截要么盖不满。举一个我实际项目里的例子。某研究区是一个矩形投影坐标系下 X 从 500000 到 512800Y 从 3200000 到 3209600也就是东西 12800 米、南北 9600 米。我要做 200 米见方的格网算法很直白列数 (512800 − 500000) ÷ 200 64行数 (3209600 − 3200000) ÷ 200 48总格数 64 × 48 3072原点坐标填 (500000, 3200000)这是左下角Y 轴坐标填 (500000, 3209600)也就是原点正上方一个总高度的位置。这两个点连成的方向就是格网的“北”两点的 X 相同格网就是正的不会有旋转。如果除不尽怎么办比如研究区东西跨度 12800 米我想用 250 米的格子12800 ÷ 250 51.2不是整数。这时候工具的行为是如果你同时给了行列数和像元大小它按你给的行列数生成格网可能盖不满或者略微超出如果你只给像元大小和对角点它会把行列数向上取整到 52多出来的 0.2 格也就是 50 米会溢出边界。我的习惯是手动向上取整然后用研究区边界去做一次裁剪Clip把溢出的半格切掉保证统计结果不包含研究区外的面积。还有一个容易忽略的参数是对角点。工具允许你只填原点和右上角对角点行列数留 0让它自己算。这在快速试参数的时候很方便但正式成果我建议还是把行列数写死因为自动取整的规则在不同版本里偶尔会有细微差别写死了才能保证可复现。2.3 旋转角与几何类型的选择渔网默认是正南正北的但它支持旋转控制方式有点反直觉——不是填角度而是改 Y 轴坐标点的位置。比如你想让格网顺时针转 30 度就把 Y 轴坐标点从原点正上方挪到右上方某个位置两点连线与正北的夹角就是旋转角。这个设计对沿河道、沿公路走向布设格网特别有用。我之前做过一个沿线监测的项目监测带是斜着穿过研究区的正交格网会浪费大量格子后来把 Y 轴点沿线路方向偏了二十多度格网贴合度立刻上来了无效格子少了将近三成。几何类型只有两个选项面POLYGON和线POLYLINE。做统计、做连接、做裁剪一律选面只想要底图上的分幅线、不参与任何分析选线更轻量要素数量一样但渲染快很多。另外工具还有一个“创建标注点”的开关勾上之后会额外生成一个点要素类每个格子的中心有一个点命名规则是在输出名后面加_label。这个点集在做样方抽样、做代表性点位选取的时候非常好用等于白送一份中心点数据。3. 三条创建路径对话框、批处理与脚本3.1 工具箱对话框的完整操作顺序ArcGIS Pro 里创建渔网在“数据管理工具 采样 创建渔网”ArcMap 里在“数据管理工具 要素类 创建渔网”位置不同但参数一模一样。打开之后的填写顺序我建议固定成下面这样能少走很多弯路输出要素类先指到一个投影坐标系的地理数据库里别用默认库原点坐标填研究区范围的左下角格式是“X Y”中间用空格Y 轴坐标填原点正上方一个总高度处X 保持不变像元宽度、像元高度填以米为单位的格网边长行数、列数按前面算出来的值填几何类型选面需要中心点就勾上创建标注点填完之后先别急着点运行用“环境”选项卡里的输出坐标系再确认一遍跟目标数据库保持一致。运行完工具不会自动把结果加到地图上——这一点跟很多人的预期不一样ArcGIS 的多数地理处理工具都是“生成文件”不是“生成图层”。你得自己去内容列表里点“添加数据”把刚生成的要素类拉进来。这一步漏掉就是最朴素意义上的“渔网不见了”。3.2 用 Python 脚本批量生成与参数复用参数一旦定下来就该转脚本了。手动点对话框最怕的就是改一个参数忘一个尤其是要给十几个分区分别建渔网的时候脚本能把出错概率压到接近零。下面这段是能直接跑的最小骨架注意参数顺序import arcpy out_fc rC:\work\project.gdb\fishnet_200m origin 500000 3200000 # 左下角 X Y y_axis 500000 3209600 # 正上方一个总高度 cell_w 200 cell_h 200 rows 48 cols 64 arcpy.management.CreateFishnet( out_fc, origin, y_axis, cell_w, cell_h, rows, cols, None, # 对角点给了行列数就不填 LABELS, # 生成中心点标注不需要就写 NO_LABELS None, # 模板范围 POLYGON )参数里最容易搞错的是第六、第七位行在前、列在后。我见过有人把 64 和 48 填反结果得到一个又扁又宽的格网还以为是自己范围算错了。另外对角点那个位置如果非要传值记得行列数要留空或者写 0两者同时给会以行列数为准。批量生成的话外面套一层循环把每个分区的范围读进来算出原点和 Y 轴点输出名带上分区编号import arcpy zones [ (Z01, 500000, 3200000, 512800, 3209600), (Z02, 512800, 3200000, 525600, 3209600), ] for name, xmin, ymin, xmax, ymax in zones: cols int((xmax - xmin) // 200) rows int((ymax - ymin) // 200) arcpy.management.CreateFishnet( rfC:\work\project.gdb\fn_{name}, f{xmin} {ymin}, f{xmin} {ymax}, 200, 200, rows, cols, None, NO_LABELS, None, POLYGON ) print(f{name} 完成{rows} 行 × {cols} 列)这种写法我在做跨区域对比研究时用得最多十几个分区一次跑完属性表里每个格网还能通过输出名反查属于哪个分区省掉了后面手动合并再拆分的麻烦。3.3 建完之后必做的三项自检渔网生成成功不等于结果可用我每次跑完都会做三个检查加起来不到一分钟能挡住后面八成的问题。第一看要素数量。在属性表里拉到最底下记录数应该等于行数乘列数对不上就说明参数有问题。第二打开属性看空间参考确认是投影坐标系而不是地理坐标系。第三在地图上用测量工具量一个格子的边长跟设定的像元大小比对。这三步做完数据的正确性基本有底了。如果第三步量出来的边长跟设定值差了十万八千里别怀疑工具先回去看坐标系。如果要素数量对、坐标系也对但地图上就是看不见那就是下一节要讲的显示问题了。4. “渔网不见了”的六种真相与逐条排查4.1 图层没被加进来或者加进来了但被视图甩在身后最朴素的原因往往最容易被忽略。地理处理工具生成的是硬盘上的文件不是地图上的图层。很多人跑完工具看内容列表没变化就认定失败了其实文件已经安安静静躺在数据库里。去目录窗格里找到那个要素类右键“添加到当前地图”问题解决。还有一种情况是图层确实加进来了但当前地图视图缩放的位置离渔网十万八千里。比如你刚才在看另一个区域的底图渔网建在几百公里外添加进来之后自然什么都看不到。判断方法很简单右键图层选“缩放至图层”如果视野“唰”地跳到一个陌生位置并且出现了格网那就说明数据一直好好的只是你没看对地方。我个人的习惯是把“缩放至图层”设成添加数据后的条件反射动作比在地图上瞎拖要快得多。4.2 坐标系不匹配造成的尺度错位这个在 2.1 节提过但值得单独拿出来说因为它伪装得特别好。要素类本身是有效的属性表记录数也对可你在地图上就是找不到——因为它要么小得像一粒沙要么大得把整个地图撑爆。排查思路是反过来的先在内容列表里右键渔网图层看“属性 源”里的空间参考。如果显示的是地理坐标系而你原本想要的是米级格网那基本可以确诊。处理方法有两个一是用投影工具把现有渔网转到投影坐标系注意如果你是按度生成的转过来尺度依然是错的转完还得重算二是老老实实回到投影坐标系重新建一遍。顺带说一句动态投影会让这个问题变得更隐蔽。地图框是投影坐标系渔网是地理坐标系ArcGIS 会在显示时自动做一次投影变换位置看着是对的但尺度感完全失真你根本意识不到单位有问题。所以我一直建议渔网这类有明确物理尺寸的数据从生成那一刻就用投影坐标系。4.3 符号系统把格子画成了隐形要素在那儿、位置也对、缩放也到位可屏幕上就是一片空白。这时候去看图层符号填充色跟底图撞了、填充透明度拉到 100%、轮廓线宽设成 0、图层整体透明度调到了极低——这几种设置任意一种成立视觉上都是“没有”。排查办法是把图层拖到最上面右键打开符号系统先把填充改成鲜艳的纯色、轮廓线宽改成 1 磅、两个透明度都拉回 100%如果图案立刻出现那就是符号问题。如果还是没有再检查图层有没有被误设成“仅显示轮廓”或者被某个定义查询过滤掉了——定义查询这个坑尤其阴图层属性里设了一个WHERE 12之类的条件数据全被过滤地图上自然空空如也但属性表打开一看记录数还是满的。提示属性表有记录、地图上没图形先怀疑符号和定义查询属性表也没记录才回去怀疑生成参数。4.4 可见比例范围把图层关掉了ArcGIS 的图层可以设置“最小可见比例”和“最大可见比例”超出范围图层就自动隐藏。这个功能原本是为了性能优化但对不熟悉的人来说就是纯粹的迷惑行为——图层在内容列表里明明勾着就是不显示。判断特征很明显你把地图稍微放大或缩小一点图案“啪”地出现或者消失。遇到这种规律性出现消失直接右键图层打开属性找到“常规”里的可见比例范围把上下限都清空问题立刻解决。有些模板工程会批量给图层设比例范围你从别人那儿拷贝过来的地图文档特别容易中这一枪。4.5 原点填错导致的整体偏移渔网确实生成了也确实显示了但位置整体偏出去一大截。最常见的错误是把研究区范围的左上角当成了原点。渔网的原点定义是左下角填了左上角整个格网会往下偏一个总高度看起来像是“跑到南边去了”。第二种错误是 X 和 Y 填反了。输入框里是“X Y”顺序如果填成“Y X”在投影坐标系下这个点可能直接飞到研究区几千公里外格网自然也就不在视野里。识别方法很简单算一下偏移方向如果整体往南偏了一个总高度是原点填错如果偏得毫无规律、动辄上千公里多半是 X/Y 反了。第三种错误是 Y 轴坐标点的 X 跟原点不一致导致格网被旋转了一个角度。如果不是有意的斜向布设看到格网歪了就回去检查这两个点的 X 值是否相同。4.6 工具其实没跑完或者跑出来了空要素还有一种“不见了”是字面意义上的文件都没生成。行列数填成 0 又没给对角点工具会直接报错退出行列数填得极大比如几万乘几万工具会跑上几个小时甚至直接内存告急你以为它完成了其实还在转圈。判断方法是看地理处理面板里的运行状态以及输出位置有没有对应的要素类文件。另外如果研究区范围本身是空的比如图层选择集为空、定义查询过滤掉了全部要素工具可能生成一个零要素的渔网看着像是成功了打开属性表一片空白。养成看一眼要素数量的习惯能省下大量自我怀疑的时间。现象最可能原因处理动作内容列表没变化工具只生成文件不加图层目录里手动添加到地图加了图层但地图空白视图范围不重合右键缩放至图层缩放后才看到密密麻麻小点地理坐标系下按度设了像元换投影坐标系重建图层勾着却不显示缩放才出现可见比例范围限制清空比例范围上下限属性表有记录但无图形符号透明、线宽 0、定义查询过滤恢复符号、清除定义查询格网整体偏南一个总高度原点填成了左上角改填范围左下角格网歪斜Y 轴点与原点 X 不一致保持两点 X 相同生成了空要素类行列数为 0 或范围为空补齐参数、检查选择集5. 让渔网真正能用的进阶处理5.1 补上行列号与格网编码字段刚生成的渔网属性表里只有 OBJECTID 和 Shape_Length、Shape_Area 这几个字段拿来统计很难对应到具体位置。我一般会立刻补三个字段行号、列号、格网编码编码格式用R03C17这种人一眼就能在地图上定位。Create Fishnet 生成要素的顺序是固定的——从左下角开始先沿 X 方向铺满一行再往上走一行。所以行号列号可以直接从 OBJECTID 反推不需要读取几何import arcpy fc rC:\work\project.gdb\fishnet_200m cols 64 arcpy.management.AddField(fc, ROW_ID, SHORT) arcpy.management.AddField(fc, COL_ID, SHORT) arcpy.management.AddField(fc, GRID_CODE, TEXT, field_length12) with arcpy.da.UpdateCursor(fc, [OID, ROW_ID, COL_ID, GRID_CODE]) as cur: for oid, r, c, code in cur: idx oid - 1 row idx // cols 1 col idx % cols 1 cur.updateRow([oid, row, col, R{:02d}C{:02d}.format(row, col)])这段代码有个前提要素类是新生成的OBJECTID 连续无空洞。如果中途删过格子序号就断了这时候得改用读取几何中心点坐标来反算行列稳妥但慢一些。顺手把中心点坐标也加上做散点图、做空间插值、导出到其他工具都用得上。方法是用SHAPETRUECENTROID令牌遍历一次把 X、Y 写进两个双精度字段就行。5.2 与空间连接、分区统计的配合打法渔网真正的价值在于它是一个“容器”。往里面装点数据、装栅格值、装线长度才能出结论。最常用的是空间连接渔网作为目标要素点数据作为连接要素连接操作选“一对一”并勾选“保留所有目标要素”这样没有点的格子也会保留计数为 0。这一步很多人忘了勾结果只得到有点的格子做密度分析时样本就有偏了。栅格统计走的是分区统计工具渔网面作为分区数据栅格作为值栅格输出一张表每个格子一行包含均值、最大值、标准差这些。这里有个性能细节渔网格子数上万之后分区统计会明显变慢我的做法是先把渔网转成栅格要素转栅格像元大小设成格子的边长用栅格做分区统计速度快一个量级代价是边界会有半个像元的误差。精度要求高的项目还是老老实实用面。还有一种玩法是用渔网做样方抽样给每个格子生成一个随机点用这些点去提取遥感影像的值做地面验证样本。生成随机点的工具支持在面内约束每个格子出一到多个点全程脚本化比人工在图上点要可靠得多。5.3 分幅出图的命名与地图系列衔接用渔网做分幅底图是很成熟的做法。把渔网的 GRID_CODE 字段作为地图系列的索引字段出图时每张图自动带页码名文件名也用它几百张图批量导出不用手动改名。这里有个小经验格网编码不要只用数字纯数字排序在某些环境下会被当字符串处理1、10、11、2 这样排非常难受。用R01C01这种带行列表头的编码排序和肉眼定位都舒服。另外如果分幅图要拼接格子之间记得留一点点重叠通常给总跨度的百分之一到二太严丝合缝的话拼接处容易出现细缝。5.4 大体量渔网的性能控制格网数量是绕不开的性能红线。我的经验值是这样的几千个面随便玩几万个面符号化开始有延迟属性表滚动变卡几十万个面地图操作明显迟滞建议关掉标注、简化符号上百万个面基本就别用矢量了转成栅格或者先分区再分块处理。如果业务确实需要超密格网我会先用渔网生成分块索引每个分块几百个格子再逐块生成细格网最后按需合并。这样每次操作的数据量可控出问题也容易定位到具体块。另外生成完成后立刻建立空间索引对后续的空间查询和连接速度提升非常明显。注意不要在渔网上开要素标注尤其是把 GRID_CODE 标在每个格子上。几千个格子就会让重绘慢到怀疑人生需要标注时临时打开、出图前再关掉。6. 几个我踩过的坑写下来省你时间第一个坑是默认地理数据库。ArcGIS 默认把工具输出丢到工程自带的 .gdb 里那个库的坐标系往往不是你想要的生成完一堆渔网混在里头找都找不着。我的做法是在每个项目开始时先建一个专用文件地理数据库明确设好投影坐标系所有中间成果都往里面放路径固定、单位固定出问题的概率直线下降。第二个坑是“重跑覆盖”。工具的输出路径如果已经存在同名要素类有的版本会直接报错有的会静默追加或覆盖行为不完全一致。所以脚本里我习惯在生成前先判断并删除或者给输出名加时间戳避免拿到一份“上一次的残骸”还以为是新的。第三个坑是范围参数的取整方向。行列数向下取整会盖不满研究区向上取整会溢出边界两种都有隐患。我的处理是向上取整保证全覆盖然后用研究区边界做一次裁剪把溢出部分切掉。裁剪之后再重新算面积别直接拿 Shape_Area 去汇总会虚高。第四个坑跟显示有关如果你在三维场景里打开渔网默认的拉伸和基底高度设置会让它浮在空中或者埋到地下看着就像“丢了”。切回二维地图看一眼问题立刻清楚。这个坑不常见但很折磨人尤其是刚接触三维视图的时候。最后一个体会是关于工具选择的。这些年我带过不少新人发现“渔网不见了”这个问题里真正因为参数填错导致失败的比例其实不到三成剩下七成全是显示、坐标系、图层添加这类“非数据问题”。所以遇到空白先别急着重跑工具花三十秒做三件事查图层在不在、缩放至图层、看空间参考。这三步能解决绝大部分困扰比反复点运行有效得多。真要重跑也先把上一次的输出找出来看一眼要素数量和坐标系别在同一个坑里摔两次。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →