postgis_adapter 0.1.8 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -12,24 +12,20 @@ lib/postgis_functions.rb
12
12
  lib/postgis_functions/bbox.rb
13
13
  lib/postgis_functions/class.rb
14
14
  lib/postgis_functions/common.rb
15
- lib/postgis_functions/linestring.rb
16
- lib/postgis_functions/point.rb
17
- lib/postgis_functions/polygon.rb
18
15
  postgis_adapter.gemspec
19
16
  rails/init.rb
20
17
  script/console
21
18
  script/destroy
22
19
  script/generate
23
- spec/acts_as_geom_spec.rb
24
- spec/common_spatial_adapter_spec.rb
25
20
  spec/db/database_postgis.yml
26
21
  spec/db/models_postgis.rb
27
22
  spec/db/schema_postgis.rb
23
+ spec/postgis_adapter/acts_as_geom_spec.rb
24
+ spec/postgis_adapter/common_spatial_adapter_spec.rb
28
25
  spec/postgis_adapter_spec.rb
29
26
  spec/postgis_functions/bbox_spec.rb
30
- spec/postgis_functions/linestring_spec.rb
31
- spec/postgis_functions/point_spec.rb
32
- spec/postgis_functions/polygon_spec.rb
27
+ spec/postgis_functions/class_spec.rb
28
+ spec/postgis_functions/common_spec.rb
33
29
  spec/postgis_functions_spec.rb
34
30
  spec/spec.opts
35
31
  spec/spec_helper.rb
@@ -14,7 +14,6 @@ module PostgisFunctions
14
14
  # acts_as_geom :geom
15
15
  def acts_as_geom(*columns)
16
16
  cattr_accessor :postgis_geoms
17
-
18
17
  geoms = columns.map do |g|
19
18
  geom_type = get_geom_type(g)
20
19
  case geom_type
@@ -25,13 +24,15 @@ module PostgisFunctions
25
24
  when :line_string
26
25
  send :include, LineStringFunctions
27
26
  end
28
- {g => geom_type}
27
+ g
29
28
  end
30
- self.postgis_geoms = {:geoms => geoms}#, :opts => options}
29
+ self.postgis_geoms = {:columns => geoms}#, :opts => options}
31
30
  end
32
31
 
33
32
  def get_geom_type(column)
34
33
  self.columns.select { |c| c.name == column.to_s}.first.geometry_type
34
+ rescue ActiveRecord::StatementInvalid => e
35
+ nil
35
36
  end
36
37
  end
37
38
  end
@@ -10,9 +10,6 @@ require 'postgis_adapter/common_spatial_adapter'
10
10
  require 'postgis_functions'
11
11
  require 'postgis_functions/common'
12
12
  require 'postgis_functions/class'
13
- require 'postgis_functions/point'
14
- require 'postgis_functions/linestring'
15
- require 'postgis_functions/polygon'
16
13
  require 'postgis_functions/bbox'
17
14
  require 'postgis_adapter/acts_as_geom'
18
15
 
@@ -20,13 +17,12 @@ include GeoRuby::SimpleFeatures
20
17
  include SpatialAdapter
21
18
 
22
19
  module PostgisAdapter
23
- VERSION = '0.1.8'
20
+ VERSION = '0.2.1'
24
21
  end
25
22
 
26
23
  #tables to ignore in migration : relative to PostGIS management of geometric columns
27
24
  ActiveRecord::SchemaDumper.ignore_tables << "spatial_ref_sys" << "geometry_columns"
28
25
 
29
-
30
26
  #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)
31
27
  GeoRuby::SimpleFeatures::Geometry.class_eval do
32
28
  def to_fixture_format
@@ -34,7 +30,6 @@ GeoRuby::SimpleFeatures::Geometry.class_eval do
34
30
  end
35
31
  end
36
32
 
37
-
38
33
  ActiveRecord::Base.class_eval do
39
34
  require 'active_record/version'
40
35
 
@@ -234,7 +234,7 @@ module PostgisFunctions
234
234
 
235
235
  def simplify!(tolerance=0.1)
236
236
  #FIXME: not good..
237
- self.geom = simplify
237
+ self.update_attribute(get_column_name, simplify)
238
238
  end
239
239
 
240
240
  #
@@ -424,6 +424,357 @@ module PostgisFunctions
424
424
  m = "'#{m}'" if m
425
425
  postgis_calculate("Relate", [self, other], m)
426
426
  end
