class Charta::Geometry
Represents a Geometry
with SRID
Public Class Methods
# File lib/charta/geometry.rb, line 311 def factory(srid = 4326) return projected_factory(srid) if srid.to_i == 4326 geos_factory(srid) end
# File lib/charta/geometry.rb, line 317 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
# File lib/charta/geometry.rb, line 328 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.message}): #{ewkt}" end
# File lib/charta/geometry.rb, line 323 def from_rgeo(rgeo) srid = rgeo.srid RGeo::Feature.cast(rgeo, factory: Geometry.factory(srid)) end
# File lib/charta/geometry.rb, line 9 def initialize(feature, properties = {}) self.feature = feature @properties = properties end
# File lib/charta/geometry.rb, line 307 def srs_database @srs_database ||= RGeo::CoordSys::SRSDatabase::Proj4Data.new('epsg', authority: 'EPSG', cache: true) end
Private Class Methods
# File lib/charta/geometry.rb, line 342 def geos_factory(srid) RGeo::Geos.factory( srid: srid, wkt_generator: { type_format: :ewkt, emit_ewkt_srid: true, convert_case: :upper }, wkt_parser: { support_ewkt: true }, wkb_generator: { type_format: :ewkb, emit_ewkb_srid: true, hex_format: true }, wkb_parser: { support_ewkb: true } ) end
# File lib/charta/geometry.rb, line 364 def projected_factory(srid) proj4 = '+proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs' RGeo::Geographic.projected_factory( srid: srid, wkt_generator: { type_format: :ewkt, emit_ewkt_srid: true, convert_case: :upper }, wkt_parser: { support_ewkt: true }, wkb_generator: { type_format: :ewkb, emit_ewkb_srid: true, hex_format: true }, wkb_parser: { support_ewkb: true }, projection_srid: 6933, projection_proj4: proj4 ) end
Public Instance Methods
Test if the other measure is equal to self
# File lib/charta/geometry.rb, line 105 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
Test if the other measure is equal to self
# 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
Returns area in unit corresponding to the SRS
# File lib/charta/geometry.rb, line 123 def area if surface? if collection? feature.sum { |geometry| Charta.new_geometry(geometry).area } else feature.area end else 0 end end
# File lib/charta/geometry.rb, line 244 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
Produces buffer
# File lib/charta/geometry.rb, line 216 def buffer(radius) feature.buffer(radius) end
Computes the geometric center of a geometry, or equivalently, the center of mass of the geometry as a POINT.
# File lib/charta/geometry.rb, line 145 def centroid return nil unless surface? && !feature.is_empty? point = feature.centroid [point.y, point.x] end
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.
# File lib/charta/geometry.rb, line 28 def collection? feature.geometry_type == RGeo::Feature::GeometryCollection end
# File lib/charta/geometry.rb, line 160 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
# File lib/charta/geometry.rb, line 237 def difference(other) other_geometry = Charta.new_geometry(other).transform(srid) feature.difference(other_geometry.feature) end
Returns true if this Geometry
is an empty geometrycollection, polygon, point etc.
# File lib/charta/geometry.rb, line 137 def empty? feature.is_empty? end
# File lib/charta/geometry.rb, line 53 def ewkt puts 'DEPRECATION WARNING: Charta::Geometry.ewkt is deprecated. Please use Charta::Geometry.to_ewkt instead' to_ewkt end
Returns the underlaying object managed by Charta: the RGeo
feature
# File lib/charta/geometry.rb, line 267 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
# File lib/charta/geometry.rb, line 281 def feature=(new_feature) raise ArgumentError.new("Feature can't be nil") if new_feature.nil? @feature = new_feature end
# File lib/charta/geometry.rb, line 262 def find_srid(name_or_srid) Charta.find_srid(name_or_srid) end
# File lib/charta/geometry.rb, line 175 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
# File lib/charta/geometry.rb, line 14 def inspect "<#{self.class.name}(#{to_ewkt})>" end
# File lib/charta/geometry.rb, line 227 def intersection(other) other_geometry = Charta.new_geometry(other).transform(srid) feature.intersection(other_geometry.feature) end
# File lib/charta/geometry.rb, line 232 def intersects?(other) other_geometry = Charta.new_geometry(other).transform(srid) feature.intersects?(other_geometry.feature) end
# File lib/charta/geometry.rb, line 220 def merge(other) other_geometry = Charta.new_geometry(other).transform(srid) feature.union(other_geometry.feature) end
# File lib/charta/geometry.rb, line 291 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
Returns a POINT guaranteed to lie on the surface.
# File lib/charta/geometry.rb, line 153 def point_on_surface return nil unless surface? point = feature.point_on_surface [point.y, point.x] end
# File lib/charta/geometry.rb, line 300 def respond_to_missing?(name, include_private = false) return false if name == :init_with super end
Return the spatial reference identifier for the ST_Geometry
# File lib/charta/geometry.rb, line 33 def srid feature.srid.to_i end
Returns true if Geometry
is a Surface
# File lib/charta/geometry.rb, line 114 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
Return the Well-Known Binary (WKB) representation of the geometry with SRID meta data.
# File lib/charta/geometry.rb, line 59 def to_binary generator = RGeo::WKRep::WKBGenerator.new(tag_format: :ewkbt, emit_ewkbt_srid: true) generator.generate(feature) end
Returns EWKT: WKT with its SRID
# File lib/charta/geometry.rb, line 47 def to_ewkt Charta.generate_ewkt(feature).to_s end
Return the geometry as a Geometry
Javascript Object Notation (GeoJSON
) element.
# File lib/charta/geometry.rb, line 84 def to_geojson to_json_object.to_json end
# File lib/charta/geometry.rb, line 287 def to_json_feature(properties = {}) { type: 'Feature', properties: properties, geometry: to_json_object } end
Returns object in JSON (Hash)
# File lib/charta/geometry.rb, line 91 def to_json_object RGeo::GeoJSON.encode(feature) end
Pas bien compris le fonctionnement
# File lib/charta/geometry.rb, line 67 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
Return the geometry as Scalar Vector Graphics (SVG) path data.
# File lib/charta/geometry.rb, line 79 def to_svg_path RGeo::SVG.encode(feature) end
Returns the Well-Known Text (WKT) representation of the geometry/geography without SRID metadata
# File lib/charta/geometry.rb, line 39 def to_text feature.as_text.match(/\ASRID=.*;(.*)/)[1] end
Returns a new geometry with the coordinates converted into the new SRS
# File lib/charta/geometry.rb, line 196 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
Returns the type of the geometry as a string. Example: point, multi_polygon, geometry_collection…
# File lib/charta/geometry.rb, line 20 def type Charta.underscore(feature.geometry_type.type_name).to_sym end