The goal of arcgislayers is to provide an R interface to the ArcGIS REST API.
Installation
It is recommend you install and use the metapackage {arcgis}
. You can install the development version of arcgis like so:
remotes::install_github("r-arcgis/arcgis", dependencies = TRUE)
Usage
Creating a simple feature object from an ArcGIS FeatureLayer
library(arcgis)
#> Attaching core arcgis packages:
#> → arcgisutils v0.3.0
#> → arcgislayers v0.3.0
#> → arcgisgeocode v0.1.3
#> → arcgisplaces v0.1.0
arc_open()
takes a URL to create a reference to a remote ArcGIS layer, server, or table. The function can return any of the following classes (corresponding to different ArcGIS service types):
FeatureLayer
Table
FeatureServer
ImageServer
MapServer
GroupLayer
For example, you can create a FeatureLayer
object based on a Feature Server URL:
furl <- "https://services.arcgis.com/P3ePLMYs2RVChkJx/ArcGIS/rest/services/USA_Counties_Generalized_Boundaries/FeatureServer/0"
county_fl <- arc_open(furl)
county_fl
#> <FeatureLayer>
#> Name: USA Counties - Generalized
#> Geometry Type: esriGeometryPolygon
#> CRS: 4326
#> Capabilities: Query,Extract
You can then use arc_select()
to query the feature layer object and return an sf
object.
If no arguments are provided to arc_select()
the entire feature layer is returned in memory as an sf
object.
arc_select(county_fl)
#> Simple feature collection with 3143 features and 12 fields
#> Geometry type: POLYGON
#> Dimension: XY
#> Bounding box: xmin: -178.2176 ymin: 18.92179 xmax: -66.96927 ymax: 71.40624
#> Geodetic CRS: WGS 84
#> First 10 features:
#> OBJECTID NAME STATE_NAME STATE_FIPS FIPS SQMI
#> 1 1 Autauga County Alabama 01 01001 604.37
#> 2 2 Baldwin County Alabama 01 01003 1633.14
#> 3 3 Barbour County Alabama 01 01005 904.52
#> 4 4 Bibb County Alabama 01 01007 626.17
#> 5 5 Blount County Alabama 01 01009 650.63
#> 6 6 Bullock County Alabama 01 01011 625.14
#> 7 7 Butler County Alabama 01 01013 777.88
#> 8 8 Calhoun County Alabama 01 01015 612.27
#> 9 9 Chambers County Alabama 01 01017 603.11
#> 10 10 Cherokee County Alabama 01 01019 599.98
#> POPULATION POP_SQMI STATE_ABBR COUNTY_FIPS Shape__Area
#> 1 1970-01-01 11:20:05 97.3 AL 001 0.1489034
#> 2 1970-01-03 11:22:47 141.9 AL 003 0.4044891
#> 3 1970-01-01 02:00:23 27.9 AL 005 0.2224307
#> 4 1970-01-01 01:11:33 35.6 AL 007 0.1577359
#> 5 1970-01-01 11:25:34 90.9 AL 009 0.1675296
#> 6 1969-12-31 21:52:37 16.6 AL 011 0.1557273
#> 7 1970-01-01 00:17:31 24.5 AL 013 0.1927305
#> 8 1970-01-02 03:20:41 190.2 AL 015 0.1523369
#> 9 1970-01-01 04:39:32 57.7 AL 017 0.1531136
#> 10 1970-01-01 01:56:11 41.6 AL 019 0.1527217
#> Shape__Length geometry
#> 1 1.884137 POLYGON ((-86.82067 32.3473...
#> 2 3.678276 POLYGON ((-87.97309 31.1648...
#> 3 2.218514 POLYGON ((-85.74337 31.6262...
#> 4 1.852453 POLYGON ((-87.41986 33.0117...
#> 5 2.067456 POLYGON ((-86.96799 33.8604...
#> 6 2.006250 POLYGON ((-85.4114 32.15551...
#> 7 1.769462 POLYGON ((-86.44912 31.9712...
#> 8 2.149825 POLYGON ((-85.79353 33.5634...
#> 9 1.637226 POLYGON ((-85.58963 32.7313...
#> 10 1.794142 POLYGON ((-85.41657 34.0869...
Filtering using where
or filter_geom
arguments
You can also use the fields
argument to select columns or the where
argument to subset rows.
For example, using a character vector of column names for fields
and a simple SQL where clause for where
you can select counties with population greater than 1,000,000:
arc_select(
county_fl,
fields = c("state_abbr", "population"),
where = "population > 1000000"
)
#> Simple feature collection with 49 features and 2 fields
#> Geometry type: POLYGON
#> Dimension: XY
#> Bounding box: xmin: -158.2674 ymin: 21.24986 xmax: -71.02671 ymax: 47.77552
#> Geodetic CRS: WGS 84
#> First 10 features:
#> STATE_ABBR POPULATION geometry
#> 1 AZ 1970-02-20 22:56:08 POLYGON ((-111.0425 33.4759...
#> 2 AZ 1970-01-12 20:50:33 POLYGON ((-110.4522 31.7360...
#> 3 CA 1970-01-20 06:19:13 POLYGON ((-121.4721 37.4777...
#> 4 CA 1970-01-14 06:52:07 POLYGON ((-122.3076 37.8917...
#> 5 CA 1970-01-12 11:10:54 POLYGON ((-120.6636 36.2787...
#> 6 CA 1970-04-26 17:40:09 POLYGON ((-118.1067 33.7475...
#> 7 CA 1970-02-06 16:16:29 POLYGON ((-117.509 33.50848...
#> 8 CA 1970-01-28 18:43:05 POLYGON ((-116.0824 33.4258...
#> 9 CA 1970-01-19 03:17:35 POLYGON ((-121.6652 38.1692...
#> 10 CA 1970-01-26 01:00:54 POLYGON ((-117.7832 33.9507...
For FeatureLayer
and Table
objects, and sometimes ImageServer
s, the list_fields()
function can be helpful to check available attributes and build a where
query:
list_fields(county_fl)
#> name type alias sqlType
#> 1 OBJECTID esriFieldTypeOID OBJECTID sqlTypeOther
#> 2 NAME esriFieldTypeString Name sqlTypeOther
#> 3 STATE_NAME esriFieldTypeString State Name sqlTypeOther
#> 4 STATE_FIPS esriFieldTypeString State FIPS sqlTypeOther
#> 5 FIPS esriFieldTypeString FIPS sqlTypeOther
#> 6 SQMI esriFieldTypeDouble Area in square miles sqlTypeOther
#> 7 POPULATION esriFieldTypeInteger 2020 Total Population sqlTypeOther
#> 8 POP_SQMI esriFieldTypeDouble People per square mile sqlTypeOther
#> 9 STATE_ABBR esriFieldTypeString State Abbreviation sqlTypeOther
#> 10 COUNTY_FIPS esriFieldTypeString County FIPS sqlTypeOther
#> 11 Shape__Area esriFieldTypeDouble Shape__Area sqlTypeDouble
#> 12 Shape__Length esriFieldTypeDouble Shape__Length sqlTypeDouble
#> nullable editable domain defaultValue length
#> 1 FALSE FALSE NA NA NA
#> 2 TRUE TRUE NA NA 50
#> 3 TRUE TRUE NA NA 20
#> 4 TRUE TRUE NA NA 2
#> 5 TRUE TRUE NA NA 5
#> 6 TRUE TRUE NA NA NA
#> 7 TRUE TRUE NA NA NA
#> 8 TRUE TRUE NA NA NA
#> 9 TRUE TRUE NA NA 2
#> 10 TRUE TRUE NA NA 3
#> 11 TRUE FALSE NA NA NA
#> 12 TRUE FALSE NA NA NA
#> description
#> 1 <NA>
#> 2 {"value":"The name of the county.","fieldValueType":"nameOrTitle"}
#> 3 {"value":"The name for the state in which the county is located.","fieldValueType":"nameOrTitle"}
#> 4 {"value":"The code (two-digit number) for the state in which the county is located.","fieldValueType":"uniqueIdentifier"}
#> 5 {"value":"The combined state and county codes. County codes begin with 001 for each state; use the combined code (five-digit number) to uniquely identify a county in the country.","fieldValueType":"uniqueIdentifier"}
#> 6 {"value":"The area of the county in square miles using the North America Albers Equal Area Conic projection.","fieldValueType":"measurement"}
#> 7 {"value":"The 2020 population of the county.","fieldValueType":"countOrAmount"}
#> 8 {"value":"The 2020 population of the county per square mile.","fieldValueType":"measurement"}
#> 9 {"value":"The two-letter abbreviation for the state in which the county is located.","fieldValueType":"uniqueIdentifier"}
#> 10 {"value":"The code (three-digit number) for the county.","fieldValueType":"uniqueIdentifier"}
#> 11 <NA>
#> 12 <NA>
You can also provide a bbox
, sfc
, or sfg
object to the filter_geom
argument to perform a spatial filter. If the sfc
object contains more than one geometry, the object is combined with sf::st_union()
. See documentation for more (?arc_select
).
nc <- sf::st_read(system.file("shape/nc.shp", package="sf"))
#> Reading layer `nc' from data source
#> `/Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/library/sf/shape/nc.shp'
#> using driver `ESRI Shapefile'
#> Simple feature collection with 100 features and 14 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS: NAD27
arc_select(
county_fl,
filter_geom = sf::st_bbox(nc[1,])
)
#> Simple feature collection with 6 features and 12 fields
#> Geometry type: POLYGON
#> Dimension: XY
#> Bounding box: xmin: -82.0477 ymin: 35.98946 xmax: -80.83795 ymax: 36.80746
#> Geodetic CRS: WGS 84
#> OBJECTID NAME STATE_NAME STATE_FIPS FIPS SQMI
#> 1 1890 Alleghany County North Carolina 37 37005 236.26
#> 2 1892 Ashe County North Carolina 37 37009 429.38
#> 3 1982 Watauga County North Carolina 37 37189 313.32
#> 4 1984 Wilkes County North Carolina 37 37193 756.33
#> 5 2471 Johnson County Tennessee 47 47091 302.69
#> 6 2855 Grayson County Virginia 51 51077 445.57
#> POPULATION POP_SQMI STATE_ABBR COUNTY_FIPS Shape__Area Shape__Length
#> 1 1969-12-31 22:01:28 46.1 NC 005 0.06140165 1.231232
#> 2 1970-01-01 02:22:57 61.9 NC 009 0.11428581 1.442112
#> 3 1970-01-01 10:01:26 172.6 NC 189 0.08142272 1.287674
#> 4 1970-01-01 13:19:29 87.2 NC 193 0.19911944 1.984232
#> 5 1969-12-31 23:59:08 59.3 TN 091 0.07960385 1.290607
#> 6 1969-12-31 23:15:33 34.4 VA 077 0.11578917 1.945424
#> geometry
#> 1 POLYGON ((-81.2397 36.36549...
#> 2 POLYGON ((-81.47258 36.2344...
#> 3 POLYGON ((-81.80605 36.1046...
#> 4 POLYGON ((-81.02037 36.0350...
#> 5 POLYGON ((-81.74091 36.3919...
#> 6 POLYGON ((-81.34512 36.5729...
Creating a SpatRaster
from an ArcGIS ImageServer
A SpatRaster
object from the terra package can be extracted from an ImageServer
using arc_raster()
.
arc_raster()
will extract the area defined by xmin
, ymin
, xmax
, and ymax
. You can optionally specify the width
and height
of the resultant image. Use format
to define what type of image is returned.
img_url <- "https://landsat2.arcgis.com/arcgis/rest/services/Landsat/MS/ImageServer"
landsat <- arc_open(img_url)
res <- arc_raster(
landsat,
xmin = -71, ymin = 43,
xmax = -67, ymax = 47.5,
bbox_crs = 4326,
width = 500, height = 500
)
terra::plotRGB(res, 4, 3, 2, scale = max(landsat[["maxValues"]]))
Authorization and publication
Authorization is not required for reading any public data sources.
Workflows that require authorization include:
- interacting with non-public services,
- publishing a new service (the authorized user must also have publishing privileges), and
- modifying or deleting any existing service (the authorized user must also have edit access to the service).
Accessing non-public data
The same functions for reading public ArcGIS Online and Enterprise services (such as arc_open()
,arc_read()
,arc_select()
,arc_raster()
, etc.) can be used to read data from non-public services by using the token
argument. For more information on tokens and authorization functions, see the authorization article.
Publishing and modifying services from R
The package includes functions to publish data to an ArcGIS Portal:
-
add_item()
: Creates a new FeatureCollection from asf
ordata.frame
object -
publish_item()
: Publishes an existing FeatureLayer -
publish_layer()
: is a higher level wrapper around bothadd_item()
andpublish_item()
There are also functions to add or modify data including add_features()
, update_features()
, and delete_features()
. For a more detailed guide to adding, updating, and deleting features, view the tutorial on the R-ArcGIS Bridge website.
These functions all require authorization since data cannot be published or modified anonymously in ArcGIS Online and ArcGIS Enterprise.