Browse Source

Merge branch 'feature/bragi-for-details' into develop

* feature/bragi-for-details:
  Handle 404 and empty cities as "not found" from upstream.
  Handle empty cities: places that return no items
  Remove unused fixtures and workflow files.
  Fix barning for unused variable by setting it on read
  Fix integration test with browser view to use VCR instead of manual added items
  WIP: implement a city as replacement for a region
  Add rubyracer and v8 for asset compilation
  Update VCR fixture for place to match better import
  Move queries into separate units
  Fetch place from Bragi: make tests pass or ignore outdated tests
  WIP: get places details from bragi, not postgres
  Ensure models set attributes from OSM tags (geocoding.properties)
tags/0.3.6^2
Bèr Kessels 1 month ago
parent
commit
12fdf61537
68 changed files with 1632 additions and 1359 deletions
  1. 1
    0
      Gemfile
  2. 7
    1
      Gemfile.lock
  3. 28
    3
      app/models/base.rb
  4. 0
    39
      app/models/base_collection.rb
  5. 67
    0
      app/models/city.rb
  6. 29
    19
      app/models/place.rb
  7. 0
    37
      app/models/place_index.rb
  8. 0
    23
      app/models/region.rb
  9. 17
    6
      app/models/search_result.rb
  10. 33
    0
      app/projections/base_query.rb
  11. 87
    0
      app/projections/city_query.rb
  12. 29
    0
      app/projections/place_query.rb
  13. 0
    93
      app/projections/query.rb
  14. 1
    1
      app/projections/search_query.rb
  15. 1
    1
      app/views/layout.erb
  16. 2
    2
      app/views/place.erb
  17. 13
    8
      app/views/region.erb
  18. 1
    1
      app/views/search.erb
  19. 17
    22
      lib/app.rb
  20. 4
    0
      lib/errors.rb
  21. 0
    22
      test/fixtures/input/aldi_arnhem.json
  22. 0
    37
      test/fixtures/input/arnhem_city.json
  23. 0
    41
      test/fixtures/input/denbosch_city.json
  24. 0
    32
      test/fixtures/input/eindhoven_city.json
  25. 0
    16
      test/fixtures/input/ekoplaza_arnhem.json
  26. 0
    24
      test/fixtures/input/hacked.json
  27. 0
    24
      test/fixtures/input/jan_de_groot_shertogenbosch.json
  28. 0
    23
      test/fixtures/input/zuidwolde_bb.json
  29. 0
    25
      test/fixtures/input/zuidwolde_dr_region.json
  30. 0
    16
      test/fixtures/input/zuidwolde_fastfood.json
  31. 0
    21
      test/fixtures/input/zuidwolde_gn_region.json
  32. 0
    16
      test/fixtures/input/zuidwolde_grillroom.json
  33. 0
    74
      test/fixtures/output/hm_burchtstraat.json
  34. 0
    70
      test/fixtures/output/places.json
  35. 37
    0
      test/fixtures/vcr_cassettes/bragi_hm_nijmegen.yml
  36. 37
    0
      test/fixtures/vcr_cassettes/bragi_jan_de_groot.yml
  37. 34
    0
      test/fixtures/vcr_cassettes/bragi_marienburg_nijmegen.yml
  38. 63
    0
      test/fixtures/vcr_cassettes/city_arnhem.yml
  39. 62
    0
      test/fixtures/vcr_cassettes/city_den_bosch.yml
  40. 65
    0
      test/fixtures/vcr_cassettes/city_eindhoven.yml
  41. 60
    0
      test/fixtures/vcr_cassettes/city_error_400.yml
  42. 63
    0
      test/fixtures/vcr_cassettes/city_nijmegen.yml
  43. 31
    0
      test/fixtures/vcr_cassettes/city_not_found.yml
  44. 64
    0
      test/fixtures/vcr_cassettes/city_zuidwolde.yml
  45. 198
    0
      test/fixtures/vcr_cassettes/city_zuidwolde_drenthe.yml
  46. 64
    0
      test/fixtures/vcr_cassettes/city_zuidwolde_groningen.yml
  47. 63
    0
      test/fixtures/vcr_cassettes/hacked.yml
  48. 30
    0
      test/fixtures/vcr_cassettes/no_node_found.yml
  49. 1
    1
      test/integration/api/add_places_test.rb
  50. 0
    133
      test/integration/api/view_places_test.rb
  51. 5
    5
      test/integration/web/browser_views_place_test.rb
  52. 62
    66
      test/integration/web/view_places_test.rb
  53. 73
    74
      test/integration/web/view_regions_test.rb
  54. 0
    48
      test/models/base_collection_test.rb
  55. 29
    5
      test/models/base_test.rb
  56. 47
    0
      test/models/city_test.rb
  57. 0
    27
      test/models/place_index_test.rb
  58. 21
    18
      test/models/place_test.rb
  59. 0
    27
      test/models/region_test.rb
  60. 8
    8
      test/models/search_result_test.rb
  61. 91
    0
      test/projections/city_query_test.rb
  62. 55
    0
      test/projections/place_query_test.rb
  63. 32
    116
      test/projections/query_test.rb
  64. 0
    83
      test/support/workflows/add_place.rb
  65. 0
    51
      test/support/workflows/add_region.rb
  66. BIN
      vendor/cache/libv8-3.16.14.19-x86_64-linux.gem
  67. BIN
      vendor/cache/ref-2.0.0.gem
  68. BIN
      vendor/cache/therubyracer-0.12.3.gem

+ 1
- 0
Gemfile View File

@@ -30,6 +30,7 @@ gem 'yajl-ruby'
# Asset management
gem 'sass', require: 'sass'
gem 'sprockets'
gem 'therubyracer'
gem 'uglifier'

group :development, :test do

+ 7
- 1
Gemfile.lock View File

