Class: NSWTopo::GeoJSON::MultiLineString

Inherits:
Object
  • Object
show all
Includes:
StraightSkeleton
Defined in:
lib/nswtopo/gis/geojson/multi_line_string.rb

Constant Summary

Constants included from StraightSkeleton

StraightSkeleton::DEFAULT_ROUNDING_ANGLE

Instance Method Summary collapse

Instance Method Details

#buffer(*margins, **options) ⇒ Object



39
40
41
# File 'lib/nswtopo/gis/geojson/multi_line_string.rb', line 39

def buffer(*margins, **options)
  MultiLineString.new(@coordinates + @coordinates.map(&:reverse), @properties).offset(*margins, **options)
end

#clip(hull) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/nswtopo/gis/geojson/multi_line_string.rb', line 6

def clip(hull)
  lines = [hull, hull.perps].transpose.inject(@coordinates) do |result, (vertex, perp)|
    result.inject([]) do |clipped, points|
      clipped + [*points, points.last].segments.inject([[]]) do |lines, segment|
        inside = segment.map { |point| point.minus(vertex).dot(perp) >= 0 }
        case
        when inside.all?
          lines.last << segment[0]
        when inside[0]
          lines.last << segment[0]
          lines.last << segment.along(vertex.minus(segment[0]).dot(perp) / segment.difference.dot(perp))
        when inside[1]
          lines << []
          lines.last << segment.along(vertex.minus(segment[0]).dot(perp) / segment.difference.dot(perp))
        end
        lines
      end
    end
  end.select(&:many?)
  lines.none? ? nil : lines.one? ? LineString.new(*lines, @properties) : MultiLineString.new(lines, @properties)
end

#lengthObject



28
29
30
# File 'lib/nswtopo/gis/geojson/multi_line_string.rb', line 28

def length
  @coordinates.sum(&:path_length)
end

#offset(*margins, **options) ⇒ Object



32
33
34
35
36
37
# File 'lib/nswtopo/gis/geojson/multi_line_string.rb', line 32

def offset(*margins, **options)
  linestrings = margins.inject Nodes.new(@coordinates) do |nodes, margin|
    nodes.progress limit: margin, **options.slice(:rounding_angle, :cutoff_angle)
  end.readout
  MultiLineString.new linestrings, @properties
end

#samples(interval) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/nswtopo/gis/geojson/multi_line_string.rb', line 52

def samples(interval)
  points = @coordinates.map do |linestring|
    distance = linestring.path_length
    linestring.sample_at(interval, along: true).map do |point, along|
      [point, (2 * along - distance).abs - distance]
    end
  end.flatten(1).sort_by(&:last).map(&:first)
  MultiPoint.new points, @properties
end

#smooth(margin, **options) ⇒ Object



43
44
45
46
47
48
49
50
# File 'lib/nswtopo/gis/geojson/multi_line_string.rb', line 43

def smooth(margin, **options)
  linestrings = Nodes.new(@coordinates).tap do |nodes|
    nodes.progress **options.slice(:rounding_angle).merge(limit: margin)
    nodes.progress **options.slice(:rounding_angle, :cutoff_angle).merge(limit: -2 * margin)
    nodes.progress **options.slice(:rounding_angle, :cutoff_angle).merge(limit: margin)
  end.readout
  MultiLineString.new linestrings, @properties
end