Module: Geos
- Defined in:
- lib/geos_extensions.rb,
lib/geos/point.rb,
lib/geos/polygon.rb,
lib/geos/geometry.rb,
lib/geos/yaml/syck.rb,
lib/geos/yaml/psych.rb,
lib/geos/google_maps.rb,
lib/geos/line_string.rb,
lib/geos/multi_point.rb,
lib/geos/multi_polygon.rb,
lib/geos/multi_line_string.rb,
lib/geos/extensions/version.rb,
lib/geos/coordinate_sequence.rb,
lib/geos/geometry_collection.rb,
lib/geos/google_maps/api_common.rb,
lib/geos/google_maps/polyline_encoder.rb
Overview
Some custom extensions to the SWIG-based Geos Ruby extension.
Defined Under Namespace
Modules: Extensions, GoogleMaps, Helper Classes: CoordinateSequence, Geometry, GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon
Constant Summary collapse
- GEOS_EXTENSIONS_BASE =
File.join(File.dirname(__FILE__))
- GEOS_EXTENSIONS_VERSION =
Geos::Extensions::VERSION
- REGEXP_FLOAT =
/(-?\d*(?:\.\d+)?|-?\d*(?:\.\d+?)[eE][-+]?\d+)/
- REGEXP_LAT_LNG =
/#{REGEXP_FLOAT}\s*,\s*#{REGEXP_FLOAT}/
- REGEXP_WKT =
/^\s*(?:SRID=(-?[0-9]+);)?(\s*[PLMCG].+)/im
- REGEXP_WKB_HEX =
/^[A-Fa-f0-9\s]+$/
- REGEXP_G_LAT_LNG_BOUNDS =
/^ \( \(#{REGEXP_LAT_LNG}\) # sw \s*,\s* \(#{REGEXP_LAT_LNG}\) # ne \) $ | ^ #{REGEXP_LAT_LNG} # sw \s*,\s* #{REGEXP_LAT_LNG} # ne $/x
- REGEXP_G_LAT_LNG =
/^ \(? #{REGEXP_LAT_LNG} \)? $/x
- REGEXP_BOX2D =
/^ BOX\s*\(\s* #{REGEXP_FLOAT}\s+#{REGEXP_FLOAT} \s*,\s* #{REGEXP_FLOAT}\s+#{REGEXP_FLOAT} \s*\) $/mix
- ALLOWED_GEOS_READ_TYPES =
[ :geometry, :wkt, :wkb, :wkb_hex, :g_lat_lng_bounds, :g_lat_lng, :box2d, :wkb, :nil ]
Class Method Summary collapse
-
.from_box2d(geometry_or_match_data) ⇒ Object
Creates a Geometry from a PostGIS-style BOX string.
-
.from_g_lat_lng(geometry_or_match_data, options = {}) ⇒ Object
Returns some kind of Geometry object from a String provided by a Google Maps object.
-
.from_g_point(geometry, options = {}) ⇒ Object
Same as from_g_lat_lng but uses GPoints instead of GLatLngs and GBounds instead of GLatLngBounds.
-
.from_wkb(wkb, options = {}) ⇒ Object
Returns some kind of Geometry object from the given WKB in hex.
-
.from_wkb_bin(wkb, options = {}) ⇒ Object
Returns some kind of Geometry object from the given WKB in binary.
-
.from_wkt(wkt_or_match_data, options = {}) ⇒ Object
Returns some kind of Geometry object from the given WKT.
-
.read(geom, options = {}) ⇒ Object
Tries its best to return a Geometry object.
- .wkb_reader_singleton ⇒ Object
- .wkt_reader_singleton ⇒ Object
Class Method Details
.from_box2d(geometry_or_match_data) ⇒ Object
Creates a Geometry from a PostGIS-style BOX string.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/geos_extensions.rb', line 227 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 "Invalid BOX2D" 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 |
.from_g_lat_lng(geometry_or_match_data, options = {}) ⇒ Object
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.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/geos_extensions.rb', line 179 def self.from_g_lat_lng(geometry_or_match_data, = {}) 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 "Invalid GLatLng format" end geom = if match_data.length > 3 coords = Array.new match_data.compact.each_slice(2) { |f| coords << f.collect(&:to_f) } unless [: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 [:points] } Geos.from_wkt("POINT(#{coords.join(' ')})") end if [:srid] geom.srid = [:srid] end geom end |
.from_g_point(geometry, options = {}) ⇒ Object
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.
222 223 224 |
# File 'lib/geos_extensions.rb', line 222 def self.from_g_point(geometry, = {}) self.from_g_lat_lng(geometry, .merge(:points => true)) end |
.from_wkb(wkb, options = {}) ⇒ Object
Returns some kind of Geometry object from the given WKB in hex.
83 84 85 86 87 |
# File 'lib/geos_extensions.rb', line 83 def self.from_wkb(wkb, = {}) geom = self.wkb_reader_singleton.read_hex(wkb) geom.srid = [:srid].to_i if [:srid] geom end |
.from_wkb_bin(wkb, options = {}) ⇒ Object
Returns some kind of Geometry object from the given WKB in binary.
76 77 78 79 80 |
# File 'lib/geos_extensions.rb', line 76 def self.from_wkb_bin(wkb, = {}) geom = self.wkb_reader_singleton.read(wkb) geom.srid = [:srid].to_i if [:srid] geom end |
.from_wkt(wkt_or_match_data, options = {}) ⇒ Object
Returns some kind of Geometry object from the given WKT. This method will also accept PostGIS-style EWKT and its various enhancements.
159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/geos_extensions.rb', line 159 def self.from_wkt(wkt_or_match_data, = {}) 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 = ([:srid] || srid).to_i if [:srid] || srid geom end |
.read(geom, options = {}) ⇒ Object
Tries its best to return a Geometry object.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/geos_extensions.rb', line 102 def self.read(geom, = {}) allowed = Geos::Helper.array_wrap([:allowed] || ALLOWED_GEOS_READ_TYPES) allowed = allowed - Geos::Helper.array_wrap([: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($~, ) when :wkb_hex Geos.from_wkb(geom, ) when :g_lat_lng_bounds, :g_lat_lng Geos.from_g_lat_lng($~, ) when :box2d Geos.from_box2d($~) when :wkb Geos.from_wkb(geom.unpack('H*').first.upcase, ) when :nil nil end if geos && [:srid] geos.srid = [:srid] end geos end |
.wkb_reader_singleton ⇒ Object
66 67 68 |
# File 'lib/geos_extensions.rb', line 66 def self.wkb_reader_singleton Thread.current[:geos_extensions_wkb_reader] ||= WkbReader.new end |
.wkt_reader_singleton ⇒ Object
70 71 72 |
# File 'lib/geos_extensions.rb', line 70 def self.wkt_reader_singleton Thread.current[:geos_extensions_wkt_reader] ||= WktReader.new end |