File: esri.rb

package info (click to toggle)
ruby-geocoder 1.8.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 900 kB
  • sloc: ruby: 8,419; makefile: 3
file content (114 lines) | stat: -rw-r--r-- 3,355 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
require 'geocoder/lookups/base'
require "geocoder/results/esri"
require 'geocoder/esri_token'

module Geocoder::Lookup
  class Esri < Base

    def name
      "Esri"
    end

      def supported_protocols
        [:https]
      end

    private # ---------------------------------------------------------------

    def base_query_url(query)
      action = query.reverse_geocode? ? "reverseGeocode" : "find"
      "#{protocol}://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/#{action}?"
    end

    def results(query)
      return [] unless doc = fetch_data(query)

      if (doc['error'].nil?)
        if (!query.reverse_geocode?)
          return [] if !doc['locations'] || doc['locations'].empty?
        end
        return [ doc ]
      else
        case [ doc['error']['code'] ]
        when [498]
          raise_error(Geocoder::InvalidApiKey, doc['error']['message']) ||
            Geocoder.log(:warn, "#{self.name} Geocoding API error: #{doc['error']['message']}")
        when [ 403 ]
          raise_error(Geocoder::RequestDenied, 'ESRI request denied') ||
            Geocoder.log(:warn, "#{self.name} ESRI request denied: #{doc['error']['message']}")
        when [ 500 ], [501]
          raise_error(Geocoder::ServiceUnavailable, 'ESRI service unavailable') ||
            Geocoder.log(:warn, "#{self.name} ESRI service error: #{doc['error']['message']}")
        else
          raise_error(Geocoder::Error, doc['error']['message']) ||
            Geocoder.log(:warn, "#{self.name} Geocoding error: #{doc['error']['message']}")
        end
      end
      return []
    end

    def query_url_params(query)
      params = {
        :f => "pjson",
        :outFields => "*"
      }
      if query.reverse_geocode?
        params[:location] = query.coordinates.reverse.join(',')
      else
        params[:text] = query.sanitized_text
      end

      params[:token] = token(query)

      if for_storage_value = for_storage(query)
        params[:forStorage] = for_storage_value
      end
      params[:sourceCountry] = configuration[:source_country] if configuration[:source_country]
      params[:preferredLabelValues] = configuration[:preferred_label_values] if configuration[:preferred_label_values]

      params.merge(super)
    end

    def for_storage(query)
      if query.options.has_key?(:for_storage)
        query.options[:for_storage]
      else
        configuration[:for_storage]
      end
    end

    def token(query)
      token_instance = if query.options[:token]
                         query.options[:token]
                       else
                         configuration[:token]
                       end

      if !valid_token_configured?(token_instance) && configuration.api_key
        token_instance = create_and_save_token!(query)
      end

      token_instance.to_s unless token_instance.nil?
    end

    def valid_token_configured?(token_instance)
      !token_instance.nil? && token_instance.active?
    end

    def create_and_save_token!(query)
      token_instance = create_token

      if query.options[:token]
        query.options[:token] = token_instance
      else
        Geocoder.merge_into_lookup_config(:esri, token: token_instance)
      end

      token_instance
    end

    def create_token
      Geocoder::EsriToken.generate_token(*configuration.api_key)
    end
  end
end