@@ -101,6 +101,7 @@ GEM
jsonapi-renderer (0.2.0)
jsonapi-serializable (0.3.1)
jsonapi-renderer (~> 0.2.0)
libv8 (3.16.14.19)
loofah (2.2.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
@@ -152,6 +153,7 @@ GEM
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
ref (2.0.0)
regexp_parser (1.6.0)
rgeo (2.1.1)
rgeo-geojson (2.1.1)
@@ -206,6 +208,9 @@ GEM
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
ref
thor (0.19.4)
thread_safe (0.3.6)
tilt (2.0.10)
@@ -262,6 +267,7 @@ DEPENDENCIES
sinatra
sinatra-contrib
sprockets
therubyracer
timecop
uglifier
uuidtools
@@ -270,4 +276,4 @@ DEPENDENCIES
yajl-ruby

BUNDLED WITH
1.17.3
2.1.4

+ 28
- 3
app/models/base.rb View File

@@ -5,7 +5,15 @@ module Hours
##
# Base model that can read from a query database
class Base
def initialize(attributes = {}, ignore_undefined_attributes = false)
attr_accessor :error, :geometry
NULL_ISLAND = GeoRuby::SimpleFeatures::Point.from_xy(0, 0)

def initialize(
attributes: {},
geometry: NULL_ISLAND,
ignore_undefined_attributes: false
)
@geometry = geometry
attributes.each do |key, value|
setter = "#{key}="
send(setter, value)
@@ -15,8 +23,25 @@ module Hours
end

def self.from_geojson_feature(feature)
attrs = feature.properties.fetch('geocoding', {})
new(attrs, true)
attrs = feature&.properties&.fetch('geocoding', {}) || {}
geometry = feature&.geometry || NULL_ISLAND
tags = attrs.fetch('properties', []) || []

# Turn # [{ key => 'name', value => 'someval' }] into
# { 'name' => someval }
extra_props = Hash[tags.map { |pair| [pair['key'], pair['value']] }]

new(
attributes: extra_props.merge(attrs),
geometry: geometry,
ignore_undefined_attributes: true
)
end

protected

def null_island
NULL_ISLAND
end
end
end

+ 0
- 39
app/models/base_collection.rb View File

@@ -1,39 +0,0 @@
# frozen_string_literal: true

module Hours
module Models
##
# Base model that holds a list of other models
class BaseCollection < Delegator
include Enumerable

attr_accessor :paginator

def __getobj__
@dataset
end

def initialize(dataset, paginator = nil)
@dataset = dataset
@paginator = paginator
end

def to_a
@dataset.map { |row| self.class::ITEM_CLASS.new(row) }
end

def each
@dataset.each do |row|
case row
when NilClass
yield self.class::NULLITEM_CLASS.new
when Hash
yield self.class::ITEM_CLASS.new(row)
when RGeo::GeoJSON::Feature
yield self.class::ITEM_CLASS.from_geojson_feature(row)
end
end
end
end
end
end

+ 67
- 0
app/models/city.rb View File

@@ -0,0 +1,67 @@
# frozen_string_literal: true

require 'babosa'

require_relative 'base.rb'

module Hours
module Models
##
# City is a collection of Places belonging to one area.
# It is, therefore, a decorator for a list of places.
class City < Base
attr_accessor :id, :label, :bbox, :geometry, :paginator, :collection

attr_writer :name, :type, :zone_type, :postcode, :city
alias places collection

def initialize(attributes: {},
geometry: NULL_ISLAND,
ignore_undefined_attributes: false,
collection: [], paginator: nil)
@collection = collection
@paginator = paginator

super(
attributes: attributes,
geometry: geometry,
ignore_undefined_attributes: ignore_undefined_attributes
)

@bbox ||= []
end

def slug
name.to_slug.normalize.to_s
end

def name
@name || 'onbekend'
end

def shape
return if bbox.empty?
RGeo::GeoJSON::EntityFactory.new.feature(factory.polygon(bbox_as_ring))
end

private

def bbox_as_ring
# Example BBOX:
# [0] 5.7576206,
# [1] 51.7905891,
# [2] 5.9083469,
# [3] 51.8946209
top_left = factory.point(bbox[0], bbox[1])
top_right = factory.point(bbox[2], bbox[1])
bottom_right = factory.point(bbox[2], bbox[3])
bottom_left = factory.point(bbox[0], bbox[3])
factory.linear_ring([top_left, top_right, bottom_right, bottom_left])
end

def factory
@factory ||= RGeo::Cartesian.simple_factory(srid: 4326)
end
end
end
end

+ 29
- 19
app/models/place.rb View File

@@ -6,6 +6,13 @@ require_relative 'base.rb'

module Hours
module Models
# Utility class to hold a place that is empty
class NullPlace < Base
def region
''
end
end

##
# A Place is a readonly model for querying the projection of "places".
# * Readonly: it is not enforced on model or ORM level, but should be
@@ -15,17 +22,9 @@ module Hours
ITERATOR = OpeningHoursConverter::Iterator.new
PARSER = OpeningHoursConverter::OpeningHoursParser.new

attr_accessor :id, :location, :place_id, :name,
:region_slug, :distance, :website
attr_writer :address, :opening_hours

def lat
location.lat
end

def lon
location.lon
end
attr_accessor :id, :place_id, :name,
:distance, :website, :administrative_regions
attr_writer :opening_hours, :geometry

def status
return :unknown if opening_hours&.empty?
@@ -35,6 +34,10 @@ module Hours
:unknown
end

def region_slug
(address&.city || 'onbekend').to_slug.normalize.to_s
end

def open_this_week
date_ranges = PARSER.parse(opening_hours)
get_intervals_as_week(date_ranges, Date.today)
@@ -43,13 +46,7 @@ module Hours
end

def address
return unless raw_address

OpenStruct.new(Sequel::Postgres::HStore.parse(raw_address).to_hash)
end

def region
address&.city
OpenStruct.new(raw_address)
end

def raw_address
@@ -57,7 +54,20 @@ module Hours
end

def opening_hours
@opening_hours || ''
@opening_hours ||= ''
end

def geometry
@geometry || null_island
end

def city=(city)
@address ||= {}
@address[:city] = city
end

def address=(address = {})
@address = (address || {}).merge(@address || {})
end

private

+ 0
- 37
app/models/place_index.rb View File

@@ -1,37 +0,0 @@
# frozen_string_literal: true

require 'georuby'

require_relative 'base_collection.rb'
require_relative 'place.rb'

module Hours
module Models
# Utility class to hold a place that is empty
class NullPlace
def region
''
end
end

##
# A collection of places
class PlaceIndex < BaseCollection
ITEM_CLASS = ::Hours::Models::Place
NULLITEM_CLASS = ::Hours::Models::NullPlace

attr_accessor :centerpoint

def initialize(dataset, paginator = nil, centerpoint = nil)
super(dataset, paginator)
@centerpoint = centerpoint || null_island
end

private

def null_island
GeoRuby::SimpleFeatures::Point.from_xy(0, 0)
end
end
end
end

+ 0
- 23
app/models/region.rb View File

@@ -1,23 +0,0 @@
# frozen_string_literal: true

require_relative 'base.rb'
require_relative 'place_index.rb'

module Hours
module Models
##
# Region is a collection of Places belonging to one region.
# It is, therefore, a decorator for a list of places.
class Region < PlaceIndex
def initialize(dataset,
paginator = nil, centerpoint = nil, region_slug = '')
@region_slug = region_slug || ''
super(dataset, paginator, centerpoint)
end

def name
@region_slug.capitalize
end
end
end
end

+ 17
- 6
app/models/search_result.rb View File

@@ -1,21 +1,32 @@
# frozen_string_literal: true

require_relative 'base.rb'
require_relative 'place_index.rb'

module Hours
module Models
##
# Region is a collection of Places belonging to one region.
# It is, therefore, a decorator for a list of places.
class SearchResult < PlaceIndex
attr_reader :query, :error
class SearchResult
attr_reader :query, :error, :paginator
ITEM_CLASS = ::Hours::Models::Place
NULLITEM_CLASS = ::Hours::Models::NullPlace

## TODO: PlaceIndex and other models need initialize with keyword args
def initialize(dataset: [], paginator: nil, query: '', error: nil)
def initialize(collection: [], paginator: nil, query: '', error: nil)
@query = query
@error = error
super(dataset, paginator)
@collection = collection
@paginator = paginator
end

def collection
@collection.map do |item|
if item.nil?
NULLITEM_CLASS.new
else
ITEM_CLASS.from_geojson_feature(item)
end
end
end
end
end

+ 33
- 0
app/projections/base_query.rb View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true

require 'pagy'

module Hours
module Projections
##
# Common behaviour for all query objects
class BaseQuery
DEFAULT_DATASET = Hours.projections_database[:query_places]
BUFFERX = 0.005302691970002
BUFFERY = 0.01297116279602
attr_reader :dataset, :page

include Pagy::Backend

def initialize(dataset)
@dataset = dataset
@page = nil
end

def self.build
new(DEFAULT_DATASET)
end

def pagy_get_vars(collection, vars)
vars[:count] = collection.count
vars[:page] = page
vars
end
end
end
end

+ 87
- 0
app/projections/city_query.rb View File

@@ -0,0 +1,87 @@
# frozen_string_literal: true

require 'pagy/backend'
require 'pagy/extras/array'

module Hours
module Projections
# Query handler that builds a list of places in a City
class CityQuery
attr_reader :page
include Pagy::Backend

def self.build
faraday = Faraday.new(url: ENV['BRAGI_URL']) do |conn|
conn.response :raise_error
conn.adapter Faraday.default_adapter
end
new(faraday)
end

def initialize(http_client)
@http_client = http_client
end

def handle(slug, page = 1)
@slug = slug
@page = page

@city = city
@city.paginator, @city.collection = pagy_array(places)

@city
end

def pagy_array_get_vars(collection, vars)
vars[:count] = collection.count
vars[:page] = page
vars
end

private

def city
return @city if @city

response = @http_client.get('/autocomplete', city_params)

geojson = RGeo::GeoJSON.decode(response.body).first
raise Hours::CityNotFound unless geojson

@city = Hours::Models::City.from_geojson_feature(geojson)
rescue Faraday::ResourceNotFound
raise Hours::CityNotFound
end

def places
# TODO: consider making the query of collection lazy.
response = @http_client.post('/features') do |request|
request.body = { shape: RGeo::GeoJSON.encode(city.shape) }.to_json
request.headers[:content_type] = 'application/json'
request.params = city_center_params
end

places = RGeo::GeoJSON.decode(response.body)

places.map do |feature|
Hours::Models::Place.from_geojson_feature(feature)
end.to_a
end

def city_params
{ q: @slug,
limit: 1,
type: ['city'] }
end

def city_center_params
{
lat: @city.geometry.y,
lon: @city.geometry.x,
limit: 20,
type: ['poi']
}
end
end
end
end

+ 29
- 0
app/projections/place_query.rb View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true

module Hours
module Projections
# Query handler that queries the projection table for a single node
class PlaceQuery
def self.build
faraday = Faraday.new(url: ENV['BRAGI_URL']) do |conn|
conn.response :raise_error
conn.adapter Faraday.default_adapter
end
new(faraday)
end

def initialize(http_client)
@http_client = http_client
end

def handle(id)
response = @http_client.get("features/#{id}")
@place = Hours::Models::Place.from_geojson_feature(
RGeo::GeoJSON.decode(response.body).first
)
rescue Faraday::ServerError, JSON::ParserError => e
Hours::Models::NullPlace.new(attributes: { error: e.message })
end
end
end
end

+ 0
- 93
app/projections/query.rb View File

@@ -1,93 +0,0 @@
# frozen_string_literal: true

require 'pagy'
require 'offline_geocoder'

module Hours
module Projections
##
# Common behaviour for all query objects
class BaseQuery
DEFAULT_DATASET = Hours.projections_database[:query_places]
BUFFERX = 0.005302691970002
BUFFERY = 0.01297116279602
attr_reader :dataset, :page

include Pagy::Backend

def initialize(dataset)
@dataset = dataset
@page = nil
end

def self.build
new(DEFAULT_DATASET)
end

def pagy_get_vars(collection, vars)
vars[:count] = collection.count
vars[:page] = page
vars
end
end

# Query handler that queries the projection table for a single node
class PlaceQuery < BaseQuery
def handle(id)
result = dataset[id: id]
Hours::Models::Place.new(result) if result
end

def uuid_for(place_id)
dataset.where(place_id: place_id).get(:id)
end
end

# Query handler that queries the projection table for all nodes
class PlacesQuery < BaseQuery
def handle(page = 1)
@page = page
pagy, records = pagy(dataset)
Hours::Models::PlaceIndex.new(records, pagy)
end
end

# Query handler that builds a list of places in a Region
class RegionQuery < BaseQuery
def handle(slug, page = 1)
@page = page
@region_slug = slug
return Hours::Models::Region.new([], {}, nil, nil) unless region

pagy, records = pagy(dataset.order(distance).where(in_envelope))
Hours::Models::Region.new(records,
pagy,
region[:centerpoint],
region[:name])
end

private

def region
raise ArgumentError if @region_slug.nil? || @region_slug.empty?

@region ||= Hours.projections_database[:query_regions]
.first(slug: @region_slug)
end

def distance
Sequel.lit('location <-> ?', region[:centerpoint])
end

def in_envelope
Sequel.lit('location && ST_MakeEnvelope(?, ?, ?, ?, 4326)',
*envelope_corners)
end

def envelope_corners
cp = region[:centerpoint]
[cp.x + BUFFERX, cp.y + BUFFERY, cp.x - BUFFERX, cp.y - BUFFERY]
end
end
end
end

+ 1
- 1
app/projections/search_query.rb View File

@@ -30,7 +30,7 @@ module Hours
features = get_bragi_features(query)
pagy, places = pagy_array(features)
Hours::Models::SearchResult.new(
dataset: places,
collection: places,
paginator: pagy,
query: query
)

+ 1
- 1
app/views/layout.erb View File

@@ -27,7 +27,7 @@
<%== yield %>
</div>
<script>
<%== content_for(:closing_js) %>
<%== content_for(:closing_js) %>
</script>
</body>
</html>

+ 2
- 2
app/views/place.erb View File

@@ -1,9 +1,9 @@
<% set_content_for(:closing_js,
"var map = L.map('map').setView([#{@place.location.y}, #{@place.location.x}], 16);
"var map = L.map('map').setView([#{@place.geometry.y}, #{@place.geometry.x}], 16);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors'
}).addTo(map);
L.marker([#{@place.location.y}, #{@place.location.x}]).addTo(map);"
L.marker([#{@place.geometry.y}, #{@place.geometry.x}]).addTo(map);"
)
%>
<% set_content_for(:region_name, @place.address.city) %>

+ 13
- 8
app/views/region.erb View File

@@ -1,10 +1,10 @@
<% if @region.empty? %>
<% if @region.places.empty? %>
<p class="alert alert-primary" role="alert">
No places found in <%= @region.name %>
</p>
<% else %>
<%-
js = "var map = L.map('map').setView([#{@region.centerpoint.y}, #{@region.centerpoint.x}], 16);
js = "var map = L.map('map').setView([#{@region.geometry.y}, #{@region.geometry.x}], 16);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors'
}).addTo(map);"
@@ -42,10 +42,10 @@
popupAnchor: [-20, -40],
});"

