使用Arcpy的替代方法


69

我似乎对几乎所有的python地理处理都使用ESRI的Arcpy站点软件包。值得ESRI赞扬的是,这些工具令人难以置信,可帮助您完成很多工作。但是,我也想在ESRI Arcpy域之外创建地理处理脚本。例如,如果我想将栅格裁剪为多边形,我将从ESRI的以下脚本开始:

# Import system modules
import arcpy
from arcpy import env
from arcpy.sa import *

# Set environment settings
env.workspace = "C:/sapyexamples/data"

# Set local variables
inRaster = "elevation"
inMaskData = "mask.shp"

# Check out the ArcGIS Spatial Analyst extension license
arcpy.CheckOutExtension("Spatial")

# Execute ExtractByMask
outExtractByMask = ExtractByMask(inRaster, inMaskData)

# Save the output 
outExtractByMask.save("C:/sapyexamples/output/extractmask")  

我不确定在没有Arcpy的情况下如何以编程方式完成相同的任务。我对认真的程序员提出的问题是: 您使用哪些python工具集合来完成ESRI用户使用Arcpy站点软件包可以完成的任务?我从哪开始呢?


Answers:


45

GDAL是要使用的工具。实际上,整个调用是gdal_rasterize的一行:

gdal_rasterize -l mask -i -burn -9999 mask.shp elevation.tif

如果您知道DEM的无数据值

对于一些python控件:

lyr = 'mask'
shp = 'mask.shp'
dem = 'elevation.tif'
ndv = -9999
p = os.Popen('gdal_rasterize -l %s -i -burn %d %s %s' % (lyr,ndv,shp,dem)

可以在python中设置变量的地方

对于完整的python:

from osgeo import gdal, ogr
from osgeo.gdalconst import *
shp = ogr.Open('mask.shp')
lyr = shp.GetLayer('mask')
dem = gdal.Open('elevation.tif', GA_Update)
ndv = dem.GetRasterBand(1).GetNoDataValue()
gdal.RasterizeLayer(dem, 1, lyr, None, ndv) # other options, such as transformer func, creation options...
dem = None

我只是快速浏览了C API的语法,所以我的python语法可能有点偏离。参见gdal_alg.h:http ://gdal.org/gdal__alg_8h.html




20

在我的大量学术研究中,我使用LiDAR数据进行地貌分析。我很快发现使用arcpy执行许多操作非常慢,尤其是在大型数据集上。结果,我开始使用:

  • pyshp操纵shapefile和更新属性表
  • numpy管理ASCII栅格并执行基于内核的分析(例如曲率计算)
  • scipy对结果进行统计分析并对曲面进行曲线拟合
  • matplotlib可以绘制图形和其他图形结果,例如用于快速可视化的基本地图

我还将向任何想学习更多有关分析栅格表面的人推荐《地球表面过程的定量建模》一书。本书附带了很棒的C ++代码示例,比ArcGIS工具更有效。这些算法也可以移植到Python,而不需要比numpy更复杂的方法,尽管它们在C ++中的运行速度更快。


16

对于使用ESRI的人,我认为GRASS将是一个非常相似的环境,具有GUI python环境,并组织在单独的“工具箱”中以完成不同的任务(栅格,矢量,太阳能工具箱等)。除了Python之外,脚本还有其他选项,但这就​​是我的用法。

一定要查看这个最新的出色链接(我相信):http : //grass.osgeo.org/wiki/GRASS_and_Python

编辑:针对那些在ESRI中有背景的人的另一个链接:http : //grass.osgeo.org/wiki/GRASS_migration_hints

我也赞成GDAL的动议。它是无价的,没有它我将迷失。


1
GRASS GIS 7中的新增功能:pyGRASS,请参见ing.unitn.it/~zambelli/projects/pygrass
markusN 2014年


16

我认为到目前为止给出的答案基本上涵盖了所有值得一提的软件包(尤其是GDAL,OGR,pyshp,NumPy)

但是,还有GIS和Python软件实验室,其中托管了两个有趣的模块。他们是:

  • Fiona:OGR的更整洁的API
  • Rtree:Python GIS的空间索引
  • Shapely:用于操纵和分析笛卡尔平面中的特征的Python软件包

我个人最近开始使用GDAL / OGR,发现它们在分析工具的速度和覆盖范围方面给人留下了深刻的印象。

这里的如何使用这些方法的一些例子(取自这个极好来源这是一个非常好的起点):

# To select by attribute:
.SetAttributeFilter("soil = 'clay'")

# To select by location, either:
.SetSpatialFilter(<geom>)   

# or
.SetSpatialFilterRect(<minx>, <miny>, <maxx>, <maxy>)

# DataSource objects have a method `ExecuteSQL(<SQL>)`
.ExecuteSQL("SELECT* FROM sites WHERE soil = 'clay' ORDER BY id DESC")


# Plus all the well known tools, like:

# intersect
poly2.Intersect(<geom_1>)

# disjoint?
<geom>.Disjoint(geom_1)

# touches (on the edge?)
<geom>.Touches(geom_1)

# cross each other?
<geom>.Crosses(geom_1)

# within?
<geom>.Within(geom_1)

#contains?
<geom>.Contains(ptB)

# overlaps?
<geom>.Overlaps(geom_1)

## geoprecessing
<geom>.Union(<geom_1>)
<geom>.Intersection(<geom_1>)
<geom>.Difference(<geom_1>)
<geom>.SymmetricDifference(<geom_1>)

# Buffer (returns a new geometry)
<geom>.Buffer(<distance>)

# Are the geometries equal?
<geom1>.Equal(<geom2>)

# Returns the shortest distance between the two geometries
<geom1>.Distance(<geom2>)

# Returns the geometry's extent as a list (minx, maxx, miny, maxy)
<geom>.GetEnvelope()

这些工具的好处是您在实现它们方面非常灵活。例如,我编写了自己的课程,CreateGeometry()以轻松地从头开始创建矢量文件。如果您有兴趣,我也可以在这里发布,即使我认为这超出了问题的范围。


10

我知道您的问题是以Python为中心的,但是R具有大量的价值统计分析方法,其中一些可用于空间分析。在这里@Whuber有一个很好的答案,说明了如何以两行将栅格剪辑到框。


6
要将其带回Python,可以使用RPy库RPy是R编程语言的非常简单但健壮的Python接口。它可以管理各种R对象,并可以执行任意R功能(包括图形功能)。R语言的所有错误都将转换为Python异常。可以从Python内部使用为R系统安装的任何模块。
RyanDalton 2012年

6

我的解决方案(快速解决方案)是将GDAL与Python结合使用。

你需要

导入子流程

命令=“ gdalwarp -of GTiff -cutline clipArea.shp -cl area_of_interest -crop_to_cutline inData.asc outData.tiff”

subprocess.call(['C:\ Temp \ abc \ Notepad.exe'])

(来自此处的答案:使用GDAL裁剪带有矢量图层的栅格

当然,您应该可以使用纯Python实现此目的,但是我不需要这样做。而且我几乎总是拥有GDAL!GDAL的灵活性非常好,尤其是在Linux环境中。它可以处理巨大的栅格,可以与Python或Shell脚本捆绑在一起,并且具有许多功能。有关基于矢量的工具,另请参见OGR。



3

我一直在研究一个名为WhiteboxTools的开源地理处理库,该库可在许多应用程序中代替ArcPy。当前计划有近300种工具可用于处理栅格,矢量和LiDAR(LAS)数据,尽管计划最终移植到Whitebox GAT中可用的全部400多种工具中。尽管这些工具是使用Rust编程语言开发的(为了提高效率),但是每个工具都可以从Python调用,如以下示例所示:

from whitebox_tools import WhiteboxTools

wbt = WhiteboxTools()

# Set the working directory. This is the path to the folder containing the data,
# i.e. files sent to tools as input/output parameters. You don't need to set
# the working directory if you specify full path names as tool parameters.
wbt.work_dir = "/path/to/data/"

# The most convenient way to run a tool is to use its associated method, e.g.:
wbt.elev_percentile("DEM.tif", "output.tif", 15, 15)

# You may also provide an optional custom callback for processing output from the
# tool. If you don't provide a callback, and verbose is set to True, tool output
# will simply be printed to the standard output.
def my_callback(value):
    if user_selected_cancel_btn: # Assumes a 'Cancel' button on a GUI
        print('Cancelling operation...')
        wbt.cancel_op = True
    else:
        print(value)

wbt.breach_depressions('DEM.flt', 'DEM_breached.flt', callback=my_callback)

# List all available tools in WhiteboxTools
print(wbt.list_tools())

# Lists tools with 'lidar' or 'LAS' in tool name or description.
print(wbt.list_tools(['lidar', 'LAS']))

# Print the help for a specific tool.
print(wbt.tool_help("ElevPercentile"))

# Want to read the source code for a tool?
# 'view_code' opens a browser and navigates to a tool's  
# source code in the WhiteboxTools GitHub repository
wbt.view_code('watershed')

可以在WhiteboxTools用户手册中找到更多详细信息。该库是独立的,没有任何其他依赖项。您只需要下载位于此处的小文件(<5Mb)。下载文件包含WhiteboxTools exe,whitebox_tools.py脚本和用户手册,该脚本提供了库的Python API(在上述脚本的顶行导入)。还有一个非常基本的tkinter GUI(wb_runner.py)与该库接口。

允许的MIT许可证旨在使WhiteboxTools作为后端与其他开源GIS集成;Alexander Bruy 为WhiteboxTools后端开发了一个QGIS插件。您也可以根据需要在单个脚本中混合使用WhiteboxTools和ArcPy中的工具。该库仍是实验性质的,是由Guelph大学的地貌和水文地质学研究小组开发的,并且当前是1.0之前的版本,使用时应考虑在内。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.