Gem Version Ruby Style Guide

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.