js += "L.marker([#{@region.centerpoint.y}, #{@region.centerpoint.x}], {icon: centerIcon}).addTo(map);"
js += "L.marker([#{@region.geometry.y}, #{@region.geometry.x}], {icon: centerIcon}).addTo(map);"
js += "var markers = [];"

@region.each do |place|
@region.collection.each do |place|
icon = if place.status == :open
'openedIcon'
elsif place.status == :closed
@@ -55,17 +55,22 @@
end
popup_content = "<strong>#{Rack::Utils.escape_html(place.name)}</strong>"
popup_content += erb(:status_badge_partial, locals: { status: place.status }).delete("\n")
js += "markers.push(L.marker([#{place.location.y}, #{place.location.x}], {icon: #{icon}}).addTo(map).bindPopup('#{popup_content}'));"
js += "markers.push(L.marker([#{place.geometry.y}, #{place.geometry.x}], {icon: #{icon}}).addTo(map).bindPopup('#{popup_content}'));"
end
js += "var group = L.featureGroup(markers);"
js += "map.fitBounds(group.getBounds());"

#js += "map.fitBounds([[#{@region.bbox[1]}, #{@region.bbox[0]}], [#{@region.bbox[3]}, #{@region.bbox[2]}]]);"

set_content_for(:closing_js, js)
%>

<% set_content_for(:region_slug, @region.slug) %>
<% set_content_for(:region_name, @region.name) %>

<h2>Openingstijden in <%= @region.name %></h2>

<section class="row">
<div class="col-3 list-group">
<%- @region.each do |place| %>
<%- @region.collection.each do |place| %>
<a href="/places/<%= place.id %>" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h3 class="mb-1 small"><%= place.name %></h3>

+ 1
- 1
app/views/search.erb View File

@@ -2,7 +2,7 @@

<section class="row">
<div class="col-3 list-group">
<%- @search_result.each do |place| %>
<%- @search_result.collection.each do |place| %>
<a href="/places/<%= place.id %>" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h3 class="mb-1 small"><%= place.name %></h3>

+ 17
- 22
lib/app.rb View File

@@ -3,6 +3,7 @@
# This contains the Sinatra App
require_relative './hours.rb'
require_relative './capture_helpers.rb'
require_relative './errors.rb'
require_relative './json_helpers.rb'
require_relative './pagination_helpers.rb'
require_relative Hours.base_path.join('config/event_sourcery.rb')
@@ -88,6 +89,11 @@ module Hours
status 400
end

def not_found
body "Not Found: 404"
status 404
end

def places_url(id)
URI.join(request.base_url, "/places/#{id}").to_s
end
@@ -97,7 +103,7 @@ module Hours
if @place
yield block
else
404
not_found
end
end

@@ -107,11 +113,6 @@ module Hours
settings.sprockets_env.call(env)
end

get '/places' do
places_index = Hours::Projections::PlacesQuery.build.handle(page_param)
body render_json(places_index.to_a, page_links(places_index.paginator))
end

put '/places' do
command = Hours::AddPlaceCommand.build(json_params)
Hours::CommandHandler.new.handle(command)
@@ -129,28 +130,22 @@ module Hours
end

