Class: OvertureMaps::Query
- Inherits:
-
Object
- Object
- OvertureMaps::Query
- Includes:
- Enumerable
- Defined in:
- lib/overture_maps/query.rb
Overview
Ad-hoc queries against Overture GeoParquet — no PostGIS import needed.
OvertureMaps.query(theme: "places", location: "Seattle").limit(10).each { |r| ... }
OvertureMaps.query(theme: "buildings", bbox: [47.5, -122.4, 47.7, -122.2]).count
OvertureMaps.query(theme: "places", bbox: "47.5,-122.4,47.7,-122.2").export("places.geojson")
Unlimited queries spool through the same cache files the import pipeline uses (so a query warms the cache for a later import and vice versa); limited queries use a throwaway temp file. Records are hashes with the geometry parsed to an RGeo feature.
Constant Summary collapse
- EXPORT_EXTENSIONS =
{ ".parquet" => "parquet", ".geojson" => "geojson", ".geojsonseq" => "geojsonseq", ".gpkg" => "gpkg" }.freeze
Instance Attribute Summary collapse
-
#release ⇒ Object
readonly
Returns the value of attribute release.
-
#theme ⇒ Object
readonly
Returns the value of attribute theme.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Instance Method Summary collapse
-
#bbox ⇒ Object
The resolved bounding box (resolves a location name on first use).
-
#count ⇒ Object
Fast remote count via row-group pushdown — nothing is downloaded.
- #each(&block) ⇒ Object
- #each_batch(size: 1000) {|batch| ... } ⇒ Object
-
#export(path, format: nil) ⇒ Object
Writes the query result straight to a file; format inferred from the extension unless given explicitly.
-
#initialize(theme:, type: nil, bbox: nil, location: nil, release: nil, limit: nil) ⇒ Query
constructor
A new instance of Query.
- #limit(count) ⇒ Object
-
#to_geojson ⇒ Object
A GeoJSON FeatureCollection hash.
Constructor Details
#initialize(theme:, type: nil, bbox: nil, location: nil, release: nil, limit: nil) ⇒ Query
Returns a new instance of Query.
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/overture_maps/query.rb', line 30 def initialize(theme:, type: nil, bbox: nil, location: nil, release: nil, limit: nil) @theme = theme @type = type || infer_type(theme) @release = Releases.validate!(release || Releases.current) @location = location @bbox = coerce_bbox(bbox) if bbox raise ArgumentError, "provide bbox: or location:" unless @bbox || @location @limit = limit && Integer(limit) end |
Instance Attribute Details
#release ⇒ Object (readonly)
Returns the value of attribute release.
28 29 30 |
# File 'lib/overture_maps/query.rb', line 28 def release @release end |
#theme ⇒ Object (readonly)
Returns the value of attribute theme.
28 29 30 |
# File 'lib/overture_maps/query.rb', line 28 def theme @theme end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
28 29 30 |
# File 'lib/overture_maps/query.rb', line 28 def type @type end |
Instance Method Details
#bbox ⇒ Object
The resolved bounding box (resolves a location name on first use).
47 48 49 |
# File 'lib/overture_maps/query.rb', line 47 def bbox @bbox ||= resolve_location end |
#count ⇒ Object
Fast remote count via row-group pushdown — nothing is downloaded.
52 53 54 55 56 57 58 |
# File 'lib/overture_maps/query.rb', line 52 def count sql, params = Import::Downloader.bbox_query( theme: theme, type: type, release: release, bbox: bbox, limit: @limit ) rows = QueryEngine.instance.query("SELECT count(*) AS n FROM (#{sql})", params) Integer(rows.first["n"]) end |
#each(&block) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/overture_maps/query.rb', line 60 def each(&block) return enum_for(:each) unless block with_extract do |path| reader = Import::ParquetReader.new(theme: theme) reader.each_record(source: path) do |record| record["geometry"] = GeometryParser.parse(record["geometry"]) block.call(record) end end self end |
#each_batch(size: 1000) {|batch| ... } ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/overture_maps/query.rb', line 73 def each_batch(size: 1000) return enum_for(:each_batch, size: size) unless block_given? batch = [] each do |record| batch << record if batch.length >= size yield batch batch = [] end end yield batch if batch.any? self end |
#export(path, format: nil) ⇒ Object
Writes the query result straight to a file; format inferred from the extension unless given explicitly.
90 91 92 93 94 95 96 |
# File 'lib/overture_maps/query.rb', line 90 def export(path, format: nil) format ||= EXPORT_EXTENSIONS[File.extname(path).downcase] or raise ArgumentError, "cannot infer format from #{path}; pass format:" downloader.extract_bbox(bbox, format: format, output_path: path, limit: @limit) or raise Error, "query returned no data" end |
#limit(count) ⇒ Object
41 42 43 44 |
# File 'lib/overture_maps/query.rb', line 41 def limit(count) self.class.new(theme: theme, type: type, bbox: bbox, location: @location, release: release, limit: count) end |
#to_geojson ⇒ Object
A GeoJSON FeatureCollection hash. Materializes everything — use #export for large results.
100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/overture_maps/query.rb', line 100 def to_geojson features = map do |record| geometry = record["geometry"] { type: "Feature", geometry: geometry && RGeo::GeoJSON.encode(geometry), properties: record.except("geometry", "bbox") } end { type: "FeatureCollection", features: features } end |