rgeo 0.1.17 → 0.1.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/History.rdoc +8 -0
  2. data/README.rdoc +40 -21
  3. data/Version +1 -1
  4. data/lib/rgeo.rb +1 -0
  5. data/lib/rgeo/cartesian.rb +1 -0
  6. data/lib/rgeo/cartesian/analysis.rb +115 -0
  7. data/lib/rgeo/cartesian/feature_classes.rb +0 -14
  8. data/lib/rgeo/features/factory.rb +5 -5
  9. data/lib/rgeo/features/factory_generator.rb +10 -0
  10. data/lib/rgeo/geo_json/coder.rb +49 -14
  11. data/lib/rgeo/geo_json/interface.rb +6 -6
  12. data/lib/rgeo/shapefile.rb +60 -0
  13. data/lib/rgeo/shapefile/reader.rb +898 -0
  14. data/tests/shapefile/shapelib_testcases/readme.txt +11 -0
  15. data/tests/shapefile/shapelib_testcases/test.dbf +0 -0
  16. data/tests/shapefile/shapelib_testcases/test.shp +0 -0
  17. data/tests/shapefile/shapelib_testcases/test.shx +0 -0
  18. data/tests/shapefile/shapelib_testcases/test0.shp +0 -0
  19. data/tests/shapefile/shapelib_testcases/test0.shx +0 -0
  20. data/tests/shapefile/shapelib_testcases/test1.shp +0 -0
  21. data/tests/shapefile/shapelib_testcases/test1.shx +0 -0
  22. data/tests/shapefile/shapelib_testcases/test10.shp +0 -0
  23. data/tests/shapefile/shapelib_testcases/test10.shx +0 -0
  24. data/tests/shapefile/shapelib_testcases/test11.shp +0 -0
  25. data/tests/shapefile/shapelib_testcases/test11.shx +0 -0
  26. data/tests/shapefile/shapelib_testcases/test12.shp +0 -0
  27. data/tests/shapefile/shapelib_testcases/test12.shx +0 -0
  28. data/tests/shapefile/shapelib_testcases/test13.shp +0 -0
  29. data/tests/shapefile/shapelib_testcases/test13.shx +0 -0
  30. data/tests/shapefile/shapelib_testcases/test2.shp +0 -0
  31. data/tests/shapefile/shapelib_testcases/test2.shx +0 -0
  32. data/tests/shapefile/shapelib_testcases/test3.shp +0 -0
  33. data/tests/shapefile/shapelib_testcases/test3.shx +0 -0
  34. data/tests/shapefile/shapelib_testcases/test4.shp +0 -0
  35. data/tests/shapefile/shapelib_testcases/test4.shx +0 -0
  36. data/tests/shapefile/shapelib_testcases/test5.shp +0 -0
  37. data/tests/shapefile/shapelib_testcases/test5.shx +0 -0
  38. data/tests/shapefile/shapelib_testcases/test6.shp +0 -0
  39. data/tests/shapefile/shapelib_testcases/test6.shx +0 -0
  40. data/tests/shapefile/shapelib_testcases/test7.shp +0 -0
  41. data/tests/shapefile/shapelib_testcases/test7.shx +0 -0
  42. data/tests/shapefile/shapelib_testcases/test8.shp +0 -0
  43. data/tests/shapefile/shapelib_testcases/test8.shx +0 -0
  44. data/tests/shapefile/shapelib_testcases/test9.shp +0 -0
  45. data/tests/shapefile/shapelib_testcases/test9.shx +0 -0
  46. data/tests/shapefile/tc_shapelib_tests.rb +527 -0
  47. data/tests/tc_cartesian_analysis.rb +107 -0
  48. data/tests/tc_oneoff.rb +1 -0
  49. metadata +118 -12
data/History.rdoc CHANGED
@@ -1,3 +1,11 @@
1
+ === 0.1.18 / 2010-11-22
2
+
3
+ * API CHANGE: GeoJSON defaults to no JSON parser rather than to the JSON library. GeoJSON also fails better when attempting to use a JSON parser that isn't installed.
4
+ * Added a decorator tool for FactoryGenerator
5
+ * Added an analysis module for Cartesian geometries, and implemented an algorithm for determining whether a ring is clockwise or counterclockwise. (We needed this to interpret shapefiles.)
6
+ * First pass implementation of shapefile reading. It passes a basic test suite I borrowed from shapelib, but I haven't yet done an exhaustive test on every case.
7
+ * The simple Cartesian implementation mistakenly clamped x and y to lat/lon limits. Fixed.
8
+
1
9
  === 0.1.17 / 2010-11-20
