overture_maps 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +29 -0
- data/LICENSE.txt +21 -0
- data/README.md +416 -0
- data/app/controllers/overture_maps/application_controller.rb +28 -0
- data/app/controllers/overture_maps/attribution_controller.rb +15 -0
- data/app/controllers/overture_maps/features_controller.rb +125 -0
- data/app/controllers/overture_maps/search_controller.rb +31 -0
- data/app/controllers/overture_maps/tiles_controller.rb +85 -0
- data/config/routes.rb +13 -0
- data/exe/overture-maps-mcp +6 -0
- data/lib/generators/overture_maps/address_generator.rb +19 -0
- data/lib/generators/overture_maps/base_features_generator.rb +19 -0
- data/lib/generators/overture_maps/base_generator.rb +22 -0
- data/lib/generators/overture_maps/building_generator.rb +19 -0
- data/lib/generators/overture_maps/division_generator.rb +19 -0
- data/lib/generators/overture_maps/install_generator.rb +42 -0
- data/lib/generators/overture_maps/place_generator.rb +19 -0
- data/lib/generators/overture_maps/transportation_generator.rb +20 -0
- data/lib/generators/templates/address_migration.rb.tt +25 -0
- data/lib/generators/templates/address_model.rb.tt +4 -0
- data/lib/generators/templates/base_feature_model.rb.tt +4 -0
- data/lib/generators/templates/base_features_migration.rb.tt +27 -0
- data/lib/generators/templates/building_migration.rb.tt +24 -0
- data/lib/generators/templates/building_model.rb.tt +4 -0
- data/lib/generators/templates/category_migration.rb.tt +15 -0
- data/lib/generators/templates/category_model.rb.tt +4 -0
- data/lib/generators/templates/connector_model.rb.tt +4 -0
- data/lib/generators/templates/division_migration.rb.tt +31 -0
- data/lib/generators/templates/division_model.rb.tt +4 -0
- data/lib/generators/templates/imported_areas_migration.rb.tt +20 -0
- data/lib/generators/templates/place_migration.rb.tt +30 -0
- data/lib/generators/templates/place_model.rb.tt +4 -0
- data/lib/generators/templates/postgis_migration.rb.tt +5 -0
- data/lib/generators/templates/segment_model.rb.tt +4 -0
- data/lib/generators/templates/transportation_migration.rb.tt +38 -0
- data/lib/overture_maps/attribution.rb +66 -0
- data/lib/overture_maps/bounding_box.rb +80 -0
- data/lib/overture_maps/changelog.rb +70 -0
- data/lib/overture_maps/configuration.rb +43 -0
- data/lib/overture_maps/database.rb +74 -0
- data/lib/overture_maps/division_search.rb +44 -0
- data/lib/overture_maps/engine.rb +32 -0
- data/lib/overture_maps/geometry_parser.rb +41 -0
- data/lib/overture_maps/gers.rb +30 -0
- data/lib/overture_maps/import/downloader.rb +248 -0
- data/lib/overture_maps/import/location_based_runner.rb +176 -0
- data/lib/overture_maps/import/parquet_reader.rb +32 -0
- data/lib/overture_maps/import/record_mapper.rb +182 -0
- data/lib/overture_maps/import/runner.rb +125 -0
- data/lib/overture_maps/import.rb +27 -0
- data/lib/overture_maps/mcp_server.rb +222 -0
- data/lib/overture_maps/models/address.rb +32 -0
- data/lib/overture_maps/models/base.rb +39 -0
- data/lib/overture_maps/models/base_feature.rb +31 -0
- data/lib/overture_maps/models/building.rb +35 -0
- data/lib/overture_maps/models/category.rb +32 -0
- data/lib/overture_maps/models/connector.rb +11 -0
- data/lib/overture_maps/models/division.rb +43 -0
- data/lib/overture_maps/models/imported_area.rb +42 -0
- data/lib/overture_maps/models/place.rb +43 -0
- data/lib/overture_maps/models/segment.rb +22 -0
- data/lib/overture_maps/models.rb +25 -0
- data/lib/overture_maps/query.rb +168 -0
- data/lib/overture_maps/query_engine.rb +268 -0
- data/lib/overture_maps/releases.rb +74 -0
- data/lib/overture_maps/storage.rb +121 -0
- data/lib/overture_maps/syncer.rb +99 -0
- data/lib/overture_maps/util.rb +30 -0
- data/lib/overture_maps/version.rb +3 -0
- data/lib/overture_maps.rb +42 -0
- data/lib/tasks/overture_maps.rake +554 -0
- metadata +301 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OvertureMaps
|
|
4
|
+
# Mapbox Vector Tiles straight from PostGIS:
|
|
5
|
+
#
|
|
6
|
+
# GET /overture/tiles/places/14/2620/5723.mvt
|
|
7
|
+
#
|
|
8
|
+
# MapLibre/Leaflet can render imported data with no separate tile server:
|
|
9
|
+
# map.addSource("places", { type: "vector",
|
|
10
|
+
# tiles: ["https://app.example.com/overture/tiles/places/{z}/{x}/{y}.mvt"] })
|
|
11
|
+
class TilesController < ApplicationController
|
|
12
|
+
LAYERS = FeaturesController::RESOURCES
|
|
13
|
+
|
|
14
|
+
PROPERTY_COLUMNS = {
|
|
15
|
+
"places" => %w[name primary_category confidence country],
|
|
16
|
+
"buildings" => %w[name subtype building_class height num_floors],
|
|
17
|
+
"addresses" => %w[number street locality postcode],
|
|
18
|
+
"divisions" => %w[name subtype country],
|
|
19
|
+
"segments" => %w[name subtype segment_class],
|
|
20
|
+
"connectors" => %w[],
|
|
21
|
+
"base_features" => %w[name feature_type subtype feature_class]
|
|
22
|
+
}.freeze
|
|
23
|
+
|
|
24
|
+
MAX_ZOOM = 22
|
|
25
|
+
TILE_EXTENT = 4096
|
|
26
|
+
TILE_BUFFER = 64
|
|
27
|
+
# Half a buffer's worth of envelope margin so buffered geometries at the
|
|
28
|
+
# tile edge are included.
|
|
29
|
+
ENVELOPE_MARGIN = TILE_BUFFER.to_f / TILE_EXTENT
|
|
30
|
+
|
|
31
|
+
def show
|
|
32
|
+
layer = params[:layer]
|
|
33
|
+
model = LAYERS[layer]
|
|
34
|
+
return render json: { error: "unknown layer" }, status: :not_found unless model
|
|
35
|
+
|
|
36
|
+
z, x, y = tile_coordinates
|
|
37
|
+
tile = build_tile(model, layer, z, x, y)
|
|
38
|
+
|
|
39
|
+
expires_in 1.hour, public: true
|
|
40
|
+
send_data tile, type: "application/vnd.mapbox-vector-tile", disposition: "inline"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def tile_coordinates
|
|
46
|
+
z = Integer(params[:z])
|
|
47
|
+
x = Integer(params[:x])
|
|
48
|
+
y = Integer(params[:y])
|
|
49
|
+
max_index = (2**z) - 1
|
|
50
|
+
unless z.between?(0, MAX_ZOOM) && x.between?(0, max_index) && y.between?(0, max_index)
|
|
51
|
+
raise ArgumentError, "tile coordinates out of range"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
[z, x, y]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def build_tile(model, layer, z, x, y)
|
|
58
|
+
connection = model.connection
|
|
59
|
+
columns = (PROPERTY_COLUMNS.fetch(layer, []) & model.column_names)
|
|
60
|
+
.map { |c| ", #{connection.quote_column_name(c)}" }.join
|
|
61
|
+
|
|
62
|
+
sql = ActiveRecord::Base.sanitize_sql(
|
|
63
|
+
[<<~SQL, { z: z, x: x, y: y, margin: ENVELOPE_MARGIN, limit: OvertureMaps.configuration.tile_feature_limit }]
|
|
64
|
+
WITH mvtgeom AS (
|
|
65
|
+
SELECT ST_AsMVTGeom(
|
|
66
|
+
ST_Transform(geometry::geometry, 3857),
|
|
67
|
+
ST_TileEnvelope(:z, :x, :y),
|
|
68
|
+
#{TILE_EXTENT}, #{TILE_BUFFER}, true
|
|
69
|
+
) AS geom,
|
|
70
|
+
id#{columns}
|
|
71
|
+
FROM #{model.quoted_table_name}
|
|
72
|
+
WHERE geometry && ST_Transform(ST_TileEnvelope(:z, :x, :y, margin => :margin), 4326)::geography
|
|
73
|
+
LIMIT :limit
|
|
74
|
+
)
|
|
75
|
+
SELECT ST_AsMVT(mvtgeom.*, #{connection.quote(layer)}, #{TILE_EXTENT}, 'geom')
|
|
76
|
+
FROM mvtgeom WHERE geom IS NOT NULL
|
|
77
|
+
SQL
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
value = connection.select_value(sql) || ""
|
|
81
|
+
# Raw query results may arrive as hex-escaped bytea.
|
|
82
|
+
value.start_with?("\\x") ? [value.delete_prefix("\\x")].pack("H*") : value
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
OvertureMaps::Engine.routes.draw do
|
|
4
|
+
resources_constraint = { resource: /places|buildings|addresses|divisions|segments|connectors|base_features/ }
|
|
5
|
+
|
|
6
|
+
get "search", to: "search#index"
|
|
7
|
+
get "attribution", to: "attribution#index"
|
|
8
|
+
get "tiles/:layer/:z/:x/:y", to: "tiles#show",
|
|
9
|
+
constraints: { z: /\d+/, x: /\d+/, y: /\d+/ }
|
|
10
|
+
|
|
11
|
+
get ":resource", to: "features#index", constraints: resources_constraint
|
|
12
|
+
get ":resource/:id", to: "features#show", constraints: resources_constraint
|
|
13
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "generators/overture_maps/base_generator"
|
|
4
|
+
|
|
5
|
+
module OvertureMaps
|
|
6
|
+
module Generators
|
|
7
|
+
class AddressGenerator < BaseGenerator
|
|
8
|
+
desc "Creates the overture_addresses table and model"
|
|
9
|
+
|
|
10
|
+
def create_migration
|
|
11
|
+
migration_template "address_migration.rb.tt", "db/migrate/create_overture_addresses.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_model
|
|
15
|
+
template "address_model.rb.tt", "app/models/overture_address.rb"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "generators/overture_maps/base_generator"
|
|
4
|
+
|
|
5
|
+
module OvertureMaps
|
|
6
|
+
module Generators
|
|
7
|
+
class BaseFeaturesGenerator < BaseGenerator
|
|
8
|
+
desc "Creates the overture_base_features table and model"
|
|
9
|
+
|
|
10
|
+
def create_migration
|
|
11
|
+
migration_template "base_features_migration.rb.tt", "db/migrate/create_overture_base_features.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_model
|
|
15
|
+
template "base_feature_model.rb.tt", "app/models/overture_base_feature.rb"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "rails/generators/active_record"
|
|
5
|
+
|
|
6
|
+
module OvertureMaps
|
|
7
|
+
module Generators
|
|
8
|
+
class BaseGenerator < Rails::Generators::Base
|
|
9
|
+
include ActiveRecord::Generators::Migration
|
|
10
|
+
|
|
11
|
+
def self.default_source_root
|
|
12
|
+
File.expand_path("../templates", __dir__)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def migration_version
|
|
18
|
+
"[#{ActiveRecord::VERSION::STRING.to_f}]"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "generators/overture_maps/base_generator"
|
|
4
|
+
|
|
5
|
+
module OvertureMaps
|
|
6
|
+
module Generators
|
|
7
|
+
class BuildingGenerator < BaseGenerator
|
|
8
|
+
desc "Creates the overture_buildings table and model"
|
|
9
|
+
|
|
10
|
+
def create_migration
|
|
11
|
+
migration_template "building_migration.rb.tt", "db/migrate/create_overture_buildings.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_model
|
|
15
|
+
template "building_model.rb.tt", "app/models/overture_building.rb"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "generators/overture_maps/base_generator"
|
|
4
|
+
|
|
5
|
+
module OvertureMaps
|
|
6
|
+
module Generators
|
|
7
|
+
class DivisionGenerator < BaseGenerator
|
|
8
|
+
desc "Creates the overture_divisions table and model"
|
|
9
|
+
|
|
10
|
+
def create_migration
|
|
11
|
+
migration_template "division_migration.rb.tt", "db/migrate/create_overture_divisions.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_model
|
|
15
|
+
template "division_model.rb.tt", "app/models/overture_division.rb"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "generators/overture_maps/base_generator"
|
|
4
|
+
|
|
5
|
+
module OvertureMaps
|
|
6
|
+
module Generators
|
|
7
|
+
class InstallGenerator < BaseGenerator
|
|
8
|
+
desc "Creates the PostGIS extension, Overture tables, and model files"
|
|
9
|
+
|
|
10
|
+
def create_migrations
|
|
11
|
+
migration_template "postgis_migration.rb.tt", "db/migrate/create_overture_postgis.rb"
|
|
12
|
+
migration_template "category_migration.rb.tt", "db/migrate/create_overture_categories.rb"
|
|
13
|
+
migration_template "place_migration.rb.tt", "db/migrate/create_overture_places.rb"
|
|
14
|
+
migration_template "building_migration.rb.tt", "db/migrate/create_overture_buildings.rb"
|
|
15
|
+
migration_template "address_migration.rb.tt", "db/migrate/create_overture_addresses.rb"
|
|
16
|
+
migration_template "division_migration.rb.tt", "db/migrate/create_overture_divisions.rb"
|
|
17
|
+
migration_template "transportation_migration.rb.tt", "db/migrate/create_overture_transportation.rb"
|
|
18
|
+
migration_template "base_features_migration.rb.tt", "db/migrate/create_overture_base_features.rb"
|
|
19
|
+
migration_template "imported_areas_migration.rb.tt", "db/migrate/create_overture_imported_areas.rb"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create_models
|
|
23
|
+
template "category_model.rb.tt", "app/models/overture_category.rb"
|
|
24
|
+
template "place_model.rb.tt", "app/models/overture_place.rb"
|
|
25
|
+
template "building_model.rb.tt", "app/models/overture_building.rb"
|
|
26
|
+
template "address_model.rb.tt", "app/models/overture_address.rb"
|
|
27
|
+
template "division_model.rb.tt", "app/models/overture_division.rb"
|
|
28
|
+
template "segment_model.rb.tt", "app/models/overture_segment.rb"
|
|
29
|
+
template "connector_model.rb.tt", "app/models/overture_connector.rb"
|
|
30
|
+
template "base_feature_model.rb.tt", "app/models/overture_base_feature.rb"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add_engine_route
|
|
34
|
+
route <<~ROUTE.strip
|
|
35
|
+
# Overture Maps read-only API (JSON/GeoJSON + MVT tiles).
|
|
36
|
+
# Guard with config.api_auth in an initializer if the app is public.
|
|
37
|
+
mount OvertureMaps::Engine => "/overture"
|
|
38
|
+
ROUTE
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "generators/overture_maps/base_generator"
|
|
4
|
+
|
|
5
|
+
module OvertureMaps
|
|
6
|
+
module Generators
|
|
7
|
+
class PlaceGenerator < BaseGenerator
|
|
8
|
+
desc "Creates the overture_places table and model"
|
|
9
|
+
|
|
10
|
+
def create_migration
|
|
11
|
+
migration_template "place_migration.rb.tt", "db/migrate/create_overture_places.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_model
|
|
15
|
+
template "place_model.rb.tt", "app/models/overture_place.rb"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "generators/overture_maps/base_generator"
|
|
4
|
+
|
|
5
|
+
module OvertureMaps
|
|
6
|
+
module Generators
|
|
7
|
+
class TransportationGenerator < BaseGenerator
|
|
8
|
+
desc "Creates the overture_segments/overture_connectors tables and models"
|
|
9
|
+
|
|
10
|
+
def create_migration
|
|
11
|
+
migration_template "transportation_migration.rb.tt", "db/migrate/create_overture_transportation.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_models
|
|
15
|
+
template "segment_model.rb.tt", "app/models/overture_segment.rb"
|
|
16
|
+
template "connector_model.rb.tt", "app/models/overture_connector.rb"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class CreateOvertureAddresses < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
create_table :overture_addresses, id: :string do |t|
|
|
4
|
+
t.string :number
|
|
5
|
+
t.string :street
|
|
6
|
+
t.string :unit
|
|
7
|
+
t.string :locality
|
|
8
|
+
t.string :region
|
|
9
|
+
t.string :postcode
|
|
10
|
+
t.string :country
|
|
11
|
+
t.string :postal_city
|
|
12
|
+
t.jsonb :address_levels, default: []
|
|
13
|
+
t.jsonb :sources, default: []
|
|
14
|
+
t.string :overture_release
|
|
15
|
+
t.timestamps
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
add_column :overture_addresses, :geometry, :st_point, geographic: true, srid: 4326
|
|
19
|
+
add_index :overture_addresses, :geometry, using: :gist
|
|
20
|
+
|
|
21
|
+
add_index :overture_addresses, :country
|
|
22
|
+
add_index :overture_addresses, :locality
|
|
23
|
+
add_index :overture_addresses, :postcode
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class CreateOvertureBaseFeatures < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
create_table :overture_base_features, id: :string do |t|
|
|
4
|
+
t.string :feature_type, null: false
|
|
5
|
+
t.string :name
|
|
6
|
+
t.jsonb :names, default: {}
|
|
7
|
+
t.string :subtype
|
|
8
|
+
t.string :feature_class
|
|
9
|
+
t.string :surface
|
|
10
|
+
t.float :elevation
|
|
11
|
+
t.integer :level
|
|
12
|
+
t.string :wikidata
|
|
13
|
+
t.jsonb :source_tags, default: {}
|
|
14
|
+
t.jsonb :sources, default: []
|
|
15
|
+
t.string :overture_release
|
|
16
|
+
t.timestamps
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Base features span points, linestrings, and polygons.
|
|
20
|
+
add_column :overture_base_features, :geometry, :geometry, geographic: true, srid: 4326
|
|
21
|
+
add_index :overture_base_features, :geometry, using: :gist
|
|
22
|
+
|
|
23
|
+
add_index :overture_base_features, :feature_type
|
|
24
|
+
add_index :overture_base_features, :subtype
|
|
25
|
+
add_index :overture_base_features, :feature_class
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class CreateOvertureBuildings < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
create_table :overture_buildings, id: :string do |t|
|
|
4
|
+
t.string :name
|
|
5
|
+
t.jsonb :names, default: {}
|
|
6
|
+
t.string :subtype
|
|
7
|
+
t.string :building_class
|
|
8
|
+
t.float :height
|
|
9
|
+
t.integer :num_floors
|
|
10
|
+
t.integer :level
|
|
11
|
+
t.boolean :is_underground, default: false
|
|
12
|
+
t.jsonb :sources, default: []
|
|
13
|
+
t.string :overture_release
|
|
14
|
+
t.timestamps
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Generic geography: building footprints are polygons/multipolygons.
|
|
18
|
+
add_column :overture_buildings, :geometry, :geometry, geographic: true, srid: 4326
|
|
19
|
+
add_index :overture_buildings, :geometry, using: :gist
|
|
20
|
+
|
|
21
|
+
add_index :overture_buildings, :height
|
|
22
|
+
add_index :overture_buildings, :building_class
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class CreateOvertureCategories < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
create_table :overture_categories do |t|
|
|
4
|
+
t.string :name, null: false
|
|
5
|
+
t.string :primary_category
|
|
6
|
+
t.integer :hierarchy_level, default: 0
|
|
7
|
+
t.jsonb :taxonomy, default: []
|
|
8
|
+
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
add_index :overture_categories, :name, unique: true
|
|
13
|
+
add_index :overture_categories, :primary_category
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class CreateOvertureDivisions < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
create_table :overture_divisions, id: :string do |t|
|
|
4
|
+
t.string :division_id
|
|
5
|
+
t.string :name
|
|
6
|
+
t.jsonb :names, default: {}
|
|
7
|
+
t.string :subtype
|
|
8
|
+
t.string :division_class
|
|
9
|
+
t.string :country
|
|
10
|
+
t.string :region
|
|
11
|
+
t.boolean :is_land
|
|
12
|
+
t.boolean :is_territorial
|
|
13
|
+
t.float :bbox_xmin
|
|
14
|
+
t.float :bbox_xmax
|
|
15
|
+
t.float :bbox_ymin
|
|
16
|
+
t.float :bbox_ymax
|
|
17
|
+
t.jsonb :sources, default: []
|
|
18
|
+
t.string :overture_release
|
|
19
|
+
t.timestamps
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Division areas are polygons/multipolygons.
|
|
23
|
+
add_column :overture_divisions, :geometry, :geometry, geographic: true, srid: 4326
|
|
24
|
+
add_index :overture_divisions, :geometry, using: :gist
|
|
25
|
+
|
|
26
|
+
add_index :overture_divisions, :name
|
|
27
|
+
add_index :overture_divisions, :subtype
|
|
28
|
+
add_index :overture_divisions, :country
|
|
29
|
+
add_index :overture_divisions, :division_id
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class CreateOvertureImportedAreas < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
create_table :overture_imported_areas do |t|
|
|
4
|
+
t.string :theme, null: false
|
|
5
|
+
t.string :feature_type, null: false
|
|
6
|
+
t.string :model_class_name, null: false
|
|
7
|
+
t.string :slug, null: false
|
|
8
|
+
t.float :bbox_xmin
|
|
9
|
+
t.float :bbox_xmax
|
|
10
|
+
t.float :bbox_ymin
|
|
11
|
+
t.float :bbox_ymax
|
|
12
|
+
t.string :release, null: false
|
|
13
|
+
t.integer :records_count, default: 0
|
|
14
|
+
t.timestamps
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
add_index :overture_imported_areas, [:theme, :feature_type, :slug], unique: true
|
|
18
|
+
add_index :overture_imported_areas, :release
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class CreateOverturePlaces < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
create_table :overture_places, id: :string do |t|
|
|
4
|
+
t.string :name
|
|
5
|
+
t.jsonb :names, default: {}
|
|
6
|
+
t.jsonb :categories, default: {}
|
|
7
|
+
t.string :primary_category
|
|
8
|
+
t.jsonb :brands, default: {}
|
|
9
|
+
t.jsonb :addresses, default: []
|
|
10
|
+
t.jsonb :sources, default: []
|
|
11
|
+
t.jsonb :websites, default: []
|
|
12
|
+
t.jsonb :socials, default: []
|
|
13
|
+
t.jsonb :emails, default: []
|
|
14
|
+
t.jsonb :phones, default: []
|
|
15
|
+
t.decimal :confidence, precision: 3, scale: 2
|
|
16
|
+
t.string :operating_status
|
|
17
|
+
t.string :country
|
|
18
|
+
t.string :overture_release
|
|
19
|
+
t.timestamps
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
add_column :overture_places, :geometry, :st_point, geographic: true, srid: 4326
|
|
23
|
+
add_index :overture_places, :geometry, using: :gist
|
|
24
|
+
|
|
25
|
+
add_index :overture_places, :name
|
|
26
|
+
add_index :overture_places, :country
|
|
27
|
+
add_index :overture_places, :primary_category
|
|
28
|
+
add_index :overture_places, :categories, using: :gin
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class CreateOvertureTransportation < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
create_table :overture_segments, id: :string do |t|
|
|
4
|
+
t.string :name
|
|
5
|
+
t.jsonb :names, default: {}
|
|
6
|
+
t.string :subtype
|
|
7
|
+
t.string :segment_class
|
|
8
|
+
t.string :subclass
|
|
9
|
+
t.jsonb :connectors, default: []
|
|
10
|
+
t.jsonb :routes, default: []
|
|
11
|
+
t.jsonb :speed_limits, default: []
|
|
12
|
+
t.jsonb :access_restrictions, default: []
|
|
13
|
+
t.jsonb :prohibited_transitions, default: []
|
|
14
|
+
t.jsonb :road_surface, default: []
|
|
15
|
+
t.jsonb :road_flags, default: []
|
|
16
|
+
t.jsonb :destinations, default: []
|
|
17
|
+
t.jsonb :sources, default: []
|
|
18
|
+
t.string :overture_release
|
|
19
|
+
t.timestamps
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Segments are linestrings.
|
|
23
|
+
add_column :overture_segments, :geometry, :geometry, geographic: true, srid: 4326
|
|
24
|
+
add_index :overture_segments, :geometry, using: :gist
|
|
25
|
+
|
|
26
|
+
add_index :overture_segments, :subtype
|
|
27
|
+
add_index :overture_segments, :segment_class
|
|
28
|
+
|
|
29
|
+
create_table :overture_connectors, id: :string do |t|
|
|
30
|
+
t.jsonb :sources, default: []
|
|
31
|
+
t.string :overture_release
|
|
32
|
+
t.timestamps
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
add_column :overture_connectors, :geometry, :st_point, geographic: true, srid: 4326
|
|
36
|
+
add_index :overture_connectors, :geometry, using: :gist
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OvertureMaps
|
|
4
|
+
# Builds license-correct attribution from the data actually imported. The
|
|
5
|
+
# `sources` column preserved on every row records which upstream datasets
|
|
6
|
+
# contributed, which is what determines the required notices:
|
|
7
|
+
#
|
|
8
|
+
# OvertureMaps::Attribution.notices # => array of notice strings
|
|
9
|
+
# OvertureMaps::Attribution.text # => single line for a map corner
|
|
10
|
+
#
|
|
11
|
+
# Overture licensing: ODbL for OSM-derived themes (base, buildings,
|
|
12
|
+
# divisions, transportation), CDLA-Permissive-2.0 for places (Foursquare
|
|
13
|
+
# requires referencing their NOTICE), per-source terms for addresses.
|
|
14
|
+
# See https://docs.overturemaps.org/attribution/
|
|
15
|
+
module Attribution
|
|
16
|
+
FOURSQUARE_NOTICE_URL = "https://opensource.foursquare.com/places-notice-txt/"
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
def notices(models: default_models)
|
|
20
|
+
datasets = dataset_names(models: models)
|
|
21
|
+
|
|
22
|
+
notices = ["Overture Maps Foundation — overturemaps.org"]
|
|
23
|
+
notices << "© OpenStreetMap contributors (ODbL)" if datasets.any? { |d| d.match?(/openstreetmap|\bosm\b/i) }
|
|
24
|
+
if datasets.any? { |d| d.match?(/foursquare/i) }
|
|
25
|
+
notices << "Includes Foursquare data (CDLA-Permissive-2.0) — see #{FOURSQUARE_NOTICE_URL}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
remaining = datasets.reject { |d| d.match?(/openstreetmap|\bosm\b|foursquare/i) }
|
|
29
|
+
notices << "Data sources: #{remaining.sort.join(", ")}" if remaining.any?
|
|
30
|
+
notices
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def text(models: default_models)
|
|
34
|
+
notices(models: models).join(" · ")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Distinct upstream dataset names across the given models' sources
|
|
38
|
+
# columns.
|
|
39
|
+
def dataset_names(models: default_models)
|
|
40
|
+
models.flat_map { |model| datasets_for(model) }.uniq
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def datasets_for(model)
|
|
44
|
+
return [] unless model.table_exists? && model.column_names.include?("sources")
|
|
45
|
+
|
|
46
|
+
model.connection.select_values(<<~SQL).compact
|
|
47
|
+
SELECT DISTINCT elem->>'dataset'
|
|
48
|
+
FROM #{model.quoted_table_name},
|
|
49
|
+
LATERAL jsonb_array_elements(sources) AS elem
|
|
50
|
+
WHERE sources IS NOT NULL AND jsonb_typeof(sources) = 'array'
|
|
51
|
+
SQL
|
|
52
|
+
rescue StandardError
|
|
53
|
+
[]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def default_models
|
|
59
|
+
[
|
|
60
|
+
Models::Place, Models::Building, Models::Address, Models::Division,
|
|
61
|
+
Models::Segment, Models::Connector, Models::BaseFeature
|
|
62
|
+
]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|