rgeo 0.2.9 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/History.rdoc +11 -0
  2. data/README.rdoc +3 -3
  3. data/Spatial_Programming_With_RGeo.rdoc +19 -8
  4. data/Version +1 -1
  5. data/ext/geos_c_impl/factory.c +1 -0
  6. data/ext/geos_c_impl/factory.h +1 -0
  7. data/ext/geos_c_impl/geometry.c +4 -5
  8. data/ext/geos_c_impl/geometry_collection.c +15 -0
  9. data/ext/geos_c_impl/line_string.c +10 -0
  10. data/ext/geos_c_impl/point.c +2 -0
  11. data/ext/geos_c_impl/polygon.c +4 -0
  12. data/lib/rgeo/cartesian/feature_classes.rb +23 -17
  13. data/lib/rgeo/cartesian/feature_methods.rb +20 -1
  14. data/lib/rgeo/feature.rb +1 -0
  15. data/lib/rgeo/feature/curve.rb +1 -2
  16. data/lib/rgeo/feature/geometry_collection.rb +1 -1
  17. data/lib/rgeo/feature/line.rb +1 -1
  18. data/lib/rgeo/feature/line_string.rb +1 -2
  19. data/lib/rgeo/feature/linear_ring.rb +1 -2
  20. data/lib/rgeo/feature/mixins.rb +198 -0
  21. data/lib/rgeo/feature/multi_curve.rb +1 -2
  22. data/lib/rgeo/feature/multi_line_string.rb +1 -2
  23. data/lib/rgeo/feature/multi_point.rb +1 -2
  24. data/lib/rgeo/feature/multi_polygon.rb +1 -2
  25. data/lib/rgeo/feature/multi_surface.rb +1 -2
  26. data/lib/rgeo/feature/point.rb +1 -2
  27. data/lib/rgeo/feature/polygon.rb +1 -3
  28. data/lib/rgeo/feature/surface.rb +1 -2
  29. data/lib/rgeo/feature/types.rb +27 -0
  30. data/lib/rgeo/geographic/projected_feature_classes.rb +31 -4
  31. data/lib/rgeo/geographic/projected_feature_methods.rb +2 -1
  32. data/lib/rgeo/geographic/spherical_feature_classes.rb +30 -3
  33. data/lib/rgeo/geos.rb +22 -0
  34. data/lib/rgeo/geos/factory.rb +11 -5
  35. data/lib/rgeo/geos/ffi_classes.rb +655 -0
  36. data/lib/rgeo/geos/ffi_factory.rb +503 -0
  37. data/lib/rgeo/geos/impl_additions.rb +1 -1
  38. data/lib/rgeo/geos/interface.rb +63 -8
  39. data/lib/rgeo/geos/zm_factory.rb +10 -4
  40. data/test/common/geometry_collection_tests.rb +1 -3
  41. data/test/coord_sys/tc_ogc_cs.rb +13 -2
  42. data/test/coord_sys/tc_proj4_srs_data.rb +1 -1
  43. data/test/{geos → geos_capi}/tc_factory.rb +2 -2
  44. data/test/{geos → geos_capi}/tc_geometry_collection.rb +2 -2
  45. data/test/{geos → geos_capi}/tc_line_string.rb +2 -2
  46. data/test/{geos → geos_capi}/tc_misc.rb +6 -2
  47. data/test/{geos → geos_capi}/tc_multi_line_string.rb +2 -2
  48. data/test/{geos → geos_capi}/tc_multi_point.rb +2 -2
  49. data/test/{geos → geos_capi}/tc_multi_polygon.rb +2 -2
  50. data/test/{geos → geos_capi}/tc_parsing_unparsing.rb +2 -2
  51. data/test/{geos → geos_capi}/tc_point.rb +2 -2
  52. data/test/{geos → geos_capi}/tc_polygon.rb +2 -2
  53. data/test/{geos → geos_capi}/tc_zmfactory.rb +2 -2
  54. data/test/geos_ffi/tc_factory.rb +91 -0
  55. data/test/geos_ffi/tc_geometry_collection.rb +62 -0
  56. data/test/geos_ffi/tc_line_string.rb +62 -0
  57. data/test/geos_ffi/tc_misc.rb +69 -0
  58. data/test/geos_ffi/tc_multi_line_string.rb +62 -0
  59. data/test/geos_ffi/tc_multi_point.rb +62 -0
  60. data/test/geos_ffi/tc_multi_polygon.rb +64 -0
  61. data/test/geos_ffi/tc_parsing_unparsing.rb +81 -0
  62. data/test/geos_ffi/tc_point.rb +87 -0
  63. data/test/geos_ffi/tc_polygon.rb +86 -0
  64. data/test/geos_ffi/tc_zmfactory.rb +86 -0
  65. data/test/tc_mixins.rb +188 -0
  66. data/test/tc_types.rb +77 -0
  67. metadata +54 -25