2
10
 
3
11
  * Implemented ActiveRecord adapters that cover MySQL Spatial for the mysql and mysql2 gems. SpatiaLite and PostGIS adapters are coming later.
data/README.rdoc CHANGED
@@ -9,10 +9,10 @@ for writing location-based applications using Ruby-based frameworks such
9
9
  as Ruby On Rails.
10
10
 
11
11
  IMPORTANT: RGeo is currently under development, and we consider it to be
12
- in a "pre-alpha" state. A number of features (such as Rails integration)
13
- are not yet complete, and there are numerous known bugs and holes in the
14
- test suite. We also expect the APIs to be in flux for a short while
15
- longer. Therefore, we do not yet recommend the use of RGeo in production.
12
+ in a "pre-alpha" state. Several features are not yet complete, and there
13
+ are known bugs and holes in the test suite. We also expect the APIs to be
14
+ in flux for a short while longer. Therefore, we do not yet recommend the
15
+ use of RGeo in production.
16
16
 
17
17
  === Summary
18
18
 
@@ -30,10 +30,10 @@ Use RGeo to:
30
30
  * Correctly handle spherical geometry, and compute projections for
31
31
  geographic data analysis.
32
32
  * Store and retrieve spatial data in industry standard spatial database
33
- systems such as PostGIS.
33
+ systems such as MySQL Spatial, SpatiaLite, and PostGIS.
34
34
  * Generate and interpret GeoJSON data for communication with common
35
- location-based services; and read and write ESRI shapefiles for
36
- interaction with legacy GIS data.
35
+ location-based web services such as SimpleGeo.
36
+ * Read legacy GIS data from ESRI shapefiles.
37
37
  * Extend Ruby On Rails to handle location data in a web application.
38
38
  * Write spatial applications following the latest open standards from
39
39
  the Open Geospatial Consortium.
@@ -48,6 +48,14 @@ RGeo has the following prerequisites:
48
48
  available without it. This C/C++ library may be available via your
49
49
  operating system's package manager, or you can download it from
50
50
  http://geos.osgeo.org/
51
+ * If you are using the GeoJSON tools under Ruby 1.8.7, you should
52
+ install the "json" gem. Ruby 1.9 has JSON support in its standard
53
+ library and does not require the gem.
54
+ * If you are using the shapefile reader, you should install the "dbf"
55
+ gem for access to shape attributes.
56
+ * The ActiveRecord adapters for MySQL Spatial, PostGIS, and SpatiaLite
57
+ require ActiveRecord 3.0.3 or later, Arel 2.0 or later, and the
58
+ corresponding database driver gems (e.g. "mysql" or "mysql2").
51
59
 
52
60
  === Installation
53
61
 
@@ -70,26 +78,34 @@ the switches interpreted by the gem command. For example:
70
78
 
71
79
  gem install rgeo -- --with-geos-dir=/path/to/my/geos/installation
72
80
 
73
- === Known issues and to-do items
81
+ === Known issues
74
82
 
75
- RGeo is currently under development and several planned features are not
76
- yet complete. These include:
83
+ * Some planned and documented functionality on the SimpleCartesian and
84
+ SimpleSpherical data implementations is not yet implemented.
85
+ * Reading of shapefile attributes is dependent on the "dbf" gem.
86
+ Unfortunately, the current version of dbf, 1.5.0, has a hard dependency
87
+ on ActiveSupport 3.0.1, which renders it incompatible with the
88
+ ActiveRecord adapters, which require at least ActiveRecord 3.0.3
89
+ (not to mention also rendering it incompatible with Rails 3.0.3...)
90
+ I have filed a bug report with dbf to try to get this resolved.
77
91
 
78
- * SpatiaLite and PostGIS adapters for ActiveRecord.
92
+ === To-do items
93
+
94
+ This is our potential feature roadmap.
95
+
96
+ * SpatiaLite and PostGIS adapters for ActiveRecord. (We already have an
97
+ adapter for MySQL Spatial.)
79
98
  * Support for bbox and crs elements of GeoJSON.
80
- * Support for ESRI shapefile reading and writing.
81
- * Projection subsystem, and support for arbitrary projections in the geography module, utilizing proj4.
82
- * Several more operations on SimpleCartesian and SimpleSpherical.
83
- * Geography implementation utilizing ellipsoidal geometry, probably utilizing geographiclib.
84
- * Additional third-party integration, possibly including SimpleGeo, GeoRSS, KML.
99
+ * Support for writing shapefiles. (Reading is now implemented.)
100
+ * Projection subsystem, and support for arbitrary projections in the
101
+ geography module, utilizing proj4.
102
+ * Geography implementation utilizing ellipsoidal geometry, probably
103
+ utilizing geographiclib.
104
+ * Integration with other third-party formats and services, potentially
105
+ including SimpleGeo, GeoRSS, KML.
85
106
  * JRuby support via JTS integration.
