module Geos
Some custom extensions to the SWIG-based Geos
Ruby extension.
Constants
- ALLOWED_GEOS_READ_TYPES
- GEOS_EXTENSIONS_BASE
- GEOS_EXTENSIONS_VERSION
- REGEXP_BOX2D
- REGEXP_FLOAT
- REGEXP_G_LAT_LNG
- REGEXP_G_LAT_LNG_BOUNDS
- REGEXP_LAT_LNG
- REGEXP_WKB_HEX
- REGEXP_WKT
Public Class Methods
Creates a Geometry
from a PostGIS-style BOX string.
# File lib/geos_extensions.rb, line 234 def self.from_box2d(geometry_or_match_data) match_data = case geometry_or_match_data when MatchData geometry_or_match_data.captures when REGEXP_BOX2D $~.captures else raise Geos::Extensions::InvalidBox2DError.new end coords = [] match_data.compact.each_slice(2) { |f| coords << f.collect(&:to_f) } Geos.from_wkt("LINESTRING(%s, %s)" % [ coords[0].join(' '), coords[1].join(' ') ]).envelope end
Returns some kind of Geometry
object from a String provided by a Google Maps object. For instance, calling toString() on a GLatLng will output (lat, lng), while calling on a GLatLngBounds will produce ((sw lat, sw lng), (ne lat, ne lng)). This method handles both GLatLngs and GLatLngBounds. In the case of GLatLngs, we return a new Geos::Point
, while for GLatLngBounds we return a Geos::Polygon
that encompasses the bounds. Use the option :points to interpret the incoming value as as GPoints rather than GLatLngs.
# File lib/geos_extensions.rb, line 186 def self.from_g_lat_lng(geometry_or_match_data, options = {}) match_data = case geometry_or_match_data when MatchData geometry_or_match_data.captures when REGEXP_G_LAT_LNG_BOUNDS, REGEXP_G_LAT_LNG $~.captures else raise Geos::Extensions::InvalidGLatLngFormatError.new end geom = if match_data.length > 3 coords = Array.new match_data.compact.each_slice(2) { |f| coords << f.collect(&:to_f) } unless options[:points] coords.each do |c| c.reverse! end end Geos.from_wkt("LINESTRING(%s, %s)" % [ coords[0].join(' '), coords[1].join(' ') ]).envelope else coords = match_data.collect(&:to_f).tap { |c| c.reverse! unless options[:points] } Geos.from_wkt("POINT(#{coords.join(' ')})") end if options[:srid] geom.srid = options[:srid] end geom end
Same as from_g_lat_lng
but uses GPoints instead of GLatLngs and GBounds instead of GLatLngBounds. Equivalent to calling from_g_lat_lng
with a non-false expression for the points parameter.
# File lib/geos_extensions.rb, line 229 def self.from_g_point(geometry, options = {}) self.from_g_lat_lng(geometry, options.merge(:points => true)) end
Returns some kind of Geometry
object from the given WKB in hex.
# File lib/geos_extensions.rb, line 90 def self.from_wkb(wkb, options = {}) geom = self.wkb_reader_singleton.read_hex(wkb) geom.srid = options[:srid].to_i if options[:srid] geom end
Returns some kind of Geometry
object from the given WKB in binary.
# File lib/geos_extensions.rb, line 83 def self.from_wkb_bin(wkb, options = {}) geom = self.wkb_reader_singleton.read(wkb) geom.srid = options[:srid].to_i if options[:srid] geom end
Returns some kind of Geometry
object from the given WKT. This method will also accept PostGIS-style EWKT and its various enhancements.
# File lib/geos_extensions.rb, line 166 def self.from_wkt(wkt_or_match_data, options = {}) srid, raw_wkt = if wkt_or_match_data.kind_of?(MatchData) [ wkt_or_match_data[1], wkt_or_match_data[2] ] else wkt_or_match_data.scan(REGEXP_WKT).first end geom = self.wkt_reader_singleton.read(raw_wkt.upcase) geom.srid = (options[:srid] || srid).to_i if options[:srid] || srid geom end
Tries its best to return a Geometry
object.
# File lib/geos_extensions.rb, line 109 def self.read(geom, options = {}) allowed = Geos::Helper.array_wrap(options[:allowed] || ALLOWED_GEOS_READ_TYPES) allowed = allowed - Geos::Helper.array_wrap(options[:excluded]) geom = geom.dup.force_encoding('BINARY') if geom.respond_to?(:force_encoding) type = case geom when Geos::Geometry :geometry when REGEXP_WKT :wkt when REGEXP_WKB_HEX :wkb_hex when REGEXP_G_LAT_LNG_BOUNDS :g_lat_lng_bounds when REGEXP_G_LAT_LNG :g_lat_lng when REGEXP_BOX2D :box2d when String :wkb when nil :nil else raise ArgumentError.new("Invalid geometry!") end if !allowed.include?(type) raise ArgumentError.new("geom appears to be a #{type} but #{type} is being filtered") end geos = case type when :geometry geom when :wkt Geos.from_wkt($~, options) when :wkb_hex Geos.from_wkb(geom, options) when :g_lat_lng_bounds, :g_lat_lng Geos.from_g_lat_lng($~, options) when :box2d Geos.from_box2d($~) when :wkb Geos.from_wkb(geom.unpack('H*').first.upcase, options) when :nil nil end if geos && options[:srid] geos.srid = options[:srid] end geos end
# File lib/geos_extensions.rb, line 73 def self.wkb_reader_singleton Thread.current[:geos_extensions_wkb_reader] ||= WkbReader.new end
# File lib/geos_extensions.rb, line 77 def self.wkt_reader_singleton Thread.current[:geos_extensions_wkt_reader] ||= WktReader.new end