data/History.rdoc CHANGED
@@ -1,3 +1,14 @@
1
+ === 0.3.0 / 2011-05-23
2
+
3
+ * RGeo can now use GEOS via the ffi-geos gem, in addition to RGeo's built-in C integration. The ffi-geos integration is experimental right now, since ffi-geos is still in early beta. In particular, I do not recommend using it in JRuby yet (as of JRuby 1.6.1), because an apparent JRuby bug (JRUBY-5813) causes intermittent segfaults. However, once the issue is resolved (soon, I hope, since I've already submitted a patch to the JRuby team), we should have GEOS functional on JRuby.
4
+ * It is now possible to add methods to geometry objects "globally". This was not possible previously because there is no global base class; however, there is now a mechanism to specify mixins that all implementations are expected to include.
5
+ * Added RGeo::Feature::Type.supertype and each_immediate_subtype.
6
+ * POSSIBLE INCOMPATIBLE CHANGE: Taking the boundary of a GEOS GeometryCollection now returns nil. It used to return an empty GeometryCollection, regardless of the contents of the original collection. GeometryCollection subclasses like MultiPoint, however, do have proper boundaries.
7
+ * Renamed the lenient_multi_polygon_assertions GEOS factory parameter to uses_lenient_multi_polygon_assertions. The older name will continue to work.
8
+ * The GEOS buffer_resolution and uses_lenient_multi_polygon_assertions options are now exposed via properties.
9
+ * The RGeo::Feature::Polygon module incorrectly included Enumerable. Fixed.
10
+ * Several of the implementations included some extraneous (and nonfunctional) methods because they included the wrong modules. Fixed.
11
+
1
12
  === 0.2.9 / 2011-04-25
2
13
 
3
14
  * INCOMPATIBLE CHANGE: mutator methods for the configurations of the WKRep parsers and generators have been removed. Create a new parser/generator if you need to change behavior.
data/README.rdoc CHANGED
@@ -46,8 +46,8 @@ RGeo is known to work with the following Ruby implementations:
46
46
  * Standard "MRI" Ruby 1.8.7 or later. (1.9.2 or later preferred.)
47
47
  * Rubinius 1.1 or later.
48
48
  * Partial support for JRuby 1.5 or later, but a bunch of features are
49
- missing because GEOS and Proj are not available from Java. We plan on
50
- integrating with JTS or possibly ffi-geos in the future.
49
+ missing or not yet stable because GEOS and Proj integration is not
50
+ yet stable in JRuby. This is high-priority ongoing work.
51
51
 
52
52
  Some features also require the following:
53
53
 
@@ -93,8 +93,8 @@ installation prefix directory using the "--with-proj-dir" option.
93
93
  The RGeo suite of tools is evolving rapidly. The current to-do list for
94
94
  the core library includes:
95
95
 
96
+ * Better JRuby support.
96
97
  * Ellipsoidal geography implementation, possibly utilizing geographiclib.
97
- * JRuby support via the JTS library, or possibly via ffi-geos.
98
98
  * Windows build support.
99
99
 
100
100
  Each of the current add-on modules also has its own feature roadmap, and
@@ -1,7 +1,7 @@
1
1
  = An Introduction to Spatial Programming With RGeo
2
2
 
3
3
  * by Daniel Azuma
4
- * version 0.3 (17 Feb 2011)
4
+ * version 0.4 (23 May 2011)
5
5
 
6
6
  == Introduction
7
7
 
@@ -38,7 +38,7 @@ Fortunately, a number of software libraries and organizations now exist to promo
38
38
 