86
107
  * Rubinius support for GEOS integration.
87
108
 
88
- Additionally, not all implemented features are well-tested yet. In
89
- general, we currently consider this library to be "pre-alpha" quality,
90
- intended for experimentation and feedback but not production. It has been
91
- deployed in production at GeoPage, but only in a limited capacity.
92
-
93
109
  === Development and support
94
110
 
95
111
  Documentation is available at http://virtuoso.rubyforge.org/rgeo/README_rdoc.html
@@ -115,6 +131,9 @@ The ActiveRecord adapters owe some debt to the spatial_adapter plugin
115
131
  design decisions for RGeo, but studying the spatial_adapter source gave us
116
132
  a head start on our implementation.
117
133
 
134
+ Although we don't use shapelib (http://shapelib.maptools.org/) to read
135
+ ESRI shapefiles, we did borrow a bunch of their test cases.
136
+
118
137
  === License
119
138
 
120
139
  Copyright 2010 Daniel Azuma
data/Version CHANGED
@@ -1 +1 @@
1
- 0.1.17
1
+ 0.1.18
data/lib/rgeo.rb CHANGED
@@ -131,6 +131,7 @@ module RGeo
131
131
  autoload(:Geos, 'rgeo/geos')
132
132
  autoload(:ImplHelpers, 'rgeo/impl_helpers')
133
133
  autoload(:WKRep, 'rgeo/wkrep')
134
+ autoload(:Shapefile, 'rgeo/shapefile')
134
135
 
135
136
  end
136
137
 
@@ -82,3 +82,4 @@ require 'rgeo/cartesian/feature_methods'
82
82
  require 'rgeo/cartesian/feature_classes'
83
83
  require 'rgeo/cartesian/factory'
84
84
  require 'rgeo/cartesian/interface'
85
+ require 'rgeo/cartesian/analysis'
@@ -0,0 +1,115 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Cartesian toplevel interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2010 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ module RGeo
38
+
39
+ module Cartesian
40
+
41
+
42
+ module Analysis
43
+
44
+ class << self
45
+
46
+
47
+ # Given a LineString, which must be a ring, determine whether the
48
+ # ring proceeds clockwise or counterclockwise.
49
+ # Returns 1 for counterclockwise, or -1 for clockwise.
50
+ #
51
+ # Returns 0 if the ring is empty.
52
+ # The return value is undefined if the object is not a ring, or
53
+ # is not in a Cartesian coordinate system.
54
+
55
+ def ring_direction(ring_)
56
+ size_ = ring_.num_points - 1
57
+ return 0 if size_ == 0
58
+
59
+ # Extract unit-length segments from the ring.
60
+ segs_ = []
61
+ size_.times do |i_|
62
+ p0_ = ring_.point_n(i_)
63
+ p1_ = ring_.point_n(i_+1)
64
+ x_ = p1_.x - p0_.x
65
+ y_ = p1_.y - p0_.y
66
+ r_ = ::Math.sqrt(x_*x_ + y_*y_)
67
+ if r_ > 0.0
68
+ segs_ << x_/r_ << y_/r_
69
+ end
70
+ end
71
+ segs_ << segs_[0] << segs_[1]
72
+
73
+ # Extract angles from the segments by subtracting the segments.
74
+ # Note angles are represented as cos/sin pairs so we don't
75
+ # have to calculate any trig functions.
76
+ angs_ = []
77
+ size_.times do |i_|
78
+ x0_, y0_, x1_, y1_ = segs_[i_*2,4]
79
+ angs_ << x0_*x1_ + y0_*y1_ << x0_*y1_ - x1_*y0_
80
+ end
81
+
82
+ # Now add the angles and count revolutions.
83
+ # Again, our running sum is represented as a cos/sin pair.
84
+ revolutions_ = 0
85
+ sin_ = 0.0
86
+ cos_ = 1.0
87
+ angs_.each_slice(2) do |(x_, y_)|
88
+ ready_ = y_ > 0.0 && sin_ > 0.0 || y_ < 0.0 && sin_ < 0.0
89
+ if y_ != 0.0
90
+ s_ = sin_*x_ + cos_*y_
91
+ c_ = cos_*x_ - sin_*y_
92
+ r_ = ::Math.sqrt(s_*s_ + c_*c_)
93
+ sin_ = s_ / r_
94
+ cos_ = c_ / r_
95
+ end
96
+ if ready_
97
+ if y_ > 0.0 && sin_ <= 0.0
98
+ revolutions_ += 1
99
+ elsif y_ < 0.0 && sin_ >= 0.0
100
+ revolutions_ -= 1
101
+ end
102
+ end
103
+ end
104
+ revolutions_
105
+ end
106
+
107
+
108
+ end
109
+
110
+ end
111
+
112
+
113
+ end
114
+
115
+ end
@@ -48,20 +48,6 @@ module RGeo
48
48
  include ::RGeo::ImplHelpers::BasicPointMethods
