From af93e66efe63d7d56cbdfd57119fd93bd7e6167d Mon Sep 17 00:00:00 2001 From: Marcos Augusto Date: Sat, 10 Jan 2009 00:35:57 -0200 Subject: [PATCH] Fix custom column names, fix migration "thing", adds transform srid --- Manifest.txt | 12 +- lib/postgis_adapter.rb | 7 +- lib/postgis_adapter/acts_as_geom.rb | 7 +- lib/postgis_functions.rb | 27 +- lib/postgis_functions/common.rb | 355 +++++++++++++++++- lib/postgis_functions/linestring.rb | 172 --------- lib/postgis_functions/point.rb | 89 ----- lib/postgis_functions/polygon.rb | 78 ---- postgis_adapter.gemspec | 24 +- spec/acts_as_geom_spec.rb | 15 - spec/db/database_postgis.yml | 2 +- spec/db/models_postgis.rb | 1 + spec/db/schema_postgis.rb | 39 +- spec/postgis_adapter/acts_as_geom_spec.rb | 27 ++ .../common_spatial_adapter_spec.rb | 2 +- spec/postgis_adapter_spec.rb | 34 +- spec/postgis_functions/bbox_spec.rb | 79 ++-- spec/postgis_functions/class_spec.rb | 0 spec/postgis_functions/common_spec.rb | 281 ++++++++++++++ spec/postgis_functions/linestring_spec.rb | 219 ----------- spec/postgis_functions/point_spec.rb | 136 ------- spec/postgis_functions/polygon_spec.rb | 146 ------- spec/postgis_functions_spec.rb | 9 +- spec/spec.opts | 3 +- spec/spec_helper.rb | 1 + 25 files changed, 762 insertions(+), 1003 deletions(-) delete mode 100644 lib/postgis_functions/linestring.rb delete mode 100644 lib/postgis_functions/point.rb delete mode 100644 lib/postgis_functions/polygon.rb delete mode 100644 spec/acts_as_geom_spec.rb create mode 100644 spec/postgis_adapter/acts_as_geom_spec.rb rename spec/{ => postgis_adapter}/common_spatial_adapter_spec.rb (99%) create mode 100644 spec/postgis_functions/class_spec.rb create mode 100644 spec/postgis_functions/common_spec.rb delete mode 100644 spec/postgis_functions/linestring_spec.rb delete mode 100644 spec/postgis_functions/point_spec.rb delete mode 100644 spec/postgis_functions/polygon_spec.rb diff --git a/Manifest.txt b/Manifest.txt index 44269fb..56d6d29 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -12,24 +12,20 @@ lib/postgis_functions.rb lib/postgis_functions/bbox.rb lib/postgis_functions/class.rb lib/postgis_functions/common.rb -lib/postgis_functions/linestring.rb -lib/postgis_functions/point.rb -lib/postgis_functions/polygon.rb postgis_adapter.gemspec rails/init.rb script/console script/destroy script/generate -spec/acts_as_geom_spec.rb -spec/common_spatial_adapter_spec.rb spec/db/database_postgis.yml spec/db/models_postgis.rb spec/db/schema_postgis.rb +spec/postgis_adapter/acts_as_geom_spec.rb +spec/postgis_adapter/common_spatial_adapter_spec.rb spec/postgis_adapter_spec.rb spec/postgis_functions/bbox_spec.rb -spec/postgis_functions/linestring_spec.rb -spec/postgis_functions/point_spec.rb -spec/postgis_functions/polygon_spec.rb +spec/postgis_functions/class_spec.rb +spec/postgis_functions/common_spec.rb spec/postgis_functions_spec.rb spec/spec.opts spec/spec_helper.rb diff --git a/lib/postgis_adapter.rb b/lib/postgis_adapter.rb index c6b79c6..be8f16a 100644 --- a/lib/postgis_adapter.rb +++ b/lib/postgis_adapter.rb @@ -10,9 +10,6 @@ require 'postgis_functions' require 'postgis_functions/common' require 'postgis_functions/class' -require 'postgis_functions/point' -require 'postgis_functions/linestring' -require 'postgis_functions/polygon' require 'postgis_functions/bbox' require 'postgis_adapter/acts_as_geom' @@ -20,13 +17,12 @@ include SpatialAdapter module PostgisAdapter - VERSION = '0.1.8' + VERSION = '0.2.1' end #tables to ignore in migration : relative to PostGIS management of geometric columns ActiveRecord::SchemaDumper.ignore_tables << "spatial_ref_sys" << "geometry_columns" - #add a method to_yaml to the Geometry class which will transform a geometry in a form suitable to be used in a YAML file (such as in a fixture) GeoRuby::SimpleFeatures::Geometry.class_eval do def to_fixture_format @@ -34,7 +30,6 @@ def to_fixture_format end end - ActiveRecord::Base.class_eval do require 'active_record/version' diff --git a/lib/postgis_adapter/acts_as_geom.rb b/lib/postgis_adapter/acts_as_geom.rb index b2a0ade..fa5eafe 100644 --- a/lib/postgis_adapter/acts_as_geom.rb +++ b/lib/postgis_adapter/acts_as_geom.rb @@ -14,7 +14,6 @@ module ClassMethods # acts_as_geom :geom def acts_as_geom(*columns) cattr_accessor :postgis_geoms - geoms = columns.map do |g| geom_type = get_geom_type(g) case geom_type @@ -25,13 +24,15 @@ def acts_as_geom(*columns) when :line_string send :include, LineStringFunctions end - {g => geom_type} + g end - self.postgis_geoms = {:geoms => geoms}#, :opts => options} + self.postgis_geoms = {:columns => geoms}#, :opts => options} end def get_geom_type(column) self.columns.select { |c| c.name == column.to_s}.first.geometry_type + rescue ActiveRecord::StatementInvalid => e + nil end end end diff --git a/lib/postgis_functions.rb b/lib/postgis_functions.rb index ee829a9..5c77605 100644 --- a/lib/postgis_functions.rb +++ b/lib/postgis_functions.rb @@ -18,9 +18,8 @@ # # module PostgisFunctions - # EARTH_SPHEROID = "'SPHEROID[\"GRS-80\",6378137,298.257222101]'" - - EARTH_SPHEROID = "'SPHEROID[\"IERS_2003\",6378136.6,298.25642]'" + EARTH_SPHEROID = "'SPHEROID[\"GRS-80\",6378137,298.257222101]'" # SRID => 4326 + #EARTH_SPHEROID = "'SPHEROID[\"IERS_2003\",6378136.6,298.25642]'" # SRID => def postgis_calculate(operation, subjects, options = nil) subjects = [subjects] unless subjects.respond_to?(:map) @@ -29,12 +28,13 @@ def postgis_calculate(operation, subjects, options = nil) raise StandardError, "#{e}" end - private - + def get_column_name + @geo_column ||= postgis_geoms[:columns].first + end + # Construct the postgis sql query - # TODO: ST_Transform() ?? # Convert between distances. Implement this? # # Area return in square feet # Distance/DWithin/Length/Perimeter — in projected units. @@ -49,7 +49,7 @@ def construct_geometric_sql(type,geoms,options) :id => t[:id] } end - fields = tables.map { |f| "#{f[:uid]}.geom" } # W1.geom + fields = tables.map { |f| "#{f[:uid]}.#{get_column_name}" } # W1.geom conditions = tables.map { |f| "#{f[:uid]}.id = #{f[:id]}" } # W1.id = 5 tables.map! { |f| "#{f[:class]} #{f[:uid]}" } # streets W1 @@ -57,17 +57,16 @@ def construct_geometric_sql(type,geoms,options) # Data => SELECT Func(A,B) # BBox => SELECT (A <=> B) # - if type == :bbox - opcode = nil - s_join = " #{options} " - else + unless type == :bbox opcode = type.to_s opcode = "ST_#{opcode}" unless opcode =~ /th3d|pesinter/ - s_join = "," fields << options if options + fields = fields.join(",") + else + fields = fields.join(" #{options} ") end - sql = "SELECT #{opcode}(#{fields.join(s_join)}) " + sql = "SELECT #{opcode}(#{fields}) " sql << "FROM #{tables.join(",")} " if tables sql << "WHERE #{conditions.join(" AND ")}" if conditions #p sql; sql @@ -94,7 +93,7 @@ def execute_geometrical_calculation(operation, subject, options) #:nodoc: # Get a unique ID for tables def unique_identifier - @u_id ||= "W1" + @u_id ||= "T1" @u_id = @u_id.succ end diff --git a/lib/postgis_functions/common.rb b/lib/postgis_functions/common.rb index b5ff2fd..7f08e77 100644 --- a/lib/postgis_functions/common.rb +++ b/lib/postgis_functions/common.rb @@ -234,7 +234,7 @@ def simplify(tolerance=0.1) def simplify!(tolerance=0.1) #FIXME: not good.. - self.geom = simplify + self.update_attribute(get_column_name, simplify) end # @@ -424,6 +424,357 @@ def relate?(other, m = nil) m = "'#{m}'" if m postgis_calculate("Relate", [self, other], m) end + + # + # Transform the geometry into a different spatial reference system. + # + # Return geometry ST_Transform(geometry g1, integer srid); + # Returns a new geometry with its coordinates transformed to spatial reference system referenced by the SRID integer parameter. The destination SRID must exist in the SPATIAL_REF_SYS table. + # ST_Transform is often confused with ST_SetSRID(). ST_Transform actually changes the coordinates of a geometry from one spatial reference system to another, while ST_SetSRID() simply changes the SRID identifier of the geometry + # Requires PostGIS be compiled with Proj support. Use PostGIS_Full_Version to confirm you have proj support compiled in. + # + # If using more than one transformation, it is useful to have a functional index on the commonly used transformations to take advantage of index usage. + # + # Prior to 1.3.4, this function crashes if used with geometries that contain CURVES. This is fixed in 1.3.4+ + # This method implements the OpenGIS Simple Features Implementation Specification for SQL. + # This method supports Circular Strings and Curves + # + def transform(new_srid) + postgis_calculate("Transform", self, new_srid) + end + + # + # LINESTRING + # + # + # + module LineStringFunctions + + # + # Returns the 2D length of the geometry if it is a linestring, multilinestring, + # ST_Curve, ST_MultiCurve. 0 is returned for areal geometries. For areal geometries + # use 'perimeter'. Measurements are in the units of the spatial reference system + # of the geometry. + # + # Returns Float + # + def length + dis = postgis_calculate(:length, self).to_f + end + + # + # Returns the 3-dimensional or 2-dimensional length of the geometry if it is + # a linestring or multi-linestring. For 2-d lines it will just return the 2-d + # length (same as 'length') + # + # Returns Float + # + def length_3d + dis = postgis_calculate(:length3d, self).to_f + end + + # + # Calculates the length of a geometry on an ellipsoid. This is useful if the + # coordinates of the geometry are in longitude/latitude and a length is + # desired without reprojection. The ellipsoid is a separate database type and + # can be constructed as follows: + # + # SPHEROID[,,] + # + # Example: + # SPHEROID["GRS_1980",6378137,298.257222101] + # + # Defaults to: + # + # SPHEROID["IERS_2003",6378136.6,298.25642] + # + # Returns Float length_spheroid(geometry linestring, spheroid); + # + def length_spheroid(spheroid = EARTH_SPHEROID) + dis = postgis_calculate(:length_spheroid, self, spheroid).to_f + end + + # + # Return the number of points of the geometry. + # PostGis ST_NumPoints does not work as nov/08 + # + # Returns Integer ST_NPoints(geometry g1); + # + def num_points + postgis_calculate(:npoints, self).to_i + end + + # + # Returns geometry start point. + # + def start_point + postgis_calculate(:startpoint, self) + end + + # + # Returns geometry end point. + # + def end_point + postgis_calculate(:endpoint, self) + end + + # + # Takes two geometry objects and returns TRUE if their intersection + # "spatially cross", that is, the geometries have some, but not all interior + # points in common. The intersection of the interiors of the geometries must + # not be the empty set and must have a dimensionality less than the the + # maximum dimension of the two input geometries. Additionally, the + # intersection of the two geometries must not equal either of the source + # geometries. Otherwise, it returns FALSE. + # + # + # Returns Boolean ST_Crosses(geometry g1, geometry g2); + # + def crosses? other + postgis_calculate(:crosses, [self, other]) + end + + # + # Returns a float between 0 and 1 representing the location of the closest point + # on LineString to the given Point, as a fraction of total 2d line length. + # + # You can use the returned location to extract a Point (ST_Line_Interpolate_Point) + # or a substring (ST_Line_Substring). + # + # This is useful for approximating numbers of addresses. + # + # Returns float (0 to 1) ST_Line_Locate_Point(geometry a_linestring, geometry a_point); + # + def locate_point point + postgis_calculate(:line_locate_point, [self, point]).to_f + end + + # + # Return a derived geometry collection value with elements that match the + # specified measure. Polygonal elements are not supported. + # + # Semantic is specified by: ISO/IEC CD 13249-3:200x(E) - Text for + # Continuation CD Editing Meeting + # + # Returns geometry ST_Locate_Along_Measure(geometry ageom_with_measure, float a_measure); + # + def locate_along_measure(measure) + postgis_calculate(:locate_along_measure, self, measure) + end + + # + # Return a derived geometry collection value with elements that match the + # specified range of measures inclusively. Polygonal elements are not supported. + # + # Semantic is specified by: ISO/IEC CD 13249-3:200x(E) - Text for Continuation CD Editing Meeting + # + # Returns geometry ST_Locate_Between_Measures(geometry geomA, float measure_start, float measure_end); + # + def locate_between_measures(a, b) + postgis_calculate(:locate_between_measures, self, [a,b]) + end + + # + # Returns a point interpolated along a line. First argument must be a LINESTRING. + # Second argument is a float8 between 0 and 1 representing fraction of total + # linestring length the point has to be located. + # + # See ST_Line_Locate_Point for computing the line location nearest to a Point. + # + # Returns geometry ST_Line_Interpolate_Point(geometry a_linestring, float a_fraction); + # + def interpolate_point(fraction) + postgis_calculate(:line_interpolate_point, self, fraction) + end + + # + # Return a linestring being a substring of the input one starting and ending + # at the given fractions of total 2d length. Second and third arguments are + # float8 values between 0 and 1. This only works with LINESTRINGs. To use + # with contiguous MULTILINESTRINGs use in conjunction with ST_LineMerge. + # + # If 'start' and 'end' have the same value this is equivalent to 'interpolate_point'. + # + # See 'locate_point' for computing the line location nearest to a Point. + # + # Returns geometry ST_Line_Substring(geometry a_linestring, float startfraction, float endfraction); + # + def line_substring(s,e) + postgis_calculate(:line_substring, self, [s, e]) + end + + ### + #Not implemented in postgis yet + # ST_max_distance Returns the largest distance between two line strings. + #def max_distance other + # #float ST_Max_Distance(geometry g1, geometry g2); + # postgis_calculate(:max_distance, [self, other]) + #end + end + + + #### + ### + ## + # + # POINT + # + # + module PointFunctions + + # + # Returns a float between 0 and 1 representing the location of the closest point + # on LineString to the given Point, as a fraction of total 2d line length. + # + # You can use the returned location to extract a Point (ST_Line_Interpolate_Point) + # or a substring (ST_Line_Substring). + # + # This is useful for approximating numbers of addresses. + # + # Returns float (0 to 1) ST_Line_Locate_Point(geometry a_linestring, geometry a_point); + # + def where_on_line line + postgis_calculate(:line_locate_point, [line, self]).to_f + end + + # + # Linear distance in meters between two lon/lat points. + # Uses a spherical earth and radius of 6370986 meters. + # Faster than 'distance_spheroid', but less accurate. + # + # Only implemented for points. + # + # Returns Float ST_Distance_Sphere(geometry pointlonlatA, geometry pointlonlatB); + # + def distance_sphere_to(other) + dis = postgis_calculate(:distance_sphere, [self, other]).to_f + end + + # + # Calculates the distance on an ellipsoid. This is useful if the + # coordinates of the geometry are in longitude/latitude and a length is + # desired without reprojection. The ellipsoid is a separate database type and + # can be constructed as follows: + # + # This is slower then 'distance_sphere_to', but more precise. + # + # SPHEROID[,,] + # + # Example: + # SPHEROID["GRS_1980",6378137,298.257222101] + # + # Defaults to: + # + # SPHEROID["IERS_2003",6378136.6,298.25642] + # + # Returns ST_Distance_Spheroid(geometry geomA, geometry geomB, spheroid); + # + def distance_spheroid_to(other, spheroid = EARTH_SPHEROID) + postgis_calculate(:distance_spheroid, [self, other], spheroid).to_f + end + + # + # The azimuth of the segment defined by the given Point geometries, + # or NULL if the two points are coincident. Return value is in radians. + # + # The Azimuth is mathematical concept defined as the angle, in this case + # measured in radian, between a reference plane and a point. + # + # Returns Float ST_Azimuth(geometry pointA, geometry pointB); + # + def azimuth other + #TODO: return if not point/point + postgis_calculate(:azimuth, [self, other]).to_f + rescue + ActiveRecord::StatementInvalid + end + + # + # True if the geometry is a point and is inside the circle. + # + # Returns Boolean ST_point_inside_circle(geometry, float, float, float) + # + def inside_circle?(x,y,r) + postgis_calculate(:point_inside_circle, self, [x,y,r]) + end + + end + + ### + ## + # + # Polygon + # + # + module PolygonFunctions + + # + # The area of the geometry if it is a polygon or multi-polygon. + # Return the area measurement of an ST_Surface or ST_MultiSurface value. + # Area is in the units of the spatial reference system. + # + # Returns Float ST_Area(geometry g1); + # + def area + postgis_calculate(:area, self).to_f + end + + # + # Returns the 2D perimeter of the geometry if it is a ST_Surface, ST_MultiSurface + # (Polygon, Multipolygon). 0 is returned for non-areal geometries. For linestrings + # use 'length'. Measurements are in the units of the spatial reference system of + # the geometry. + # + # Returns Float ST_Perimeter(geometry g1); + # + def perimeter + postgis_calculate(:perimeter, self).to_f + end + + # + # Returns the 3-dimensional perimeter of the geometry, if it is a polygon or multi-polygon. + # If the geometry is 2-dimensional, then the 2-dimensional perimeter is returned. + # + # Returns Float ST_Perimeter3D(geometry geomA); + # + def perimeter3d + postgis_calculate(:perimeter3d, self).to_f + end + + # + # True if the LineString's start and end points are coincident. + # + # This method implements the OpenGIS Simple Features Implementation + # Specification for SQL. + # + # SQL-MM defines the result of ST_IsClosed(NULL) to be 0, while PostGIS returns NULL. + # + # Returns boolean ST_IsClosed(geometry g); + # + def closed? + postgis_calculate(:isclosed, self) + end + alias_method "is_closed?", "closed?" + + # + # True if no point in Geometry B is outside Geometry A + # + # This function call will automatically include a bounding box comparison + # that will make use of any indexes that are available on the geometries. + # To avoid index use, use the function _ST_Covers. + # + # Do not call with a GEOMETRYCOLLECTION as an argument + # Do not use this function with invalid geometries. You will get unexpected results. + # + # Performed by the GEOS module. + # + # Returns Boolean ST_Covers(geometry geomA, geometry geomB); + # + def covers? other + postgis_calculate(:covers, [self, other]) + end + + end end @@ -435,4 +786,4 @@ def relate?(other, m = nil) #x ST_SnapToGrid(geometry, geometry, sizeX, sizeY, sizeZ, sizeM) -# ST_X , ST_Y, SE_M, SE_Z, SE_IsMeasured has_m? \ No newline at end of file +# ST_X , ST_Y, SE_M, SE_Z, SE_IsMeasured has_m? diff --git a/lib/postgis_functions/linestring.rb b/lib/postgis_functions/linestring.rb deleted file mode 100644 index 5077ac5..0000000 --- a/lib/postgis_functions/linestring.rb +++ /dev/null @@ -1,172 +0,0 @@ -module PostgisFunctions -#### -### -## -# -# LINESTRING -# - - module LineStringFunctions - - # - # Returns the 2D length of the geometry if it is a linestring, multilinestring, - # ST_Curve, ST_MultiCurve. 0 is returned for areal geometries. For areal geometries - # use 'perimeter'. Measurements are in the units of the spatial reference system - # of the geometry. - # - # Returns Float - # - def length - dis = postgis_calculate(:length, self).to_f - end - - # - # Returns the 3-dimensional or 2-dimensional length of the geometry if it is - # a linestring or multi-linestring. For 2-d lines it will just return the 2-d - # length (same as 'length') - # - # Returns Float - # - def length_3d - dis = postgis_calculate(:length3d, self).to_f - end - - # - # Calculates the length of a geometry on an ellipsoid. This is useful if the - # coordinates of the geometry are in longitude/latitude and a length is - # desired without reprojection. The ellipsoid is a separate database type and - # can be constructed as follows: - # - # SPHEROID[,,] - # - # Example: - # SPHEROID["GRS_1980",6378137,298.257222101] - # - # Defaults to: - # - # SPHEROID["IERS_2003",6378136.6,298.25642] - # - # Returns Float length_spheroid(geometry linestring, spheroid); - # - def length_spheroid(spheroid = EARTH_SPHEROID) - dis = postgis_calculate(:length_spheroid, self, spheroid).to_f - end - - # - # Return the number of points of the geometry. - # PostGis ST_NumPoints does not work as nov/08 - # - # Returns Integer ST_NPoints(geometry g1); - # - def num_points - postgis_calculate(:npoints, self).to_i - end - - # - # Returns geometry start point. - # - def start_point - postgis_calculate(:startpoint, self) - end - - # - # Returns geometry end point. - # - def end_point - postgis_calculate(:endpoint, self) - end - - # - # Takes two geometry objects and returns TRUE if their intersection - # "spatially cross", that is, the geometries have some, but not all interior - # points in common. The intersection of the interiors of the geometries must - # not be the empty set and must have a dimensionality less than the the - # maximum dimension of the two input geometries. Additionally, the - # intersection of the two geometries must not equal either of the source - # geometries. Otherwise, it returns FALSE. - # - # - # Returns Boolean ST_Crosses(geometry g1, geometry g2); - # - def crosses? other - postgis_calculate(:crosses, [self, other]) - end - - # - # Returns a float between 0 and 1 representing the location of the closest point - # on LineString to the given Point, as a fraction of total 2d line length. - # - # You can use the returned location to extract a Point (ST_Line_Interpolate_Point) - # or a substring (ST_Line_Substring). - # - # This is useful for approximating numbers of addresses. - # - # Returns float (0 to 1) ST_Line_Locate_Point(geometry a_linestring, geometry a_point); - # - def locate_point point - postgis_calculate(:line_locate_point, [self, point]).to_f - end - - # - # Return a derived geometry collection value with elements that match the - # specified measure. Polygonal elements are not supported. - # - # Semantic is specified by: ISO/IEC CD 13249-3:200x(E) - Text for - # Continuation CD Editing Meeting - # - # Returns geometry ST_Locate_Along_Measure(geometry ageom_with_measure, float a_measure); - # - def locate_along_measure(measure) - postgis_calculate(:locate_along_measure, self, measure) - end - - # - # Return a derived geometry collection value with elements that match the - # specified range of measures inclusively. Polygonal elements are not supported. - # - # Semantic is specified by: ISO/IEC CD 13249-3:200x(E) - Text for Continuation CD Editing Meeting - # - # Returns geometry ST_Locate_Between_Measures(geometry geomA, float measure_start, float measure_end); - # - def locate_between_measures(a, b) - postgis_calculate(:locate_between_measures, self, [a,b]) - end - - # - # Returns a point interpolated along a line. First argument must be a LINESTRING. - # Second argument is a float8 between 0 and 1 representing fraction of total - # linestring length the point has to be located. - # - # See ST_Line_Locate_Point for computing the line location nearest to a Point. - # - # Returns geometry ST_Line_Interpolate_Point(geometry a_linestring, float a_fraction); - # - def interpolate_point(fraction) - postgis_calculate(:line_interpolate_point, self, fraction) - end - - # - # Return a linestring being a substring of the input one starting and ending - # at the given fractions of total 2d length. Second and third arguments are - # float8 values between 0 and 1. This only works with LINESTRINGs. To use - # with contiguous MULTILINESTRINGs use in conjunction with ST_LineMerge. - # - # If 'start' and 'end' have the same value this is equivalent to 'interpolate_point'. - # - # See 'locate_point' for computing the line location nearest to a Point. - # - # Returns geometry ST_Line_Substring(geometry a_linestring, float startfraction, float endfraction); - # - def line_substring(s,e) - postgis_calculate(:line_substring, self, [s, e]) - end - - ### - #Not implemented in postgis yet - # ST_max_distance Returns the largest distance between two line strings. - #def max_distance other - # #float ST_Max_Distance(geometry g1, geometry g2); - # postgis_calculate(:max_distance, [self, other]) - #end - end -end \ No newline at end of file diff --git a/lib/postgis_functions/point.rb b/lib/postgis_functions/point.rb deleted file mode 100644 index d233500..0000000 --- a/lib/postgis_functions/point.rb +++ /dev/null @@ -1,89 +0,0 @@ -module PostgisFunctions - #### - ### - ## - # - # POINT - # - # - module PointFunctions - - # - # Returns a float between 0 and 1 representing the location of the closest point - # on LineString to the given Point, as a fraction of total 2d line length. - # - # You can use the returned location to extract a Point (ST_Line_Interpolate_Point) - # or a substring (ST_Line_Substring). - # - # This is useful for approximating numbers of addresses. - # - # Returns float (0 to 1) ST_Line_Locate_Point(geometry a_linestring, geometry a_point); - # - def where_on_line line - postgis_calculate(:line_locate_point, [line, self]).to_f - end - - # - # Linear distance in meters between two lon/lat points. - # Uses a spherical earth and radius of 6370986 meters. - # Faster than 'distance_spheroid', but less accurate. - # - # Only implemented for points. - # - # Returns Float ST_Distance_Sphere(geometry pointlonlatA, geometry pointlonlatB); - # - def distance_sphere_to(other) - dis = postgis_calculate(:distance_sphere, [self, other]).to_f - end - - # - # Calculates the distance on an ellipsoid. This is useful if the - # coordinates of the geometry are in longitude/latitude and a length is - # desired without reprojection. The ellipsoid is a separate database type and - # can be constructed as follows: - # - # This is slower then 'distance_sphere_to', but more precise. - # - # SPHEROID[,,] - # - # Example: - # SPHEROID["GRS_1980",6378137,298.257222101] - # - # Defaults to: - # - # SPHEROID["IERS_2003",6378136.6,298.25642] - # - # Returns ST_Distance_Spheroid(geometry geomA, geometry geomB, spheroid); - # - def distance_spheroid_to(other, spheroid = EARTH_SPHEROID) - postgis_calculate(:distance_spheroid, [self, other], spheroid).to_f - end - - # - # The azimuth of the segment defined by the given Point geometries, - # or NULL if the two points are coincident. Return value is in radians. - # - # The Azimuth is mathematical concept defined as the angle, in this case - # measured in radian, between a reference plane and a point. - # - # Returns Float ST_Azimuth(geometry pointA, geometry pointB); - # - def azimuth other - #TODO: return if not point/point - postgis_calculate(:azimuth, [self, other]).to_f - rescue - ActiveRecord::StatementInvalid - end - - # - # True if the geometry is a point and is inside the circle. - # - # Returns Boolean ST_point_inside_circle(geometry, float, float, float) - # - def inside_circle?(x,y,r) - postgis_calculate(:point_inside_circle, self, [x,y,r]) - end - - end - -end \ No newline at end of file diff --git a/lib/postgis_functions/polygon.rb b/lib/postgis_functions/polygon.rb deleted file mode 100644 index 6dd2e86..0000000 --- a/lib/postgis_functions/polygon.rb +++ /dev/null @@ -1,78 +0,0 @@ -module PostgisFunctions - ### - ## - # - # Polygon - # - # - module PolygonFunctions - - # - # The area of the geometry if it is a polygon or multi-polygon. - # Return the area measurement of an ST_Surface or ST_MultiSurface value. - # Area is in the units of the spatial reference system. - # - # Returns Float ST_Area(geometry g1); - # - def area - postgis_calculate(:area, self).to_f - end - - # - # Returns the 2D perimeter of the geometry if it is a ST_Surface, ST_MultiSurface - # (Polygon, Multipolygon). 0 is returned for non-areal geometries. For linestrings - # use 'length'. Measurements are in the units of the spatial reference system of - # the geometry. - # - # Returns Float ST_Perimeter(geometry g1); - # - def perimeter - postgis_calculate(:perimeter, self).to_f - end - - # - # Returns the 3-dimensional perimeter of the geometry, if it is a polygon or multi-polygon. - # If the geometry is 2-dimensional, then the 2-dimensional perimeter is returned. - # - # Returns Float ST_Perimeter3D(geometry geomA); - # - def perimeter3d - postgis_calculate(:perimeter3d, self).to_f - end - - # - # True if the LineString's start and end points are coincident. - # - # This method implements the OpenGIS Simple Features Implementation - # Specification for SQL. - # - # SQL-MM defines the result of ST_IsClosed(NULL) to be 0, while PostGIS returns NULL. - # - # Returns boolean ST_IsClosed(geometry g); - # - def closed? - postgis_calculate(:isclosed, self) - end - alias_method "is_closed?", "closed?" - - # - # True if no point in Geometry B is outside Geometry A - # - # This function call will automatically include a bounding box comparison - # that will make use of any indexes that are available on the geometries. - # To avoid index use, use the function _ST_Covers. - # - # Do not call with a GEOMETRYCOLLECTION as an argument - # Do not use this function with invalid geometries. You will get unexpected results. - # - # Performed by the GEOS module. - # - # Returns Boolean ST_Covers(geometry geomA, geometry geomB); - # - def covers? other - postgis_calculate(:covers, [self, other]) - end - - end - -end \ No newline at end of file diff --git a/postgis_adapter.gemspec b/postgis_adapter.gemspec index 6ee74cd..d40bd92 100644 --- a/postgis_adapter.gemspec +++ b/postgis_adapter.gemspec @@ -1,21 +1,23 @@ +# -*- encoding: utf-8 -*- + Gem::Specification.new do |s| - s.name = "postgis_adapter" - s.version = "0.1.8" + s.name = %q{postgis_adapter} + s.version = "0.2.1" + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Marcos Piccinini"] - s.date = "2008-12-16" - s.description = "Postgis Adapter for Activer Record" + s.date = %q{2009-01-10} + s.description = %q{Postgis Adapter for Activer Record} s.email = ["x@nofxx.com"] s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"] - s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "init.rb", "install.rb", "lib/postgis_adapter.rb", "lib/postgis_adapter/acts_as_geom.rb", "lib/postgis_adapter/common_spatial_adapter.rb", "lib/postgis_functions.rb", "lib/postgis_functions/bbox.rb", "lib/postgis_functions/class.rb", "lib/postgis_functions/common.rb", "lib/postgis_functions/linestring.rb", "lib/postgis_functions/point.rb", "lib/postgis_functions/polygon.rb", "postgis_adapter.gemspec", "rails/init.rb", "script/console", "script/destroy", "script/generate", "uninstall.rb"] - s.test_files = ["spec/acts_as_geom_spec.rb", "spec/common_spatial_adapter_spec.rb", "spec/db/database_postgis.yml", "spec/db/models_postgis.rb", "spec/db/schema_postgis.rb", "spec/postgis_adapter_spec.rb", "spec/postgis_functions/bbox_spec.rb", "spec/postgis_functions/linestring_spec.rb", "spec/postgis_functions/point_spec.rb", "spec/postgis_functions/polygon_spec.rb", "spec/postgis_functions_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"] + s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "init.rb", "install.rb", "lib/postgis_adapter.rb", "lib/postgis_adapter/acts_as_geom.rb", "lib/postgis_adapter/common_spatial_adapter.rb", "lib/postgis_functions.rb", "lib/postgis_functions/bbox.rb", "lib/postgis_functions/class.rb", "lib/postgis_functions/common.rb", "postgis_adapter.gemspec", "rails/init.rb", "script/console", "script/destroy", "script/generate", "spec/db/database_postgis.yml", "spec/db/models_postgis.rb", "spec/db/schema_postgis.rb", "spec/postgis_adapter/acts_as_geom_spec.rb", "spec/postgis_adapter/common_spatial_adapter_spec.rb", "spec/postgis_adapter_spec.rb", "spec/postgis_functions/bbox_spec.rb", "spec/postgis_functions/class_spec.rb", "spec/postgis_functions/common_spec.rb", "spec/postgis_functions_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "uninstall.rb"] s.has_rdoc = true - s.homepage = "http://github.com/nofxx/postgis_adapter" + s.homepage = %q{http://github.com/nofxx/postgis_adapter} s.rdoc_options = ["--main", "README.rdoc"] s.require_paths = ["lib"] s.rubyforge_project = %q{postgis_adapter} s.rubygems_version = %q{1.3.1} - s.summary = "Postgis Adapter for Activer Record" + s.summary = %q{Postgis Adapter for Activer Record} if s.respond_to? :specification_version then current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION @@ -23,16 +25,16 @@ Gem::Specification.new do |s| if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q, [">= 2.0.2"]) - s.add_development_dependency(%q, [">= 1.1.0"]) + s.add_development_dependency(%q, [">= 1.2.3"]) s.add_development_dependency(%q, [">= 1.8.0"]) else s.add_dependency(%q, [">= 2.0.2"]) - s.add_dependency(%q, [">= 1.1.0"]) + s.add_dependency(%q, [">= 1.2.3"]) s.add_dependency(%q, [">= 1.8.0"]) end else s.add_dependency(%q, [">= 2.0.2"]) - s.add_dependency(%q, [">= 1.1.0"]) + s.add_dependency(%q, [">= 1.2.3"]) s.add_dependency(%q, [">= 1.8.0"]) end end diff --git a/spec/acts_as_geom_spec.rb b/spec/acts_as_geom_spec.rb deleted file mode 100644 index 7e55400..0000000 --- a/spec/acts_as_geom_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require File.dirname(__FILE__) + '/spec_helper.rb' - -describe "ActsAsGeom" do - - before(:each) do - class City < ActiveRecord::Base - acts_as_geom :geom - end - end - - it "should get the geom type" do - City.get_geom_type(:geom).should eql(:polygon) - end - -end diff --git a/spec/db/database_postgis.yml b/spec/db/database_postgis.yml index 288f226..55c9682 100644 --- a/spec/db/database_postgis.yml +++ b/spec/db/database_postgis.yml @@ -1,4 +1,4 @@ adapter: postgresql -database: postgis_plugin_test +database: postgis_plugin username: postgres password: diff --git a/spec/db/models_postgis.rb b/spec/db/models_postgis.rb index 3aff2cb..73034fd 100644 --- a/spec/db/models_postgis.rb +++ b/spec/db/models_postgis.rb @@ -53,4 +53,5 @@ class Street < ActiveRecord::Base end class CommonGeo < ActiveRecord::Base + acts_as_geom :geom end diff --git a/spec/db/schema_postgis.rb b/spec/db/schema_postgis.rb index 2f92d5f..6898c09 100644 --- a/spec/db/schema_postgis.rb +++ b/spec/db/schema_postgis.rb @@ -54,33 +54,30 @@ t.point "geom", :null => false, :with_m => true, :with_z => true end - create_table "table_srid_line_strings", :force => true do |t| - t.line_string "geom", :null => false , :srid => 123 + create_table "table_srid_line_strings", :force => true do |t| + t.line_string "geom", :null => false , :srid => 4326 end create_table "table_srid4d_polygons", :force => true do |t| - t.polygon "geom", :with_m => true, :with_z => true, :srid => 123 + t.polygon "geom", :with_m => true, :with_z => true, :srid => 4326 end - create_table :cities do |t| - t.string :data, :limit => 100 - t.integer :value - t.polygon :geom,:null=>false,:srid=>123 - end - - create_table :positions do |t| - t.string :data, :limit => 100 - t.integer :value - t.point :geom,:null=>false,:srid=>123 - end - - create_table :streets do |t| - t.string :data, :limit => 100 - t.integer :value - t.line_string :geom,:null=>false,:srid=>123 - end - + create_table :cities do |t| + t.string :data, :limit => 100 + t.integer :value + t.polygon :geom,:null=>false,:srid=>4326 + end + create_table :positions do |t| + t.string :data, :limit => 100 + t.integer :value + t.point :geom,:null=>false,:srid=>4326 + end + create_table :streets do |t| + t.string :data, :limit => 100 + t.integer :value + t.line_string :geom,:null=>false,:srid=>4326 + end end diff --git a/spec/postgis_adapter/acts_as_geom_spec.rb b/spec/postgis_adapter/acts_as_geom_spec.rb new file mode 100644 index 0000000..2558b4f --- /dev/null +++ b/spec/postgis_adapter/acts_as_geom_spec.rb @@ -0,0 +1,27 @@ +require File.dirname(__FILE__) + '/../spec_helper.rb' + +describe "ActsAsGeom" do + + before(:each) do + class DiffColumn < ActiveRecord::Base + acts_as_geom :ponto + end + + class NotInDb < ActiveRecord::Base + acts_as_geom :geom + end + end + + it "should get the geom type" do + City.get_geom_type(:geom).should eql(:polygon) + end + + it "should not interfere with migrations" do + NotInDb.get_geom_type(:geom).should be_nil + end + + it "should query a diff column name" do + # DiffColumn + end + +end diff --git a/spec/common_spatial_adapter_spec.rb b/spec/postgis_adapter/common_spatial_adapter_spec.rb similarity index 99% rename from spec/common_spatial_adapter_spec.rb rename to spec/postgis_adapter/common_spatial_adapter_spec.rb index 5287293..4eed489 100644 --- a/spec/common_spatial_adapter_spec.rb +++ b/spec/postgis_adapter/common_spatial_adapter_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/spec_helper.rb' +require File.dirname(__FILE__) + '/../spec_helper.rb' describe "CommonSpatialAdapter" do diff --git a/spec/postgis_adapter_spec.rb b/spec/postgis_adapter_spec.rb index f23b558..27c2e83 100644 --- a/spec/postgis_adapter_spec.rb +++ b/spec/postgis_adapter_spec.rb @@ -48,9 +48,9 @@ end it "should test multipoint" do - mp = TableMultiPoint.create!(:geom => MultiPoint.from_coordinates([[12.4,-123.3],[-65.1,123.4],[123.55555555,123]])) + mp = TableMultiPoint.create!(:geom => MultiPoint.from_coordinates([[12.4,-4326.3],[-65.1,4326.4],[4326.55555555,4326]])) find = TableMultiPoint.find(:first) - find.geom.should == MultiPoint.from_coordinates([[12.4,-123.3],[-65.1,123.4],[123.55555555,123]]) + find.geom.should == MultiPoint.from_coordinates([[12.4,-4326.3],[-65.1,4326.4],[4326.55555555,4326]]) end end @@ -68,18 +68,18 @@ end it "should test_srid_line_string" do - ls = TableSridLineString.create!(:geom => LineString.from_coordinates([[1.4,2.5],[1.5,6.7]],123)) + ls = TableSridLineString.create!(:geom => LineString.from_coordinates([[1.4,2.5],[1.5,6.7]],4326)) ls = TableSridLineString.find(:first) - ls_e = LineString.from_coordinates([[1.4,2.5],[1.5,6.7]],123) + ls_e = LineString.from_coordinates([[1.4,2.5],[1.5,6.7]],4326) ls.geom.should be_instance_of(LineString) - ls.geom.srid.should eql(123) + ls.geom.srid.should eql(4326) end it "hsould test_multi_line_string" do - ml = TableMultiLineString.create!(:geom => MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]]),LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012],[45.123,123.3]])])) + ml = TableMultiLineString.create!(:geom => MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.432612,-0.012]]),LineString.from_coordinates([[1.5,45.2],[-54.432612,-0.012],[45.4326,4326.3]])])) find = TableMultiLineString.find(:first) - find.geom.should == MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]]),LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012],[45.123,123.3]])]) + find.geom.should == MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.432612,-0.012]]),LineString.from_coordinates([[1.5,45.2],[-54.432612,-0.012],[45.4326,4326.3]])]) end end @@ -103,11 +103,11 @@ end it "should test_srid_4d_polygon" do - pg = TableSrid4dPolygon.create(:geom => Polygon.from_coordinates([[[0,0,2,-45.1],[4,0,2,5],[4,4,2,4.67],[0,4,2,1.34],[0,0,2,-45.1]],[[1,1,2,12.3],[3,1,2,123],[3,3,2,12.2],[1,3,2,12],[1,1,2,12.3]]],123,true,true)) + pg = TableSrid4dPolygon.create(:geom => Polygon.from_coordinates([[[0,0,2,-45.1],[4,0,2,5],[4,4,2,4.67],[0,4,2,1.34],[0,0,2,-45.1]],[[1,1,2,12.3],[3,1,2,4326],[3,3,2,12.2],[1,3,2,12],[1,1,2,12.3]]],4326,true,true)) find = TableSrid4dPolygon.find(:first) - pg_e = Polygon.from_coordinates([[[0,0,2,-45.1],[4,0,2,5],[4,4,2,4.67],[0,4,2,1.34],[0,0,2,-45.1]],[[1,1,2,12.3],[3,1,2,123],[3,3,2,12.2],[1,3,2,12],[1,1,2,12.3]]],123,true,true) + pg_e = Polygon.from_coordinates([[[0,0,2,-45.1],[4,0,2,5],[4,4,2,4.67],[0,4,2,1.34],[0,0,2,-45.1]],[[1,1,2,12.3],[3,1,2,4326],[3,3,2,12.2],[1,3,2,12],[1,1,2,12.3]]],4326,true,true) pg.geom.should == pg_e - pg.geom.srid.should eql(123) + pg.geom.srid.should eql(4326) end end @@ -134,7 +134,7 @@ create_table "parks", :force => true do |t| t.column "data" , :string, :limit => 100 t.column "value", :integer - t.column "geom", :point,:null=>false,:srid=>123 + t.column "geom", :point,:null=>false,:srid=>4326 end add_index "parks","geom",:spatial=>true,:name => "example_spatial_index" end @@ -143,13 +143,13 @@ class Park < ActiveRecord::Base end it "should create some points" do - Park.create!(:data => "Point1", :geom => Point.from_x_y(1.2,0.75,123)) - Park.create!(:data => "Point2",:geom => Point.from_x_y(0.6,1.3,123)) - Park.create!(:data => "Point3", :geom => Point.from_x_y(2.5,2,123)) + Park.create!(:data => "Point1", :geom => Point.from_x_y(1.2,0.75,4326)) + Park.create!(:data => "Point2",:geom => Point.from_x_y(0.6,1.3,4326)) + Park.create!(:data => "Point3", :geom => Point.from_x_y(2.5,2,4326)) end it "should find by geom" do - pts = Park.find_all_by_geom(LineString.from_coordinates([[0,0],[2,2]],123)) + pts = Park.find_all_by_geom(LineString.from_coordinates([[0,0],[2,2]],4326)) pts.should be_instance_of(Array) pts.length.should eql(2) pts[0].data.should match /Point/ @@ -157,12 +157,12 @@ class Park < ActiveRecord::Base end it "should find by geom again" do - pts = Park.find_all_by_geom(LineString.from_coordinates([[2.49,1.99],[2.51,2.01]],123)) + pts = Park.find_all_by_geom(LineString.from_coordinates([[2.49,1.99],[2.51,2.01]],4326)) pts[0].data.should eql("Point3") end it "should find by geom column bbox condition" do - pts = Park.find_all_by_geom([[0,0],[2,2],123]) + pts = Park.find_all_by_geom([[0,0],[2,2],4326]) pts.should be_instance_of(Array) pts.length.should eql(2) pts[0].data.should match /Point/ diff --git a/spec/postgis_functions/bbox_spec.rb b/spec/postgis_functions/bbox_spec.rb index d849d6c..81de0d8 100644 --- a/spec/postgis_functions/bbox_spec.rb +++ b/spec/postgis_functions/bbox_spec.rb @@ -4,18 +4,17 @@ describe "Point" do before(:all) do - @c1 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[12,45],[45,41],[4,1],[12,45]],[[2,5],[5,1],[14,1],[2,5]]],123)) - @c2 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[22,66],[65,65],[20,10],[22,66]],[[10,15],[15,11],[34,14],[10,15]]],123)) - @c3 ||= City.create!(:data => "City3", :geom => Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],123)) - @s1 ||= Street.create!(:data => "Street1", :geom => LineString.from_coordinates([[1,1],[2,2]],123)) - @s2 ||= Street.create!(:data => "Street2", :geom => LineString.from_coordinates([[4,4],[7,7]],123)) - @s3 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[8,8],[18,18],[20,20],[25,25],[30,30],[38,38]],123)) - @s4 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[10,8],[15,18]],123)) - @p1 ||= Position.create!(:data => "Point1", :geom => Point.from_x_y(1,1,123)) - @p2 ||= Position.create!(:data => "Point2", :geom => Point.from_x_y(5,5,123)) - @p3 ||= Position.create!(:data => "Point3", :geom => Point.from_x_y(8,8,123)) + @c1 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[12,45],[45,41],[4,1],[12,45]],[[2,5],[5,1],[14,1],[2,5]]],4326)) + @c2 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[22,66],[65,65],[20,10],[22,66]],[[10,15],[15,11],[34,14],[10,15]]],4326)) + @c3 ||= City.create!(:data => "City3", :geom => Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],4326)) + @s1 ||= Street.create!(:data => "Street1", :geom => LineString.from_coordinates([[1,1],[2,2]],4326)) + @s2 ||= Street.create!(:data => "Street2", :geom => LineString.from_coordinates([[4,4],[7,7]],4326)) + @s3 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[8,8],[18,18],[20,20],[25,25],[30,30],[38,38]],4326)) + @s4 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[10,8],[15,18]],4326)) + @p1 ||= Position.create!(:data => "Point1", :geom => Point.from_x_y(1,1,4326)) + @p2 ||= Position.create!(:data => "Point2", :geom => Point.from_x_y(5,5,4326)) + @p3 ||= Position.create!(:data => "Point3", :geom => Point.from_x_y(8,8,4326)) end - describe "BBox operations" do @@ -27,49 +26,17 @@ @p1.bbox(">>", @c1).should be_false end - it do - @p1.should be_strictly_left_of(@c1) - end - - it do - @p1.should_not be_strictly_right_of(@c1) - end - - it do - @p1.should_not be_overlaps_or_right_of(@c1) - end - - it do - @p1.should be_overlaps_or_left_of(@c1) - end - - it do - @p1.should_not be_completely_contained_by(@c1) - end - - it do - @c2.completely_contains?(@p1).should be_false - end - - it do - @p1.should be_overlaps_or_above(@c1) - end - - it do - @p1.should be_overlaps_or_below(@c1) - end - - it do - @p1.should_not be_strictly_above(@c1) - end - - it do - @p1.should_not be_strictly_below(@c1) - end - - it do - @p1.interacts_with?(@c1).should be_false - end + it do @p1.should be_strictly_left_of(@c1) end + it do @p1.should_not be_strictly_right_of(@c1) end + it do @p1.should_not be_overlaps_or_right_of(@c1) end + it do @p1.should be_overlaps_or_left_of(@c1) end + it do @p1.should_not be_completely_contained_by(@c1) end + it do @c2.completely_contains?(@p1).should be_false end + it do @p1.should be_overlaps_or_above(@c1) end + it do @p1.should be_overlaps_or_below(@c1) end + it do @p1.should_not be_strictly_above(@c1) end + it do @p1.should_not be_strictly_below(@c1) end + it do @p1.interacts_with?(@c1).should be_false end it do @p1.binary_equal?(@c1).should be_false @@ -79,6 +46,6 @@ @p1.same_as?(@c1).should be_false end - end - end \ No newline at end of file + + end diff --git a/spec/postgis_functions/class_spec.rb b/spec/postgis_functions/class_spec.rb new file mode 100644 index 0000000..e69de29 diff --git a/spec/postgis_functions/common_spec.rb b/spec/postgis_functions/common_spec.rb new file mode 100644 index 0000000..c94ce30 --- /dev/null +++ b/spec/postgis_functions/common_spec.rb @@ -0,0 +1,281 @@ +require File.dirname(__FILE__) + '/../spec_helper.rb' + +describe "Common Functions" do + + before(:all) do + @c1 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[12,45],[45,41],[4,1],[12,45]],[[2,5],[5,1],[14,1],[2,5]]],4326)) + @c2 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[22,66],[65,65],[20,10],[22,66]],[[10,15],[15,11],[34,14],[10,15]]],4326)) + @c3 ||= City.create!(:data => "City3", :geom => Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],4326)) + @s1 ||= Street.create!(:data => "Street1", :geom => LineString.from_coordinates([[1,1],[2,2]],4326)) + @s2 ||= Street.create!(:data => "Street2", :geom => LineString.from_coordinates([[4,4],[7,7]],4326)) + @s3 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[8,8],[18,18],[20,20],[25,25],[30,30],[38,38]],4326)) + @s4 ||= Street.create!(:data => "Street4", :geom => LineString.from_coordinates([[10,8],[15,18]],4326)) + @p1 ||= Position.create!(:data => "Point1", :geom => Point.from_x_y(1,1,4326)) + @p2 ||= Position.create!(:data => "Point2", :geom => Point.from_x_y(5,5,4326)) + @p3 ||= Position.create!(:data => "Point3", :geom => Point.from_x_y(8,8,4326)) + @p4 ||= Position.create!(:data => "Point4", :geom => Point.from_x_y(18.1,18,4326)) + @p5 ||= Position.create!(:data => "Point5", :geom => Point.from_x_y(30,30,4326)) + end + + describe "Point" do + + it "should find the closest other point" do + Position.close_to(@p1.geom,4326)[0].data.should == @p1.data + end + + it "should find the closest other point" do + Position.closest_to(@p1.geom,4326).data.should == @p1.data + end + + it { @p1.distance_to(@s2).should be_close(4.24264068711928, 0.0001) } + it { @p1.distance_to(@s3).should be_close(9.89949493661167, 0.0001) } + it { @p2.distance_to(@s3).should be_close(4.24264068711928, 0.0001) } + it { @p1.distance_to(@p2).should be_close(5.65685424949238, 0.0001) } + it { @p1.distance_to(@c1).should be_close(3.0, 0.0001) } + it { @p1.distance_to(@c2).should be_close(21.0237960416286, 0.000001) } + it { @p1.distance_to(@s2).should be_close(4.24264068711928, 0.000001) } + it { @p1.distance_sphere_to(@p2).should be_close(628516.874554178, 0.0001) } + it { @p1.distance_sphere_to(@p3).should be_close(1098726.61466584, 0.00001) } + it { @p1.distance_spheroid_to(@p2).should be_close(627129.50,0.01) } + it { @p1.distance_spheroid_to(@p2).should be_close(627129.502639041, 0.000001) } + it { @p1.distance_spheroid_to(@p3).should be_close(1096324.48117672, 0.000001) } + + it { @p1.should_not be_inside(@c1) } + it { @p1.should be_outside(@c1) } + it { @p1.should be_inside_circle(2.0,2.0,20.0) } + it { @p1.should_not be_inside_circle(50,50,2) } + it { @p1.should be_in_bounds(@s1) } + it { @p3.should_not be_in_bounds(@s1, 1) } + it { @p4.in_bounds?(@s3, 0.01).should be_false } + + it { @p1.azimuth(@p2).should be_close(0.785398163397448,0.000001) } + it { @p1.azimuth(@s2).should raise_error } + it { @p1.disjoint?(@s2).should be_true } + it { @p3.polygonize.geometries.should be_empty } + it { @p4.where_on_line(@s3).should be_close(0.335, 0.0001) } + it { @s3.locate_point(@p4).should be_close(0.335, 0.1)} + it { @s3.interpolate_point(0.335).x.should be_close(18.05, 0.01) } + + it { @p1.relate?(@s3, "T*T***FF*").should be_false } + it { @p1.relate?(@s3).should eql("FF0FFF102") } + + it "should transform srid" do + @p1.geom = @p1.transform(29101) + @p1.geom.srid.should eql(29101) + end + + it "should see in what fraction of the ls it is" do + @p1.where_on_line(@s1).should eql(0.0) + end + + end + + describe "Polygon" do + + it "sort by area size" do + City.by_area.first.data.should == "City1" #[@c1, @c2, @c3] + end + + it "find all cities that contains a point" do + City.contains(@p1.geom, 4326).should eql([]) + end + + it "should find one city (first) that contains a point" do + City.contain(@p4.geom, 4326).data.should eql("City1") + end + + it { @c2.should be_closed } + it { @c3.area.should be_close(1093.270089, 0.1) } + it { @c2.area.should be_close(1159.5, 0.1) } + + it { @c2.dimension.should eql(2) } + it { @c2.perimeter.should be_close(219.770013855493, 0.1) } + it { @c2.perimeter3d.should be_close(219.770013855493, 0.1) } + it { @c1.contains?(@p1).should be_false } + it { @c1.contains?(@p4).should be_true } + + it { @c1.should_not be_spatially_equal(@c2) } + + it { @c1.covers?(@p1).should be_false } + it { @c1.covers?(@p4).should be_true } + it { @c1.should_not be_within(@c2) } + + it "city overlaps point?" do + lambda { @c3.overlaps?(@c2) }.should raise_error # WHY?? + end + + it "should get a polygon for envelope" do + @c2.envelope.should be_instance_of(Polygon) + end + + it "should get a polygon for envelope" do + @c2.envelope.rings[0].points[0].should be_instance_of(Point) + end + + it "should get the center" do + @c2.centroid.x.should be_close(36.2945235015093,0.00001) + @c2.centroid.y.should be_close(48.3211154233146,0.00001) + end + + it "should get the center with the correct srid" do + @c1.centroid.srid.should eql(4326) + end + + it "distance from another" do + @c1.distance_to(@c3).should eql(0.0) + end + + it "distance to a linestring" do + @c1.distance_to(@s1).should be_close(1.8,0.001) + end + + it "should simplify me" do + @c3.simplify.should be_instance_of(Polygon) + end + + it "should simplify me number of points" do + @c3.simplify[0].length.should eql(4) + end + + #Strange again.... s2 s3 ... error + it { @c3.touches?(@s1).should be_false } + it { @c2.should be_simple } + it { @c2.disjoint?(@p2).should be_true } + it { @c3.polygonize.should have(2).geometries } + + # weird... + # it do + # @c1.disjoint?(@s2).should be_true + # end + + end + + describe "LineString" do + + it "should sort by size" do + Street.by_length.first.data.should == "Street1" + Street.by_length.last.data.should == "Street3" + end + + it "largest" do + Street.longest.data.should == "Street3" + end + + describe "Length" do + it { @s1.length.should be_close(1.4142135623731, 0.000001) } + it { @s2.length.should be_close(4.2, 0.1) } + it { @s3.length.should be_close(42.4264068, 0.001) } + it { @s1.length_spheroid.should be_close(156876.1494,0.0001) } + it { @s1.length_3d.should be_close(1.4142135623731,0.0001) } + end + + it { @s1.crosses?(@s2).should be_false } + it { @s4.crosses?(@s3).should be_true } + it { @s1.touches?(@s2).should be_false } + it { @s4.touches?(@s3).should be_false } + + it "should intersect with linestring" do + @s4.intersects?(@s3).should be_true + end + + it "should not intersect with this linestring" do + @s4.intersects?(@s1).should be_false + end + + it "intersection with a point" do + @s1.intersection(@p2).should be_instance_of(GeometryCollection) + end + + describe "Self" do + + it do + @s1.envelope.should be_instance_of(Polygon) + end + + it "should get a polygon for envelope" do + @s1.envelope.rings[0].points[0].should be_instance_of(Point) + end + + it "should get the center" do + @s1.centroid.x.should be_close(1.5,0.01) + @s1.centroid.y.should be_close(1.5,0.01) + end + + it "should get the center with the correct srid" do + @s1.centroid.srid.should eql(4326) + end + + it "number of points" do + @s3.num_points.should eql(6) + end + + it "startpoint" do + @s3.start_point.should be_instance_of(Point) + @s3.start_point.x.should be_close(8.0, 0.1) + end + + it "endpoint" do + @s2.end_point.should be_instance_of(Point) + @s2.end_point.x.should be_close(7.0, 0.1) + end + + it { @s1.should_not be_envelopes_intersect(@s2) } + it { @s1.boundary.should be_instance_of(MultiPoint) } + + end + + describe "Distance" do + + it { @s1.distance_to(@p3).should be_close(8.48528137423857,0.0001) } + it { @s1.distance_to(@p3).should be_close(8.48,0.01) } + + it do + lambda { @p1.distance_spheroid_to(@c3) }.should raise_error + end + + it do + lambda { @p3.distance_spheroid_to(@s1) }.should raise_error + end + + end + + it do @s1.locate_point(@p1).should eql(0.0) end + it do @s1.locate_point(@p2).should eql(1.0) end + + it "should simplify a line" do + @s3.simplify.points.length.should eql(2) + end + + it "should simplify the first correcty" do + @s3.simplify.points[0].y.should be_close(8.0, 0.1) + end + + it "should simplify the last correcty" do + @s3.simplify.points[1].y.should be_close(38.0, 0.1) + end + + it { @s1.overlaps?(@c2).should be_false } + it { @s1.overlaps?(@s2).should be_false } + it { @s1.convex_hull.should be_instance_of(LineString) } + it { @s1.line_substring(0.2,0.5).should be_instance_of(LineString) } + + it do + @s1.interpolate_point(0.7).should be_instance_of(Point) + @s1.interpolate_point(0.7).x.should be_close(1.7,0.1) + end + + it { @s1.should be_simple } + it { @s1.disjoint?(@s2).should be_true } + it { @s1.polygonize.should be_instance_of(GeometryCollection) } + it { @s3.polygonize.geometries.should be_empty } + it { @s2.locate_along_measure(1.6).should be_nil } + it { @s2.locate_between_measures(0.1,0.3).should be_nil } + + it "should build area" do + @s2.build_area.should be_nil + end + + end + +end + diff --git a/spec/postgis_functions/linestring_spec.rb b/spec/postgis_functions/linestring_spec.rb deleted file mode 100644 index d35acc3..0000000 --- a/spec/postgis_functions/linestring_spec.rb +++ /dev/null @@ -1,219 +0,0 @@ -require File.dirname(__FILE__) + '/../spec_helper.rb' - -describe "LineString" do - - before(:all) do - @c1 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[12,45],[45,41],[4,1],[12,45]],[[2,5],[5,1],[14,1],[2,5]]],123)) - @c2 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[22,66],[65,65],[20,10],[22,66]],[[10,15],[15,11],[34,14],[10,15]]],123)) - @c3 ||= City.create!(:data => "City3", :geom => Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],123)) - @s1 ||= Street.create!(:data => "Street1", :geom => LineString.from_coordinates([[1,1],[2,2]],123)) - @s2 ||= Street.create!(:data => "Street2", :geom => LineString.from_coordinates([[4,4],[7,7]],123)) - @s3 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[8,8],[18,18],[20,20],[25,25],[30,30],[38,38]],123)) - @s4 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[10,8],[15,18]],123)) - @p1 ||= Position.create!(:data => "Point1", :geom => Point.from_x_y(1,1,123)) - @p2 ||= Position.create!(:data => "Point2", :geom => Point.from_x_y(5,5,123)) - @p3 ||= Position.create!(:data => "Point3", :geom => Point.from_x_y(8,8,123)) - end - - it "should sort by size" do - Street.by_length.first.data.should == "Street1" - Street.by_length.last.data.should == "Street3" - end - - it "largest" do - Street.longest.data.should == "Street3" - end - - describe "Length" do - - it do - @s1.length.should be_close(1.4142135623731, 0.000001) - end - - it do - @s2.length.should be_close(4.2, 0.1) - end - - it do - @s3.length.should be_close(42.4264068, 0.001) - end - - it "3d length" do - @s1.length_3d.should be_close(1.4142135623731,0.0001) - end - - it do - @s1.length_spheroid.should be_close(156876.1381,0.0001) - end - - # it do - # @s1.length_spheroid.in_miles.should be_close(156.876,0.001) - # end - end - - it "should not cross s2" do - @s1.crosses?(@s2).should be_false - end - - it "should cross s3" do - @s4.crosses?(@s3).should be_true - end - - it do - @s1.touches?(@s2).should be_false - end - - it do - @s4.touches?(@s3).should be_false - end - - it "should intersect with linestring" do - @s4.intersects?(@s3).should be_true - end - - it "should not intersect with this linestring" do - @s4.intersects?(@s1).should be_false - end - - - it "intersection with a point" do - @s1.intersection(@p2).should be_instance_of(GeometryCollection) - end - - - describe "Self" do - - it do - @s1.envelope.should be_instance_of(Polygon) - end - - it "should get a polygon for envelope" do - @s1.envelope.rings[0].points[0].should be_instance_of(Point) - end - - it "should get the center" do - @s1.centroid.x.should be_close(1.5,0.01) - @s1.centroid.y.should be_close(1.5,0.01) - end - - it "should get the center with the correct srid" do - @s1.centroid.srid.should eql(123) - end - - it "number of points" do - @s3.num_points.should eql(6) - end - - it "startpoint" do - @s3.start_point.should be_instance_of(Point) - @s3.start_point.x.should be_close(8.0, 0.1) - end - - it "endpoint" do - @s2.end_point.should be_instance_of(Point) - @s2.end_point.x.should be_close(7.0, 0.1) - end - - it do - @s1.should_not be_envelopes_intersect(@s2) - end - - - it do - @s1.boundary.should be_instance_of(MultiPoint) - end - - end - - describe "Distance" do - - it do - @s1.distance_to(@p3).should be_close(8.48528137423857,0.0001) - end - - it do - lambda { @p1.distance_spheroid_to(@c3) }.should raise_error - end - - it do - lambda { @p3.distance_spheroid_to(@s1) }.should raise_error - end - - it do - @s1.distance_to(@p3).should be_close(8.48,0.01) - end - - - - end - - it "should locate a point" do - @s1.locate_point(@p1).should eql(0.0) - end - - it "should locate a point" do - @s1.locate_point(@p2).should eql(1.0) - end - - it "should simplify a line" do - @s3.simplify.points.length.should eql(2) - end - - it "should simplify the first correcty" do - @s3.simplify.points[0].y.should be_close(8.0, 0.1) - end - - it "should simplify the last correcty" do - @s3.simplify.points[1].y.should be_close(38.0, 0.1) - end - - it do - @s1.overlaps?(@c2).should be_false - end - - it do - @s1.overlaps?(@s2).should be_false - end - - it do - @s1.convex_hull.should be_instance_of(LineString) - end - - it do - @s1.line_substring(0.2,0.5).should be_instance_of(LineString) - end - - it do - @s1.interpolate_point(0.7).should be_instance_of(Point) - @s1.interpolate_point(0.7).x.should be_close(1.7,0.1) - end - - it do - @s1.should be_simple #?.should be_true - end - - it do - @s1.disjoint?(@s2).should be_true - end - - it do - @s1.polygonize.should be_instance_of(GeometryCollection) - end - - it do - @s3.polygonize.geometries.should be_empty - end - - it do - @s2.locate_along_measure(1.6).should be_nil - end - - it do - @s2.locate_between_measures(0.1,0.3).should be_nil - end - - it "should build area" do - @s2.build_area.should be_nil - end - -end \ No newline at end of file diff --git a/spec/postgis_functions/point_spec.rb b/spec/postgis_functions/point_spec.rb deleted file mode 100644 index ff6d9a6..0000000 --- a/spec/postgis_functions/point_spec.rb +++ /dev/null @@ -1,136 +0,0 @@ -require File.dirname(__FILE__) + '/../spec_helper.rb' - - -describe "Point" do - - before(:all) do - @c1 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[12,45],[45,41],[4,1],[12,45]],[[2,5],[5,1],[14,1],[2,5]]],123)) - @c2 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[22,66],[65,65],[20,10],[22,66]],[[10,15],[15,11],[34,14],[10,15]]],123)) - @c3 ||= City.create!(:data => "City3", :geom => Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],123)) - @s1 ||= Street.create!(:data => "Street1", :geom => LineString.from_coordinates([[1,1],[2,2]],123)) - @s2 ||= Street.create!(:data => "Street2", :geom => LineString.from_coordinates([[4,4],[7,7]],123)) - @s3 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[8,8],[18,18],[20,20],[25,25],[30,30],[38,38]],123)) - @s4 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[10,8],[15,18]],123)) - @p1 ||= Position.create!(:data => "Point1", :geom => Point.from_x_y(1,1,123)) - @p2 ||= Position.create!(:data => "Point2", :geom => Point.from_x_y(5,5,123)) - @p3 ||= Position.create!(:data => "Point3", :geom => Point.from_x_y(8,8,123)) - @p4 ||= Position.create!(:data => "Point5", :geom => Point.from_x_y(18.1,18,123)) - end - - - - it "should find the closest other point" do - Position.close_to(@p1.geom,123)[0].data.should == @p1.data - end - - it "should find the closest other point" do - Position.closest_to(@p1.geom,123).data.should == @p1.data - end - - it do - @p1.distance_to(@s2).should be_close(4.24264068711928, 0.0001) - end - - it do - @p1.distance_to(@s3).should be_close(9.89949493661167, 0.0001) - end - - it do - @p2.distance_to(@s3).should be_close(4.24264068711928, 0.0001) - end - - it do - @p1.distance_to(@p2).should be_close(5.65685424949238, 0.0001) - end - - it do - @p1.distance_sphere_to(@p2).should be_close(628516.874554178, 0.0001) - end - - it do - @p1.distance_sphere_to(@p3).should be_close(1098726.61466584, 0.00001) - end - - it do - @p1.distance_to(@c1).should be_close(3.0, 0.0001) - end - - it do - @p1.distance_to(@c2).should be_close(21.0237960416286, 0.000001) - end - - it do - @p1.distance_to(@s2).should be_close(4.24264068711928, 0.000001) - end - - it do - @p1.distance_spheroid_to(@p2).should be_close(627129.45,0.01) - end - - it do - @p1.distance_spheroid_to(@p2).should be_close(627129.457699803, 0.000001) - end - - it do - @p1.distance_spheroid_to(@p3).should be_close(1096324.40267746, 0.000001) - end - - it do - @p1.should_not be_inside(@c1) - end - - it do - @p1.should be_outside(@c1) - end - - - it do - @p1.azimuth(@p2).should be_close(0.785398163397448,0.000001) - end - - it do - @p1.azimuth(@s2).should raise_error - end - - it "should see in what fraction of the ls it is" do - @p1.where_on_line(@s1).should eql(0.0) - end - - it do - @p1.should be_inside_circle(2.0,2.0,20.0) - end - - it do - @p1.should_not be_inside_circle(50,50,2) - end - - it do - @p1.disjoint?(@s2).should be_true - end - - it do - @p3.polygonize.geometries.should be_empty - end - - it do - @p1.should be_in_bounds(@s1) - end - - it "in bounds of a geometry? with option" do - @p3.should_not be_in_bounds(@s1, 1) - end - - it { @p4.in_bounds?(@s3, 0.01).should be_false } - - it { @p4.where_on_line(@s3).should be_close(0.335, 0.0001) } - - it { @s3.locate_point(@p4).should be_close(0.335, 0.1)} - - it { @s3.interpolate_point(0.335).x.should be_close(18.05, 0.01) } - - it { @p1.relate?(@s3, "T*T***FF*").should be_false } - - it { @p1.relate?(@s3).should eql("FF0FFF102") } - -end - diff --git a/spec/postgis_functions/polygon_spec.rb b/spec/postgis_functions/polygon_spec.rb deleted file mode 100644 index 3006dd2..0000000 --- a/spec/postgis_functions/polygon_spec.rb +++ /dev/null @@ -1,146 +0,0 @@ -require File.dirname(__FILE__) + '/../spec_helper.rb' - - -describe "Point" do - - before(:all) do - @c1 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[12,45],[45,41],[4,1],[12,45]],[[2,5],[5,1],[14,1],[2,5]]],123)) - @c2 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[22,66],[65,65],[20,10],[22,66]],[[10,15],[15,11],[34,14],[10,15]]],123)) - @c3 ||= City.create!(:data => "City3", :geom => Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]],123)) - @s1 ||= Street.create!(:data => "Street1", :geom => LineString.from_coordinates([[1,1],[2,2]],123)) - @s2 ||= Street.create!(:data => "Street2", :geom => LineString.from_coordinates([[4,4],[7,7]],123)) - @s3 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[8,8],[18,18],[20,20],[25,25],[30,30],[38,38]],123)) - @s4 ||= Street.create!(:data => "Street3", :geom => LineString.from_coordinates([[10,8],[15,18]],123)) - @p1 ||= Position.create!(:data => "Point1", :geom => Point.from_x_y(1,1,123)) - @p2 ||= Position.create!(:data => "Point2", :geom => Point.from_x_y(5,5,123)) - @p3 ||= Position.create!(:data => "Point3", :geom => Point.from_x_y(8,8,123)) - @p4 ||= Position.create!(:data => "Point4", :geom => Point.from_x_y(30,30,123)) - - end - - - - - describe "Polygon" do - - it "sort by area size" do - City.by_area.first.data.should == "City1" #[@c1, @c2, @c3] - end - - it do - @c2.should be_closed - end - - it do - @c3.area.should be_close(1093.270089, 0.1) - end - - it do - @c2.area.should be_close(1159.5, 0.1) - end - - it "dimension x" do - @c2.dimension.should eql(2) - end - - it "perimter 2d" do - @c2.perimeter.should be_close(219.770013855493, 0.1) - end - - it "perimter 3d" do - @c2.perimeter3d.should be_close(219.770013855493, 0.1) - end - - it "contains points?" do - @c1.contains?(@p1).should be_false - end - - it "contains created point?" do - @c1.contains?(@p4).should be_true - end - - it do - @c1.should_not be_spatially_equal(@c2) - end - - it "find all cities that contains a point" do - City.contains(@p1.geom, 123).should eql([]) - end - - it "should find one city (first) that contains a point" do - City.contain(@p4.geom, 123).data.should eql("City1") - end - - it do - @c1.covers?(@p1).should be_false - end - - it do - @c1.covers?(@p4).should be_true - end - - it do - @c1.should_not be_within(@c2) - end - - it "city overlaps point?" do - lambda { @c3.overlaps?(@c2) }.should raise_error # WHY?? - end - - it "should get a polygon for envelope" do - @c2.envelope.should be_instance_of(Polygon) - end - - it "should get a polygon for envelope" do - @c2.envelope.rings[0].points[0].should be_instance_of(Point) - end - - it "should get the center" do - @c2.centroid.x.should be_close(36.2945235015093,0.00001) - @c2.centroid.y.should be_close(48.3211154233146,0.00001) - end - - it "should get the center with the correct srid" do - @c1.centroid.srid.should eql(123) - end - - it "distance from another" do - @c1.distance_to(@c3).should eql(0.0) - end - - it "distance to a linestring" do - @c1.distance_to(@s1).should be_close(1.8,0.001) - end - - it "should simplify me" do - @c3.simplify.should be_instance_of(Polygon) - end - - it "should simplify me number of points" do - @c3.simplify[0].length.should eql(4) - end - - #Strange again.... s2 s3 ... error - it do - @c3.touches?(@s1).should be_false - end - - it do - @c2.should be_simple - end - - it do - @c2.disjoint?(@p2).should be_true - end - - it do - @c3.polygonize.should have(2).geometries - end - - # weird... - # it do - # @c1.disjoint?(@s2).should be_true - # end - - end -end \ No newline at end of file diff --git a/spec/postgis_functions_spec.rb b/spec/postgis_functions_spec.rb index 994273f..4c9d55a 100644 --- a/spec/postgis_functions_spec.rb +++ b/spec/postgis_functions_spec.rb @@ -3,14 +3,13 @@ describe "PostgisFunctions" do before(:all) do #load_schema - @c1 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[12,45],[45,41],[4,1],[12,45]],[[2,5],[5,1],[14,1],[2,5]]],123)) - @s1 ||= Street.create!(:data => "Street1", :geom => LineString.from_coordinates([[-43,-20],[-42,-28]],123)) - @p1 ||= Position.create!(:data => "Point1", :geom => Point.from_x_y(-43,-22,123)) + @c1 ||= City.create!(:data => "City1", :geom => Polygon.from_coordinates([[[12,45],[45,41],[4,1],[12,45]],[[2,5],[5,1],[14,1],[2,5]]],4326)) + @s1 ||= Street.create!(:data => "Street1", :geom => LineString.from_coordinates([[-43,-20],[-42,-28]],4326)) + @p1 ||= Position.create!(:data => "Point1", :geom => Point.from_x_y(-43,-22,4326)) end describe "Common Mix" do - it "should calculate distance point to line" do @p1.distance_to(@s1).should be_close(0.248069469178417, 0.00000001) end @@ -19,10 +18,8 @@ @p1.should_not be_inside(@c1) end - end - #TODO is sorted rspec helper describe "Class methods" do diff --git a/spec/spec.opts b/spec/spec.opts index 8f5e216..81a1b3d 100644 --- a/spec/spec.opts +++ b/spec/spec.opts @@ -1,6 +1,5 @@ --colour ---format -spinner +--format RspecSpinner::Spinner --timeout 20 --diff diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f26c822..8a072c0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,6 +9,7 @@ require 'postgres' require 'activerecord' end + require 'rspec_spinner' $:.unshift(File.dirname(__FILE__) + '/../lib') config = YAML.load_file(File.dirname(__FILE__) + '/db/database_postgis.yml')