get '/in/:slug', provides: 'html' do
@region = Hours::Projections::RegionQuery.build.handle(
@region = Hours::Projections::CityQuery.build.handle(
params[:slug],
page_param
)
erb :region
rescue Faraday::BadRequestError => e
bad_request(e)
rescue Hours::CityNotFound
not_found
end

get %r{/places/(?<uuid>#{UUID_REGEX})}, provides: 'html' do
handle_get_place do
erb :place
end
end

get %r{/places/(?<uuid>#{UUID_REGEX})}, provides: 'json' do
handle_get_place do
body render_json(@place)
end
end

get '/places/:place_id', provides: 'json' do
uuid = Hours::Projections::PlaceQuery.build.uuid_for(params[:place_id])
redirect to("/places/#{uuid}"), 303
get %r{/places/(?<id>[\w:]+)}, provides: 'html' do
@place = Hours::Projections::PlaceQuery.build.handle(params[:id])
erb :place
rescue Faraday::ResourceNotFound
not_found
end
end
end

+ 4
- 0
lib/errors.rb View File

@@ -0,0 +1,4 @@
## Raised when we recieved an empty city or a 404 for a city
module Hours
class CityNotFound < ::StandardError; end
end

+ 0
- 22
test/fixtures/input/aldi_arnhem.json View File

@@ -1,22 +0,0 @@
{
"type": "Feature",
"id": "34045145",
"geometry": {
"type": "Point",
"coordinates": [
5.8941842,
51.9413713
]
},
"properties": {
"brand": "Aldi",
"brand:wikidata": "Q125054",
"brand:wikipedia": "en:Aldi",
"description": "Arnhem, Het toneel",
"name": "Aldi",
"note": "ODBL clean: geen disclaimer/copyright aangetroffen op winkelgegevens Aldi (stand: juni 2012)",
"opening_hours": "Mo-Sa 08:00-20:00; Su 12:00-18:00",
"shop": "supermarket",
"wheelchair": "limited"
}
}

+ 0
- 37
test/fixtures/input/arnhem_city.json View File

@@ -1,37 +0,0 @@
{
"type": "Feature",
"id": "6394641551",
"geometry": {
"type": "Point",
"coordinates": [
5.9108573,
51.984257
]
},
"properties": {
"capital": "4",
"name": "Arnhem",
"name:ar": "أرنهيم",
"name:de": "Arnheim",
"name:en": "Arnhem",
"name:es": "Arnhem",
"name:fr": "Arnhem",
"name:fy": "Arnhim",
"name:he": "ארנהם",
"name:la": "Arenacum",
"name:lt": "Arnhemas",
"name:nds": "Arnem",
"name:nl": "Arnhem",
"name:ru": "Арнем",
"name:sr": "Арнем",
"name:uk": "Арнем",
"place": "city",
"population": "155694",
"population:date": "2017-01-01",
"population:note": "Inwonertal inclusief Elden en Schaarsbergen",
"source:population": "https://arnhem.buurtmonitor.nl//jive",
"website": "https://www.arnhem.nl/",
"wikidata": "Q1310",
"wikipedia": "nl:Arnhem"
}
}

+ 0
- 41
test/fixtures/input/denbosch_city.json View File

@@ -1,41 +0,0 @@
{
"type": "Feature",
"id": "60400458",
"geometry": {
"type": "Point",
"coordinates": [
5.3031044,
51.6889351
]
},
"properties": {
"alt_name": "Den Bosch",
"capital": "4",
"loc_name": "Den Bosch",
"name": "'s-Hertogenbosch",
"name:ar": "سيرتوخيمبوس",
"name:carnaval": "Oeteldonk",
"name:de": "Herzogenbusch",
"name:es": "Bolduque",
"name:fr": "Bois-le-Duc",
"name:fy": "De Bosk",
"name:id": "Den Bosch",
"name:la": "Silva Ducis",
"name:li": "De Bósj",
"name:lt": "Hertogenbosas",
"name:mk": "Хертогенбос",
"name:nds": "Den Bosch",
"name:ru": "Хертогенбос",
"name:sr": "Хертогенбос",
"name:uk": "Гертогенбос",
"name:zh": "斯海尔托亨博斯",
"place": "city",
"population": "115903",
"population:date": "2017-01-01",
"population:note": "Inwonertal gemeente minus Rosmalen, Nuland en Vinkel.",
"source:population": "https://www.s-hertogenbosch.nl",
"website": "https://www.s-hertogenbosch.nl/",
"wikidata": "Q2766547",
"wikipedia": "nl:'s-Hertogenbosch"
}
}

+ 0
- 32
test/fixtures/input/eindhoven_city.json View File

@@ -1,32 +0,0 @@
{
"type": "Feature",
"id": "42616340",
"geometry": {
"type": "Point",
"coordinates": [
5.478633,
51.4392648
]
},
"properties": {
"name": "Eindhoven",
"name:carnaval": "Lampegat",
"name:el": "Αϊντχόφεν",
"name:he": "איינדהובן",
"name:la": "Endhovia",
"name:lt": "Eindhovenas",
"name:mk": "Ајндховен",
"name:ru": "Эйндховен",
"name:sr": "Ајндховен",
"name:uk": "Ейндговен",
"name:zh": "埃因霍温",
"place": "city",
"population": "226921",
"population:date": "2017-01-01",
"population:note": "Inwonertal inclusief Kerkdorp Acht",
"source:population": "https://eindhoven.incijfers.nl",
"website": "https://www.eindhoven.nl/",
"wikidata": "Q9832",
"wikipedia": "nl:Eindhoven"
}
}

+ 0
- 16
test/fixtures/input/ekoplaza_arnhem.json View File

@@ -1,16 +0,0 @@
{
"type": "Feature",
"id": "3210878424",
"geometry": {
"type": "Point",
"coordinates": [
5.9112061,
51.983185
]
},
"properties": {
"name": "Ekoplaza",
"shop": "supermarket",
"wheelchair": "yes"
}
}

+ 0
- 24
test/fixtures/input/hacked.json View File

@@ -1,24 +0,0 @@
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
5.8653234,
51.8473397
]
},
"properties": {
"addr:city": "Nijmegen",
"addr:country": "NL",
"addr:housenumber": "1",
"addr:postcode": "<script>alert('1000AB');</script>",
"addr:street": "Burchtstraat\n",
"name": "H@ckedM",
"opening_hours": "this 10s! unparsable 18:00+",
"shop": "clothes",
"shop:number": "NL0050",
"source": "BAG;http://www.hm.com/nl/",
"source:date": "2014-05-07",
"wheelchair": "yes"
}
}

+ 0
- 24
test/fixtures/input/jan_de_groot_shertogenbosch.json View File

@@ -1,24 +0,0 @@
{
"type": "Feature",
"id": "945471470",
"geometry": {
"type": "Point",
"coordinates": [
5.2966174,
51.690227
]
},
"properties": {
"addr:city": "'s-Hertogenbosch",
"addr:housenumber": "24",
"addr:postcode": "5211TW",
"addr:street": "Stationsweg",
"name": "Jan de Groot",
"shop": "bakery",
"source": "BAG",
"source:date": "2014-02-11",
"toilets:wheelchair": "no",
"website": "https://www.bosschebollen.nl/",
"wheelchair": "limited"
}
}

+ 0
- 23
test/fixtures/input/zuidwolde_bb.json View File

@@ -1,23 +0,0 @@
{
"type": "Feature",
"id": "2754051107",
"geometry": {
"type": "Point",
"coordinates": [
6.5941314,
53.2602521
]
},
"properties": {
"addr:city": "Zuidwolde",
"addr:housenumber": "8",
"addr:postcode": "9785AE",
"addr:street": "Oosterseweg",
"guest_house": "bed_and_breakfast",
"name": "Bed en brood 'Irene'",
"phone": "+31 6 51961751",
"source": "BAG",
"source:date": "2014-03-24",
"tourism": "guest_house"
}
}

+ 0
- 25
test/fixtures/input/zuidwolde_dr_region.json View File

@@ -1,25 +0,0 @@
{
"type": "Feature",
"id": "3523151185",
"geometry": {
"type": "Point",
"coordinates": [
6.4317343,
52.6749542
]
},
"properties": {
"is_in:continent": "Europe",
"is_in:country": "The Netherlands",
"is_in:country_code": "NL",
"name": "Zuidwolde",
"name:ru": "Зёйдволде",
"place": "village",
"population": "6240",
"population:date": "2017-01-01",
"postal_code": "7921",
"source:population": "CBS Wijk 2017",
"wikidata": "Q2754055",
"wikipedia": "nl:Zuidwolde (Drenthe)"
}
}

+ 0
- 16
test/fixtures/input/zuidwolde_fastfood.json View File

@@ -1,16 +0,0 @@
{
"type": "Feature",
"id": "2311319392",
"geometry": {
"type": "Point",
"coordinates": [
6.5921197,
53.260827
]
},
"properties": {
"amenity": "fast_food",
"name": "Moeke Vaatstra",
"wheelchair": "limited"
}
}

+ 0
- 21
test/fixtures/input/zuidwolde_gn_region.json View File

@@ -1,21 +0,0 @@
{
"type": "Feature",
"id": "48298240",
"geometry": {
"type": "Point",
"coordinates": [
6.5918683,
53.2607348
]
},
"properties": {
"is_in": "NL",
"name": "Zuidwolde",
"name:ru": "Зёйдволде",
"place": "village",
"population": "1010",
"population:date": "2017-01-01",
"postal_code": "9785",
"source:population": "CBS Buurt 2017"
}
}

+ 0
- 16
test/fixtures/input/zuidwolde_grillroom.json View File

@@ -1,16 +0,0 @@
{
"type": "Feature",
"id": "2599631016",
"geometry": {
"type": "Point",
"coordinates": [
6.4295856,
52.6714759
]
},
"properties": {
"amenity": "restaurant",
"cuisine": "kebab",
"name": "Grillroom Yusuf"
}
}

+ 0
- 74
test/fixtures/output/hm_burchtstraat.json View File

@@ -1,74 +0,0 @@
{
"data": {
"id": "9ae7f8f1-164d-4145-b472-d7c7da05a679",
"type": "place",
"attributes": {
"place_id": "9F37RV00+;shop:clothes;hm",
"name": "H&M",
"lat": 51.8473397,
"lon": 5.8653234,
"status": "open",
"open_this_week": {
"1": [
{
"start": "1989-11-06 10:00:00 +0100",
"end": "1989-11-06 18:00:00 +0100"
}
],
"2": [
{
"start": "1989-11-07 10:00:00 +0100",
"end": "1989-11-07 18:00:00 +0100"
}
],
"3": [
{
"start": "1989-11-08 10:00:00 +0100",
"end": "1989-11-08 18:00:00 +0100"
}
],
"4": [
{
"start": "1989-11-09 10:00:00 +0100",
"end": "1989-11-09 21:00:00 +0100"
}
],
"5": [
{
"start": "1989-11-10 10:00:00 +0100",
"end": "1989-11-10 18:00:00 +0100"
}
],
"6": [
{
"start": "1989-11-11 09:30:00 +0100",
"end": "1989-11-11 17:30:00 +0100"
}
],
"0": [
{
"start": "1989-11-12 12:00:00 +0100",
"end": "1989-11-12 17:30:00 +0100"
}
]
},
"raw_opening_hours": "Mo-We 10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30; Su 12:00-17:30",
"website": null,
"address": {
"postcode": "6511RA",
"city": "Nijmegen",
"housenumber": "1",
"street": "Burchtstraat"
}
},
"relationships": {
"region": { "links": { "self": "/in/nijmegen" } }
},
"links": {
"self": "/places/9ae7f8f1-164d-4145-b472-d7c7da05a679"
},
"meta": {
"copyright": "OpenStreetMap-contributors"
}
}
}

+ 0
- 70
test/fixtures/output/places.json View File

@@ -1,70 +0,0 @@
{
"links": {
"self" : "/places",
"first": "/places?page=1",
"last": "/places?page=1",
"prev": null,
"next": null
},
"data": [
{
"links" : {
"self" : "/places/:UUID"
},
"meta" : {
"copyright" : "OpenStreetMap-contributors"
},
"type" : "place",
"attributes" : {
"place_id": "9F37RV00+;shop:clothes;hm",
"raw_opening_hours" : "Mo-We 10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30; Su 12:00-17:30",
"open_this_week" : {
"1": [{
"start" : "1989-11-06 10:00:00 +0100",
"end" : "1989-11-06 18:00:00 +0100"
}],
"2": [{
"start" : "1989-11-07 10:00:00 +0100",
"end" : "1989-11-07 18:00:00 +0100"
}],
"3": [{
"start" : "1989-11-08 10:00:00 +0100",
"end" : "1989-11-08 18:00:00 +0100"
}],
"4": [{
"start" : "1989-11-09 10:00:00 +0100",
"end" : "1989-11-09 21:00:00 +0100"
}],
"5": [{
"start" : "1989-11-10 10:00:00 +0100",
"end" : "1989-11-10 18:00:00 +0100"
}],
"6": [{
"start" : "1989-11-11 09:30:00 +0100",
"end" : "1989-11-11 17:30:00 +0100"
}],
"0": [{
"start": "1989-11-12 12:00:00 +0100",
"end": "1989-11-12 17:30:00 +0100"
}]
},
"name" : "H&M",
"status" : "open",
"website": null,
"lat": 51.8473397,
"lon": 5.8653234,
"address" : {
"postcode" : "6511RA",
"city" : "Nijmegen",
"housenumber" : "1",
"street" : "Burchtstraat"
}
},
"relationships": {
"region": { "links": { "self": "/in/nijmegen" } }
},
"id" : "1337"
}
]
}


+ 37
- 0
test/fixtures/vcr_cassettes/bragi_hm_nijmegen.yml View File

@@ -0,0 +1,37 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/features/poi:osm:node:989225414
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200
message: OK
headers:
content-length:
- '2623'
connection:
- close
cache-control:
- max-age=3600
content-type:
- application/json
date:
- Thu, 23 Apr 2020 14:39:02 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[{"type":"Feature","geometry":{"coordinates":[5.865323399999999,51.8473397],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:989225414","type":"poi","label":"H&M
(Nijmegen)","name":"H&M","postcode":"6511RA","city":"Nijmegen","citycode":"","administrative_regions":[{"id":"admin:osm:relation:1200994","insee":"","level":10,"label":"Nijmegen,
Gelderland, Nederland","name":"Nijmegen","zip_codes":[],"coord":{"lon":5.833201435730207,"lat":51.83480943401887},"bbox":[5.7576206,51.7905891,5.9083469,51.8946209],"zone_type":"city","parent_id":"admin:osm:relation:47554","codes":[{"name":"ref:woonplaatscode","value":"3030"},{"name":"wikidata","value":"Q47887"}]},{"id":"admin:osm:relation:47554","insee":"","level":4,"label":"Gelderland,
Nederland","name":"Gelderland","zip_codes":[],"coord":{"lon":5.9108573,"lat":51.984257},"bbox":[4.9938547,51.7335807,6.8328017,52.522025],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-GE"},{"name":"ref:provinciecode","value":"25"},{"name":"wikidata","value":"Q775"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744389],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:shop:clothes","name":"Kledingwinkel"}],"properties":[{"key":"addr:city","value":"Nijmegen"},{"key":"addr:country","value":"NL"},{"key":"addr:housenumber","value":"1"},{"key":"addr:postcode","value":"6511RA"},{"key":"addr:street","value":"Burchtstraat"},{"key":"name","value":"H&M"},{"key":"opening_hours","value":"Mo-We
10:00-18:00; Th 10:00-21:00; Fr 10:00-18:00; Sa 09:30-17:30"},{"key":"shop","value":"clothes"},{"key":"shop:number","value":"NL0050"},{"key":"source","value":"BAG;http://www.hm.com/nl/"},{"key":"source:date","value":"2014-05-07"},{"key":"wheelchair","value":"yes"}],"address":{"id":"addr:5.8652752;51.8473134:4","type":"house","label":"Gapershof
4 (Nijmegen)","name":"Gapershof 4","housenumber":"4","street":"Gapershof","postcode":"6511VA","city":"Nijmegen","citycode":"","administrative_regions":[{"id":"admin:osm:relation:1201020","insee":"","level":8,"label":"Nijmegen","name":"Nijmegen","zip_codes":[],"coord":{"lon":5.8634696,"lat":51.8427385},"bbox":[5.7576206,51.7905891,5.9083469,51.8946209],"zone_type":"city","parent_id":null,"codes":[{"name":"ref:gemeentecode","value":"268"},{"name":"wikidata","value":"Q47887"}]}]}}}}]}'
http_version: null
recorded_at: Thu, 23 Apr 2020 14:39:02 GMT
recorded_with: VCR 5.1.0

+ 37
- 0
test/fixtures/vcr_cassettes/bragi_jan_de_groot.yml View File

@@ -0,0 +1,37 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/features/poi:osm:node:945471470
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200
message: OK
headers:
content-length:
- '2278'
connection:
- close
cache-control:
- max-age=3600
content-type:
- application/json
date:
- Wed, 22 Apr 2020 09:13:51 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[{"type":"Feature","geometry":{"coordinates":[5.2966174,51.690227],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:945471470","type":"poi","label":"Jan
de Groot (''s-Hertogenbosch)","name":"Jan de Groot","postcode":"5211TW","city":"''s-Hertogenbosch","citycode":"","administrative_regions":[{"id":"admin:osm:relation:162798","insee":"","level":10,"label":"''s-Hertogenbosch,
Noord-Brabant, Nederland","name":"''s-Hertogenbosch","zip_codes":[],"coord":{"lon":5.295758880751707,"lat":51.71000807857934},"bbox":[5.2064942,51.6639966,5.3822104,51.7557341],"zone_type":"city","parent_id":"admin:osm:relation:47696","codes":[{"name":"ref:woonplaatscode","value":"1595"},{"name":"wikidata","value":"Q2766547"}]},{"id":"admin:osm:relation:47696","insee":"","level":4,"label":"Noord-Brabant,
Nederland","name":"Noord-Brabant","zip_codes":[],"coord":{"lon":5.3031044,"lat":51.688935099999995},"bbox":[4.1901242,51.2209094,6.0481207999999995,51.830751],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-NB"},{"name":"ref:provinciecode","value":"30"},{"name":"wikidata","value":"Q1101"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744389],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:shop:bakery","name":"Bakkerij"}],"properties":[{"key":"addr:city","value":"''s-Hertogenbosch"},{"key":"addr:housenumber","value":"24"},{"key":"addr:postcode","value":"5211TW"},{"key":"addr:street","value":"Stationsweg"},{"key":"name","value":"Jan
de Groot"},{"key":"shop","value":"bakery"},{"key":"source","value":"BAG"},{"key":"source:date","value":"2014-02-11"},{"key":"toilets:wheelchair","value":"no"},{"key":"website","value":"https://www.bosschebollen.nl/"},{"key":"wheelchair","value":"limited"}],"address":{"id":"addr:5.2966249;51.6902236:24","type":"house","label":"Stationsweg
24","name":"Stationsweg 24","housenumber":"24","street":"Stationsweg","postcode":"5211TW","city":null,"citycode":null,"administrative_regions":[]}}}}]}'
http_version: null
recorded_at: Wed, 22 Apr 2020 09:13:51 GMT
recorded_with: VCR 5.1.0

+ 34
- 0
test/fixtures/vcr_cassettes/bragi_marienburg_nijmegen.yml View File

@@ -0,0 +1,34 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/features/poi:osm:node:989371189
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200
message: OK
headers:
content-length:
- '1186'
connection:
- close
content-type:
- application/json
cache-control:
- max-age=3600
date:
- Wed, 26 Mar 2020 16:14:01 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[{"type":"Feature","geometry":{"coordinates":[5.865323399999999,51.8473397],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:989225414","type":"poi","label":"H&M","name":"H&M","postcode":"6511RA","city":null,"citycode":null,"administrative_regions":[],"poi_types":[{"id":"poi_type:shop:clothes","name":"Kledingwinkel"}],"properties":[{"key":"addr:city","value":"Nijmegen"},{"key":"addr:country","value":"NL"},{"key":"addr:housenumber","value":"1"},{"key":"addr:postcode","value":"6511RA"},{"key":"addr:street","value":"Burchtstraat"},{"key":"name","value":"H&M"},
{"key":"shop","value":"clothes"},{"key":"source:date","value":"2014-05-07"},{"key":"wheelchair","value":"yes"}],"address":{"id":"addr:5.8652752;51.8473134:4","type":"house","label":"Gapershof
4","name":null,"housenumber":null,"street":"Mariënburg","postcode":null,"city":null,"citycode":null,"administrative_regions":[]}}}}]}'
http_version: null
recorded_at: Thu, 09 Nov 1989 17:57:00 GMT
recorded_with: VCR 5.1.0

+ 63
- 0
test/fixtures/vcr_cassettes/city_arnhem.yml
File diff suppressed because it is too large
View File


+ 62
- 0
test/fixtures/vcr_cassettes/city_den_bosch.yml
File diff suppressed because it is too large
View File


+ 65
- 0
test/fixtures/vcr_cassettes/city_eindhoven.yml View File

@@ -0,0 +1,65 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/autocomplete?limit=1&q=eindhoven&type%5B%5D=city
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200
message: OK
headers:
content-length:
- '1272'
connection:
- close
content-type:
- application/json
cache-control:
- max-age=3600
date:
- Wed, 17 Jun 2020 12:29:56 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[{"type":"Feature","geometry":{"coordinates":[5.478632999999999,51.4392648],"type":"Point"},"properties":{"geocoding":{"id":"admin:osm:relation:296014","type":"zone","zone_type":"city","label":"Eindhoven,
Noord-Brabant, Nederland","name":"Eindhoven","postcode":null,"city":null,"citycode":"","level":10,"administrative_regions":[{"id":"admin:osm:relation:47696","insee":"","level":4,"label":"Noord-Brabant,
Nederland","name":"Noord-Brabant","zip_codes":[],"coord":{"lon":5.3031044,"lat":51.688935099999995},"bbox":[4.1901242,51.2209094,6.0481207999999995,51.830751],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-NB"},{"name":"ref:provinciecode","value":"30"},{"name":"wikidata","value":"Q1101"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"codes":[{"name":"ref:woonplaatscode","value":"1101"},{"name":"wikidata","value":"Q9832"}],"bbox":[5.3567184,51.4000475,5.5488528,51.4970779]}}}]}'
http_version: null
recorded_at: Wed, 17 Jun 2020 12:29:56 GMT
- request:
method: post
uri: http://localhost:4000/features?lat=51.4392648&limit=20&lon=5.478632999999999&type%5B%5D=poi
body:
encoding: UTF-8
string: '{"shape":{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[5.3567184,51.4000475],[5.5488528,51.4000475],[5.5488528,51.4970779],[5.3567184,51.4970779],[5.3567184,51.4000475]]]},"properties":{}}}'
headers:
User-Agent:
- Faraday v1.0.0
Content-Type:
- application/json
response:
status:
code: 200
message: OK
headers:
content-length:
- '61699'
connection:
- close
content-type:
- application/json
cache-control:
- max-age=3600
date:
- Wed, 17 Jun 2020 12:29:56 GMT
body:
encoding: ASCII-8BIT
string: '{ "type": "FeatureCollection", "geocoding": { "version": "0.1.0", "query": "" }, "features": [] }'
http_version: null
recorded_at: Wed, 17 Jun 2020 12:29:57 GMT
recorded_with: VCR 5.1.0

+ 60
- 0
test/fixtures/vcr_cassettes/city_error_400.yml View File

@@ -0,0 +1,60 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/autocomplete?limit=1&q=foo&type%5B%5D=city
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200
message: OK
headers:
content-length:
- '85'
connection:
- close
content-type:
- application/json
cache-control:
- max-age=3600
date:
- Mon, 15 Jun 2020 14:40:53 GMT
body:
encoding: UTF-8
## Note to emulate reailyt that goes amiss: return empty BBOX
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[{"type":"Feature","geometry":{"coordinates":[5.9108573,51.984257],"type":"Point"},"properties":{"geocoding":{"bbox":[]}}}]}'
http_version: null
recorded_at: Mon, 15 Jun 2020 14:40:53 GMT
- request:
method: post
uri: http://localhost:4000/features?lat=51.984257&limit=20&lon=5.9108573&type%5B%5D=poi
body:
encoding: UTF-8
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 400
message: Bad Request
headers:
content-length:
- '70'
connection:
- close
content-type:
- application/json
date:
- Mon, 15 Jun 2020 14:40:53 GMT
body:
encoding: UTF-8
string: '{"short":"validation error","long":"invalid json: Content type error"}'
http_version: null
recorded_at: Mon, 15 Jun 2020 14:40:53 GMT
recorded_with: VCR 5.1.0

+ 63
- 0
test/fixtures/vcr_cassettes/city_nijmegen.yml
File diff suppressed because it is too large
View File


+ 31
- 0
test/fixtures/vcr_cassettes/city_not_found.yml View File

@@ -0,0 +1,31 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/autocomplete?limit=1&q=nonexisting&type%5B%5D=city
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200 # NOTE: thsi is correct: Bragi returns a 200 when no city is found
message: OK
headers:
content-length:
- '85'
connection:
- close
content-type:
- application/json
cache-control:
- max-age=3600
date:
- Wed, 17 Jun 2020 12:48:18 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[]}'
http_version: null
recorded_at: Wed, 17 Jun 2020 12:48:18 GMT

+ 64
- 0
test/fixtures/vcr_cassettes/city_zuidwolde.yml
File diff suppressed because it is too large
View File


+ 198
- 0
test/fixtures/vcr_cassettes/city_zuidwolde_drenthe.yml View File

@@ -0,0 +1,198 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/autocomplete?limit=1&q=zuidwolde-drenthe&type%5B%5D=city
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200
message: OK
headers:
content-length:
- '1276'
connection:
- close
cache-control:
- max-age=3600
content-type:
- application/json
date:
- Sun, 14 Jun 2020 16:09:08 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[{"type":"Feature","geometry":{"coordinates":[6.41926898445426,52.66255725914056],"type":"Point"},"properties":{"geocoding":{"id":"admin:osm:relation:2681061","type":"zone","zone_type":"city","label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","postcode":null,"city":null,"citycode":"","level":10,"administrative_regions":[{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}],"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816]}}}]}'
http_version: null
recorded_at: Sun, 14 Jun 2020 16:09:08 GMT
- request:
method: post
uri: http://localhost:4000/features?lat=52.66255725914056&limit=20&lon=6.41926898445426&type%5B%5D=poi
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200
message: OK
headers:
content-length:
- '61250'
connection:
- close
cache-control:
- max-age=3600
content-type:
- application/json
date:
- Sun, 14 Jun 2020 16:09:08 GMT
body:
encoding: UTF-8
string: '{"type":"FeatureCollection","geocoding":{"version":"0.1.0","query":""},"features":[{"type":"Feature","geometry":{"coordinates":[6.4186128,52.666644899999994],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:1591501026","type":"poi","label":"Cultuurhistorisch
Museum de Wemme (Zuidwolde)","name":"Cultuurhistorisch Museum de Wemme","postcode":"7921KB","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:museum","name":"Museum"}],"properties":[{"key":"addr:city","value":"Zuidwolde"},{"key":"addr:housenumber","value":"49"},{"key":"addr:postcode","value":"7921KB"},{"key":"addr:street","value":"Burgemeester
Tonckensstraat"},{"key":"name","value":"Cultuurhistorisch Museum de Wemme"},{"key":"tourism","value":"museum"},{"key":"website","value":"https://www.dewemme.nl/"}],"address":{"id":"addr:6.4187186;52.6664665:49-ts","type":"house","label":"Burgemeester
Tonckensstraat 49-ts (Zuidwolde)","name":"Burgemeester Tonckensstraat 49-ts","housenumber":"49-ts","street":"Burgemeester
Tonckensstraat","postcode":"7921KB","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":456},{"type":"Feature","geometry":{"coordinates":[6.4198562,52.6669778],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:4154107900","type":"poi","label":"Toeristeninformatie
(Zuidwolde)","name":"Toeristeninformatie","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:information","name":"Toeristeninformatie"}],"properties":[{"key":"bicycle","value":"yes"},{"key":"guidepost","value":"paddenstoel"},{"key":"hiking","value":"yes"},{"key":"horse","value":"yes"},{"key":"information","value":"guidepost"},{"key":"mtb","value":"yes"},{"key":"operator","value":"Nationale
Bewegwijzeringsdienst"},{"key":"ref","value":"23590/001"},{"key":"tourism","value":"information"}],"address":{"id":"addr:6.419561;52.6671246:48","type":"house","label":"Burgemeester
Tonckensstraat 48 (Zuidwolde)","name":"Burgemeester Tonckensstraat 48","housenumber":"48","street":"Burgemeester
Tonckensstraat","postcode":"7921KD","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":493},{"type":"Feature","geometry":{"coordinates":[6.4226535,52.6672818],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:2818938765","type":"poi","label":"BBcare
(Zuidwolde)","name":"BBcare","postcode":"7921EL","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:shop:clothes","name":"Kledingwinkel"}],"properties":[{"key":"addr:city","value":"Zuidwolde"},{"key":"addr:housenumber","value":"2"},{"key":"addr:postcode","value":"7921EL"},{"key":"addr:street","value":"De
Zoom"},{"key":"clothes","value":"women;Mammacare_Adviseur"},{"key":"name","value":"BBcare"},{"key":"operator","value":"Betty
van den Berg"},{"key":"shop","value":"clothes"},{"key":"source","value":"BAG"},{"key":"source:date","value":"2014-03-24"}],"address":{"id":"addr:6.4226909;52.6672846:2","type":"house","label":"De
Zoom 2 (Zuidwolde)","name":"De Zoom 2","housenumber":"2","street":"De Zoom","postcode":"7921EL","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":572},{"type":"Feature","geometry":{"coordinates":[6.419629,52.669721499999994],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:4154107936","type":"poi","label":"Toeristeninformatie
(Zuidwolde)","name":"Toeristeninformatie","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:information","name":"Toeristeninformatie"}],"properties":[{"key":"bicycle","value":"yes"},{"key":"guidepost","value":"paddenstoel"},{"key":"hiking","value":"yes"},{"key":"horse","value":"yes"},{"key":"information","value":"guidepost"},{"key":"mtb","value":"yes"},{"key":"operator","value":"Nationale
Bewegwijzeringsdienst"},{"key":"ref","value":"23589/001"},{"key":"tourism","value":"information"}],"address":{"id":"addr:6.419885;52.6699641:16c","type":"house","label":"Westerveldseweg
16c (Zuidwolde)","name":"Westerveldseweg 16c","housenumber":"16c","street":"Westerveldseweg","postcode":"7921NB","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":796},{"type":"Feature","geometry":{"coordinates":[6.428754199999999,52.6694232],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:2590212313","type":"poi","label":"Chinees
Indisch Restaurant Tong-Fang (Zuidwolde)","name":"Chinees Indisch Restaurant
Tong-Fang","postcode":"7921AR","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:restaurant","name":"Restaurant"}],"properties":[{"key":"addr:city","value":"Zuidwolde"},{"key":"addr:housenumber","value":"122"},{"key":"addr:postcode","value":"7921AR"},{"key":"addr:street","value":"Hoofdstraat"},{"key":"amenity","value":"restaurant"},{"key":"contact:email","value":"tongfang@live.nl"},{"key":"contact:phone","value":"+31
528 372665"},{"key":"contact:website","value":"http://www.chineeszuidwolde.nl/"},{"key":"cuisine","value":"chinese"},{"key":"name","value":"Chinees
Indisch Restaurant Tong-Fang"}],"address":{"id":"addr:6.4286319;52.6694253:122","type":"house","label":"Hoofdstraat
122 (Zuidwolde)","name":"Hoofdstraat 122","housenumber":"122","street":"Hoofdstraat","postcode":"7921AR","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":995},{"type":"Feature","geometry":{"coordinates":[6.414575,52.653766],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:4154107896","type":"poi","label":"Toeristeninformatie
(Zuidwolde)","name":"Toeristeninformatie","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:information","name":"Toeristeninformatie"}],"properties":[{"key":"bicycle","value":"yes"},{"key":"guidepost","value":"paddenstoel"},{"key":"hiking","value":"yes"},{"key":"horse","value":"yes"},{"key":"information","value":"guidepost"},{"key":"mtb","value":"yes"},{"key":"operator","value":"Nationale
Bewegwijzeringsdienst"},{"key":"ref","value":"23591/001"},{"key":"tourism","value":"information"}],"address":{"id":"addr:6.4142362;52.6544594:8","type":"house","label":"Kerkweg
8 (Zuidwolde)","name":"Kerkweg 8","housenumber":"8","street":"Kerkweg","postcode":"7921RP","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1027},{"type":"Feature","geometry":{"coordinates":[6.4295592,52.6703182],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:552561686","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"}],"address":{"id":"addr:6.4298359;52.6704215:1","type":"house","label":"Burgerzinstraat
1 (Zuidwolde)","name":"Burgerzinstraat 1","housenumber":"1","street":"Burgerzinstraat","postcode":"7921JL","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1107},{"type":"Feature","geometry":{"coordinates":[6.4313167,52.669782899999994],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:730786706","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"}],"address":{"id":"street:osm:way:6437187","type":"street","label":"Zuider
Esweg (Zuidwolde)","name":"Zuider Esweg","street":"Zuider Esweg","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1142},{"type":"Feature","geometry":{"coordinates":[6.4294369,52.671040299999994],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:2767669986","type":"poi","label":"Kruidvat
(Zuidwolde)","name":"Kruidvat","postcode":"7921AG","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:shop:chemist","name":"Drogist"}],"properties":[{"key":"addr:city","value":"Zuidwolde"},{"key":"addr:housenumber","value":"111A"},{"key":"addr:postcode","value":"7921AG"},{"key":"addr:street","value":"Hoofdstraat"},{"key":"brand","value":"Kruidvat"},{"key":"brand:wikidata","value":"Q2226366"},{"key":"brand:wikipedia","value":"en:Kruidvat"},{"key":"name","value":"Kruidvat"},{"key":"operator","value":"Kruidvat"},{"key":"shop","value":"chemist"},{"key":"source","value":"BAG"},{"key":"website","value":"https://www.kruidvat.nl/"}],"address":{"id":"addr:6.4294534;52.6710712:111a","type":"house","label":"Hoofdstraat
111a (Zuidwolde)","name":"Hoofdstraat 111a","housenumber":"111a","street":"Hoofdstraat","postcode":"7921AG","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1166},{"type":"Feature","geometry":{"coordinates":[6.4348648,52.667192799999995],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:397000952","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"access","value":"customers"},{"key":"amenity","value":"parking"},{"key":"fee","value":"no"},{"key":"parking","value":"surface"}],"address":{"id":"addr:6.4350924;52.667226:14a","type":"house","label":"Nijverheidsweg
14a (Zuidwolde)","name":"Nijverheidsweg 14a","housenumber":"14a","street":"Nijverheidsweg","postcode":"7921JJ","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1171},{"type":"Feature","geometry":{"coordinates":[6.42943,52.6711342],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:2590383362","type":"poi","label":"Bloemen
(Zuidwolde)","name":"Bloemen","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:shop:florist","name":"Bloemenwinkel"}],"properties":[{"key":"name","value":"Bloemen"},{"key":"shop","value":"florist"}],"address":{"id":"addr:6.4294648;52.6711578:111","type":"house","label":"Hoofdstraat
111 (Zuidwolde)","name":"Hoofdstraat 111","housenumber":"111","street":"Hoofdstraat","postcode":"7921AG","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1174},{"type":"Feature","geometry":{"coordinates":[6.4356186,52.666725],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:397000955","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"},{"key":"parking","value":"surface"}],"address":{"id":"addr:6.4350698;52.6667817:14","type":"house","label":"Nijverheidsweg
14 (Zuidwolde)","name":"Nijverheidsweg 14","housenumber":"14","street":"Nijverheidsweg","postcode":"7921JJ","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1196},{"type":"Feature","geometry":{"coordinates":[6.4305802,52.671006],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:264336812","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"}],"address":{"id":"addr:6.4308575;52.6711259:6a","type":"house","label":"Zuider
Esweg 6a (Zuidwolde)","name":"Zuider Esweg 6a","housenumber":"6a","street":"Zuider
Esweg","postcode":"7921JE","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1210},{"type":"Feature","geometry":{"coordinates":[6.429585599999999,52.6714759],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:2599631016","type":"poi","label":"Grillroom
Yusuf (Zuidwolde)","name":"Grillroom Yusuf","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:restaurant","name":"Restaurant"}],"properties":[{"key":"amenity","value":"restaurant"},{"key":"cuisine","value":"kebab"},{"key":"name","value":"Grillroom
Yusuf"}],"address":{"id":"addr:6.4295908;52.6714781:107a","type":"house","label":"Hoofdstraat
107a (Zuidwolde)","name":"Hoofdstraat 107a","housenumber":"107a","street":"Hoofdstraat","postcode":"7921AG","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1211},{"type":"Feature","geometry":{"coordinates":[6.4359901,52.6667835],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:397000956","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"},{"key":"parking","value":"surface"}],"address":{"id":"addr:6.4360861;52.6664275:1","type":"house","label":"Industrieweg
1 (Zuidwolde)","name":"Industrieweg 1","housenumber":"1","street":"Industrieweg","postcode":"7921JP","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1221},{"type":"Feature","geometry":{"coordinates":[6.4333047,52.6695347],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:730275960","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"}],"address":{"id":"addr:6.43328;52.6695911:17c","type":"house","label":"Zuider
Esweg 17c (Zuidwolde)","name":"Zuider Esweg 17c","housenumber":"17c","street":"Zuider
Esweg","postcode":"7921JC","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1223},{"type":"Feature","geometry":{"coordinates":[6.4358358,52.6674519],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:node:3226450563","type":"poi","label":"Argos
(Zuidwolde)","name":"Argos","postcode":"7921JH","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:fuel","name":"Benzinestation"}],"properties":[{"key":"addr:city","value":"Zuidwolde"},{"key":"addr:housenumber","value":"19"},{"key":"addr:postcode","value":"7921JH"},{"key":"addr:street","value":"Nijverheidsweg"},{"key":"amenity","value":"fuel"},{"key":"brand","value":"Argos"},{"key":"fuel:diesel","value":"yes"},{"key":"fuel:octane_95","value":"yes"},{"key":"name","value":"Argos"},{"key":"opening_hours","value":"24/7"},{"key":"operator","value":"Varo
Energy"},{"key":"self_service","value":"yes"},{"key":"website","value":"https://www.argos.nl/tankstation/argos-zuidwolde/"}],"address":{"id":"addr:6.4362025;52.6676799:19","type":"house","label":"Nijverheidsweg
19 (Zuidwolde)","name":"Nijverheidsweg 19","housenumber":"19","street":"Nijverheidsweg","postcode":"7921JH","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1242},{"type":"Feature","geometry":{"coordinates":[6.4308872,52.6719695],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:263088747","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"}],"address":{"id":"addr:6.4310375;52.6720672:7","type":"house","label":"Zantingehof
7 (Zuidwolde)","name":"Zantingehof 7","housenumber":"7","street":"Zantingehof","postcode":"7921GG","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1307},{"type":"Feature","geometry":{"coordinates":[6.4323877,52.671317599999995],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:730786709","type":"poi","label":"Parkeren
(Zuidwolde)","name":"Parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"}],"address":{"id":"addr:6.4323517;52.6715594:14","type":"house","label":"Oosterweg
14 (Zuidwolde)","name":"Oosterweg 14","housenumber":"14","street":"Oosterweg","postcode":"7921GB","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1315},{"type":"Feature","geometry":{"coordinates":[6.429916899999999,52.67252],"type":"Point"},"properties":{"geocoding":{"id":"poi:osm:way:253032464","type":"poi","label":"parkeren
(Zuidwolde)","name":"parkeren","postcode":null,"city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}],"poi_types":[{"id":"poi_type:amenity:parking","name":"Parkeren"}],"properties":[{"key":"amenity","value":"parking"},{"key":"name","value":"parkeren"},{"key":"parking","value":"surface"}],"address":{"id":"addr:6.4299699;52.6723526:103","type":"house","label":"Hoofdstraat
103 (Zuidwolde)","name":"Hoofdstraat 103","housenumber":"103","street":"Hoofdstraat","postcode":"7921AG","city":"Zuidwolde","citycode":"","administrative_regions":[{"id":"admin:osm:relation:2681061","insee":"","level":10,"label":"Zuidwolde,
Drenthe, Nederland","name":"Zuidwolde","zip_codes":[],"coord":{"lon":6.41926898445426,"lat":52.66255725914056},"bbox":[6.3663966,52.612184899999995,6.466306299999999,52.7069816],"zone_type":"city","parent_id":"admin:osm:relation:47540","codes":[{"name":"ref:woonplaatscode","value":"3172"},{"name":"wikidata","value":"Q2754055"}]},{"id":"admin:osm:relation:47540","insee":"","level":4,"label":"Drenthe,
Nederland","name":"Drenthe","zip_codes":[],"coord":{"lon":6.560553,"lat":52.9953538},"bbox":[6.11982,52.612184899999995,7.0927397,53.203832299999995],"zone_type":"state","parent_id":"admin:osm:relation:47796","codes":[{"name":"ISO3166-2","value":"NL-DR"},{"name":"ref:provinciecode","value":"22"},{"name":"wikidata","value":"Q772"}]},{"id":"admin:osm:relation:47796","insee":"","level":3,"label":"Nederland","name":"Nederland","zip_codes":[],"coord":{"lon":4.8936041,"lat":52.3727598},"bbox":[3.080161,50.7503658,7.227498499999999,53.744025],"zone_type":"country","parent_id":null,"codes":[{"name":"wikidata","value":"Q55"}]}]}}},"distance":1320}]}'
http_version: null
recorded_at: Sun, 14 Jun 2020 16:09:08 GMT
recorded_with: VCR 5.1.0

+ 64
- 0
test/fixtures/vcr_cassettes/city_zuidwolde_groningen.yml
File diff suppressed because it is too large
View File


+ 63
- 0
test/fixtures/vcr_cassettes/hacked.yml View File

@@ -0,0 +1,63 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/features/poi:osm:node:1337
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v1.0.0
response:
status:
code: 200
message: OK
headers:
content-length:
- '1186'
connection:
- close
content-type:
- application/json
cache-control:
- max-age=3600
date:
- Wed, 26 Mar 2020 16:14:01 GMT
body:
encoding: UTF-8
string:
'{"type":"FeatureCollection", "geocoding":{"version":"0.1.0", "query":""},
"features":[
{"type":"Feature",
"geometry":{"coordinates":[5.865323399999999, 51.8473397], "type":"Point"},
"properties":{
"geocoding":{"id":"poi:osm:node:989225414",
"type":"poi",
"label":"H&M",
"name":"H@ckedM",
"postcode":"6511RA",
"city":null,
"citycode":null,
"administrative_regions":[],
"poi_types":[{"id":"poi_type:shop:clothes",
"name":"Kledingwinkel"}],
"properties":[],
"address":{
"id":"addr:5.8652752;51.8473134:4",
"type":"house",
"label": "",
"name":null,
"housenumber":null,
"street":"Mariënburg",
"postcode":"<script>alert(\"1000AB\")</script>",
"city":null,
"citycode":null,
"administrative_regions":[]
}
}
}
}]}'
http_version: null
recorded_at: Thu, 09 Nov 1989 17:57:00 GMT
recorded_with: VCR 5.1.0

+ 30
- 0
test/fixtures/vcr_cassettes/no_node_found.yml View File

@@ -0,0 +1,30 @@
---
http_interactions:
- request:
method: get
uri: http://localhost:4000/features/poi:osm:node:42