49
49
 
50
50
 
51
- def _validate_geometry
52
- @x = @x % 360.0
53
- @x -= 360.0 if @x >= 180.0
54
- @y = 90.0 if @y > 90.0
55
- @y = -90.0 if @y < -90.0
56
- super
57
- end
58
-
59
-
60
- def _xyz
61
- @xyz ||= PointXYZ.from_latlon(@y, @x)
62
- end
63
-
64
-
65
51
  def distance(rhs_)
66
52
  rhs_ = ::RGeo::Features.cast(rhs_, @factory)
67
53
  case rhs_
@@ -90,12 +90,12 @@ module RGeo
90
90
  #
91
91
  # <tt>:z_coordinate</tt>::
92
92
  # Supports a "z" coordinate. When an implementation supports
93
- # z_coordinate, the Factory#epoint and Point#z methods are
94
- # available.
93
+ # this capability, geometries know about Z coordinates, and the
94
+ # Point#z method is available.
95
95
  # <tt>:m_coordinate</tt>::
96
- # Supports a "m" coordinate. When an implementation supports
97
- # m_coordinate, the Factory#epoint and Point#m methods are
98
- # available.
96
+ # Supports an "m" coordinate. When an implementation supports
97
+ # this capability, geometries know about M coordinates, and the
98
+ # Point#m method is available.
99
99
 
100
100
  def has_capability?(name_)
101
101
  nil
@@ -101,6 +101,16 @@ module RGeo
101
101
  end
102
102
 
103
103
 
104
+ # Return a new FactoryGenerator that calls the given delegate, but
105
+ # modifies the configuration passed to it. You can provide defaults
106
+ # for configuration values not explicitly specified, and you can
107
+ # force certain values to override the given configuration.
108
+
109
+ def self.decorate(delegate_, default_config_={}, force_config_={})
110
+ ::Proc.new{ |c_| delegate_.call(default_config_.merge(c_).merge(force_config_)) }
111
+ end
112
+
113
+
104
114
  end
105
115
 
106
116
 
@@ -47,6 +47,11 @@ module RGeo
47
47
  class Coder
48
48
 
49
49
 
50
+ @@json_available = nil
51
+ @@yajl_available = nil
52
+ @@activesupport_available = nil
53
+
54
+
50
55
  # Create a new coder settings object. The geo factory is passed as
51
56
  # a required argument.
52
57
  #
@@ -67,36 +72,60 @@ module RGeo
67
72
  # sole argument and returning the JSON hash, or it may be one of
68
73
  # the special values <tt>:json</tt>, <tt>:yajl</tt>, or
69
74
  # <tt>:active_support</tt>. Setting one of those special values
70
- # will require the corresponding library to be available. The
71
- # default is <tt>:json</tt>, which is present in the standard
75
+ # will require the corresponding library to be available. Note
76
+ # that the <tt>:json</tt> library is present in the standard
72
77
  # library in Ruby 1.9, but requires the "json" gem in Ruby 1.8.
73
- # If the specified parser is not available, then decode will not
78
+ # If a parser is not specified, then the decode method will not
74
79
  # accept a String or IO object; it will require a Hash.
75
80
 
76
81
  def initialize(opts_={})
77
82
  @geo_factory = opts_[:geo_factory] || ::RGeo::Cartesian.preferred_factory
78
83
  @entity_factory = opts_[:entity_factory] || EntityFactory.instance
79
- @json_parser = opts_[:json_parser] || :json
84
+ @json_parser = opts_[:json_parser]
80
85
  case @json_parser
81
86
  when :json
82
- begin
83
- require 'json'
87
+ if @@json_available.nil?
88
+ begin
89
+ require 'json'
90
+ @@json_available = true
91
+ rescue ::LoadError
92
+ @@json_available = false
93
+ end
94
+ end
95
+ if @@json_available
84
96
  @json_parser = ::Proc.new{ |str_| ::JSON.parse(str_) }
85
- rescue ::LoadError
97
+ else
98
+ raise Errors::RGeoError, "JSON library is not available. You may need to install the 'json' gem."
86
99
  end