39
39
  Visualization tools have advanced considerably in recent years. Mapping services such as {Google Maps}[http://maps.google.com/] and {Bing Maps}[http://www.bing.com/maps/] now have extensive API support for developing mapping applications. An open mapping service, {OpenStreetMap}[http://www.openstreetmap.org/], has also been launched and is gaining momentum. In addition, tools which let you serve your own map data, such as {OpenLayers}[http://openlayers.org/] and {PolyMaps}[http://polymaps.org/], have also appeared.
40
40
 
41
- Most major relational databases now support spatial extensions. The {MySQL}[http://mysql.com/] database provides basic spatial column support out of the box. Third-party add-on libraries exist for {Sqlite3}[http://www.sqlite.org/] and {PostgreSQL}[http://www.postgresql.org/] in the form of {SpatiaLite}[http://www.gaia-gis.it/spatialite/] and {PostGIS}[http://www.postgis.org/], respectively. Commercial databases such as Oracle and Microsoft SQL Server also provide facilities for storing and querying spatial data. Spatial features are also appearing in non-relational data stores. {MongoDB}[http://www.mongodb.org/] recently introduced geospatial indexing, {Solr}[http://lucene.apache.org/solr/] is expected to support spatial queries in the next release of its Lucene-based search engine, and {Sphinx}[http://sphinxsearch.com/] also provides limited spatial search capabilities.
41
+ Most major relational databases now support spatial extensions. The {MySQL}[http://mysql.com/] database provides basic spatial column support out of the box. Third-party add-on libraries exist for {Sqlite3}[http://www.sqlite.org/] and {PostgreSQL}[http://www.postgresql.org/] in the form of {SpatiaLite}[http://www.gaia-gis.it/spatialite/] and {PostGIS}[http://www.postgis.org/], respectively. Commercial databases such as Oracle and Microsoft SQL Server also provide facilities for storing and querying spatial data. Spatial features are also appearing in non-relational data stores. {MongoDB}[http://www.mongodb.org/] recently introduced geospatial indexing, {Solr}[http://lucene.apache.org/solr/] supports spatial queries in the latest release of its Lucene-based search engine, and {Sphinx}[http://sphinxsearch.com/] also provides limited spatial search capabilities.
42
42
 
43
43
  A variety of data services have also appeared. Geocoding, the process approximating a latitude/longitude coordinate from a street address, is now offered by most major mapping service vendors such as {Google}[http://code.google.com/apis/maps/documentation/geocoding/], {Microsoft}[http://www.microsoft.com/maps/developers/], and {Yahoo}[http://developer.yahoo.com/geo/placefinder/]. Place databases with geocoded business and major location listings are now also available from a variety of vendors. Several services, notably {SimpleGeo}[http://www.simplegeo.com/], have recently appeared for cloud-based storage and querying of custom location data.
44
44
 
@@ -48,9 +48,9 @@ Perhaps most important of all, however, are the organizations that have appeared
48
48
 
49
49
  === 1.3. Ruby Libraries and \RGeo
50
50
 
51
- Ruby developers have had access to a fair number of spatial tools, primarily integration libraries for external services. {Geokit}[http://geokit.rubyforge.org/] provides a common interface for querying geocoding services, and a basic ActiveRecord extension for simple spatial queries. {YM4R}[http://ym4r.rubyforge.org/] provides a simple interface for integrating the Google and Yahoo map visualization tools in a Ruby application. Finally, {GeoRuby}[http://georuby.rubyforge.org/] provides classes for basic spatial data types such as points, lines, and polygons, and the add-on library {spatial_adapter}[http://github.com/fragility/spatial_adapter] hacks a few of the popular ActiveRecord database adapters to support spatial columns in the database.
51
+ Ruby developers have had access to a fair number of spatial tools, primarily integration libraries for external services. {Geokit}[http://geokit.rubyforge.org/] and {Geocoder}[http://www.rubygeocoder.com/] provide a common interfaces for querying geocoding services, and basic ActiveRecord extensions for simple spatial queries. {YM4R}[http://ym4r.rubyforge.org/] provides a simple interface for integrating the Google and Yahoo map visualization tools in a Ruby application. Finally, {GeoRuby}[http://georuby.rubyforge.org/] provides classes for basic spatial data types such as points, lines, and polygons, and the add-on library {spatial_adapter}[http://github.com/fragility/spatial_adapter] hacks a few of the popular ActiveRecord database adapters to support spatial columns in the database.
52
52
 
53
- In this document, we will cover {RGeo}[http://github.com/dazuma/rgeo], a new spatial data library for Ruby that provides a complete and robust implementation of the standard OGC spatial data types and operations. It covers some of the same functionality as GeoRuby and spatial_adapter. However, where GeoRuby implements only a minimal subset of the OGC feature interfaces, \RGeo supports the entire specification, as well as providing many features and extensions not available with the older libraries.
53
+ In this document, we will cover {RGeo}[http://github.com/dazuma/rgeo], a recent spatial data library for Ruby that provides a complete and robust implementation of the standard OGC spatial data types and operations. It covers some of the same functionality as GeoRuby and spatial_adapter. However, where GeoRuby implements only a minimal subset of the OGC feature interfaces, \RGeo supports the entire specification, as well as providing many features and extensions not available with the older libraries.
54
54
 
55
55
  \RGeo comprises several libraries, distributed as gems: a core library, and a suite of optional add-on modules. The core library, distributed as the {rgeo}[http://github.com/dazuma/rgeo] gem, includes the spatial data implementation itself. Currently available add-on modules include {rgeo-geojson}[http://github.com/dazuma/rgeo-geojson], which reads and writes the {GeoJSON}[http://www.geojson.org/] format, and {rgeo-shapefile}[http://github.com/dazuma/rgeo-shapefile], which reads ESRI shapefiles. A number of ActiveRecord adapters also utilize \RGeo to communicate with spatial databases; these include {mysqlspatial}[http://github.com/dazuma/activerecord-mysqlspatial-adapter], {mysql2spatial}[http://github.com/dazuma/activerecord-mysql2spatial-adapter], {spatialite}[http://github.com/dazuma/activerecord-spatialite-adapter], and {postgis}[http://github.com/dazuma/activerecord-postgis-adapter].
56
56
 
@@ -62,7 +62,7 @@ This section will cover the standard types of spatial data used in geospatial ap
62
62
 
63
63
  The Open Geospatial Consortium (OGC) defines and publishes a specification entitled "{Geographic information -- Simple feature access}[http://www.opengeospatial.org/standards/sfa]", which defines, among other things, a set of spatial data types and operations that can be done on them. This standard, which we will refer to as the Simple Features Specification (SFS), defines the core types and interfaces used by most spatial applications and databases. Although more recent versions of the spec are now available, most current implementations, including \RGeo, follow version 1.1 of the SFS, and this is the specification we will cover here.
64
64
 
65
- A "feature" in the SFS is a geometric object in 2 or 3 dimensional space. These objects can be points, lines, curves, surfaces, and polygons-- in general, most 0, 1, or 2 dimensional objects are supported. Each of these objects is identified by coordinates (X, Y, and sometimes Z), and has an object-oriented interface associated with it, defining a set of operations that can be done. In \RGeo, these interfaces exist as modules in the RGeo::Feature namespace.
65
+ A "feature" in the SFS is a geometric object in 2 or 3 dimensional space. These objects can be points, lines, curves, surfaces, and polygons-- in general, most 0, 1, or 2 dimensional objects are supported. Each of these objects is identified by coordinates (X, Y, and sometimes Z), and has an object-oriented interface associated with it, defining a set of operations that can be performed. In \RGeo, these interfaces exist as modules in the RGeo::Feature namespace.
66
66
 
67
67
  We will quickly cover the types of geometric objects supported, and then discuss how to use \RGeo to create and manipulate spatial data as Ruby objects.
68
68
 
@@ -242,10 +242,10 @@ Several size and distance calculations are available. You can compute the distan
242
242
  The SFS defines two serialization schemes for geometric objects, known as the WKT (well-known text) and WKB (well-known binary) formats. The WKT is often used for textual display and transmission of a geometric object, while the WKB is sometimes used as an internal data format by spatial databases. Geometric objects in \RGeo define the <tt>as_text</tt> and <tt>as_binary</tt> methods to serialize the object into a data string, while \RGeo factories provide <tt>parse_wkt</tt> and <tt>parse_wkb</tt> methods to reconstruct geometric objects from their serialized form.
243
243
 
244
244
  p00 = factory.point(0, 0)
245
- p00.as_text # returns "Point (0.0 0.0)"
245
+ p00.as_text # returns "POINT (0.0 0.0)"
246
246
  p10 = factory.point(1, 0)
247
247
  line = factory.line(p00, p10)
248
- line.as_text # returns "LineString (0.0 0.0, 1.0 0.0)"
248
+ line.as_text # returns "LINESTRING (0.0 0.0, 1.0 0.0)"
249
249
  p = factory.parse_wkt('POINT (3 4)')
250
250
  p.x # returns 3.0
251
251
 
@@ -329,7 +329,7 @@ Under most circumstances, when you're working with geographic data in \RGeo, you
329
329
 
330
330
  === 4.5. Spatial Reference Systems and the EPSG Dataset
331
331
 
332
- The OGC also defines a syntax for specifying coordinate systems, the {Coordinate Transformation Services Specification}[http://www.opengeospatial.org/standards/ct]. This specification defines both an object model and a well-known text representation for coordinate systems and transformations. \RGeo also provides basic support for this specification; you can attach an OGC coordinate system specification to a factory to indicate the coordinate system. However, if you want \RGeo to automatically convert spatial data between coordinate systems, you must use Proj4 syntax.
332
+ The OGC also defines a syntax for specifying coordinate systems, the {Coordinate Transformation Services Specification}[http://www.opengeospatial.org/standards/ct]. This specification defines both an object model and a well-known text representation for coordinate systems and transformations. \RGeo also provides basic support for this specification; you can attach an OGC coordinate system specification to a factory to indicate the coordinate system. However, if you want \RGeo to convert spatial data between coordinate systems, you must use Proj4 syntax.
333
333
 
334
334
  Finally, there also exists a <i>de facto</i> standard database of coordinate systems and related parameters, published by EPSG (now the OGP Geomatics Committee). This is a set of coordinate systems, each tagged with a well-known ID number, including geographic and projected systems. You can browse this database, including both OGC and Proj4 representations, at http://www.spatialreference.org/. This database is also included as a table in many popular spatial databases including PostGIS and SpatiaLite. Typically, the EPSG number is used as the SRID identifying the coordinate system for geometric objects stored in the database.
335
335
 
@@ -411,6 +411,16 @@ PostGIS uses as its internal format a variant of WKB known as EWKB. This variant
411
411
  * *spatialite*: Subclasses the sqlite3 adapter and adds support for the SpatiaLite extension. Available as the <b>activerecord-spatialite-adapter</b> gem.
412
412
  * *postgis*: Subclasses the postgresql adapter and adds support for the PostGIS extension. Available as the <b>activerecord-postgis-adapter</b> gem.
413
413
 
414
+ === 5.6. Commercial SQL Databases and Non-SQL Databases
415
+
416
+ Major commercial relational databases also include various levels of support for the OGC SQL specification. Recent versions of the venerable Oracle database include {Oracle Spatial}[http://www.oracle.com/technetwork/database/options/spatial/index.html], and Microsoft's latest SQL Server also includes {spatial data tools}[http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx]. I have not had a chance to evaluate the spatial tools in these commercial databases, though I have heard them described as "powerful, but moody". \RGeo does not yet have direct ActiveRecord support for Oracle or SQL Server spatial.
417
+
418
+ Several "NoSQL" databases also provide various degrees of limited support for geospatial data. Because these databases intentionally eschew the SQL standard, there is no OGC-defined standard interface for these databases, and so you will need to study the individual database's documentation to get an idea of the capabilities and API. \RGeo does not yet provide direct integration support for non-relational databases, but in most cases, it should not be too difficult to write glue code yourself.
419
+
420
+ {MongoDB}[http://www.mongodb.org/] provides limited support for storing and indexing point data. In the current stable release series (1.8.x), you can store a point field as a longitude-latitude pair, and perform basic proximity and bounds searches. It does not support LineString or Polygon data. As far as I can determine, MongoDB uses a simple indexing system based on geo-hashing, which also limits its ability to support non-point data.
421
+
422
+ {GeoCouch}[http://github.com/couchbase/geocouch] is an addition to {CouchDB}[http://couchdb.apache.org/] that provides an r-tree-based spatial index for point data. I have not studied it much, but it also appears to be limited to point data.
423
+
414
424
  == 6. Location Service Integration
415
425
 
416
426
  When writing a location-aware application, you will often need to interact with external sources of data and external location-based services. \RGeo provides several tools to facilitate this data transfer.
@@ -438,3 +448,4 @@ At the time of this writing, a number of open source geospatial tools and librar
438
448
  * Version 0.1 / 5 Dec 2010: Initial draft
439
449
  * Version 0.2 / 7 Dec 2010: More code examples and other minor updates
440
450
  * Version 0.3 / 17 Feb 2011: Further minor clarifications and fixes, and coverage of features in newer \RGeo releases
451
+ * Version 0.4 / 23 May 2011: Minor updates to keep up with new releases
data/Version CHANGED
@@ -1 +1 @@
1
- 0.2.9
1
+ 0.3.0
@@ -246,6 +246,7 @@ RGeo_Globals* rgeo_init_geos_factory()
246
246
  VALUE rgeo_module = rb_define_module("RGeo");
247
247
  globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
248
248
  globals->feature_module = rb_define_module_under(rgeo_module, "Feature");
249
+ globals->global_mixins = rb_const_get_at(rb_const_get_at(globals->feature_module, rb_intern("MixinCollection")), rb_intern("GLOBAL"));
249
250
 
250
251
  // Add C methods to the factory.
251
252
  VALUE geos_factory_class = rb_const_get_at(globals->geos_module, rb_intern("Factory"));
@@ -51,6 +51,7 @@ RGEO_BEGIN_C
51
51
  */
52
52
  typedef struct {
53
53
  VALUE feature_module;
54
+ VALUE global_mixins;
54
55
  VALUE feature_geometry;
55
56
  VALUE feature_point;
56
57
  VALUE feature_line_string;
@@ -191,12 +191,9 @@ static VALUE method_geometry_boundary(VALUE self)
191
191
  if (self_geom) {
192
192
  GEOSContextHandle_t geos_context = self_data->geos_context;
193
193
  GEOSGeometry* boundary = GEOSBoundary_r(geos_context, self_geom);
194
- // GEOS returns NULL for the boundary of an empty collection.
195
- // Replace that with an empty collection.
196
- if (!boundary) {
197
- boundary = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
194
+ if (boundary) {
195
+ result = rgeo_wrap_geos_geometry(self_data->factory, boundary, Qnil);
198
196
  }
199
- result = rgeo_wrap_geos_geometry(self_data->factory, boundary, Qnil);
200
197
  }
201
198
  return result;
202
199
  }
@@ -655,6 +652,8 @@ void rgeo_init_geos_geometry(RGeo_Globals* globals)
655
652
  VALUE geos_geometry_class = rb_define_class_under(globals->geos_module, "GeometryImpl", rb_cObject);
656
653
  globals->geos_geometry = geos_geometry_class;
657
654
  globals->feature_geometry = rb_const_get_at(globals->feature_module, rb_intern("Geometry"));
655
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
656
+ globals->feature_geometry, geos_geometry_class);
658
657
 
659
658
  rb_define_alloc_func(geos_geometry_class, alloc_geometry);
660
659
  rb_define_method(geos_geometry_class, "_set_factory", method_geometry_set_factory, 1);
@@ -390,15 +390,30 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
390
390
  VALUE geos_geometry_collection_class = rb_define_class_under(globals->geos_module, "GeometryCollectionImpl", globals->geos_geometry);
391
391
  globals->geos_geometry_collection = geos_geometry_collection_class;
392
392
  globals->feature_geometry_collection = rb_const_get_at(globals->feature_module, rb_intern("GeometryCollection"));
393
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
394
+ globals->feature_geometry_collection, geos_geometry_collection_class);
395
+
393
396
  VALUE geos_multi_point_class = rb_define_class_under(globals->geos_module, "MultiPointImpl", geos_geometry_collection_class);
394
397
  globals->geos_multi_point = geos_multi_point_class;
395
398
  globals->feature_multi_point = rb_const_get_at(globals->feature_module, rb_intern("MultiPoint"));
399
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
400
+ globals->feature_multi_point, geos_multi_point_class);
401
+
396
402
  VALUE geos_multi_line_string_class = rb_define_class_under(globals->geos_module, "MultiLineStringImpl", geos_geometry_collection_class);
397
403
  globals->geos_multi_line_string = geos_multi_line_string_class;
398
404
  globals->feature_multi_line_string = rb_const_get_at(globals->feature_module, rb_intern("MultiLineString"));
405
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
406
+ rb_const_get_at(globals->feature_module, rb_intern("MultiCurve")), geos_multi_line_string_class);
407
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
408
+ globals->feature_multi_line_string, geos_multi_line_string_class);
409
+
399
410
  VALUE geos_multi_polygon_class = rb_define_class_under(globals->geos_module, "MultiPolygonImpl", geos_geometry_collection_class);
400
411
  globals->geos_multi_polygon = geos_multi_polygon_class;
401
412
  globals->feature_multi_polygon = rb_const_get_at(globals->feature_module, rb_intern("MultiPolygon"));
413
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
414
+ rb_const_get_at(globals->feature_module, rb_intern("MultiSurface")), geos_multi_polygon_class);
415
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
416
+ globals->feature_multi_polygon, geos_multi_polygon_class);
402
417
 
403
418
  // Methods for GeometryCollectionImpl
404
419
  rb_define_module_function(geos_geometry_collection_class, "create", cmethod_geometry_collection_create, 2);
@@ -447,12 +447,22 @@ void rgeo_init_geos_line_string(RGeo_Globals* globals)
447
447
  VALUE geos_line_string_class = rb_define_class_under(globals->geos_module, "LineStringImpl", globals->geos_geometry);
448
448
  globals->geos_line_string = geos_line_string_class;
449
449
  globals->feature_line_string = rb_const_get_at(globals->feature_module, rb_intern("LineString"));
450
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
451
+ rb_const_get_at(globals->feature_module, rb_intern("Curve")), geos_line_string_class);
452
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
453
+ globals->feature_line_string, geos_line_string_class);
454
+
450
455
  VALUE geos_linear_ring_class = rb_define_class_under(globals->geos_module, "LinearRingImpl", geos_line_string_class);
451
456
  globals->geos_linear_ring = geos_linear_ring_class;
452
457
  globals->feature_linear_ring = rb_const_get_at(globals->feature_module, rb_intern("LinearRing"));
458
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
459
+ globals->feature_linear_ring, geos_linear_ring_class);
460
+
453
461
  VALUE geos_line_class = rb_define_class_under(globals->geos_module, "LineImpl", geos_line_string_class);
454
462
  globals->geos_line = geos_line_class;
455
463
  globals->feature_line = rb_const_get_at(globals->feature_module, rb_intern("Line"));
464
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
465
+ globals->feature_line, geos_line_class);
456
466
 
457
467
  rb_define_module_function(geos_line_string_class, "create", cmethod_create_line_string, 2);
458
468
  rb_define_module_function(geos_line_string_class, "_copy_from", cmethod_line_string_copy_from, 2);
@@ -154,6 +154,8 @@ void rgeo_init_geos_point(RGeo_Globals* globals)
154
154
  VALUE geos_point_class = rb_define_class_under(globals->geos_module, "PointImpl", globals->geos_geometry);
155
155
  globals->geos_point = geos_point_class;
156
156
  globals->feature_point = rb_const_get_at(globals->feature_module, rb_intern("Point"));
157
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
158
+ globals->feature_point, geos_point_class);
157
159
 
158
160
  rb_define_module_function(geos_point_class, "create", cmethod_create, 4);
159
161
 
@@ -223,6 +223,10 @@ void rgeo_init_geos_polygon(RGeo_Globals* globals)
223
223
  VALUE geos_polygon_class = rb_define_class_under(globals->geos_module, "PolygonImpl", globals->geos_geometry);
224
224
  globals->geos_polygon = geos_polygon_class;
225
225
  globals->feature_polygon = rb_const_get_at(globals->feature_module, rb_intern("Polygon"));
226
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
227
+ rb_const_get_at(globals->feature_module, rb_intern("Surface")), geos_polygon_class);
228
+ rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
229
+ globals->feature_polygon, geos_polygon_class);
226
230
 
227
231
  rb_define_module_function(geos_polygon_class, "create", cmethod_create, 3);
228
232
 
@@ -1,6 +1,6 @@
1
1
  # -----------------------------------------------------------------------------
2
2
  #
3
- # Spherical geography feature classes
3
+ # Cartesian feature classes
4
4
  #
5
5
  # -----------------------------------------------------------------------------
6
6
  # Copyright 2010 Daniel Azuma
@@ -46,19 +46,9 @@ module RGeo
46
46
  include ::RGeo::ImplHelper::BasicGeometryMethods
47
47
  include ::RGeo::ImplHelper::BasicPointMethods
48
48
  include ::RGeo::Cartesian::GeometryMethods
49
+ include ::RGeo::Cartesian::PointMethods
49
50
 
50
-
51
- def distance(rhs_)
52
- rhs_ = ::RGeo::Feature.cast(rhs_, @factory)
53
- case rhs_
54
- when PointImpl
55
- dx_ = @x - rhs_.x
56
- dy_ = @y - rhs_.y
57
- ::Math.sqrt(dx_ * dx_ + dy_ * dy_)
58
- else
59
- super
60
- end
61
- end
51
+ Feature::MixinCollection::GLOBAL.for_type(Feature::Point).include_in_class(self, true)
62
52
 
63
53
 
64
54
  end
@@ -73,6 +63,8 @@ module RGeo
73
63
  include ::RGeo::Cartesian::GeometryMethods
74
64
  include ::RGeo::Cartesian::LineStringMethods
75
65
 
66
+ Feature::MixinCollection::GLOBAL.for_type(Feature::LineString).include_in_class(self, true)
67
+
76
68
 
77
69
  end
78
70
 
@@ -87,6 +79,8 @@ module RGeo
87
79
  include ::RGeo::Cartesian::GeometryMethods
88
80
  include ::RGeo::Cartesian::LineStringMethods
89
81
 
82
+ Feature::MixinCollection::GLOBAL.for_type(Feature::Line).include_in_class(self, true)
83
+
90
84
 
91
85
  end
92
86
 
@@ -94,13 +88,15 @@ module RGeo
94
88
  class LinearRingImpl # :nodoc:
95
89
 
96
90
 
97
- include ::RGeo::Feature::Line
91
+ include ::RGeo::Feature::LinearRing
98
92
  include ::RGeo::ImplHelper::BasicGeometryMethods
99
93
  include ::RGeo::ImplHelper::BasicLineStringMethods
100
94
  include ::RGeo::ImplHelper::BasicLinearRingMethods
101
95
  include ::RGeo::Cartesian::GeometryMethods
102
96
  include ::RGeo::Cartesian::LineStringMethods
103
97
 
98
+ Feature::MixinCollection::GLOBAL.for_type(Feature::LinearRing).include_in_class(self, true)
99
+
104
100
 
105
101
  end
106
102
 
@@ -113,6 +109,8 @@ module RGeo
113
109
  include ::RGeo::ImplHelper::BasicPolygonMethods
114
110
  include ::RGeo::Cartesian::GeometryMethods
115
111
 
112
+ Feature::MixinCollection::GLOBAL.for_type(Feature::Polygon).include_in_class(self, true)
113
+
116
114
 
117
115
  end
118
116
 
@@ -125,6 +123,8 @@ module RGeo
125
123
  include ::RGeo::ImplHelper::BasicGeometryCollectionMethods
126
124
  include ::RGeo::Cartesian::GeometryMethods
127
125
 
126
+ Feature::MixinCollection::GLOBAL.for_type(Feature::GeometryCollection).include_in_class(self, true)
127
+
128
128
 
129
129
  end
130
130
 
@@ -132,12 +132,14 @@ module RGeo
132
132
  class MultiPointImpl # :nodoc:
133
133
 
134
134
 
135
- include ::RGeo::Feature::GeometryCollection
135
+ include ::RGeo::Feature::MultiPoint
136
136
  include ::RGeo::ImplHelper::BasicGeometryMethods
137
137
  include ::RGeo::ImplHelper::BasicGeometryCollectionMethods
138
138
  include ::RGeo::ImplHelper::BasicMultiPointMethods
139
139
  include ::RGeo::Cartesian::GeometryMethods
140
140
 
141
+ Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPoint).include_in_class(self, true)
142
+
141
143
 
