The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
The arcpy module provides classes and methods a variety of tasks, including manipulating geometries. These classes and methods can be accessed in R as well using functionality provided by the reticulate package.
This document demonstrates an example task where the geometry of polygons in a shapefile is shifted 5000 linear units in the y-direction and 2500 linear units in the x-direction. This contrived task demonstrates an approach to manipulating the arcobjects
class instances.
library(arcpy)
# set workspace
arcpy$env$workspace = tempdir()
arcpy$env$scratchWorkspace = tempdir()
# copy feature for example
fc = arcpy$management$CopyFeatures(system.file("CA_Counties",
"CA_Counties_TIGER2016.shp", package = "arcpy"), "CA_Counties")
# get the width and height of the layer
arcpy$Describe(fc)$extent$XMin
## [1] -13857275
arcpy$Describe(fc)$extent$YMin
## [1] 3832931
The reticulate package provides functions for manipulating python objects. These tools include iterators and the %as%
operator for aliasing. The code below uses %as%
to create an instance of the fc
layer, which we can use to iterate over the polygons.
# create iterable instance of the SHAPE@ objects in the layer
with(arcpy$da$UpdateCursor(fc, "SHAPE@") %as% rows, {
# move to first row
row = iter_next(rows)
# iterate over the features
while (!is.null(row)) {
# create an arcpy array for storing features
arr_feat = arcpy$Array()
# get the parts of the current feature
feat = row[[1]]$getPart()
# get the first part of the current feature
part = iter_next(feat)
# iterate over the parts of this feature
while (!is.null(part)) {
# create another arcpy array to store feature parts
arr_part = arcpy$Array()
# get the first point of this part
pnt = iter_next(part)
# iterate over the points in this part
while (!is.null(pnt)) {
# get the point X coordinate and subtract 5000
x = pnt$X + 2500
# get the point Y coordinate and add 5000
y = pnt$Y + 5000
# create a new point
arr_part$add(arcpy$Point(x, y))
# iterate to next point
pnt = iter_next(part)
}
# add the modified part to the feature array
arr_feat$add(arr_part)
# iterate to next part
part = iter_next(feat)
}
# create a new polygon from the feature array
polygon = arcpy$Polygon(arr_feat)
# overwrite the original polygon with the new polygon
row[[1]] = polygon
# update the cursor
rows$updateRow(row)
# iterate to next feature
row = iter_next(rows)
}
})
# recalculate the width and height of the layer
arcpy$management$RecalculateFeatureClassExtent(paste(fc))
arcpy$Describe(fc)$extent$XMin
arcpy$Describe(fc)$extent$YMin
## <Result ''>
## [1] -13854775
## [1] 3837931
It's also possible to mix and match iterators and R functions, often with significantly faster results. Here's an alternative approach that makes judicious use of reticulate's iterate()
function in combination with lapply()
and the da_read()
and da_update()
functions:
translate_geom = function(g, dx, dy) {
arr_feat = arcpy$Array()
feat = g$getPart()
parts = iterate(feat, function(part) {
arr_part = arcpy$Array()
pnts = iterate(part, function(pnt) {
x = pnt$X + dx
y = pnt$Y + dy
arcpy$Point(x, y)
})
lapply(pnts, function(part) arr_part$add(part))
arr_part
})
lapply(parts, function(feat) arr_feat$add(feat))
arcpy$Polygon(arr_feat)
}
fc.d = da_read(fc, "SHAPE@")
fc.d[["SHAPE@"]] = lapply(fc.d[["SHAPE@"]][1], translate_geom,
dx = 2500, dy = 5000)
da_update(fc, fc.d)
arcpy$management$RecalculateFeatureClassExtent(fc)
arcpy$Describe(fc)$extent$XMin
arcpy$Describe(fc)$extent$YMin
## <Result ''>
## [1] -13471139
## [1] 4787916
Handling python objects can be challenging in some cases, but reticulate
provides virtually all the tools needed to manipulate arcpy classes.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.