87
100
  when :yajl
88
- begin
89
- require 'yajl'
101
+ if @@yajl_available.nil?
102
+ begin
103
+ require 'yajl'
104
+ @@yajl_available = true
105
+ rescue ::LoadError
106
+ @@yajl_available = false
107
+ end
108
+ end
109
+ if @@yajl_available
90
110
  @json_parser = ::Proc.new{ |str_| ::Yajl::Parser.new.parse(str_) }
91
- rescue ::LoadError
111
+ else
112
+ raise Errors::RGeoError, "Yajl library is not available. You may need to install the 'yajl' gem."
92
113
  end
93
114
  when :active_support
94
- begin
95
- require 'active_support/json'
115
+ if @@activesupport_available.nil?
116
+ begin
117
+ require 'active_support/json'
118
+ @@activesupport_available = true
119
+ rescue ::LoadError
120
+ @@activesupport_available = false
121
+ end
122
+ end
123
+ if @@activesupport_available
96
124
  @json_parser = ::Proc.new{ |str_| ::ActiveSupport::JSON.decode(str_) }
97
- rescue ::LoadError
125
+ else
126
+ raise Errors::RGeoError, "ActiveSupport::JSON library is not available. You may need to install the 'activesupport' gem."
98
127
  end
99
- when ::Proc
128
+ when ::Proc, nil
100
129
  # Leave as is
101
130
  else
102
131
  raise ::ArgumentError, "Unrecognzied json_parser: #{@json_parser.inspect}"
@@ -110,6 +139,12 @@ module RGeo
110
139
  # Encode the given object as GeoJSON. The object may be one of the
111
140
  # geometry objects specified in RGeo::Features, or an appropriate
112
141
  # GeoJSON wrapper entity supported by this coder's entity factory.
142
+ #
143
+ # This method returns a JSON object (i.e. a hash). In order to
144
+ # generate a string suitable for transmitting to a service, you
145
+ # will need to JSON-encode it. This is usually accomplished by
146
+ # calling <tt>to_json</tt> on the hash object, if you have the
147
+ # appropriate JSON library installed.
113
148
 
114
149
  def encode(object_)
115
150
  if @entity_factory.is_feature_collection?(object_)
@@ -78,10 +78,10 @@ module RGeo
78
78
  # sole argument and returning the JSON hash, or it may be one of
79
79
  # the special values <tt>:json</tt>, <tt>:yajl</tt>, or
80
80
  # <tt>:active_support</tt>. Setting one of those special values
81
- # will require the corresponding library to be available. The
82
- # default is <tt>:json</tt>, which is present in the standard
81
+ # will require the corresponding library to be available. Note
82
+ # that the <tt>:json</tt> library is present in the standard
83
83
  # library in Ruby 1.9, but requires the "json" gem in Ruby 1.8.
84
- # If the specified parser is not available, then decode will not
84
+ # If a parser is not specified, then the decode method will not
85
85
  # accept a String or IO object; it will require a Hash.
86
86
 
87
87
  def decode(input_, opts_={})
@@ -111,10 +111,10 @@ module RGeo
111
111
  # sole argument and returning the JSON hash, or it may be one of
112
112
  # the special values <tt>:json</tt>, <tt>:yajl</tt>, or
113
113
  # <tt>:active_support</tt>. Setting one of those special values
114
- # will require the corresponding library to be available. The
115
- # default is <tt>:json</tt>, which is present in the standard
114
+ # will require the corresponding library to be available. Note
115
+ # that the <tt>:json</tt> library is present in the standard
116
116
  # library in Ruby 1.9, but requires the "json" gem in Ruby 1.8.
117
- # If the specified parser is not available, then decode will not
117
+ # If a parser is not specified, then the decode method will not
118
118
  # accept a String or IO object; it will require a Hash.
119
119
 
120
120
  def coder(opts_={})
@@ -0,0 +1,60 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Shapefile processing for RGeo
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2010 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ # Parent file
38
+ require 'rgeo'
39
+
40
+
41
+ module RGeo
42
+
43
+
44
+ # This module contains an implementation of ESRI Shapefiles.
45
+ # Use the Shapefile::Reader class to read a shapefile, extracting
46
+ # geometry and attribute data from it.
47
+ # RGeo does not yet have support for writing shapefiles.
48
+
49
+ module Shapefile
50
+ end
51
+
52
+
53
+ end
54
+
55
+
56
+ # Dependency files
57
+ require 'rgeo/features'
58
+
59
+ # Implementation files
60
+ require 'rgeo/shapefile/reader'