142
144
  end
143
145
 
@@ -145,12 +147,14 @@ module RGeo
145
147
  class MultiLineStringImpl # :nodoc:
146
148
 
147
149
 
148
- include ::RGeo::Feature::GeometryCollection
150
+ include ::RGeo::Feature::MultiLineString
149
151
  include ::RGeo::ImplHelper::BasicGeometryMethods
150
152
  include ::RGeo::ImplHelper::BasicGeometryCollectionMethods
151
153
  include ::RGeo::ImplHelper::BasicMultiLineStringMethods
152
154
  include ::RGeo::Cartesian::GeometryMethods
153
155
 
156
+ Feature::MixinCollection::GLOBAL.for_type(Feature::MultiLineString).include_in_class(self, true)
157
+
154
158
 
155
159
  end
156
160
 
@@ -158,12 +162,14 @@ module RGeo
158
162
  class MultiPolygonImpl # :nodoc:
159
163
 
160
164
 
161
- include ::RGeo::Feature::GeometryCollection
165
+ include ::RGeo::Feature::MultiPolygon
162
166
  include ::RGeo::ImplHelper::BasicGeometryMethods
163
167
  include ::RGeo::ImplHelper::BasicGeometryCollectionMethods
164
168
  include ::RGeo::ImplHelper::BasicMultiPolygonMethods