427
+
428
+ #
429
+ # Transform the geometry into a different spatial reference system.
430
+ #
431
+ # Return geometry ST_Transform(geometry g1, integer srid);
432
+ # 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.
433
+ # 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
434
+ # Requires PostGIS be compiled with Proj support. Use PostGIS_Full_Version to confirm you have proj support compiled in.
435
+ #
436
+ # 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.
437
+ #
438
+ # Prior to 1.3.4, this function crashes if used with geometries that contain CURVES. This is fixed in 1.3.4+
439
+ # This method implements the OpenGIS Simple Features Implementation Specification for SQL.
440
+ # This method supports Circular Strings and Curves
441
+ #
442
+ def transform(new_srid)
443
+ postgis_calculate("Transform", self, new_srid)
444
+ end
445
+
446
+ #
447
+ # LINESTRING
448
+ #
449
+ #
450
+ #
451
+ module LineStringFunctions
452
+
453
+ #
454
+ # Returns the 2D length of the geometry if it is a linestring, multilinestring,
455
+ # ST_Curve, ST_MultiCurve. 0 is returned for areal geometries. For areal geometries
456
+ # use 'perimeter'. Measurements are in the units of the spatial reference system
457
+ # of the geometry.
458
+ #
459
+ # Returns Float
460
+ #
461
+ def length
462
+ dis = postgis_calculate(:length, self).to_f
463
+ end
464
+
465
+ #
466
+ # Returns the 3-dimensional or 2-dimensional length of the geometry if it is
467
+ # a linestring or multi-linestring. For 2-d lines it will just return the 2-d
468
+ # length (same as 'length')
469
+ #
470
+ # Returns Float
471
+ #
472
+ def length_3d
473
+ dis = postgis_calculate(:length3d, self).to_f
474
+ end
475
+
476
+ #
477
+ # Calculates the length of a geometry on an ellipsoid. This is useful if the
478
+ # coordinates of the geometry are in longitude/latitude and a length is
479
+ # desired without reprojection. The ellipsoid is a separate database type and
480
+ # can be constructed as follows:
481
+ #
482
+ # SPHEROID[<NAME>,<SEMI-MAJOR AXIS>,<INVERSE FLATTENING>]
483
+ #
484
+ # Example:
485
+ # SPHEROID["GRS_1980",6378137,298.257222101]
486
+ #
487
+ # Defaults to:
488
+ #
489
+ # SPHEROID["IERS_2003",6378136.6,298.25642]
490
+ #
491
+ # Returns Float length_spheroid(geometry linestring, spheroid);
492
+ #
493
+ def length_spheroid(spheroid = EARTH_SPHEROID)
494
+ dis = postgis_calculate(:length_spheroid, self, spheroid).to_f
495
+ end
496
+
497
+ #
498
+ # Return the number of points of the geometry.
499
+ # PostGis ST_NumPoints does not work as nov/08
500
+ #
501
+ # Returns Integer ST_NPoints(geometry g1);
502
+ #
503
+ def num_points
504
+ postgis_calculate(:npoints, self).to_i
505
+ end
506
+
507
+ #
508
+ # Returns geometry start point.
509
+ #
510
+ def start_point
511
+ postgis_calculate(:startpoint, self)
512
+ end
513
+
514
+ #
515
+ # Returns geometry end point.
516
+ #
517
+ def end_point
518
+ postgis_calculate(:endpoint, self)
519
+ end
520
+
521
+ #
522
+ # Takes two geometry objects and returns TRUE if their intersection
523
+ # "spatially cross", that is, the geometries have some, but not all interior
524
+ # points in common. The intersection of the interiors of the geometries must
525
+ # not be the empty set and must have a dimensionality less than the the
526
+ # maximum dimension of the two input geometries. Additionally, the
527
+ # intersection of the two geometries must not equal either of the source
528
+ # geometries. Otherwise, it returns FALSE.
529
+ #
530
+ #
531
+ # Returns Boolean ST_Crosses(geometry g1, geometry g2);
532
+ #
533
+ def crosses? other
534
+ postgis_calculate(:crosses, [self, other])
535
+ end
536
+
537
+ #
538
+ # Returns a float between 0 and 1 representing the location of the closest point
539
+ # on LineString to the given Point, as a fraction of total 2d line length.
540
+ #
541
+ # You can use the returned location to extract a Point (ST_Line_Interpolate_Point)
542
+ # or a substring (ST_Line_Substring).
543
+ #
544
+ # This is useful for approximating numbers of addresses.
545
+ #
546
+ # Returns float (0 to 1) ST_Line_Locate_Point(geometry a_linestring, geometry a_point);
547
+ #
548
+ def locate_point point
549
+ postgis_calculate(:line_locate_point, [self, point]).to_f
550
+ end
551
+
552
+ #
553
+ # Return a derived geometry collection value with elements that match the
554
+ # specified measure. Polygonal elements are not supported.
555
+ #
556
+ # Semantic is specified by: ISO/IEC CD 13249-3:200x(E) - Text for
557
+ # Continuation CD Editing Meeting
558
+ #
559
+ # Returns geometry ST_Locate_Along_Measure(geometry ageom_with_measure, float a_measure);
560
+ #
561
+ def locate_along_measure(measure)
562
+ postgis_calculate(:locate_along_measure, self, measure)
563
+ end
564
+
565
+ #
566
+ # Return a derived geometry collection value with elements that match the
567
+ # specified range of measures inclusively. Polygonal elements are not supported.
568
+ #
569
+ # Semantic is specified by: ISO/IEC CD 13249-3:200x(E) - Text for Continuation CD Editing Meeting
570
+ #
571
+ # Returns geometry ST_Locate_Between_Measures(geometry geomA, float measure_start, float measure_end);
572
+ #
573
+ def locate_between_measures(a, b)
574
+ postgis_calculate(:locate_between_measures, self, [a,b])
575
+ end
576
+
577
+ #
578
+ # Returns a point interpolated along a line. First argument must be a LINESTRING.
579
+ # Second argument is a float8 between 0 and 1 representing fraction of total
580
+ # linestring length the point has to be located.
581
+ #
582
+ # See ST_Line_Locate_Point for computing the line location nearest to a Point.
583
+ #
584
+ # Returns geometry ST_Line_Interpolate_Point(geometry a_linestring, float a_fraction);
585
+ #
586
+ def interpolate_point(fraction)
587
+ postgis_calculate(:line_interpolate_point, self, fraction)
588
+ end
589
+
590
+ #
591
+ # Return a linestring being a substring of the input one starting and ending
592
+ # at the given fractions of total 2d length. Second and third arguments are
593
+ # float8 values between 0 and 1. This only works with LINESTRINGs. To use
594
+ # with contiguous MULTILINESTRINGs use in conjunction with ST_LineMerge.
595
+ #
596
+ # If 'start' and 'end' have the same value this is equivalent to 'interpolate_point'.
597
+ #
598
+ # See 'locate_point' for computing the line location nearest to a Point.
599
+ #
600
+ # Returns geometry ST_Line_Substring(geometry a_linestring, float startfraction, float endfraction);
601
+ #
602
+ def line_substring(s,e)
603
+ postgis_calculate(:line_substring, self, [s, e])
604
+ end
605
+
606
+ ###
607
+ #Not implemented in postgis yet
608
+ # ST_max_distance Returns the largest distance between two line strings.
609
+ #def max_distance other
610
+ # #float ST_Max_Distance(geometry g1, geometry g2);
611
+ # postgis_calculate(:max_distance, [self, other])
612
+ #end
613
+ end
614
+
615
+
616
+ ####
617
+ ###
618
+ ##
619
+ #
620
+ # POINT
621
+ #
622
+ #
623
+ module PointFunctions
624
+
625
+ #
626
+ # Returns a float between 0 and 1 representing the location of the closest point
627
+ # on LineString to the given Point, as a fraction of total 2d line length.
628
+ #
629
+ # You can use the returned location to extract a Point (ST_Line_Interpolate_Point)
630
+ # or a substring (ST_Line_Substring).
631
+ #
632
+ # This is useful for approximating numbers of addresses.
633
+ #
634
+ # Returns float (0 to 1) ST_Line_Locate_Point(geometry a_linestring, geometry a_point);
635
+ #
636
+ def where_on_line line
637
+ postgis_calculate(:line_locate_point, [line, self]).to_f
638
+ end
639
+
640
+ #
641
+ # Linear distance in meters between two lon/lat points.
642
+ # Uses a spherical earth and radius of 6370986 meters.
643
+ # Faster than 'distance_spheroid', but less accurate.
644
+ #
645
+ # Only implemented for points.
646
+ #
647
+ # Returns Float ST_Distance_Sphere(geometry pointlonlatA, geometry pointlonlatB);
648
+ #
649
+ def distance_sphere_to(other)
650
+ dis = postgis_calculate(:distance_sphere, [self, other]).to_f
651
+ end
652
+
653
+ #
654
+ # Calculates the distance on an ellipsoid. This is useful if the
655
+ # coordinates of the geometry are in longitude/latitude and a length is
656
+ # desired without reprojection. The ellipsoid is a separate database type and
657
+ # can be constructed as follows:
658
+ #
659
+ # This is slower then 'distance_sphere_to', but more precise.
660
+ #
661
+ # SPHEROID[<NAME>,<SEMI-MAJOR AXIS>,<INVERSE FLATTENING>]
662
+ #
663
+ # Example:
664
+ # SPHEROID["GRS_1980",6378137,298.257222101]
665
+ #
666
+ # Defaults to:
667
+ #
668
+ # SPHEROID["IERS_2003",6378136.6,298.25642]
669
+ #
670
+ # Returns ST_Distance_Spheroid(geometry geomA, geometry geomB, spheroid);
671
+ #
672
+ def distance_spheroid_to(other, spheroid = EARTH_SPHEROID)
673
+ postgis_calculate(:distance_spheroid, [self, other], spheroid).to_f
674
+ end
675
+
676
+ #
677
+ # The azimuth of the segment defined by the given Point geometries,
678
+ # or NULL if the two points are coincident. Return value is in radians.
679
+ #
680
+ # The Azimuth is mathematical concept defined as the angle, in this case
681
+ # measured in radian, between a reference plane and a point.
682
+ #
683
+ # Returns Float ST_Azimuth(geometry pointA, geometry pointB);
684
+ #
685
+ def azimuth other
686
+ #TODO: return if not point/point
687
+ postgis_calculate(:azimuth, [self, other]).to_f
688
+ rescue
689
+ ActiveRecord::StatementInvalid
690
+ end
691
+
692
+ #
693
+ # True if the geometry is a point and is inside the circle.
694
+ #
695
+ # Returns Boolean ST_point_inside_circle(geometry, float, float, float)
696
+ #
697
+ def inside_circle?(x,y,r)
698
+ postgis_calculate(:point_inside_circle, self, [x,y,r])
699
+ end
700
+
701
+ end
702
+
703
+ ###
704
+ ##
705
+ #
706
+ # Polygon
707
+ #
708
+ #
709
+ module PolygonFunctions
710
+
711
+ #
712
+ # The area of the geometry if it is a polygon or multi-polygon.
713
+ # Return the area measurement of an ST_Surface or ST_MultiSurface value.
714
+ # Area is in the units of the spatial reference system.
715
+ #
716
+ # Returns Float ST_Area(geometry g1);
717
+ #
718
+ def area
719
+ postgis_calculate(:area, self).to_f
720
+ end
721
+
722
+ #
723
+ # Returns the 2D perimeter of the geometry if it is a ST_Surface, ST_MultiSurface
724
+ # (Polygon, Multipolygon). 0 is returned for non-areal geometries. For linestrings
725
+ # use 'length'. Measurements are in the units of the spatial reference system of
726
+ # the geometry.
727
+ #
728
+ # Returns Float ST_Perimeter(geometry g1);
729
+ #
730
+ def perimeter
731
+ postgis_calculate(:perimeter, self).to_f
732
+ end
733
+
734
+ #
735
+ # Returns the 3-dimensional perimeter of the geometry, if it is a polygon or multi-polygon.
736
+ # If the geometry is 2-dimensional, then the 2-dimensional perimeter is returned.
737
+ #
738
+ # Returns Float ST_Perimeter3D(geometry geomA);
739
+ #
740
+ def perimeter3d
741
+ postgis_calculate(:perimeter3d, self).to_f
742
+ end
743
+
744
+ #
745
+ # True if the LineString's start and end points are coincident.
746
+ #
747
+ # This method implements the OpenGIS Simple Features Implementation
748
+ # Specification for SQL.
749
+ #
750
+ # SQL-MM defines the result of ST_IsClosed(NULL) to be 0, while PostGIS returns NULL.
751
+ #
752
+ # Returns boolean ST_IsClosed(geometry g);
753
+ #
754
+ def closed?
755
+ postgis_calculate(:isclosed, self)
756
+ end
757
+ alias_method "is_closed?", "closed?"
758
+
759
+ #
760
+ # True if no point in Geometry B is outside Geometry A
761
+ #
762
+ # This function call will automatically include a bounding box comparison
763
+ # that will make use of any indexes that are available on the geometries.
764
+ # To avoid index use, use the function _ST_Covers.
765
+ #
766
+ # Do not call with a GEOMETRYCOLLECTION as an argument
767
+ # Do not use this function with invalid geometries. You will get unexpected results.
768
+ #
769
+ # Performed by the GEOS module.
770
+ #
771
+ # Returns Boolean ST_Covers(geometry geomA, geometry geomB);
772
+ #
773
+ def covers? other
774
+ postgis_calculate(:covers, [self, other])
775
+ end
776
+
777
+ end
427
778
 
428
779
  end
429
780
 
@@ -435,4 +786,4 @@ end
435
786
 
436
787
 
437
788
  #x ST_SnapToGrid(geometry, geometry, sizeX, sizeY, sizeZ, sizeM)
438
- # ST_X , ST_Y, SE_M, SE_Z, SE_IsMeasured has_m?
789
+ # ST_X , ST_Y, SE_M, SE_Z, SE_IsMeasured has_m?