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