在ArcGIS Pro中使用Jupyter Notebook进行地理处理与面积统计实战
简介面向GIS初学者及希望用Python扩展ArcGIS Pro的开发者这份项目源码以简洁示例演示了在ArcGIS Pro中启动并固定Jupyter Notebook工作目录的完整配置方法。资源共3个文件以inscode文件承载启动逻辑、HTML页面呈现说明外加.gitignore用于版本管理压缩包仅4KB却覆盖了环境配置、目录设置与项目结构关键点。已有95人学习浏览适合刚接触Jupyter交互式编程或想优化GIS工作流的用户。通过源码可掌握生成配置文件、修改c.NotebookApp.notebook_dir指定永久目录以及直接从ArcGIS Pro的Python环境打开Jupyter到目标目录的操作思路还能学习将Python脚本、软件包和源代码组织为可维护结构的方法为后续空间数据分析、自动化批处理及GIS二次开发打下扎实基础。1. 为什么要把jupyter notebook搬进ArcGIS Pro我最早接触ArcGIS Pro时其实有点抗拒里面内置的Python环境总觉得命令行跑脚本就够了没必要折腾notebook。直到有一次做土地利用变化分析需要反复调整筛选条件、可视化中间结果命令行那种“写完-运行-出bug-再修改”的循环让我效率极低我才认真试了Pro自带的jupyter notebook结果回不去了。先说清楚这个组合解决什么问题。ArcGIS Pro的架构和旧版ArcMap最大的区别之一就是Python被深度嵌入你可以在Pro里直接打开notebook连arcpy的导入和环境配置都省了。这时候你面对的不仅是一个代码编辑器而是一个能边写边跑、边跑边看地图的交互环境。对于做数据分析、批量处理、方法验证的人来说这种“即时反馈”是纯脚本难以替代的。那“项目源码”这一块怎么理解我个人的习惯是把一套完整的分析流程拆成若干cell从数据读取、字段计算、统计汇总到结果导出每一步都有对应的可执行代码。这样不仅自己能复用团队协作时别人也能快速看懂你的分析脉络比一堆孤立脚本好维护得多。适合谁三类人最有必要看这篇文章正在从ArcMap迁移到Pro的老用户不太适应新环境的Python工作流。做地理数据处理、空间分析的研究人员需要快速验证方法。想用Python批处理代替手工重复操作的Pro用户但不知道从哪下手。这篇文章不是简单的“打开notebook”教程我尽量把我踩过的坑、验证过能跑的代码、以及排查问题的思路都写出来你跟着走完一遍应该就能独立搭起自己的notebook分析环境了。2. 环境与界面先搞清你手上有什么工具2.1 ArcGIS Pro的Python环境到底是怎么回事很多人在第一步就卡住是因为没搞懂Pro的Python环境跟普通Python环境的区别。ArcGIS Pro 2.x以上版本安装时会自带一个独立的conda环境默认叫arcgispro-py3。这个环境里有arcpy、numpy、pandas这些常用库而且版本是Esri官方测试过的跟Pro的内核深度绑定。这意味着什么如果你自己拿Python官网的安装包或者Anaconda另建环境直接pip install arcpy是不行的arcpy并不在PyPI上提供独立安装包。所以最省心的方式是所有跟Pro相关的Python工作都直接用Pro自带的这个环境。你可以在Pro界面内打开notebook也可以在Pro安装目录下找到python.exe然后通过命令行启动jupyter。我自己习惯的做法是直接点Pro界面顶部的“分析”选项卡然后选择“Python”Pro会打开一个内嵌的notebook窗口不需要额外配置任何东西。首次打开会稍微慢一点因为要初始化内核之后就好很多了。2.2 两种打开notebook的路径各自怎么选具体来说打开方式我整理成下面几种在ArcGIS Pro里分析 - Python。适合日常交互分析跟地图联动最方便。在Windows命令行进入C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3运行python -m jupyter notebook。适合需要自定义工作目录、或者没开Pro界面但想跑脚本的场景。通过ArcGIS Pro的包管理器给arcgispro-py3环境单独装一个jupyterlab这样你可以用更现代一点的notebook界面。平时我推荐第一种。因为Pro内置的notebook跟地图文档是关联的你在notebook里执行arcpy操作后Pro的目录、地图内容能实时刷新调试时特别爽。2.3 一个容易被忽略但很关键的细节工作路径真正用起来以后有一个细节我建议你特别留意——工作路径。Pro内置notebook的工作目录默认跟项目工程.aprx所在的目录保持一致但你不是总能记得当前目录到底在哪。我有一次跑了半天代码导出结果后发现文件跑到工程文件旁边去了一时没找到还以为是代码写错了。所以每次新建notebook我的习惯是第一行就先打印当前路径顺便把工作空间设置好。比如import os print(os.getcwd()) import arcpy arcpy.env.workspace rC:\Users\你的用户名\Documents\ArcGIS\Projects\你的工程名 arcpy.env.overwriteOutput TrueoverwriteOutput True这个设置也很重要。arcpy默认不允许覆盖已有数据如果你重复跑同一段分析会直接报错说数据已存在。开了这个开关后就不用来回删中间数据了。3. 项目实战从要素类读取到面积统计的完整源码3.1 案例背景为什么拿面积统计来说事面积统计算是最常见也最容易被轻视的需求。比如我手头有一个地块要素类里面有不同类型的用地领导往往就一句话“把每种类型的面积算一下保留两位小数。”听起来简单但实际做起来数据量大、字段类型杂、坐标系不同导致的面积单位不一致都是坑。尤其是“只保留小数点后两位”这个点热搜里也出现了说明很多人被这个细节折磨过。直接round()只能管住Python里的数值显示但保存到属性表或者导出成表格格式可能又被“打回原形”了。我会在下面的代码里用两种方式处理一种是用Python格式化另一种是用字段计算器写到目标字段。3.2 完整代码使用SearchCursor做属性统计我先写一个不需要安装任何第三方库、直接用arcpy内置功能就能跑的代码。需求是统计某个小班图层里不同地类代码的面积并格式化输出。# -*- coding: utf-8 -*- import arcpy fc rC:\data\land_use.gdb\land_parcels type_field LAND_CODE area_field SHAPEAREA stats {} with arcpy.da.SearchCursor(fc, [type_field, area_field]) as cursor: for row in cursor: code row[0] area row[1] if code not in stats: stats[code] 0.0 stats[code] area print(统计结果原始平方米) for code, total_area in stats.items(): print(f地类代码 {code}: {total_area:.2f} 平方米)这段代码的底层的逻辑是游标逐行扫描要素类把相同地类代码的面积累加在一起。SHAPEarea是arcpy里获取要素几何面积的固定写法不需要你自己再算投影。值得注意的是这个面积是要素本身存储的坐标系下的面积如果图层是WGS84经纬度算出来不是平方米而是度这点后面会细说。3.3 保留两位小数的正确姿势如果你只是想在notebook里看着好看那么用f-string格式化就够了就像上面那样。但如果想把结果更新回到数据里或者输出成Excel表格就要小心了。我常用的一种方式是用arcpy.management.CalculateField配合Python表达式arcpy.management.AddField(fc, AREA_SQKM, DOUBLE) arcpy.management.CalculateField( fc, AREA_SQKM, round(!SHAPE.areaSQUAREKILOMETERS!, 2), PYTHON3 )这里用到了!SHAPE.areaSQUAREKILOMETERS!这种字段表达式可以直接在字段计算里做单位换算并保留两位小数。在notebook里跑完之后记得刷新一下图层属性表看看计算结果是不是符合预期。我第一次用这个语法时忘了加SQUAREKILOMETERS后缀结果面积数值全部变成平方米跟预期的千差万别排查了好一会儿才发现。3.4 更实用的批量处理场景按属性分组统计并导出上面只是单要素类的统计。实际工作中我经常需要对多个要素类做同样的一套分析比如不同年份的用地数据每年跑一遍。这时候我就会把代码封装成函数然后用循环目录的方式批量处理。import arcpy import os gdb rC:\data\years_data.gdb output_txt rC:\data\area_stats.txt with open(output_txt, w, encodingutf-8) as f: for year in range(2018, 2024): fc os.path.join(gdb, fland_use_{year}) if not arcpy.Exists(fc): print(f{year}: 要素类不存在跳过) continue stats {} with arcpy.da.SearchCursor(fc, [TYPE, SHAPEAREA]) as cursor: for row in cursor: stats[row[0]] stats.get(row[0], 0.0) row[1] f.write(f {year} \n) for typ, area in stats.items(): f.write(f{typ}: {area:.2f}\n) print(批量统计完成结果已写入, output_txt)这里用arcpy.Exists先判断要素类存在与否避免中间某年数据缺失导致整个流程中断。输出到txt而不是直接print好处是结果不容易丢notebook一旦关闭print的内容就没了但文件还在这个经验也是我跑长任务时被坑出来的。4. 常见问题与排查技巧实录4.1 jupyter notebook安装报错subprocess-exited-with-error这个词条在热搜里出现了我猜是很多人尝试在conda环境里装jupyter或装扩展包时遇到的。subprocess-exited-with-error这串错误本质上是pip在安装某个包时触发底层编译或子进程执行但子进程以非零状态结束。常见原因有几个一是包版本和Python版本不兼容二是缺少Microsoft C Build Tools三是网络问题导致下载的包损坏。先说最简单有效的解法尽量不要自己去折腾pip install jupyter。ArcGIS Pro默认环境已经包含notebook模块直接打开分析选项卡就能用。如果你确实想要jupyterlab或者需要安装扩展包建议用Pro内置的“Python包管理器”它底层是conda能自动处理依赖关系比直接pip稳得多。如果你还是想用pip遇到报错时可以先加--no-cache-dir参数重试排除缓存导致的下载文件损坏问题python -m pip install jupyterlab --no-cache-dir如果还是不行就去看完整的错误日志注意看最后面有没有error: command gcc failed或者Microsoft Visual C 14.0 is required这类提示前者表示缺编译工具后者很明确就是缺C运行库。解决办法就是安装Visual C Build Tools我个人的经验是装好之后重启一下Pro和命令行工具基本能解决。4.2 notebook能打开但代码运行一直卡住不输出这个问题我碰到过不止一次。症状是点击运行cell之后In [*]一直显示但结果迟迟出不来代码看起来也没死循环。先排查是不是数据量太大。arcpy处理上百万条记录时SearchCursor逐行扫描确实需要时间但这通常不至于卡死。如果卡了很久多半是网络盘文件访问、或者图层坐标系操作时触发了几何网络计算这种场景我在Shapefile转GDB时遇到过几次。一个有效的排查技巧是在notebook里新建一个cell只跑print(1)看看内核是否还活着。如果print(1)瞬间有输出说明内核正常问题出在具体代码上如果连print(1)都没反应说明内核已经死了直接重启kernel吧。4.3 导入arcpy失败ModuleNotFoundError这也是新手最容易出现的错误。你在notebook里写import arcpy结果报错说找不到arcpy第一反应往往是“我装的Python有问题”。其实十有八九是用的Python环境不对。你当前notebook的kernel如果选的是baseAnaconda自带的那个环境那里面当然没有arcpy。解决办法是在notebook界面里点一下右上角的kernel名称确认当前内核是不是arcgispro-py3。如果你是命令行方式启动的jupyter一定要从Pro安装目录下的那个python.exe启动而不是系统盘里的Python。我自己长期用下来姿势是直接从Pro的“分析”选项卡打开notebook这样环境永远不会选错。如果非要命令行启动也要先激活环境这一步省不得省了后面全是坑。4.4 面积统计结果看起来不对坐标系问题前面的代码提到了面积单位受坐标系影响。这里单独展开说因为我见过不少人在这上面栽跟头。如果你的要素类存储坐标系是WGS84经纬度那么SHAPEAREA返回的面积单位是平方度不是平方米。平方度是一个随纬度变化很大的单位无法直接用来做面积统计。解决办法是在统计之前用arcpy.management.Project把数据投影到合适的投影坐标系。如果是全国范围的分析用Albers等积投影如果是省级或者市级用对应的高斯-克吕格投影更好。wgs84 arcpy.SpatialReference(4326) albers arcpy.SpatialReference(102025) # Asia North Albers Equal Area Conic fc_projected rC:\data\land_use_projected.gdb\land_parcels arcpy.management.Project(fc, fc_projected, albers)跑完投影后再用前面的统计代码面积数值才是一致可比的。这个步骤虽然多了一道工序但能保证后续不管是面积统计还是空间分析结果都站得住脚。5. 把notebook工程化的几个建议5.1 善用markdown cell把分析思路写下来很多人用notebook只写代码markdown cell基本不用。但我觉得这是最大的浪费。在每段分析前面用markdown写清楚这段代码的输入是什么、输出是什么、为什么这么做回头再来看的时候或者别人拿你的notebook去复现的时候都会轻松非常多。我自己的notebook通常长这样标题和日期、数据来源数据预处理思路每个步骤的代码块前面配上简单的说明最后的结论和备注这种做法在其他领域可能叫“可复现研究”放到GIS项目里同理非常实用。5.2 封装常用操作慢慢积累自己的工具库写多了你会发现很多代码是在重复的。比如读取GDB里的要素类、统计字段、批量导出图片这些操作每次写一遍语法很麻烦。我建议把常用功能封装成my_gis_tools.py放在固定的路径下notebook里每次只需要import sys sys.path.append(rC:\code\utils) import my_gis_tools as mgt mgt.area_stats(fc, [TYPE], unitkm2)这样即使用户换了新电脑、新项目代码依然能快速复用。这也是把零散的notebook脚本往“项目源码”方向沉淀的做法。5.3 一万次脚本运行后的提醒定期保存、导出备份notebook本身有自动保存功能但有一次Pro异常崩溃后我发现新建的cell内容没完全恢复丢失了一点分析记录。后来我每完成一阶段分析就主动用File - Export把notebook导出为.py文件或HTML备份一份。这样即使Pro出问题我的分析逻辑和代码都还在顶多重新跑一遍不至于从头再来。另外如果脚本里涉及重要的中间数据建议在开头就集中定义路径不要裸写一堆硬编码路径在代码里。好的习惯是RAW_DATA rC:\data\input GDB_PATH rC:\data\result.gdb TEMP_DIR rC:\data\temp需要改路径的时候只需要改一处方便维护也避免后面自己都忘了哪个文件是哪来的。6. 实操心得我踩过最深的三个坑你在代码里要注意上述内容已经写了不少最后说三个最实际的经验吧。第一个坑是环境变量冲突。去年我用的Pro还是2.9版本系统的Path变量里同时配了Anaconda的Python和Pro的Python结果命令行启动jupyter时经常加载错环境。折腾了半天最后是把Anaconda从Path里临时移除或者直接双击Pro安装目录下的python.exe进入交互模式才彻底绕开这个问题。如果你机器上也装了多套Python这一点千万要留意。第二个坑是字段名大小写和中文编码。notebook里输入要素类字段名时我建议直接用arcpy的ListFields提前打印一下真实字段名不要凭印象敲。尤其是从Excel转过来的数据字段名经常自动变成F1、F2不检查的话你后面所有代码都会跑偏。输出中文时要注意csv/txt的编码写文件时用encodingutf-8-sig而不是utf-8这样用Excel打开csv时中文才不会乱码这个细节我调试过多回才记住。第三个坑是长时间运行的notebook会内存膨胀。如果你在一个cell里反复创建大数据集的几何对象内存占用会一直涨。我建议处理完一批数据后主动把不需要的dataframe或大列表清掉用del变量名释放一下。虽然Python有自动垃圾回收但GIS数据的底层对象并不总是立刻释放跑批任务时你就知道这个习惯有多重要了。其实ArcGIS Pro里跑jupyter notebook并不神秘它就是一个有地图联动能力的Python交互环境。但正因为Pro把环境和工具都准备好了你反而更要知道背后的原理、路径和边界在哪里。拿这套环境跑通一个完整的小项目从数据读取到统计导出走一遍你就会发现很多以前要手工处理的流程现在几段代码就能搞定。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →