File: ban_data_gouv_fr.rb

package info (click to toggle)
ruby-geocoder 1.5.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 732 kB
  • sloc: ruby: 6,173; makefile: 3
file content (257 lines) | stat: -rw-r--r-- 6,631 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# encoding: utf-8
require 'geocoder/results/base'

module Geocoder::Result
  class BanDataGouvFr < Base

    #### BASE METHODS ####

    def self.response_attributes
      %w[limit attribution version licence type features]
    end

    response_attributes.each do |a|
      unless method_defined?(a)
        define_method a do
          @data[a]
        end
      end
    end

    #### BEST RESULT ####

    def result
      features[0] if features.any?
    end

    #### GEOMETRY ####

    def geometry
      result['geometry'] if result
    end

    def precision
      geometry['type'] if geometry
    end

    def coordinates
      coords = geometry["coordinates"]
      return [coords[1].to_f, coords[0].to_f]
    end

    #### PROPERTIES ####

    # List of raw attrbutes returned by BAN data gouv fr API:
    #
    #   :id           =>    [string] UUID of the result, said to be not stable
    #                       atm, based on IGN reference (Institut national de
    #                       l'information géographique et forestière)
    #
    #   :type         =>    [string] result type (housenumber, street, city,
    #                       town, village, locality)
    #
    #   :score        =>    [float] value between 0 and 1 giving result's
    #                       relevancy
    #
    #   :housenumber  =>    [string] street number and extra information
    #                       (bis, ter, A, B)
    #
    #   :street       =>    [string] street name
    #
    #   :name         =>    [string] housenumber and street name
    #
    #   :postcode     =>    [string] city post code (used for mails by La Poste,
    #                       beware many cities got severeal postcodes)
    #
    #   :citycode     =>    [string] city code (INSEE reference,
    #                       consider it as a french institutional UUID)
    #
    #   :city         =>    [string] city name
    #
    #   :context      =>    [string] department code, department name and
    #                       region code
    #
    #   :label        =>    [string] full address without state, country name
    #                       and country code
    #
    # CITIES ONLY PROPERTIES
    #
    #   :adm_weight   =>    [string] administrative weight (importance) of
    #                       the city
    #
    #   :population   =>    [float] number of inhabitants with a 1000 factor
    #
    # For up to date doc (in french only) : https://adresse.data.gouv.fr/api/
    #
    def properties
      result['properties'] if result
    end

    # List of usable Geocoder results' methods
    #
    #   score                   =>    [float] result relevance 0 to 1
    #
    #   location_id             =>    [string] location's IGN UUID
    #
    #   result_type             =>    [string] housenumber / street / city
    #                                 / town / village / locality
    #
    #   international_address   =>    [string] full address with country code
    #
    #   national_address        =>    [string] full address with country code
    #
    #   street_address          =>    [string] housenumber + extra inf
    #                                 + street name
    #
    #   street_number           =>    [string] housenumber + extra inf
    #                                 (bis, ter, etc)
    #
    #   street_name             =>    [string] street's name
    #
    #   city_name               =>    [string] city's name
    #
    #   city_code               =>    [string] city's INSEE UUID
    #
    #   postal_code             =>    [string] city's postal code (used for mails)
    #
    #   context                 =>    [string] city's department code, department
    #                                  name and region name
    #
    #   demartment_name         =>    [string] city's department name
    #
    #   department_code         =>    [string] city's department INSEE UUID
    #
    #   region_name             =>    [string] city's region name
    #
    #   population              =>    [string] city's inhabitants count
    #
    #   administrative_weight   =>    [integer] city's importance on a scale
    #                                 from 6 (capital city) to 1 (regular village)
    #
    def score
      properties['score']
    end

    def location_id
      properties['id']
    end

    # Types
    #
    #   housenumber
    #   street
    #   city
    #   town
    #   village
    #   locality
    #
    def result_type
      properties['type']
    end

    def international_address
      "#{national_address}, #{country}"
    end

    def national_address
      properties['label']
    end

    def street_address
      properties['name']
    end

    def street_number
      properties['housenumber']
    end

    def street_name
      properties['street']
    end

    def city_name
      properties['city']
    end

    def city_code
      properties['citycode']
    end

    def postal_code
      properties['postcode']
    end

    def context
      properties['context'].split(/,/).map(&:strip)
    end

    def department_code
      context[0] if context.length > 0
    end

    # Monkey logic to handle fact Paris is both a city and a department
    # in Île-de-France region
    def department_name
      if context.length > 1
        if context[1] == "Île-de-France"
          "Paris"
        else
          context[1]
        end
      end
    end

    def region_name
      if context.length == 2 && context[1] == "Île-de-France"
        context[1]
      elsif context.length > 2
        context[2]
      end
    end

    def country
      "France"
    end

    # Country code types
    #    FR : France
    #    GF : Guyane Française
    #    RE : Réunion
    #    NC : Nouvelle-Calédonie
    #    GP : Guadeloupe
    #    MQ : Martinique
    #    MU : Maurice
    #    PF : Polynésie française
    #
    # Will need refacto to handle different country codes, but BAN API
    # is currently mainly designed for geocode FR country code addresses
    def country_code
      "FR"
    end

    #### ALIAS METHODS ####

    alias_method :address, :international_address
    alias_method :street, :street_name
    alias_method :city, :city_name
    alias_method :state, :region_name
    alias_method :state_code, :state

    #### CITIES' METHODS ####

    def population
      (properties['population'].to_f * 1000).to_i if city?(result_type)
    end

    def administrative_weight
      properties['adm_weight'].to_i if city?(result_type)
    end

    private

    def city?(result_type)
      %w(village town city).include?(result_type)
    end

  end
end