The goal of {arcgislayers}
is to provide an R interface to the ArcGIS
REST API.
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)
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...
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...
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 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).
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.
The package includes functions to publish data to an ArcGIS Portal:
add_item()
: Creates a new FeatureCollection from asf
ordata.frame
objectpublish_item()
: Publishes an existing FeatureLayerpublish_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.