class Charta::Geometry

Represents a Geometry with SRID

Public Class Methods

factory(srid = 4326) click to toggle source
# File lib/charta/geometry.rb, line 311
def factory(srid = 4326)
  return projected_factory(srid) if srid.to_i == 4326

  geos_factory(srid)
end
feature(ewkt_or_rgeo) click to toggle source
# 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
from_ewkt(ewkt) click to toggle source
# 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
from_rgeo(rgeo) click to toggle source
# File lib/charta/geometry.rb, line 323
def from_rgeo(rgeo)
  srid = rgeo.srid
  RGeo::Feature.cast(rgeo, factory: Geometry.factory(srid))
end
new(feature, properties = {}) click to toggle source
# File lib/charta/geometry.rb, line 9
def initialize(feature, properties = {})
  self.feature = feature
  @properties = properties
end
srs_database() click to toggle source
# 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

geos_factory(srid) click to toggle source
# 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
projected_factory(srid) click to toggle source
# 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

!=(other) click to toggle source

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
+(other)
Alias for: merge
-(other)
Alias for: difference
==(other) click to toggle source

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
area() click to toggle source

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
as_text()
Alias for: to_text
blank?()
Alias for: empty?
bounding_box() click to toggle source
# 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
buffer(radius) click to toggle source

Produces buffer

# File lib/charta/geometry.rb, line 216
def buffer(radius)
  feature.buffer(radius)
end
centroid() click to toggle source

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
collection?() click to toggle source

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
convert_to(new_type) click to toggle source
# 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
difference(other) click to toggle source
# File lib/charta/geometry.rb, line 237
def difference(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  feature.difference(other_geometry.feature)
end
Also aliased as: -
empty?() click to toggle source

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
Also aliased as: blank?
ewkt() click to toggle source
# 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
feature() click to toggle source

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
Also aliased as: to_rgeo
feature=(new_feature) click to toggle source
# 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
find_srid(name_or_srid) click to toggle source
# File lib/charta/geometry.rb, line 262
def find_srid(name_or_srid)
  Charta.find_srid(name_or_srid)
end
flatten_multi(as_type) click to toggle source
# 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
inspect() click to toggle source
# File lib/charta/geometry.rb, line 14
def inspect
  "<#{self.class.name}(#{to_ewkt})>"
end
intersection(other) click to toggle source
# File lib/charta/geometry.rb, line 227
def intersection(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  feature.intersection(other_geometry.feature)
end
intersects?(other) click to toggle source
# File lib/charta/geometry.rb, line 232
def intersects?(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  feature.intersects?(other_geometry.feature)
end
merge(other) click to toggle source
# File lib/charta/geometry.rb, line 220
def merge(other)
  other_geometry = Charta.new_geometry(other).transform(srid)
  feature.union(other_geometry.feature)
end
Also aliased as: +
method_missing(name, *args, &block) click to toggle source
# 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
point_on_surface() click to toggle source

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
respond_to_missing?(name, include_private = false) click to toggle source
Calls superclass method
# File lib/charta/geometry.rb, line 300
def respond_to_missing?(name, include_private = false)
  return false if name == :init_with

  super
end
srid() click to toggle source

Return the spatial reference identifier for the ST_Geometry

# File lib/charta/geometry.rb, line 33
def srid
  feature.srid.to_i
end
surface?() click to toggle source

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
to_binary() click to toggle source

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
Also aliased as: to_ewkb
to_ewkb()
Alias for: to_binary
to_ewkt() click to toggle source

Returns EWKT: WKT with its SRID

# File lib/charta/geometry.rb, line 47
def to_ewkt
  Charta.generate_ewkt(feature).to_s
end
Also aliased as: to_s
to_geojson() click to toggle source

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
Also aliased as: to_json
to_json()
Alias for: to_geojson
to_json_feature(properties = {}) click to toggle source
# File lib/charta/geometry.rb, line 287
def to_json_feature(properties = {})
  { type: 'Feature', properties: properties, geometry: to_json_object }
end
to_json_object() click to toggle source

Returns object in JSON (Hash)

# File lib/charta/geometry.rb, line 91
def to_json_object
  RGeo::GeoJSON.encode(feature)
end
to_rgeo()
Alias for: feature
to_s()
Alias for: to_ewkt
to_svg(options = {}) click to toggle source

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
to_svg_path() click to toggle source

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
to_text() click to toggle source

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
Also aliased as: as_text, to_wkt
to_wkt()
Alias for: to_text
transform(new_srid) click to toggle source

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
type() click to toggle source

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