ArcREST
Ruby Gem wrapper around the ArcGIS REST API
Requirements
Ruby >= 3.3.3
Current Limitations
API FeatureServer query capabilities only at present.
Installation
Add this line to your application's Gemfile:
$ gem 'arcrest'
And then execute:
$ bundle
Or install it yourself as:
$ gem install arcrest
Usage
The API defines a resource heirarchy which includes a Catalog of Services (MapServer or FeatureServer). Services have one or more Layers and Layers have Features, which may be queried in various ways, including by spatial coordinates.
require 'arcrest'
catalog = ArcREST::Catalog.new 'https://sampleserver6.arcgisonline.com/arcgis/rest/services'
puts catalog.services
#=> {"name"=>"911CallsHotspot", "type"=>"GPServer"}
#=> {"name"=>"911CallsHotspot", "type"=>"MapServer"}
#=> {"name"=>"911CallsHotspotPro", "type"=>"GPServer"}
...
puts catalog.folders
#=> AGP
#=> Elevation
#=> Energy
...
It is also possible to pass a Referer (or any other) header which will be added to all HTTP requests:
catalog = ArcREST::Catalog.new('https://gojdippmaps.azurewebsites.net/proxy.ashx?https://maps.gov.je/arcgis/rest/services', headers: {referer: 'https://www.gov.je/'})
A Service (FeatureServer) is instantiated like this:
service = ArcREST::Service.new 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/FeatureServer'
puts service.layers
#=> {"id"=>2, "name"=>"Units", "parentLayerId"=>-1, "defaultVisibility"=>true, "subLayerIds"=>nil, "minScale"=>0, "maxScale"=>0, "type"=>"Feature Layer", "geometryType"=>"esriGeometryPoint"}
...
layer = ArcREST::Layer.new "#{service.url}/2"
puts layer.name
#=> Units
puts layer.type
#=> Feature Layer
puts layer.max_record_count
#=> 1000 # maximum number of features that can be queried, see below
puts layer.count
#=> 36 # count of the layer's features
puts layer.object_ids.inspect
#=> [420224, 420225, 420226, 420227, 420228, 420229.. ]
puts layer.fields
#=> {"name"=>"objectid", "type"=>"esriFieldTypeOID", "alias"=>"OBJECTID", "domain"=>nil, "editable"=>false, "nullable"=>false, "defaultValue"=>nil, "modelName"=>"OBJECTID"}
...
Catalog, Service and Layer have a json method which returns information from the relevant server as a Hash. In addition to the example methods above this can be parsed in the usual way - e.g:
puts layer.json.keys.inspect
#=> ["currentVersion", "cimVersion", "id", "name", "type", "parentLayer", "defaultVisibility", ... ]
Once you have a Layer object, you can perform queries on it. The documention shows the possibilities. Here is a very simple example:
The query method returns the whole server response as a Hash:
puts layer.query(where: '1=0').inspect
#=> {"objectIdFieldName"=>"objectid", "globalIdFieldName"=>"", "geometryType"=>"esriGeometryPoint", "spatialReference"=>{"wkid"=>4326, "latestWkid"=>4326}, "hasZ"=>false, "features"=>[]}
If you just want the features, use the features method:
features = layer.features
puts features.count
#=> 36
puts features[1]
#=> {"attributes"=>{"objectid"=>420225, "echelon"=>3, "reinforced"=>0, "combateffectiveness"=>nil, ... }
third_echelon = layer.features(where: "echelon=3", returnGeometry: false)
puts third_echelon.size
#=> 18
puts features.first['attributes']
#=> {"objectid"=>420224, "echelon"=>3, "reinforced"=>0, "combateffectiveness"=>nil, "higherformation"=>nil, ... }
query and features take an options hash of API call params. Invalid key values raise an error. Valid params for the server can be listed like this:
puts layer.valid_opts.inspect
#=> ["dbVersion", "distance", "geometry", "geometryPrecision", ... , "where"]
or by consulting the docs. One default is set: outFields: '*' - which requests data for all fields.
The :where key is used with any valid SQL to query the layer fields. The default is '1=1' which returns all records (up to the layer.max_record_count value, usually 1,000). An error is raised if the server gives a 400 error of this form:
{
"error": {
"code": 400,
"message": "Unable to complete operation.",
"details": [
"Unable to perform query operation.",
"Invalid query"
]
}
}
Specification & Tests
Full specification documentation is available by running the test suite thus:
$ bundle exec rake spec
Contributing
Bug reports and pull requests are welcome on GitHub at https://gitlab.com/matzfan/arcrest
License
The gem is available as open source under the terms of the MIT License.