165
169
  include ::RGeo::Cartesian::GeometryMethods
166
170
 
171
+ Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPolygon).include_in_class(self, true)
172
+
167
173
 
168
174
  end
169
175
 
@@ -1,6 +1,6 @@
1
1
  # -----------------------------------------------------------------------------
2
2
  #
3
- # Spherical geometry common methods
3
+ # Cartesian common methods
4
4
  #
5
5
  # -----------------------------------------------------------------------------
6
6
  # Copyright 2010 Daniel Azuma
@@ -55,6 +55,25 @@ module RGeo
55
55
  end
56
56
 
57
57
 
58
+ module PointMethods # :nodoc:
59
+
60
+
61
+ def distance(rhs_)
62
+ rhs_ = ::RGeo::Feature.cast(rhs_, @factory)
63
+ case rhs_
64
+ when PointImpl
65
+ dx_ = @x - rhs_.x
66
+ dy_ = @y - rhs_.y
67
+ ::Math.sqrt(dx_ * dx_ + dy_ * dy_)
68
+ else
69
+ super
70
+ end
71
+ end
72
+
73
+
74
+ end
75
+
76
+
58
77
  module LineStringMethods # :nodoc:
59
78
 
60
79
 
data/lib/rgeo/feature.rb CHANGED
@@ -70,6 +70,7 @@ end
70
70
 
71
71
  # Implementation files
72
72
  require 'rgeo/feature/factory'
73
+ require 'rgeo/feature/mixins'
73
74
  require 'rgeo/feature/types'
74
75
  require 'rgeo/feature/geometry'
75
76
  require 'rgeo/feature/point'
@@ -74,9 +74,8 @@ module RGeo
74
74
 
75
75
  module Curve
76
76
 
77
- extend Type
78
-
79
77
  include Geometry
78
+ extend Type
80
79
 
81
80
 
82
81
  # === SFS 1.1 Description
@@ -62,9 +62,9 @@ module RGeo
62
62
 
63
63
  module GeometryCollection
64
64
 
65
+ include Geometry
65
66
  extend Type
66
67
 
67
- include Geometry
68
68
  include ::Enumerable
69
69
 
70
70
 
@@ -53,9 +53,9 @@ module RGeo
53
53
 
54
54
  module Line
55
55
 
56
- extend Type
57
56
 
58
57
  include LineString
58
+ extend Type
59
59
 
60
60
 
61
61
  end