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



86
87
88
# File 'lib/underpass/shape.rb', line 86

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



33
34
35
# File 'lib/underpass/shape.rb', line 33

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



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/underpass/shape.rb', line 71

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



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/underpass/shape.rb', line 52

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



41
42
43
# File 'lib/underpass/shape.rb', line 41

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)

    the polygon geometry



24
25
26
# File 'lib/underpass/shape.rb', line 24

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