lib/rgeo/geos/ffi_factory.rb in rgeo-0.3.3 vs lib/rgeo/geos/ffi_factory.rb in rgeo-0.3.4
- old
+ new
@@ -1,26 +1,26 @@
# -----------------------------------------------------------------------------
-#
+#
# FFI-GEOS factory implementation
-#
+#
# -----------------------------------------------------------------------------
-# Copyright 2010 Daniel Azuma
-#
+# Copyright 2010-2012 Daniel Azuma
+#
# All rights reserved.
-#
+#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
-#
+#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the copyright holder, nor the names of any other
# contributors to this software, may be used to endorse or promote products
# derived from this software without specific prior written permission.
-#
+#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
@@ -33,27 +33,27 @@
# -----------------------------------------------------------------------------
;
module RGeo
-
+
module Geos
-
-
+
+
# This the FFI-GEOS implementation of ::RGeo::Feature::Factory.
-
+
class FFIFactory
-
-
+
+
include Feature::Factory::Instance
-
-
+
+
# Create a new factory. Returns nil if the FFI-GEOS implementation
# is not supported.
- #
+ #
# See ::RGeo::Geos.factory for a list of supported options.
-
+
def initialize(opts_={})
# Main flags
@uses_lenient_multi_polygon_assertions = opts_[:lenient_multi_polygon_assertions] ||
opts_[:uses_lenient_multi_polygon_assertions]
@has_z = opts_[:has_z_coordinate]
@@ -62,11 +62,12 @@
raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
end
@_has_3d = @has_z || @has_m
@buffer_resolution = opts_[:buffer_resolution].to_i
@buffer_resolution = 1 if @buffer_resolution < 1
-
+ @_auto_prepare = opts_[:auto_prepare] == :disabled ? false : true
+
# Interpret the generator options
wkt_generator_ = opts_[:wkt_generator]
case wkt_generator_
when :geos
@wkt_writer = ::Geos::WktWriter.new
@@ -88,11 +89,11 @@
@wkb_writer = nil
else
@wkb_generator = WKRep::WKBGenerator.new
@wkb_writer = nil
end
-
+
# Coordinate system (srid, proj4, and coord_sys)
@srid = opts_[:srid]
@proj4 = opts_[:proj4]
if CoordSys::Proj4.supported?
if @proj4.kind_of?(::String) || @proj4.kind_of?(::Hash)
@@ -112,11 +113,11 @@
@coord_sys ||= entry_.coord_sys
end
end
@srid ||= @coord_sys.authority_code if @coord_sys
@srid = @srid.to_i
-
+
# Interpret parser options
wkt_parser_ = opts_[:wkt_parser]
case wkt_parser_
when :geos
@wkt_reader = ::Geos::WktReader.new
@@ -139,51 +140,51 @@
else
@wkb_parser = WKRep::WKBParser.new(self)
@wkb_reader = nil
end
end
-
-
+
+
def inspect # :nodoc:
"#<#{self.class}:0x#{object_id.to_s(16)} srid=#{srid}>"
end
-
-
+
+
# Factory equivalence test.
-
+
def eql?(rhs_)
rhs_.is_a?(self.class) && @srid == rhs_.srid &&
@has_z == rhs_.property(:has_z_coordinate) &&
@has_m == rhs_.property(:has_m_coordinate)
end
alias_method :==, :eql?
-
-
+
+
# Returns the SRID of geometries created by this factory.
-
+
def srid
@srid
end
-
-
+
+
# Returns the resolution used by buffer calculations on geometries
# created by this factory
-
+
def buffer_resolution
@buffer_resolution
end
-
-
+
+
# Returns true if this factory is lenient with MultiPolygon assertions
-
+
def lenient_multi_polygon_assertions?
@uses_lenient_multi_polygon_assertions
end
-
-
+
+
# See ::RGeo::Feature::Factory#property
-
+
def property(name_)
case name_
when :has_z_coordinate
@has_z
when :has_m_coordinate
@@ -192,38 +193,40 @@
true
when :buffer_resolution
@buffer_resolution
when :uses_lenient_multi_polygon_assertions
@uses_lenient_multi_polygon_assertions
+ when :auto_prepare
+ @_auto_prepare ? :simple : :disabled
else
nil
end
end
-
-
+
+
# See ::RGeo::Feature::Factory#parse_wkt
-
+
def parse_wkt(str_)
if @wkt_reader
@wkt_reader.read(str_)
else
@wkt_parser.parse(str_)
end
end
-
-
+
+
# See ::RGeo::Feature::Factory#parse_wkb
-
+
def parse_wkb(str_)
if @wkb_reader
@wkb_reader.read(str_)
else
@wkb_parser.parse(str_)
end
end
-
-
+
+
def wrap_fg_geom(fg_geom_, klass_=nil) # :nodoc:
klasses_ = nil
unless klass_.kind_of?(::Class)
is_collection_ = false
case fg_geom_.type_id
@@ -255,25 +258,25 @@
end
klass_ = inferred_klass_
end
klass_.new(self, fg_geom_, klasses_)
end
-
-
+
+
# See ::RGeo::Feature::Factory#point
-
+
def point(x_, y_, z_=0)
cs_ = ::Geos::CoordinateSequence.new(1, 3)
cs_.set_x(0, x_)
cs_.set_y(0, y_)
cs_.set_z(0, z_)
FFIPointImpl.new(self, ::Geos::Utils.create_point(cs_), nil)
end
-
-
+
+
# See ::RGeo::Feature::Factory#line_string
-
+
def line_string(points_)
points_ = points_.to_a unless points_.kind_of?(::Array)
size_ = points_.size
return nil if size_ == 1
cs_ = ::Geos::CoordinateSequence.new(size_, 3)
@@ -287,14 +290,14 @@
cs_.set_z(i_, p_.m)
end
end
FFILineStringImpl.new(self, ::Geos::Utils.create_line_string(cs_), nil)
end
-
-
+
+
# See ::RGeo::Feature::Factory#line
-
+
def line(start_, end_)
return nil unless ::RGeo::Feature::Point.check_type(start_) &&
::RGeo::Feature::Point.check_type(end_)
cs_ = ::Geos::CoordinateSequence.new(2, 3)
cs_.set_x(0, start_.x)
@@ -308,23 +311,23 @@
cs_.set_z(0, start_.m)
cs_.set_z(1, end_.m)
end
FFILineImpl.new(self, ::Geos::Utils.create_line_string(cs_), nil)
end
-
-
+
+
# See ::RGeo::Feature::Factory#linear_ring
-
+
def linear_ring(points_)
points_ = points_.to_a unless points_.kind_of?(::Array)
fg_geom_ = _create_fg_linear_ring(points_)
fg_geom_ ? FFILinearRingImpl.new(self, fg_geom_, nil) : nil
end
-
-
+
+
# See ::RGeo::Feature::Factory#polygon
-
+
def polygon(outer_ring_, inner_rings_=nil)
inner_rings_ = inner_rings_.to_a unless inner_rings_.kind_of?(::Array)
return nil unless ::RGeo::Feature::LineString.check_type(outer_ring_)
outer_ring_ = _create_fg_linear_ring(outer_ring_.points)
inner_rings_.map! do |r_|
@@ -333,14 +336,14 @@
end
inner_rings_.compact!
fg_geom_ = ::Geos::Utils.create_polygon(outer_ring_, *inner_rings_)
fg_geom_ ? FFIPolygonImpl.new(self, fg_geom_, nil) : nil
end
-
-
+
+
# See ::RGeo::Feature::Factory#collection
-
+
def collection(elems_)
elems_ = elems_.to_a unless elems_.kind_of?(::Array)
klasses_ = []
fg_geoms_ = []
elems_.each do |elem_|
@@ -353,14 +356,14 @@
end
fg_geom_ = ::Geos::Utils.create_collection(
::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION, fg_geoms_)
fg_geom_ ? FFIGeometryCollectionImpl.new(self, fg_geom_, klasses_) : nil
end
-
-
+
+
# See ::RGeo::Feature::Factory#multi_point
-
+
def multi_point(elems_)
elems_ = elems_.to_a unless elems_.kind_of?(::Array)
fg_geoms_ = []
elems_.map! do |elem_|
elem_ = ::RGeo::Feature.cast(elem_, self, ::RGeo::Feature::Point,
@@ -371,14 +374,14 @@
klasses_ = ::Array.new(elems_.size, FFIPointImpl)
fg_geom_ = ::Geos::Utils.create_collection(
::Geos::GeomTypes::GEOS_MULTIPOINT, elems_)
fg_geom_ ? FFIMultiPointImpl.new(self, fg_geom_, klasses_) : nil
end
-
-
+
+
# See ::RGeo::Feature::Factory#multi_line_string
-
+
def multi_line_string(elems_)
elems_ = elems_.to_a unless elems_.kind_of?(::Array)
klasses_ = []
elems_.map! do |elem_|
elem_ = ::RGeo::Feature.cast(elem_, self, ::RGeo::Feature::LineString,
@@ -389,14 +392,14 @@
end
fg_geom_ = ::Geos::Utils.create_collection(
::Geos::GeomTypes::GEOS_MULTILINESTRING, elems_)
fg_geom_ ? FFIMultiLineStringImpl.new(self, fg_geom_, klasses_) : nil
end
-
-
+
+
# See ::RGeo::Feature::Factory#multi_polygon
-
+
def multi_polygon(elems_)
elems_ = elems_.to_a unless elems_.kind_of?(::Array)
elems_.map! do |elem_|
elem_ = ::RGeo::Feature.cast(elem_, self, ::RGeo::Feature::Polygon,
:force_new, :keep_subtype)
@@ -416,47 +419,48 @@
klasses_ = ::Array.new(elems_.size, FFIPolygonImpl)
fg_geom_ = ::Geos::Utils.create_collection(
::Geos::GeomTypes::GEOS_MULTIPOLYGON, elems_)
fg_geom_ ? FFIMultiPolygonImpl.new(self, fg_geom_, klasses_) : nil
end
-
-
+
+
# See ::RGeo::Feature::Factory#proj4
-
+
def proj4
@proj4
end
-
-
+
+
# See ::RGeo::Feature::Factory#coord_sys
-
+
def coord_sys
@coord_sys
end
-
-
+
+
# See ::RGeo::Feature::Factory#override_cast
-
+
def override_cast(original_, ntype_, flags_)
false
# TODO
end
-
-
+
+
attr_reader :_has_3d # :nodoc:
-
-
+ attr_reader :_auto_prepare # :nodoc:
+
+
def _convert_to_fg_geometry(obj_, type_=nil) # :nodoc:
if type_.nil? && obj_.factory == self
obj_
else
obj_ = Feature.cast(obj_, self, type_)
end
obj_ ? obj_.fg_geom : nil
end
-
-
+
+
def _create_fg_linear_ring(points_) # :nodoc:
size_ = points_.size
return nil if size_ == 1 || size_ == 2
if size_ > 0 && points_.first != points_.last
points_ = points_ + [points_.first]
@@ -473,31 +477,31 @@
cs_.set_z(i_, p_.m)
end
end
::Geos::Utils.create_linear_ring(cs_)
end
-
-
+
+
def _generate_wkt(geom_) # :nodoc:
if @wkt_writer
@wkt_writer.write(geom_.fg_geom)
else
@wkt_generator.generate(geom_)
end
end
-
-
+
+
def _generate_wkb(geom_) # :nodoc:
if @wkb_writer
@wkb_writer.write(geom_.fg_geom)
else
@wkb_generator.generate(geom_)
end
end
-
-
+
+
end
-
-
+
+
end
-
+
end