Class: Underpass::Shape

Inherits:
Object
  • Object
show all
Defined in:
lib/underpass/shape.rb

Overview

Converts OSM element data into RGeo geometry objects.

All methods operate on the parsed response hashes produced by QL::Response and return RGeo geometries built with a WGS 84 spherical factory.

Class Method Summary collapse

Class Method Details

.factoryRGeo::Geographic::SphericalFactory

Returns the shared RGeo spherical factory (SRID 4326).

Returns:

  • (RGeo::Geographic::SphericalFactory)

    the factory instance



89
90
91
# File 'lib/underpass/shape.rb', line 89

def factory
  @factory ||= RGeo::Geographic.spherical_factory(srid: 4326)
end

.line_string_from_way(way, nodes) ⇒ RGeo::Feature::LineString

Builds an RGeo line string from a way’s node references.

Parameters:

  • way (Hash)

    a parsed way element

  • nodes (Hash{Integer => Hash})

    node lookup table

Returns:

  • (RGeo::Feature::LineString)

    the line string geometry



36
37
38
# File 'lib/underpass/shape.rb', line 36

def line_string_from_way(way, nodes)
  factory.line_string(points_from_node_ids(way[:nodes], nodes))
end

.multi_line_string_from_relation(relation, ways, nodes) ⇒ RGeo::Feature::MultiLineString

Assembles a multi-line-string from a route relation’s way members.

Parameters:

  • relation (Hash)

    a parsed relation element

  • ways (Hash{Integer => Hash})

    way lookup table

  • nodes (Hash{Integer => Hash})

    node lookup table

Returns:

  • (RGeo::Feature::MultiLineString)

    the multi-line-string geometry



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/underpass/shape.rb', line 74

def multi_line_string_from_relation(relation, ways, nodes)
  way_members = relation[:members].select { |m| m[:type] == 'way' }
  line_strings = way_members.filter_map do |member|
    way = ways[member[:ref]]
    next unless way

    line_string_from_way(way, nodes)
  end

  factory.multi_line_string(line_strings)
end

.multipolygon_from_relation(relation, ways, nodes) ⇒ RGeo::Feature::Polygon, RGeo::Feature::MultiPolygon

Assembles a multipolygon from a relation with outer and inner members.

Parameters:

  • relation (Hash)

    a parsed relation element

  • ways (Hash{Integer => Hash})

    way lookup table

  • nodes (Hash{Integer => Hash})

    node lookup table

Returns:

  • (RGeo::Feature::Polygon, RGeo::Feature::MultiPolygon)

    a polygon if only one outer ring, otherwise a multi-polygon



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/underpass/shape.rb', line 55

def multipolygon_from_relation(relation, ways, nodes)
  outer_rings = build_rings(members_by_role(relation, 'outer'), ways, nodes)
  inner_rings = build_rings(members_by_role(relation, 'inner'), ways, nodes)

  polygons = outer_rings.map do |outer_ring|
    factory.polygon(outer_ring, matching_inner_rings(outer_ring, inner_rings))
  end

  return polygons.first if polygons.size == 1

  factory.multi_polygon(polygons)
end

.open_way?(way) ⇒ Boolean

Checks whether a way forms a closed ring (first node equals last node).

Parameters:

  • way (Hash)

    a parsed way element

Returns:

  • (Boolean)

    true if the way is closed



15
16
17
# File 'lib/underpass/shape.rb', line 15

def open_way?(way)
  way[:nodes].first == way[:nodes].last
end

.point_from_node(node) ⇒ RGeo::Feature::Point

Builds an RGeo point from a node element.

Parameters:

  • node (Hash)

    a parsed node element with :lon and :lat keys

Returns:

  • (RGeo::Feature::Point)

    the point geometry



44
45
46
# File 'lib/underpass/shape.rb', line 44

def point_from_node(node)
  factory.point(node[:lon], node[:lat])
end

.polygon_from_way(way, nodes) ⇒ RGeo::Feature::Polygon?

Builds an RGeo polygon from a closed way.

Parameters:

  • way (Hash)

    a parsed way element

  • nodes (Hash{Integer => Hash})

    node lookup table

Returns:

  • (RGeo::Feature::Polygon, nil)

    the polygon geometry, or nil if the way has fewer than 4 points



25
26
27
28
29
# File 'lib/underpass/shape.rb', line 25

def polygon_from_way(way, nodes)
  return nil if way[:nodes].size < 4

  factory.polygon(line_string_from_way(way, nodes))
end