Class: Charta::Geometry

Inherits:
Object
  • Object
show all
Defined in:
lib/charta/geometry.rb

Overview

Represents a Geometry with SRID

Direct Known Subclasses

GeometryCollection, LineString, Point, Polygon

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(feature, properties = {}) ⇒ Geometry

Returns a new instance of Geometry.



8
9
10
11
12
# File 'lib/charta/geometry.rb', line 8

def initialize(feature, properties = {})
  @feature = feature
  @properties = properties
  # raise ArgumentError, 'Need EWKT to instantiate Geometry' if @ewkt.to_s =~ /\A[[:space:]]*\z/
end

Class Method Details

.factory(srid = 4326) ⇒ Object



247
248
249
250
# File 'lib/charta/geometry.rb', line 247

def factory(srid = 4326)
  return projected_factory(srid) if srid.to_i == 4326
  geos_factory(srid)
end

.feature(ewkt_or_rgeo) ⇒ Object



252
253
254
255
# File 'lib/charta/geometry.rb', line 252

def feature(ewkt_or_rgeo)
  return from_rgeo(ewkt_or_rgeo) if ewkt_or_rgeo.is_a? RGeo::Feature::Instance
  from_ewkt(ewkt_or_rgeo)
end

.srs_databaseObject



243
244
245
# File 'lib/charta/geometry.rb', line 243

def srs_database
  @srs_database ||= RGeo::CoordSys::SRSDatabase::Proj4Data.new('epsg', authority: 'EPSG', cache: true)
end

Instance Method Details

#!=(other) ⇒ Object

Test if the other measure is equal to self



104
105
106
107
108
109
# File 'lib/charta/geometry.rb', line 104

