rgeo 2.0.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8472a195fa15704c94ed5074f539d815477b9d05e1354e4a47dcf7110235f5e
4
- data.tar.gz: 81914f85026703454776fd5816c25869a35ba00f77f6509dc815205d2f35b604
3
+ metadata.gz: 1e86885f1c2a19a3b89ea73784add4644f6cbfa6afb1cf73dc0f1dda22151923
4
+ data.tar.gz: 83690993b988a200dc689750e31f8aabdb78fc7aade2af339a068f5adb41b9a1
5
5
  SHA512:
6
- metadata.gz: 6a6e0a821118e84e0052585431df5af8956a9f89882ce3314eeca72ff386617859bbe52a857b7761b8f8d8bc644a60734b5197fe209b20dd0d9fc294121735af
7
- data.tar.gz: 2f68c55105f188e1f8c1b9c4bc1a5ae32e20b4dd630a3ade0038169a9d62fb3409cc85bad3c08bfb60bf0c73331f7c33192fb5c94622073974021e5b6447e9ae
6
+ metadata.gz: 733c109fc5858536ca56a18bac9d9ab78204365a1ea5cd2e4eb7f9d06eaf833cafb28907a547698954c5b5963be921b415b9e5cc881f7235d644be2619de482f
7
+ data.tar.gz: 7ab29b70bcfb8f7a58832271245a6a125861c5298db870a3ecad3ff2869aa56045fb42213b44609b44edcf7531349a205ef0e688773bab1f652508c66925730d
data/README.md ADDED
@@ -0,0 +1,160 @@
1
+ ## RGeo
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rgeo.svg)](http://badge.fury.io/rb/rgeo)
4
+ [![CI](https://github.com/rgeo/rgeo/workflows/CI/badge.svg)](https://github.com/rgeo/rgeo/actions?query=workflow%3ACI+branch%3Amaster+event%3Apush)
5
+
6
+ RGeo is a geospatial data library for Ruby.
7
+
8
+ :warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning:
9
+
10
+ This organization is looking for maintainers, see [this issue](https://github.com/rgeo/rgeo/issues/216) for more information.
11
+
12
+ :warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning::warning:
13
+
14
+ ### Summary
15
+
16
+ RGeo is a key component for writing location-aware applications in the Ruby
17
+ programming language. At its core is an implementation of the industry
18
+ standard OGC Simple Features Specification, which provides data
19
+ representations of geometric objects such as points, lines, and polygons,
20
+ along with a set of geometric analysis operations. This makes it ideal for
21
+ modeling geolocation data. It also supports a suite of optional add-on modules
22
+ that provide various geolocation-related services.
23
+
24
+ Use the core **rgeo** gem to:
25
+
26
+ * Represent spatial and geolocation data objects such as points, lines, and
27
+ polygons in your Ruby application.
28
+ * Perform standard spatial analysis operations such as finding
29
+ intersections, creating buffers, and computing lengths and areas.
30
+ * Correctly handle spherical geometry, and compute geographic projections
31
+ for map display and data analysis.
32
+ * Read and write location data in the WKT and WKB representations used by
33
+ spatial databases.
34
+
35
+
36
+ ### Dependencies
37
+
38
+ RGeo works with the following Ruby implementations:
39
+
40
+ * MRI Ruby 2.3.0 or later.
41
+ * Partial support for JRuby 9.0 or later. The FFI implementation of GEOS
42
+ is available (ffi-geos gem required) but CAPI is not.
43
+ * See earlier versions for support for older ruby versions.
44
+
45
+ Some features also require the following:
46
+
47
+ * GEOS 3.2 or later is highly recommended. (3.3.3 or later preferred.) Some
48
+ functions will not be available without it. This C/C++ library may be
49
+ available via your operating system's package manager (`sudo aptitude
50
+ install libgeos-dev` for debian based Linux distributions, `yum install geos geos-devel` for redhat based Linux distributions), or you can
51
+ download it from http://trac.osgeo.org/geos
52
+ * On some platforms, you should install the ffi-geos gem (version 1.2.0 or
53
+ later recommended.) JRuby requires this gem to link properly with Geos,
54
+ and Windows builds probably do as well.
55
+
56
+ ### Installation
57
+
58
+ Install the RGeo gem:
59
+
60
+ ```sh
61
+ gem install rgeo
62
+ ```
63
+
64
+ or include it in your Gemfile:
65
+
66
+ ```ruby
67
+ gem "rgeo"
68
+ ```
69
+
70
+ If you are using proj.4 extensions, include
71
+ [`rgeo-proj4`](https://github.com/rgeo/rgeo-proj4):
72
+
73
+ ```ruby
74
+ gem "rgeo-proj4"
75
+ ```
76
+
77
+
78
+ ### Extensions
79
+
80
+ The [RGeo organization](https://github.com/rgeo) provides several gems that extend RGeo:
81
+
82
+ #### [`rgeo-proj4`](https://github.com/rgeo/rgeo-proj4)
83
+
84
+ Proj4 extensions
85
+
86
+ #### [`rgeo-geojson`](https://github.com/rgeo/rgeo-geojson)
87
+
88
+ Read and write GeoJSON
89
+
90
+ #### [`rgeo-shapefile`](https://github.com/rgeo/rgeo-shapefile)
91
+
92
+ Read ESRI shapefiles
93
+
94
+ #### [`activerecord-postgis-adapter`](https://github.com/rgeo/activerecord-postgis-adapter)
95
+
96
+ ActiveRecord connection adapter for PostGIS, based on postgresql (pg gem)
97
+
98
+ #### [`activerecord-mysql2spatial-adapter`](https://github.com/rgeo/activerecord-mysql2spatial-adapter)
99
+
100
+ ActiveRecord connection adapter for MySQL Spatial Extensions, based on mysql2
101
+
102
+ #### [`activerecord-spatialite-adapter`](https://github.com/rgeo/activerecord-spatialite-adapter)
103
+
104
+ ActiveRecord connection adapter for SpatiaLite, based on sqlite3 (*not maintained)
105
+
106
+
107
+ ### Development and support
108
+
109
+ RDoc Documentation is available at https://www.rubydoc.info/gems/rgeo
110
+
111
+ Contributions are welcome. Please read the
112
+ [Contributing guidelines](https://github.com/rgeo/rgeo/blob/master/CONTRIBUTING.md).
113
+
114
+ Support may be available on the
115
+ [rgeo-users google group](https://groups.google.com/forum/#!forum/rgeo-users)
116
+ or on [Stack Overflow](https://stackoverflow.com/questions/tagged/rgeo).
117
+
118
+ ### Documentation
119
+
120
+ You can see more in-depth documentation in the `doc` folder. Factories and
121
+ methods are documented inline, you should consider checking
122
+ https://rubydoc.info/gems/rgeo with the version you are currently using. Or
123
+ generate documentation locally if you're working on RGeo: `yardoc server`.
124
+
125
+ Here's the current list of available topics:
126
+
127
+ - [An introduction to Spatial Programming With RGeo](https://github.com/rgeo/rgeo/blob/master/doc/An-Introduction-to-Spatial-Programming-With-RGeo.md)
128
+ - [Enable GEOS and Proj4 on Heroku](https://github.com/rgeo/rgeo/blob/master/doc/Enable-GEOS-and-Proj4-on-Heroku.md)
129
+ - [Installing GEOS](https://github.com/rgeo/rgeo/blob/master/doc/Installing-GEOS.md)
130
+ - [Factory Compatibility](https://github.com/rgeo/rgeo/blob/master/doc/Factory-Compatibility.md)
131
+ - [Which factory should I use?](https://github.com/rgeo/rgeo/blob/master/doc/Which-factory-should-I-use.md)
132
+ - [Examples](https://github.com/rgeo/rgeo/blob/master/doc/Examples.md)
133
+ - [Who uses `rgeo`?](https://github.com/rgeo/rgeo/blob/master/doc/Gallery.md)
134
+
135
+ You can see an exhaustive and up to date list at https://rubydoc.info/gems/rgeo/index.
136
+ ### Acknowledgments
137
+
138
+ [Daniel Azuma](http://www.daniel-azuma.com) created RGeo.
139
+ [Tee Parham](http://twitter.com/teeparham) is a former maintainer.
140
+ [Keith Doggett](http://www.github.com/keithdoggett), [Ulysse Buonomo](http://www.github.com/BuonOmo) are current maintainers.
141
+
142
+ Development is supported by:
143
+
144
+ - [Klaxit](https://www.github.com/klaxit)
145
+ - Goldfish Ads
146
+
147
+ RGeo calls the GEOS library to handle most Cartesian geometric calculations,
148
+ and the Proj4 library to handle projections and coordinate transformations.
149
+ These libraries are maintained by the Open Source Geospatial Foundation; more
150
+ information is available on [OSGeo's web site](http://www.osgeo.org).
151
+
152
+ JRuby support is made possible by the ffi-geos (and upcoming ffi-proj4) gems,
153
+ by [J Smith](https://github.com/dark-panda).
154
+
155
+
156
+ ### License
157
+
158
+ Copyright (c) Daniel Azuma, Tee Parham
159
+
160
+ [License](https://github.com/rgeo/rgeo/blob/master/LICENSE.txt)
@@ -0,0 +1,78 @@
1
+ /*
2
+ Analysis methos for GEOS wrapper
3
+ */
4
+
5
+ #include "preface.h"
6
+
7
+ #ifdef RGEO_GEOS_SUPPORTED
8
+
9
+ #include <ruby.h>
10
+ #include <geos_c.h>
11
+
12
+ #include "analysis.h"
13
+ #include "factory.h"
14
+ #include "errors.h"
15
+
16
+ RGEO_BEGIN_C
17
+
18
+ /*
19
+ * call-seq:
20
+ * RGeo::Geos::Analysis.ccw? -> true or false
21
+ *
22
+ * Checks direction for a ring, returns +true+ if counter-clockwise, +false+
23
+ * otherwise.
24
+ */
25
+ #ifdef RGEO_GEOS_SUPPORTS_ISCCW
26
+ VALUE rgeo_geos_analysis_ccw_p(VALUE self, VALUE ring)
27
+ {
28
+
29
+ const RGeo_GeometryData* ring_data;
30
+ const GEOSCoordSequence* coord_seq;
31
+ char is_ccw;
32
+
33
+ rgeo_check_geos_object(ring);
34
+
35
+ ring_data = RGEO_GEOMETRY_DATA_PTR(ring);
36
+
37
+ coord_seq = GEOSGeom_getCoordSeq_r(ring_data->geos_context, ring_data->geom);
38
+ if (!coord_seq) { rb_raise(geos_error, "Could not retrieve CoordSeq from given ring."); }
39
+ if (!GEOSCoordSeq_isCCW_r(ring_data->geos_context, coord_seq, &is_ccw)) {
40
+ rb_raise(geos_error, "Could not determine if the CoordSeq is CCW.");
41
+ }
42
+
43
+ return is_ccw ? Qtrue : Qfalse;
44
+ };
45
+ #endif // RGEO_GEOS_SUPPORTS_ISCCW
46
+
47
+
48
+ /**
49
+ * call-seq:
50
+ * RGeo::Geos::Analysis.ccw_supported? -> true or false
51
+ *
52
+ * Checks if the RGEO_GEOS_SUPPORTS_ISCCW macro is defined, returns +true+
53
+ * if it is, +false+ otherwise
54
+ */
55
+ VALUE rgeo_geos_analysis_supports_ccw(VALUE self)
56
+ {
57
+ #ifdef RGEO_GEOS_SUPPORTS_ISCCW
58
+ return Qtrue;
59
+ #else
60
+ return Qfalse;
61
+ #endif
62
+ }
63
+
64
+
65
+ void rgeo_init_geos_analysis(RGeo_Globals* globals)
66
+ {
67
+ VALUE geos_analysis_module;
68
+
69
+ geos_analysis_module = rb_define_module_under(globals->geos_module, "Analysis");
70
+ rb_define_singleton_method(geos_analysis_module, "ccw_supported?", rgeo_geos_analysis_supports_ccw, 0);
71
+ #ifdef RGEO_GEOS_SUPPORTS_ISCCW
72
+ rb_define_singleton_method(geos_analysis_module, "ccw?", rgeo_geos_analysis_ccw_p, 1);
73
+ #endif // RGEO_GEOS_SUPPORTS_ISCCW
74
+ }
75
+
76
+ RGEO_END_C
77
+
78
+ #endif
@@ -0,0 +1,42 @@
1
+ /*
2
+ Analysis methos for GEOS wrapper
3
+ */
4
+
5
+ #ifndef RGEO_GEOS_ANALYSIS_INCLUDED
6
+ #define RGEO_GEOS_ANALYSIS_INCLUDED
7
+
8
+ #include <ruby.h>
9
+
10
+ #ifdef RGEO_GEOS_SUPPORTED
11
+
12
+ #include "factory.h"
13
+
14
+ RGEO_BEGIN_C
15
+
16
+ /*
17
+ * call-seq:
18
+ * RGeo::Geos::Analysis.ccw? -> true or false
19
+ *
20
+ * Checks direction for a ring, returns +true+ if counter-clockwise, +false+
21
+ * otherwise.
22
+ */
23
+ #ifdef RGEO_GEOS_SUPPORTS_CCW
24
+ VALUE rgeo_geos_analysis_ccw_p(VALUE self, VALUE ring);
25
+ #endif // RGEO_GEOS_SUPPORTS_CCW
26
+
27
+ /**
28
+ * call-seq:
29
+ * RGeo::Geos::Analysis.ccw_supported? -> true or false
30
+ *
31
+ * Checks if the RGEO_GEOS_SUPPORTS_ISCCW macro is defined, returns +true+
32
+ * if it is, +false+ otherwise
33
+ */
34
+ VALUE rgeo_geos_analysis_supports_ccw(VALUE self);
35
+
36
+ void rgeo_init_geos_analysis(RGeo_Globals* globals);
37
+
38
+ RGEO_END_C
39
+
40
+ #endif // RGEO_GEOS_SUPPORTED
41
+
42
+ #endif // RGEO_GEOS_ANALYSIS_INCLUDED
@@ -0,0 +1,35 @@
1
+
2
+ #ifndef RGEO_GEOS_ERROS_INCLUDED
3
+ #define RGEO_GEOS_ERROS_INCLUDED
4
+
5
+ #include <ruby.h>
6
+
7
+ #include "preface.h"
8
+
9
+ #ifdef RGEO_GEOS_SUPPORTED
10
+
11
+ #include "errors.h"
12
+
13
+ RGEO_BEGIN_C
14
+
15
+ // Any error relative to RGeo.
16
+ VALUE rgeo_error;
17
+ // RGeo error specific to the GEOS implementation.
18
+ VALUE geos_error;
19
+
20
+
21
+ void rgeo_init_geos_errors() {
22
+ VALUE rgeo_module;
23
+ VALUE error_module;
24
+
25
+ rgeo_module = rb_define_module("RGeo");
26
+ error_module = rb_define_module_under(rgeo_module, "Error");
27
+ rgeo_error = rb_define_class_under(error_module, "RGeoError", rb_eRuntimeError);
28
+ geos_error = rb_define_class_under(error_module, "GeosError", rgeo_error);
29
+ }
30
+
31
+ RGEO_END_C
32
+
33
+ #endif // RGEO_GEOS_SUPPORTED
34
+
35
+ #endif // RGEO_GEOS_ERROS_INCLUDED
@@ -0,0 +1,22 @@
1
+
2
+ #ifndef RGEO_GEOS_ERROS_INCLUDED
3
+ #define RGEO_GEOS_ERROS_INCLUDED
4
+
5
+ #include <ruby.h>
6
+
7
+ #ifdef RGEO_GEOS_SUPPORTED
8
+
9
+ RGEO_BEGIN_C
10
+
11
+ // Any error relative to RGeo.
12
+ extern VALUE rgeo_error;
13
+ // RGeo error specific to the GEOS implementation.
14
+ extern VALUE geos_error;
15
+
16
+ void rgeo_init_geos_errors();
17
+
18
+ RGEO_END_C
19
+
20
+ #endif // RGEO_GEOS_SUPPORTED
21
+
22
+ #endif // RGEO_GEOS_ERROS_INCLUDED
@@ -31,6 +31,7 @@ else
31
31
  have_func("GEOSPreparedContains_r", "geos_c.h")
32
32
  have_func("GEOSPreparedDisjoint_r", "geos_c.h")
33
33
  have_func("GEOSUnaryUnion_r", "geos_c.h")
34
+ have_func("GEOSCoordSeq_isCCW_r", "geos_c.h")
34
35
  have_func("rb_memhash", "ruby.h")
35
36
  end
36
37
 
@@ -16,6 +16,7 @@
16
16
  #include "line_string.h"
17
17
  #include "polygon.h"
18
18
  #include "geometry_collection.h"
19
+ #include "errors.h"
19
20
 
20
21
  RGEO_BEGIN_C
21
22
 
@@ -576,10 +577,11 @@ RGeo_Globals* rgeo_init_geos_factory()
576
577
  VALUE wrapped_globals;
577
578
  VALUE feature_module;
578
579
 
580
+ rgeo_module = rb_define_module("RGeo");
581
+
579
582
  globals = ALLOC(RGeo_Globals);
580
583
 
581
584
  // Cache some modules so we don't have to look them up by name every time
582
- rgeo_module = rb_define_module("RGeo");
583
585
  feature_module = rb_define_module_under(rgeo_module, "Feature");
584
586
  globals->feature_module = feature_module;
585
587
  globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
@@ -831,6 +833,13 @@ char rgeo_is_geos_object(VALUE obj)
831
833
  return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? 1 : 0;
832
834
  }
833
835
 
836
+ void rgeo_check_geos_object(VALUE obj)
837
+ {
838
+ if (!rgeo_is_geos_object(obj)) {
839
+ rb_raise(rgeo_error, "Not a GEOS Geometry object.");
840
+ }
841
+ }
842
+
834
843
 
835
844
  const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
836
845
  {
@@ -10,7 +10,6 @@
10
10
 
11
11
  RGEO_BEGIN_C
12
12
 
13
-
14
13
  /*
15
14
  Per-interpreter globals.
16
15
  Most of these are cached references to commonly used classes, modules,
@@ -187,6 +186,11 @@ GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, V
187
186
  */
188
187
  char rgeo_is_geos_object(VALUE obj);
189
188
 
189
+ /*
190
+ Raises a rgeo error if the object is not a GEOS Geometry implementation.
191
+ */
192
+ void rgeo_check_geos_object(VALUE obj);
193
+
190
194
  /*
191
195
  Gets the underlying GEOS geometry for a given ruby object. Returns NULL
192
196
  if the given ruby object is not a GEOS geometry wrapper.
@@ -756,7 +756,9 @@ static VALUE method_geometry_buffer_with_style(VALUE self, VALUE distance, VALUE
756
756
  GEOSBufferWithStyle_r(self_data->geos_context, self_geom,
757
757
  rb_num2dbl(distance),
758
758
  RGEO_FACTORY_DATA_PTR(factory)->buffer_resolution,
759
- endCapStyle, joinStyle, mitreLimit),
759
+ rb_num2int(endCapStyle),
760
+ rb_num2int(joinStyle),
761
+ rb_num2dbl(mitreLimit)),
760
762
  Qnil);
761
763
  }
762
764
  return result;
@@ -1043,12 +1045,28 @@ static VALUE method_geometry_invalid_reason(VALUE self)
1043
1045
  self_geom = self_data->geom;
1044
1046
  if (self_geom) {
1045
1047
  str = GEOSisValidReason_r(self_data->geos_context, self_geom);
1046
- if (str) {
1047
- result = rb_str_new2(str);
1048
- }
1049
- else {
1050
- result = rb_str_new2("Exception");
1051
- }
1048
+ // Per documentation, a valid geometry should give an empty string.
1049
+ // However it seems not to be the case. Hence the comparison against
1050
+ // the string that is really given: `"Valid Geometry"`.
1051
+ // See https://github.com/libgeos/geos/issues/431.
1052
+ if (str) result = (str[0] == '\0' || !strcmp(str, "Valid Geometry")) ? Qnil : rb_str_new2(str);
1053
+ else result = rb_str_new2("Exception");
1054
+ GEOSFree_r(self_data->geos_context, str);
1055
+ }
1056
+ return result;
1057
+ }
1058
+
1059
+ static VALUE method_geometry_point_on_surface(VALUE self)
1060
+ {
1061
+ VALUE result;
1062
+ RGeo_GeometryData* self_data;
1063
+ const GEOSGeometry* self_geom;
1064
+
1065
+ result = Qnil;
1066
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
1067
+ self_geom = self_data->geom;
1068
+ if (self_geom) {
1069
+ result = rgeo_wrap_geos_geometry(self_data->factory, GEOSPointOnSurface_r(self_data->geos_context, self_geom), Qnil);
1052
1070
  }
1053
1071
  return result;
1054
1072
  }
@@ -1107,6 +1125,7 @@ void rgeo_init_geos_geometry(RGeo_Globals* globals)
1107
1125
  rb_define_method(geos_geometry_methods, "sym_difference", method_geometry_sym_difference, 1);
1108
1126
  rb_define_method(geos_geometry_methods, "valid?", method_geometry_is_valid, 0);
1109
1127
  rb_define_method(geos_geometry_methods, "invalid_reason", method_geometry_invalid_reason, 0);
1128
+ rb_define_method(geos_geometry_methods, "point_on_surface", method_geometry_point_on_surface, 0);
1110
1129
  }
1111
1130
 
1112
1131