Class: Charta::Geometry
- Inherits:
-
Object
- Object
- Charta::Geometry
- Defined in:
- lib/charta/geometry.rb
Overview
Represents a Geometry with SRID
Direct Known Subclasses
Class Method Summary collapse
- .factory(srid = 4326) ⇒ Object
- .feature(ewkt_or_rgeo) ⇒ Object
- .from_ewkt(ewkt) ⇒ Object
- .from_rgeo(rgeo) ⇒ Object
- .srs_database ⇒ Object
Instance Method Summary collapse
-
#!=(other) ⇒ Object
Test if the other measure is equal to self.
-
#==(other) ⇒ Object
Test if the other measure is equal to self.
-
#area ⇒ Object
Returns area in unit corresponding to the SRS.
- #bounding_box ⇒ Object
-
#buffer(radius) ⇒ Object
Produces buffer.
-
#centroid ⇒ Object
Computes the geometric center of a geometry, or equivalently, the center of mass of the geometry as a POINT.
-
#collection? ⇒ Boolean
Returns the type of the geometry as a string.
- #convert_to(new_type) ⇒ Object
- #difference(other) ⇒ Object (also: #-)
-
#empty? ⇒ Boolean
(also: #blank?)
Returns true if this Geometry is an empty geometrycollection, polygon, point etc.
- #ewkt ⇒ Object
-
#feature ⇒ Object
Returns the underlaying object managed by Charta: the RGeo feature.
- #feature=(new_feature) ⇒ Object
- #find_srid(name_or_srid) ⇒ Object
- #flatten_multi(as_type) ⇒ Object
-
#initialize(feature, properties = {}) ⇒ Geometry
constructor
A new instance of Geometry.
- #inspect ⇒ Object
- #intersection(other) ⇒ Object
- #intersects?(other) ⇒ Boolean
- #merge(other) ⇒ Object (also: #+)
- #method_missing(name, *args, &block) ⇒ Object
-
#point_on_surface ⇒ Object
Returns a POINT guaranteed to lie on the surface.
- #respond_to_missing?(name, include_private = false) ⇒ Boolean
-
#srid ⇒ Object
Return the spatial reference identifier for the ST_Geometry.
-
#surface? ⇒ Boolean
Returns true if Geometry is a Surface.
-
#to_binary ⇒ Object
(also: #to_ewkb)
Return the Well-Known Binary (WKB) representation of the geometry with SRID meta data.
-
#to_ewkt ⇒ Object
(also: #to_s)
Returns EWKT: WKT with its SRID.
-
#to_geojson ⇒ Object
(also: #to_json)
Return the geometry as a Geometry Javascript Object Notation (GeoJSON) element.
- #to_json_feature(properties = {}) ⇒ Object
-
#to_json_object ⇒ Object
Returns object in JSON (Hash).
-
#to_rgeo ⇒ Object
Returns the underlaying object managed by Charta: the RGeo feature.
-
#to_svg(options = {}) ⇒ String
Generate SVG from geometry.
-
#to_svg_path ⇒ Object
Return the geometry as Scalar Vector Graphics (SVG) path data.
-
#to_text ⇒ Object
(also: #as_text, #to_wkt)
Returns the Well-Known Text (WKT) representation of the geometry/geography without SRID metadata.
-
#transform(new_srid) ⇒ Object
Returns a new geometry with the coordinates converted into the new SRS.
-
#type ⇒ Object
Returns the type of the geometry as a string.
Constructor Details
#initialize(feature, properties = {}) ⇒ Geometry
Returns a new instance of Geometry.
10 11 12 13 |
# File 'lib/charta/geometry.rb', line 10 def initialize(feature, properties = {}) self.feature = feature @properties = properties end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
312 313 314 315 316 317 318 319 |
# File 'lib/charta/geometry.rb', line 312 def method_missing(name, *args, &block) target = to_rgeo if target.respond_to? name target.send name, *args else raise StandardError.new("Method #{name} does not exist for #{self.class.name}") end end |
Class Method Details
.factory(srid = 4326) ⇒ Object
332 333 334 335 336 |
# File 'lib/charta/geometry.rb', line 332 def factory(srid = 4326) return projected_factory(srid) if srid.to_i == 4326 geos_factory(srid) end |
.feature(ewkt_or_rgeo) ⇒ Object
338 339 340 341 342 |
# File 'lib/charta/geometry.rb', line 338 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 |
.from_ewkt(ewkt) ⇒ Object
349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/charta/geometry.rb', line 349 def from_ewkt(ewkt) # Cleans empty geometries ewkt = ewkt.gsub(/(GEOMETRYCOLLECTION|GEOMETRY|((MULTI)?(POINT|LINESTRING|POLYGON)))\(\)/, '\1 EMPTY') srs = ewkt.split(/[\=\;]+/)[0..1] srid = nil srid = srs[1] if srs[0] =~ /srid/i srid ||= 4326 factory(srid).parse_wkt(ewkt) rescue RGeo::Error::ParseError => e raise "Invalid EWKT (#{e.class.name}: #{e.}): #{ewkt}" end |
.from_rgeo(rgeo) ⇒ Object
344 345 346 347 |
# File 'lib/charta/geometry.rb', line 344 def from_rgeo(rgeo) srid = rgeo.srid RGeo::Feature.cast(rgeo, factory: Geometry.factory(srid)) end |
.srs_database ⇒ Object
328 329 330 |
# File 'lib/charta/geometry.rb', line 328 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
126 127 128 129 130 131 132 |
# File 'lib/charta/geometry.rb', line 126 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
117 118 119 120 121 122 123 |
# File 'lib/charta/geometry.rb', line 117 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 |
#area ⇒ Object
Returns area in unit corresponding to the SRS
144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/charta/geometry.rb', line 144 def area if surface? if collection? feature.sum { |geometry| Charta.new_geometry(geometry).area } else feature.area end else 0 end end |
#bounding_box ⇒ Object
265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/charta/geometry.rb', line 265 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
237 238 239 |
# File 'lib/charta/geometry.rb', line 237 def buffer(radius) feature.buffer(radius) end |
#centroid ⇒ Object
Computes the geometric center of a geometry, or equivalently, the center of mass of the geometry as a POINT.
166 167 168 169 170 171 |
# File 'lib/charta/geometry.rb', line 166 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.
29 30 31 |
# File 'lib/charta/geometry.rb', line 29 def collection? feature.geometry_type == RGeo::Feature::GeometryCollection end |
#convert_to(new_type) ⇒ Object
181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/charta/geometry.rb', line 181 def convert_to(new_type) case new_type when type self when :multi_point flatten_multi(:point) when :multi_line_string flatten_multi(:line_string) when :multi_polygon flatten_multi(:polygon) else self end end |
#difference(other) ⇒ Object Also known as: -
258 259 260 261 |
# File 'lib/charta/geometry.rb', line 258 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.
158 159 160 |
# File 'lib/charta/geometry.rb', line 158 def empty? feature.is_empty? end |
#ewkt ⇒ Object
54 55 56 57 |
# File 'lib/charta/geometry.rb', line 54 def ewkt puts 'DEPRECATION WARNING: Charta::Geometry.ewkt is deprecated. Please use Charta::Geometry.to_ewkt instead' to_ewkt end |
#feature ⇒ Object
Returns the underlaying object managed by Charta: the RGeo feature
288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/charta/geometry.rb', line 288 def feature unless defined? @feature if defined? @ewkt @feature = ::Charta::Geometry.from_ewkt(@ewkt) @properties = @options.dup if @options else raise StandardError.new('Invalid geometry (no feature, no EWKT)') end end @feature.dup end |
#feature=(new_feature) ⇒ Object
302 303 304 305 306 |
# File 'lib/charta/geometry.rb', line 302 def feature=(new_feature) raise ArgumentError.new("Feature can't be nil") if new_feature.nil? @feature = new_feature end |
#find_srid(name_or_srid) ⇒ Object
283 284 285 |
# File 'lib/charta/geometry.rb', line 283 def find_srid(name_or_srid) Charta.find_srid(name_or_srid) end |
#flatten_multi(as_type) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/charta/geometry.rb', line 196 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 |
#inspect ⇒ Object
15 16 17 |
# File 'lib/charta/geometry.rb', line 15 def inspect "<#{self.class.name}(#{to_ewkt})>" end |
#intersection(other) ⇒ Object
248 249 250 251 |
# File 'lib/charta/geometry.rb', line 248 def intersection(other) other_geometry = Charta.new_geometry(other).transform(srid) feature.intersection(other_geometry.feature) end |
#intersects?(other) ⇒ Boolean
253 254 255 256 |
# File 'lib/charta/geometry.rb', line 253 def intersects?(other) other_geometry = Charta.new_geometry(other).transform(srid) feature.intersects?(other_geometry.feature) end |
#merge(other) ⇒ Object Also known as: +
241 242 243 244 |
# File 'lib/charta/geometry.rb', line 241 def merge(other) other_geometry = Charta.new_geometry(other).transform(srid) feature.union(other_geometry.feature) end |
#point_on_surface ⇒ Object
Returns a POINT guaranteed to lie on the surface.
174 175 176 177 178 179 |
# File 'lib/charta/geometry.rb', line 174 def point_on_surface return nil unless surface? point = feature.point_on_surface [point.y, point.x] end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean
321 322 323 324 325 |
# File 'lib/charta/geometry.rb', line 321 def respond_to_missing?(name, include_private = false) return false if name == :init_with super end |
#srid ⇒ Object
Return the spatial reference identifier for the ST_Geometry
34 35 36 |
# File 'lib/charta/geometry.rb', line 34 def srid feature.srid.to_i end |
#surface? ⇒ Boolean
Returns true if Geometry is a Surface
135 136 137 138 139 140 141 |
# File 'lib/charta/geometry.rb', line 135 def surface? if collection? feature.any? { |geometry| Charta.new_geometry(geometry).surface? } else [RGeo::Feature::Polygon, RGeo::Feature::MultiPolygon].include? feature.geometry_type end end |
#to_binary ⇒ Object Also known as: to_ewkb
Return the Well-Known Binary (WKB) representation of the geometry with SRID meta data.
60 61 62 63 |
# File 'lib/charta/geometry.rb', line 60 def to_binary generator = RGeo::WKRep::WKBGenerator.new(tag_format: :ewkbt, emit_ewkbt_srid: true) generator.generate(feature) end |
#to_ewkt ⇒ Object Also known as: to_s
Returns EWKT: WKT with its SRID
48 49 50 |
# File 'lib/charta/geometry.rb', line 48 def to_ewkt Charta.generate_ewkt(feature).to_s end |
#to_geojson ⇒ Object Also known as: to_json
Return the geometry as a Geometry Javascript Object Notation (GeoJSON) element.
105 106 107 |
# File 'lib/charta/geometry.rb', line 105 def to_geojson to_json_object.to_json end |
#to_json_feature(properties = {}) ⇒ Object
308 309 310 |
# File 'lib/charta/geometry.rb', line 308 def to_json_feature(properties = {}) { type: 'Feature', properties: properties, geometry: to_json_object } end |
#to_json_object ⇒ Object
Returns object in JSON (Hash)
112 113 114 |
# File 'lib/charta/geometry.rb', line 112 def to_json_object RGeo::GeoJSON.encode(feature) end |
#to_rgeo ⇒ Object
Returns the underlaying object managed by Charta: the RGeo feature
300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/charta/geometry.rb', line 300 def feature unless defined? @feature if defined? @ewkt @feature = ::Charta::Geometry.from_ewkt(@ewkt) @properties = @options.dup if @options else raise StandardError.new('Invalid geometry (no feature, no EWKT)') end end @feature.dup end |
#to_svg(options = {}) ⇒ String
more informations on developer.mozilla.org/fr/docs/Web/SVG/Tutorial/Fills_and_Strokes
Generate SVG from geometry
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/charta/geometry.rb', line 77 def to_svg( = {}) # set default options if not present [:mode] ||= :stroke [:color] ||= 'black' [:fill_opacity] ||= '100' # 0 to 100 [:stroke_linecap] ||= 'butt' # round, square, butt [:stroke_linejoin] ||= 'round' # [:stroke_width] ||= '5%' svg = Victor::SVG.new template: :html svg.setup width: 180, height: 180, viewBox: bounding_box.svg_view_box.join(' ') # return a stroke SVG with options if [:mode] == :stroke svg.path d: to_svg_path, fill: 'none', stroke: [:color], stroke_linecap: [:stroke_linecap], stroke_linejoin: [:stroke_linejoin], stroke_width: [:stroke_width] # return a fill SVG with options elsif [:mode] == :fill svg.path d: to_svg_path, fill: [:color], fill_opacity: [:fill_opacity] end svg.render end |
#to_svg_path ⇒ Object
Return the geometry as Scalar Vector Graphics (SVG) path data.
100 101 102 |
# File 'lib/charta/geometry.rb', line 100 def to_svg_path RGeo::SVG.encode(feature) end |
#to_text ⇒ Object Also known as: as_text, to_wkt
Returns the Well-Known Text (WKT) representation of the geometry/geography without SRID metadata
40 41 42 |
# File 'lib/charta/geometry.rb', line 40 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
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/charta/geometry.rb', line 217 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 |
#type ⇒ Object
Returns the type of the geometry as a string. Example: point, multi_polygon, geometry_collection…
21 22 23 |
# File 'lib/charta/geometry.rb', line 21 def type Charta.underscore(feature.geometry_type.type_name).to_sym end |