def !=(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  return true if empty? && other_geometry.empty?
  return inspect == other_geometry.inspect if collection? && other_geometry.collection?
  !@feature.equals?(other_geometry.feature)
end

#==(other) ⇒ Object

Test if the other measure is equal to self



96
97
98
99
100
101
# File 'lib/charta/geometry.rb', line 96

def ==(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  return true if empty? && other_geometry.empty?
  return inspect == other_geometry.inspect if collection? && other_geometry.collection?
  @feature.equals?(other_geometry.feature)
end

#areaObject

Returns area in unit corresponding to the SRS



117
118
119
# File 'lib/charta/geometry.rb', line 117

def area
  surface? ? @feature.area : 0
end

#bounding_boxObject



212
213
214
215
216
217
218
219
220
221
222
# File 'lib/charta/geometry.rb', line 212

def bounding_box
  unless defined? @bounding_box
    bbox = RGeo::Cartesian::BoundingBox.create_from_geometry(@feature)
    instance_variable_set('@x_min', bbox.min_x || 0)
    instance_variable_set('@y_min', bbox.min_y || 0)
    instance_variable_set('@x_max', bbox.max_x || 0)
    instance_variable_set('@y_max', bbox.max_y || 0)
    @bounding_box = BoundingBox.new(@y_min, @x_min, @y_max, @x_max)
  end
  @bounding_box
end

#buffer(radius) ⇒ Object

Produces buffer



191
192
193
# File 'lib/charta/geometry.rb', line 191

def buffer(radius)
  @feature.buffer(radius)
end

#centroidObject

Computes the geometric center of a geometry, or equivalently, the center of mass of the geometry as a POINT.



130
131
132
133
134
# File 'lib/charta/geometry.rb', line 130

def centroid
  return nil unless surface? && !@feature.is_empty?
  point = @feature.centroid
  [point.y, point.x]
end

#collection?Boolean

Returns the type of the geometry as a string. EG: ‘ST_Linestring’, ‘ST_Polygon’, ‘ST_MultiPolygon’ etc. This function differs from GeometryType(geometry) in the case of the string and ST in front that is returned, as well as the fact that it will not indicate whether the geometry is measured.

Returns:

  • (Boolean)


28
29
30
# File 'lib/charta/geometry.rb', line 28

def collection?
  @feature.geometry_type == RGeo::Feature::GeometryCollection
end

#convert_to(new_type) ⇒ Object



143
144
145
146
147
148
149
150
# File 'lib/charta/geometry.rb', line 143

def convert_to(new_type)
  case new_type
  when type then self
  when :multi_point then flatten_multi(:point)
  when :multi_line_string then flatten_multi(:line_string)
  when :multi_polygon then flatten_multi(:polygon)
  end
end

#difference(other) ⇒ Object Also known as: -



206
207
208
209
# File 'lib/charta/geometry.rb', line 206

def difference(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  @feature.difference(other_geometry.feature)
end

#empty?Boolean Also known as: blank?

Returns true if this Geometry is an empty geometrycollection, polygon, point etc.

Returns:

  • (Boolean)


123
124
125
# File 'lib/charta/geometry.rb', line 123

def empty?
  @feature.is_empty?
end

#ewktObject



55
56
57
58
# File 'lib/charta/geometry.rb', line 55

def ewkt
  puts 'DEPRECATION WARNING: Charta::Geometry.ewkt is deprecated. Please use Charta::Geometry.to_ewkt instead'
  to_ewkt
end

#featureObject



234
235
236
# File 'lib/charta/geometry.rb', line 234

def feature
  @feature
end

#find_srid(name_or_srid) ⇒ Object



230
231
232
# File 'lib/charta/geometry.rb', line 230

def find_srid(name_or_srid)
  Charta.find_srid(name_or_srid)
end

#flatten_multi(as_type) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/charta/geometry.rb', line 152

def flatten_multi(as_type)
  items = []
  as_multi_type = "multi_#{as_type}".to_sym
  if type == as_type
    items << @feature
  elsif type == :geometry_collection
    @feature.each do |geom|
      type_name = Charta.underscore(geom.geometry_type.type_name).to_sym
      if type_name == as_type
        items << geom
      elsif type_name == as_multi_type
        geom.each do |item|
          items << item
        end
      end
    end
  end
  Charta.new_geometry(@feature.factory.send(as_multi_type, items))
end

#inspectObject



14
15
16
# File 'lib/charta/geometry.rb', line 14

def inspect
  "<#{self.class.name}(#{to_ewkt})>"
end

#intersection(other) ⇒ Object



201
202
203
204
# File 'lib/charta/geometry.rb', line 201

def intersection(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  @feature.intersection(other_geometry.feature)
end

#merge(other) ⇒ Object Also known as: +



195
196
197
198
# File 'lib/charta/geometry.rb', line 195

def merge(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  @feature.union(other_geometry.feature)
end

#point_on_surfaceObject

Returns a POINT guaranteed to lie on the surface.



137
138
139
140
141
# File 'lib/charta/geometry.rb', line 137

def point_on_surface
  return nil unless surface?
  point = @feature.point_on_surface
  [point.y, point.x]
end

#sridObject

Return the spatial reference identifier for the ST_Geometry



33
34
35
# File 'lib/charta/geometry.rb', line 33

def srid
  @feature.srid.to_i
end

#surface?Boolean

Returns true if Geometry is a Surface

Returns:

  • (Boolean)


112
113
114
# File 'lib/charta/geometry.rb', line 112

def surface?
  [RGeo::Feature::Polygon, RGeo::Feature::MultiPolygon].include? @feature.geometry_type
end

#to_binaryObject Also known as: to_ewkb

Return the Well-Known Binary (WKB) representation of the geometry with SRID meta data.



61
62
63
64
# File 'lib/charta/geometry.rb', line 61

def to_binary
  generator = RGeo::WKRep::WKBGenerator.new(tag_format: :ewkbt, emit_ewkbt_srid: true)
  generator.generate(@feature)
end

#to_ewktObject Also known as: to_s

Returns EWKT: WKT with its SRID



50
51
52
# File 'lib/charta/geometry.rb', line 50

def to_ewkt
  Charta.generate_ewkt(@feature).to_s
end

#to_geojsonObject Also known as: to_json

Return the geometry as a Geometry Javascript Object Notation (GeoJSON) element.



85
86
87
# File 'lib/charta/geometry.rb', line 85

def to_geojson
  to_json_object.to_json
end

#to_json_feature(properties = {}) ⇒ Object



238
239
240
# File 'lib/charta/geometry.rb', line 238

def to_json_feature(properties = {})
  { type: 'Feature', properties: properties, geometry: to_json_object }
end

#to_json_objectObject

Returns object in JSON (Hash)



91
92
93
# File 'lib/charta/geometry.rb', line 91

def to_json_object
  RGeo::GeoJSON.encode(@feature)
end

#to_rgeoObject

Returns the underlaying object managed by Charta: the RGeo feature



38
39
40
# File 'lib/charta/geometry.rb', line 38

def to_rgeo
  @feature
end

#to_svg(options = {}) ⇒ Object

Pas bien compris le fonctionnement



68
69
70
71
72
73
74
75
76
77
# File 'lib/charta/geometry.rb', line 68

def to_svg(options = {})
  svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1"'
  { preserve_aspect_ratio: 'xMidYMid meet',
    width: 180, height: 180,
    view_box: bounding_box.svg_view_box.join(' ') }.merge(options).each do |attr, value|
    svg << " #{Charta.camelcase(attr.to_s, :lower)}=\"#{value}\""
  end
  svg << "><path d=\"#{to_svg_path}\"/></svg>"
  svg
end

#to_svg_pathObject

Return the geometry as Scalar Vector Graphics (SVG) path data.



80
81
82
# File 'lib/charta/geometry.rb', line 80

def to_svg_path
  RGeo::SVG.encode(@feature)
end

#to_textObject Also known as: as_text, to_wkt

Returns the Well-Known Text (WKT) representation of the geometry/geography without SRID metadata



43
44
45
# File 'lib/charta/geometry.rb', line 43

def to_text
  @feature.as_text.match(/\ASRID=.*;(.*)/)[1]
end

#transform(new_srid) ⇒ Object

Returns a new geometry with the coordinates converted into the new SRS



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/charta/geometry.rb', line 173

def transform(new_srid)
  return self if new_srid == srid
  raise 'Proj is not supported. Cannot tranform' unless RGeo::CoordSys::Proj4.supported?
  new_srid = Charta::SRS[new_srid] || new_srid
  database = self.class.srs_database
  new_proj_entry = database.get(new_srid)
  raise "Cannot find proj for SRID: #{new_srid}" if new_proj_entry.nil?
  new_feature = RGeo::CoordSys::Proj4.transform(
    database.get(srid).proj4,
    @feature,
    new_proj_entry.proj4,
    self.class.factory(new_srid)
  )
  generator = RGeo::WKRep::WKTGenerator.new(tag_format: :ewkt, emit_ewkt_srid: true)
  Charta.new_geometry(generator.generate(new_feature))
end

#typeObject

Returns the type of the geometry as a string. Example: point, multi_polygon, geometry_collection…



20
21
22
# File 'lib/charta/geometry.rb', line 20

def type
  Charta.underscore(@feature.geometry_type.type_name).to_sym
end