adressevaelger 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 39ce3fca5b50b066546e6325522fb11677182fc4cf9a766a6baa138c937e0860
4
+ data.tar.gz: d01d7d4289c3a52997c744bade5d6c094f398b52547a7135964c06d87774dcc8
5
+ SHA512:
6
+ metadata.gz: 362d1a947156be0ecf9f8914596388136382e30748fd62289e13eaf05a836584092a9abd70bc86f9bb37a065451699e4ca310c8a0441f7fddcfdefc8d4528226
7
+ data.tar.gz: 875591926ea41fcfb4ada343652cd567c47a4d43e668f994e853318278a6641196daaececc21921c585fc23dbff357732139d98f6ff44d5d27931acb0c79975f
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Initial public release: Adressevælger client (`autocomplete` / `search`),
6
+ resolve by husnummer or adresse id, Adressevask `validate` / `vask`, and
7
+ optional ETRS89→WGS84 via soft-required `rgeo-proj4`.
8
+ - VCR cassettes for husnummer search and resolve (tokens redacted).
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rasmus Bergholdt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # Adressevaelger
2
+
3
+ Ruby client for Klimadatastyrelsen **Adressevælger** and **Adressevask**
4
+ (Danmarks Adresseregister / DAR). Denmark only — no multi-country router,
5
+ manual entry adapter, or commercial geocoder fallback.
6
+
7
+ ## Install
8
+
9
+ ```ruby
10
+ # Gemfile
11
+ gem "adressevaelger"
12
+
13
+ # Optional: fill ResolvedAddress#latitude / #longitude from ETRS89
14
+ gem "rgeo-proj4"
15
+ ```
16
+
17
+ ```sh
18
+ bundle add adressevaelger
19
+ # or: gem install adressevaelger
20
+ ```
21
+
22
+ Requires Ruby 3.3+. No Rails dependency.
23
+
24
+ ## Usage
25
+
26
+ ```ruby
27
+ require "adressevaelger"
28
+
29
+ client = Adressevaelger::Client.new(
30
+ token: ENV.fetch("ADRESSEVAELGER_TOKEN") # or rely on demo default locally
31
+ )
32
+
33
+ # Autocomplete / search (min 3 characters)
34
+ suggestions = client.autocomplete("Vestergade 1")
35
+ suggestions.first.id # => DAR husnummer id
36
+ suggestions.first.label # => "Vestergade 1, 1456 København K"
37
+
38
+ # Resolve husnummer or adresse by id
39
+ resolved = client.resolve(id: suggestions.first.id, type: "husnummer")
40
+ resolved.line1 # => "Vestergade 1"
41
+ resolved.postal_code # => "1456"
42
+ resolved.coord_easting # => ETRS89/UTM32N
43
+ resolved.latitude # => WGS84 if rgeo-proj4 is installed, else nil
44
+
45
+ # Adressevask (free-text wash)
46
+ washed = client.validate("vestergade 1 københavn")
47
+ # alias: client.vask(...)
48
+ ```
49
+
50
+ Environment variables:
51
+
52
+ | Variable | Purpose |
53
+ | --- | --- |
54
+ | `ADRESSEVAELGER_TOKEN` | API token (preferred over the demo default) |
55
+ | `ADRESSEVAELGER_BASE_URL` | Override host (default `https://adressevaelger.dk`) |
56
+
57
+ ## Optional ETRS89 → WGS84
58
+
59
+ `Adressevaelger::Etrs89ToWgs84` soft-requires [`rgeo-proj4`](https://github.com/rgeo/rgeo-proj4).
60
+ If PROJ is unavailable, `resolve` still returns ETRS89 easting/northing and leaves
61
+ WGS84 latitude/longitude `nil`.
62
+
63
+ ```ruby
64
+ Adressevaelger::Etrs89ToWgs84.available? # => true/false
65
+ lat, lon = Adressevaelger::Etrs89ToWgs84.call(easting: 724_533.07, northing: 6_176_026.84)
66
+ ```
67
+
68
+ ## Token notes
69
+
70
+ The Adressevælger HTTP API requires a `token` query parameter. Until Brugerstyring
71
+ lands, Klimadatastyrelsen documents a shared demo token for exploration. The gem
72
+ falls back to that demo token when none is configured — **do not rely on it in
73
+ production**. Obtain a proper token via [Dataforsyningen](https://dataforsyningen.dk/).
74
+
75
+ ## Testing
76
+
77
+ ```sh
78
+ bundle exec rake test
79
+ ```
80
+
81
+ HTTP integration tests use [VCR](https://github.com/vcr/vcr) cassettes recorded
82
+ against the real API (tokens redacted). CI uses `record: :none` (fail-closed).
83
+ To refresh cassettes locally:
84
+
85
+ ```sh
86
+ VCR_RECORD=all bundle exec rake test TEST=test/client_vcr_test.rb
87
+ ```
88
+
89
+ Never hand-write cassette response bodies.
90
+
91
+ ## Scope
92
+
93
+ **In:** Adressevælger search/autocomplete, resolve by husnummer/adresse id,
94
+ Adressevask validate, optional PROJ transform.
95
+
96
+ **Out:** Multi-country routing, Manual adapters, commercial fallback geocoders,
97
+ Rails controllers/Stimulus, CRM persistence helpers.
98
+
99
+ ## Attribution
100
+
101
+ Address data via [Dataforsyningen](https://dataforsyningen.dk/) /
102
+ Klimadatastyrelsen Adressevælger and Adressevask. This gem is an independent
103
+ open-source client and is not affiliated with or endorsed by Klimadatastyrelsen.
104
+
105
+ ## Releasing
106
+
107
+ Version bumps are intentional — CI does not auto-bump on every `main` push.
108
+
109
+ 1. Bump `Adressevaelger::VERSION` in `lib/adressevaelger/version.rb` (gemspec reads it).
110
+ 2. Update `CHANGELOG.md` for that version.
111
+ 3. Commit and push to `main`.
112
+ 4. Tag and push: `git tag vX.Y.Z && git push origin vX.Y.Z`
113
+ (or create a GitHub Release for `vX.Y.Z` — that also pushes the tag).
114
+ 5. Tag **must** match the gem version (`v0.1.0` ↔ `0.1.0`). The
115
+ [push_gem](.github/workflows/push_gem.yml) workflow verifies this, then
116
+ publishes via [RubyGems Trusted Publishing](https://guides.rubygems.org/trusted-publishing/)
117
+ (`rubygems/release-gem`, OIDC — no `RUBYGEMS_API_KEY` secret).
118
+
119
+ ### One-time RubyGems Trusted Publisher setup
120
+
121
+ The gem is not on RubyGems yet, so use a **pending** trusted publisher
122
+ (Rasmus must click through the UI; no credentials belong in this repo):
123
+
124
+ 1. Sign in at [rubygems.org](https://rubygems.org/) (MFA on).
125
+ 2. Open [Pending trusted publishers](https://rubygems.org/profile/oidc/pending_trusted_publishers).
126
+ 3. Click **Create**.
127
+ 4. Fill in:
128
+ - **Gem name:** `adressevaelger`
129
+ - **Repository owner:** `bergholdt`
130
+ - **Repository name:** `adressevaelger`
131
+ - **Workflow filename:** `push_gem.yml`
132
+ - **Environment name:** `release`
133
+ 5. Click **Create Pending trusted publisher**.
134
+ 6. In GitHub → repo **Settings → Environments**, create an environment named
135
+ `release` (no required reviewers needed for a solo maintainer).
136
+
137
+ After the first successful tag-triggered publish, the pending publisher becomes
138
+ a normal trusted publisher and you own the gem on RubyGems.org.
139
+
140
+ ## License
141
+
142
+ MIT. See [LICENSE.txt](LICENSE.txt).
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/adressevaelger/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "adressevaelger"
7
+ spec.version = Adressevaelger::VERSION
8
+ spec.authors = ["Rasmus Bergholdt"]
9
+ spec.email = ["rasmus.bergholdt@gmail.com"]
10
+
11
+ spec.summary = "Ruby client for Klimadatastyrelsen Adressevælger and Adressevask (DAR)."
12
+ spec.description = <<~DESC
13
+ HTTP client for the Danish Adressevælger autocomplete/search and Adressevask
14
+ address-wash APIs (Danmarks Adresseregister / DAR), with an optional
15
+ ETRS89/UTM32N → WGS84 helper via PROJ.
16
+ DESC
17
+ spec.homepage = "https://github.com/bergholdt/adressevaelger"
18
+ spec.license = "MIT"
19
+ spec.required_ruby_version = ">= 3.3.0"
20
+
21
+ spec.metadata["homepage_uri"] = spec.homepage
22
+ spec.metadata["source_code_uri"] = "https://github.com/bergholdt/adressevaelger/tree/v#{spec.version}"
23
+ spec.metadata["changelog_uri"] = "https://github.com/bergholdt/adressevaelger/blob/v#{spec.version}/CHANGELOG.md"
24
+ spec.metadata["bug_tracker_uri"] = "https://github.com/bergholdt/adressevaelger/issues"
25
+ spec.metadata["rubygems_mfa_required"] = "true"
26
+
27
+ spec.files = Dir.chdir(__dir__) do
28
+ `git ls-files -z`.split("\x0").reject do |f|
29
+ f.start_with?(*%w[bin/ test/ .git .github Gemfile Rakefile])
30
+ end
31
+ end
32
+ spec.require_paths = ["lib"]
33
+ end
@@ -0,0 +1,223 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+ require "uri"
6
+
7
+ require_relative "suggestion"
8
+ require_relative "resolved_address"
9
+
10
+ module Adressevaelger
11
+ # HTTP client for Klimadatastyrelsen Adressevælger (+ Adressevask).
12
+ #
13
+ # Official host is adressevaelger.dk (api.adressevaelger.dk does not resolve).
14
+ class Client
15
+ # Token is required by the API. Until Brugerstyring lands, KDS recommends
16
+ # this shared demo token for exploration — replace it in production.
17
+ DEFAULT_TOKEN = "adressevaelger123"
18
+ DEFAULT_BASE_URL = "https://adressevaelger.dk"
19
+ EPSG = 25832
20
+
21
+ attr_reader :base_url, :token
22
+
23
+ def initialize(token: nil, base_url: nil, http: nil)
24
+ @token = present_string(token) || present_string(ENV["ADRESSEVAELGER_TOKEN"]) || DEFAULT_TOKEN
25
+ @base_url = present_string(base_url) || present_string(ENV["ADRESSEVAELGER_BASE_URL"]) || DEFAULT_BASE_URL
26
+ @http = http
27
+ end
28
+
29
+ # Autocomplete husnumre by free-text query (min 3 characters).
30
+ def autocomplete(query)
31
+ return [] if blank?(query) || query.to_s.length < 3
32
+
33
+ payload = get_json("/husnumre/soeg", tekst: query)
34
+ Array(payload["fund"]).filter_map do |fund|
35
+ next unless present?(fund["id"]) && present?(fund["titel"])
36
+
37
+ Suggestion.from_fund(fund)
38
+ end
39
+ end
40
+
41
+ # Alias used by callers that think in "search" terms.
42
+ alias search autocomplete
43
+
44
+ # Resolve a husnummer or adresse by DAR id.
45
+ def resolve(id:, type: "husnummer")
46
+ path = case type.to_s
47
+ when "adresse" then "/adresser/#{id}"
48
+ else "/husnumre/#{id}"
49
+ end
50
+
51
+ payload = get_json(path)
52
+ build_resolved(payload, type: type.to_s)
53
+ end
54
+
55
+ # Wash / validate a free-text address via Adressevask (`/vask/`).
56
+ def validate(text)
57
+ return [] if blank?(text)
58
+
59
+ payload = get_json("/vask/", adresse: text)
60
+ results = Array(payload["resultater"] || payload["fund"] || payload["adresser"])
61
+ results.filter_map do |row|
62
+ id = row["adresse_id_lokalid"] || row["id"] || dig_hash(row, "adresse", "id")
63
+ label = row["betegnelse"] || row["titel"] || row["adressebetegnelse"]
64
+ next if blank?(id) || blank?(label)
65
+
66
+ Suggestion.new(
67
+ id: id,
68
+ type: present_string(row["type"]) || "adresse",
69
+ label: label,
70
+ provider: Adressevaelger::PROVIDER
71
+ )
72
+ end
73
+ end
74
+
75
+ # Alias matching the Adressevask product name.
76
+ alias vask validate
77
+
78
+ private
79
+
80
+ attr_reader :http
81
+
82
+ def build_resolved(payload, type:)
83
+ data = nested_entity(payload)
84
+ vejnavn = scalar(pick(data, "vejnavn")) || dig_hash(data, "vejstykke", "navn") || dig_hash(data, "navngivenvej", "vejnavn")
85
+ husnr = scalar(pick(data, "husnr", "husnummertekst", "husnummer"))
86
+ postal = scalar(pick(data, "postnr")) || dig_hash(data, "postnummer", "postnr") || dig_hash(data, "postnummer", "nr")
87
+ city = scalar(pick(data, "postnrnavn", "bynavn")) || dig_hash(data, "postnummer", "navn")
88
+ etage = scalar(pick(data, "etagebetegnelse", "etage"))
89
+ doer = scalar(pick(data, "doerbetegnelse", "dør", "doer"))
90
+
91
+ point = data["adgangspunkt"] || dig_hash(data, "adgangsadresse", "adgangspunkt") || data["position"]
92
+ easting, northing = extract_etrs89(point)
93
+ latitude, longitude = transform_etrs89(easting, northing)
94
+
95
+ id = pick(data, "id", "id_lokalid")
96
+ husnummer_id = pick(data, "husnummer_id", "adgangsadresseid") || (type == "husnummer" ? id : nil)
97
+ adresse_id = type == "adresse" ? id : pick(data, "adresse_id")
98
+
99
+ ResolvedAddress.new(
100
+ line1: [vejnavn, husnr].compact.reject { |part| blank?(part) }.join(" "),
101
+ line2: nil,
102
+ postal_code: postal.to_s,
103
+ city: city.to_s,
104
+ country: "DK",
105
+ etage: etage,
106
+ doer: doer,
107
+ address_provider: Adressevaelger::PROVIDER,
108
+ external_address_id: adresse_id || husnummer_id,
109
+ external_building_id: husnummer_id,
110
+ latitude: latitude,
111
+ longitude: longitude,
112
+ coord_easting: easting,
113
+ coord_northing: northing,
114
+ coord_epsg: easting ? EPSG : nil
115
+ )
116
+ end
117
+
118
+ def nested_entity(payload)
119
+ %w[data husnummer adresse].each do |key|
120
+ value = payload[key]
121
+ return value if value.is_a?(Hash)
122
+ end
123
+ payload
124
+ end
125
+
126
+ def pick(hash, *keys)
127
+ keys.each do |key|
128
+ value = hash[key]
129
+ return value if present?(value)
130
+ end
131
+ nil
132
+ end
133
+
134
+ def dig_hash(hash, *keys)
135
+ return nil unless hash.is_a?(Hash)
136
+
137
+ hash.dig(*keys)
138
+ end
139
+
140
+ def scalar(value)
141
+ return nil if blank?(value) || value.is_a?(Hash) || value.is_a?(Array)
142
+
143
+ value
144
+ end
145
+
146
+ def extract_etrs89(point)
147
+ return [nil, nil] if blank?(point)
148
+
149
+ if point.is_a?(Array) && point.size >= 2
150
+ return [point[0].to_f, point[1].to_f]
151
+ end
152
+
153
+ coords = point["koordinater"] || point["coordinates"] || point["position"] || dig_hash(point, "geometri", "coordinates")
154
+ if coords.is_a?(Array) && coords.size >= 2
155
+ return [coords[0].to_f, coords[1].to_f]
156
+ end
157
+ if coords.is_a?(Hash)
158
+ easting = coords["x"] || coords["øst"] || coords["oest"] || coords["easting"]
159
+ northing = coords["y"] || coords["nord"] || coords["northing"]
160
+ return [easting.to_f, northing.to_f] if present?(easting) && present?(northing)
161
+ end
162
+
163
+ easting = point["øst"] || point["oest"] || point["easting"] || point["x"]
164
+ northing = point["nord"] || point["northing"] || point["y"]
165
+ return [nil, nil] if blank?(easting) || blank?(northing)
166
+
167
+ [easting.to_f, northing.to_f]
168
+ end
169
+
170
+ # Wired when optional rgeo-proj4 / PROJ is available; otherwise leave WGS84 nil.
171
+ def transform_etrs89(easting, northing)
172
+ return [nil, nil] if easting.nil? || northing.nil?
173
+
174
+ Adressevaelger::Etrs89ToWgs84.call(easting: easting, northing: northing) || [nil, nil]
175
+ end
176
+
177
+ def get_json(path, params = {})
178
+ uri = URI.join("#{base_url}/", path.delete_prefix("/"))
179
+ query = params.merge(token: token).compact
180
+ uri.query = URI.encode_www_form(query)
181
+
182
+ request = Net::HTTP::Get.new(uri)
183
+ request["Accept"] = "application/json"
184
+ request["User-Agent"] = "Adressevaelger/#{VERSION}"
185
+
186
+ response = perform(uri, request)
187
+ unless response.is_a?(Net::HTTPSuccess)
188
+ raise ProviderError, "Adressevælger error (#{response.code})"
189
+ end
190
+
191
+ JSON.parse(response.body)
192
+ rescue JSON::ParserError
193
+ raise ProviderError, "Adressevælger returned invalid JSON"
194
+ end
195
+
196
+ def perform(uri, request)
197
+ if http
198
+ return http.call(uri, request)
199
+ end
200
+
201
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", open_timeout: 5, read_timeout: 10) do |client|
202
+ client.request(request)
203
+ end
204
+ rescue Net::OpenTimeout, Net::ReadTimeout, Errno::ECONNREFUSED, SocketError, Socket::ResolutionError => e
205
+ raise ProviderError, "Adressevælger unreachable (#{e.class})"
206
+ end
207
+
208
+ def blank?(value)
209
+ value.nil? || (value.respond_to?(:empty?) && value.empty?) ||
210
+ (value.is_a?(String) && value.strip.empty?)
211
+ end
212
+
213
+ def present?(value)
214
+ !blank?(value)
215
+ end
216
+
217
+ def present_string(value)
218
+ return nil if blank?(value)
219
+
220
+ value.to_s
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adressevaelger
4
+ Error = Class.new(StandardError)
5
+ # Raised when the Adressevælger HTTP API fails, returns invalid JSON, or is unreachable.
6
+ ProviderError = Class.new(Error)
7
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adressevaelger
4
+ # ETRS89/UTM32N (EPSG:25832) → WGS84 (EPSG:4326) via PROJ (`rgeo-proj4`).
5
+ #
6
+ # Soft-requires `rgeo/proj4`. Returns `nil` when the optional gem is not
7
+ # installed or PROJ cannot load; resolve still returns ETRS89 easting/northing.
8
+ module Etrs89ToWgs84
9
+ module_function
10
+
11
+ def available?
12
+ return @available if defined?(@available)
13
+
14
+ begin
15
+ require "rgeo/proj4"
16
+ @source = RGeo::CoordSys::Proj4.create(25832)
17
+ @target = RGeo::CoordSys::Proj4.create(4326)
18
+ @available = true
19
+ rescue LoadError, StandardError
20
+ @available = false
21
+ end
22
+ end
23
+
24
+ def call(easting:, northing:)
25
+ return nil unless available?
26
+
27
+ lon, lat = RGeo::CoordSys::Proj4.transform_coords(
28
+ @source,
29
+ @target,
30
+ easting.to_f,
31
+ northing.to_f,
32
+ nil
33
+ )
34
+
35
+ [lat.round(7), lon.round(7)]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adressevaelger
4
+ # Provider-shaped resolved Danish address (no host-app persistence helpers).
5
+ ResolvedAddress = Data.define(
6
+ :line1,
7
+ :line2,
8
+ :postal_code,
9
+ :city,
10
+ :country,
11
+ :etage,
12
+ :doer,
13
+ :address_provider,
14
+ :external_address_id,
15
+ :external_building_id,
16
+ :latitude,
17
+ :longitude,
18
+ :coord_easting,
19
+ :coord_northing,
20
+ :coord_epsg
21
+ )
22
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adressevaelger
4
+ PROVIDER = "adressevaelger"
5
+
6
+ # Autocomplete / vask hit from Adressevælger or Adressevask.
7
+ Suggestion = Data.define(:id, :type, :label, :provider) do
8
+ def self.from_fund(fund)
9
+ new(
10
+ id: fund.fetch("id"),
11
+ type: fund.fetch("type"),
12
+ label: fund.fetch("titel"),
13
+ provider: Adressevaelger::PROVIDER
14
+ )
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adressevaelger
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "adressevaelger/version"
4
+ require_relative "adressevaelger/error"
5
+ require_relative "adressevaelger/suggestion"
6
+ require_relative "adressevaelger/resolved_address"
7
+ require_relative "adressevaelger/etrs89_to_wgs84"
8
+ require_relative "adressevaelger/client"
9
+
10
+ # Ruby client for Klimadatastyrelsen Adressevælger + Adressevask (DAR).
11
+ #
12
+ # Denmark only. Country routing, manual entry, and commercial geocoders belong
13
+ # in the host application.
14
+ module Adressevaelger
15
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adressevaelger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rasmus Bergholdt
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: |
13
+ HTTP client for the Danish Adressevælger autocomplete/search and Adressevask
14
+ address-wash APIs (Danmarks Adresseregister / DAR), with an optional
15
+ ETRS89/UTM32N → WGS84 helper via PROJ.
16
+ email:
17
+ - rasmus.bergholdt@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - CHANGELOG.md
23
+ - LICENSE.txt
24
+ - README.md
25
+ - adressevaelger.gemspec
26
+ - lib/adressevaelger.rb
27
+ - lib/adressevaelger/client.rb
28
+ - lib/adressevaelger/error.rb
29
+ - lib/adressevaelger/etrs89_to_wgs84.rb
30
+ - lib/adressevaelger/resolved_address.rb
31
+ - lib/adressevaelger/suggestion.rb
32
+ - lib/adressevaelger/version.rb
33
+ homepage: https://github.com/bergholdt/adressevaelger
34
+ licenses:
35
+ - MIT
36
+ metadata:
37
+ homepage_uri: https://github.com/bergholdt/adressevaelger
38
+ source_code_uri: https://github.com/bergholdt/adressevaelger/tree/v0.1.0
39
+ changelog_uri: https://github.com/bergholdt/adressevaelger/blob/v0.1.0/CHANGELOG.md
40
+ bug_tracker_uri: https://github.com/bergholdt/adressevaelger/issues
41
+ rubygems_mfa_required: 'true'
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 3.3.0
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubygems_version: 4.0.20
57
+ specification_version: 4
58
+ summary: Ruby client for Klimadatastyrelsen Adressevælger and Adressevask (DAR).
59
+ test_files: []