Class: NSWTopo::GeoJSON::Collection

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/nswtopo/gis/geojson/collection.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(projection = Projection.wgs84, features = []) ⇒ Collection

Returns a new instance of Collection.



4
5
6
# File 'lib/nswtopo/gis/geojson/collection.rb', line 4

def initialize(projection = Projection.wgs84, features = [])
  @projection, @features = projection, features
end

Instance Attribute Details

#featuresObject (readonly)

Returns the value of attribute features.



7
8
9
# File 'lib/nswtopo/gis/geojson/collection.rb', line 7

def features
  @features
end

#projectionObject (readonly)

Returns the value of attribute projection.



7
8
9
# File 'lib/nswtopo/gis/geojson/collection.rb', line 7

def projection
  @projection
end

Class Method Details

.load(json, projection = nil) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/nswtopo/gis/geojson/collection.rb', line 9

def self.load(json, projection = nil)
  collection = JSON.parse(json)
  proj4 = collection.dig "crs", "properties", "name"
  projection ||= proj4 ? Projection.new(proj4) : Projection.wgs84
  collection["features"].map do |feature|
    geometry, properties = feature.values_at "geometry", "properties"
    type, coordinates = geometry.values_at "type", "coordinates"
    raise Error, "unsupported geometry type: #{type}" unless TYPES === type
    GeoJSON.const_get(type).new coordinates, properties
  end.yield_self do |features|
    new projection, features
  end
rescue JSON::ParserError
  raise Error, "invalid GeoJSON data"
end

Instance Method Details

#<<(feature) ⇒ Object Also known as: push



25
26
27
# File 'lib/nswtopo/gis/geojson/collection.rb', line 25

def <<(feature)
  tap { @features << feature }
end

#boundsObject

TODO: what about empty collections?



89
90
91
# File 'lib/nswtopo/gis/geojson/collection.rb', line 89

def bounds
  map(&:bounds).transpose.map(&:flatten).map(&:minmax)
end

#clip!(hull) ⇒ Object



81
82
83
84
85
86
# File 'lib/nswtopo/gis/geojson/collection.rb', line 81

def clip!(hull)
  @features.map! do |feature|
    feature.clip hull
  end.compact!
  self
end

#each(&block) ⇒ Object



31
32
33
# File 'lib/nswtopo/gis/geojson/collection.rb', line 31

def each(&block)
  block_given? ? tap { @features.each(&block) } : @features.each
end

#explodeObject



63
64
65
# File 'lib/nswtopo/gis/geojson/collection.rb', line 63

def explode
  Collection.new @projection, flat_map(&:explode)
end

#merge(other) ⇒ Object

Raises:



71
72
73
74
# File 'lib/nswtopo/gis/geojson/collection.rb', line 71

def merge(other)
  raise Error, "can't merge different projections" unless @projection == other.projection
  Collection.new @projection, @features + other.features
end

#merge!(other) ⇒ Object

Raises:



76
77
78
79
# File 'lib/nswtopo/gis/geojson/collection.rb', line 76

def merge!(other)
  raise Error, "can't merge different projections" unless @projection == other.projection
  tap { @features.concat other.features }
end

#multiObject



67
68
69
# File 'lib/nswtopo/gis/geojson/collection.rb', line 67

def multi
  Collection.new @projection, map(&:multi)
end

#reproject_to(projection) ⇒ Object



35
36
37
38
39
40
41
# File 'lib/nswtopo/gis/geojson/collection.rb', line 35

def reproject_to(projection)
  return self if self.projection == projection
  json = OS.ogr2ogr "-t_srs", projection, "-f", "GeoJSON", "-lco", "RFC7946=NO", "/vsistdout/", "GeoJSON:/vsistdin/" do |stdin|
    stdin.puts to_json
  end
  Collection.load json, projection
end

#reproject_to_wgs84Object



43
44
45
# File 'lib/nswtopo/gis/geojson/collection.rb', line 43

def reproject_to_wgs84
  reproject_to Projection.wgs84
end

#to_hObject



47
48
49
50
51
52
53
# File 'lib/nswtopo/gis/geojson/collection.rb', line 47

def to_h
  {
    "type" => "FeatureCollection",
    "crs" => { "type" => "name", "properties" => { "name" => @projection } },
    "features" => map(&:to_h)
  }
end

#to_json(**extras) ⇒ Object



59
60
61
# File 'lib/nswtopo/gis/geojson/collection.rb', line 59

def to_json(**extras)
  to_h.merge(extras).to_json
end