rgeo 3.0.0.pre.rc.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/ext/geos_c_impl/factory.c +41 -5
  4. data/ext/geos_c_impl/factory.h +13 -2
  5. data/ext/geos_c_impl/geometry.c +151 -122
  6. data/ext/geos_c_impl/geometry_collection.c +17 -19
  7. data/ext/geos_c_impl/line_string.c +46 -36
  8. data/ext/geos_c_impl/point.c +0 -2
  9. data/ext/geos_c_impl/polygon.c +10 -11
  10. data/ext/geos_c_impl/polygon.h +1 -1
  11. data/ext/geos_c_impl/ruby_more.c +7 -0
  12. data/ext/geos_c_impl/ruby_more.h +8 -0
  13. data/lib/rgeo/cartesian/analysis.rb +5 -3
  14. data/lib/rgeo/cartesian/bounding_box.rb +74 -79
  15. data/lib/rgeo/cartesian/calculations.rb +20 -26
  16. data/lib/rgeo/cartesian/factory.rb +47 -49
  17. data/lib/rgeo/cartesian/planar_graph.rb +10 -16
  18. data/lib/rgeo/cartesian/sweepline_intersector.rb +1 -3
  19. data/lib/rgeo/cartesian/valid_op.rb +1 -3
  20. data/lib/rgeo/coord_sys/cs/entities.rb +87 -101
  21. data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
  22. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +70 -29
  23. data/lib/rgeo/feature/curve.rb +0 -1
  24. data/lib/rgeo/feature/factory.rb +25 -27
  25. data/lib/rgeo/feature/factory_generator.rb +3 -4
  26. data/lib/rgeo/feature/geometry.rb +41 -30
  27. data/lib/rgeo/feature/geometry_collection.rb +3 -4
  28. data/lib/rgeo/feature/line_string.rb +1 -2
  29. data/lib/rgeo/feature/linear_ring.rb +0 -1
  30. data/lib/rgeo/feature/multi_curve.rb +0 -1
  31. data/lib/rgeo/feature/multi_surface.rb +0 -1
  32. data/lib/rgeo/feature/point.rb +0 -1
  33. data/lib/rgeo/feature/polygon.rb +1 -2
  34. data/lib/rgeo/feature/surface.rb +0 -1
  35. data/lib/rgeo/feature/types.rb +73 -83
  36. data/lib/rgeo/geographic/factory.rb +87 -80
  37. data/lib/rgeo/geographic/interface.rb +40 -23
  38. data/lib/rgeo/geographic/projected_feature_methods.rb +2 -6
  39. data/lib/rgeo/geographic/projected_window.rb +35 -21
  40. data/lib/rgeo/geographic/simple_mercator_projector.rb +25 -13
  41. data/lib/rgeo/geographic/spherical_feature_methods.rb +8 -3
  42. data/lib/rgeo/geographic/spherical_math.rb +17 -20
  43. data/lib/rgeo/geos/capi_factory.rb +50 -50
  44. data/lib/rgeo/geos/ffi_factory.rb +41 -42
  45. data/lib/rgeo/geos/ffi_feature_methods.rb +72 -97
  46. data/lib/rgeo/geos/interface.rb +16 -16
  47. data/lib/rgeo/geos/utils.rb +3 -3
  48. data/lib/rgeo/geos/zm_factory.rb +50 -42
  49. data/lib/rgeo/geos/zm_feature_methods.rb +15 -8
  50. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +4 -4
  51. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
  52. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +18 -24
  53. data/lib/rgeo/impl_helper/basic_point_methods.rb +1 -3
  54. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +15 -16
  55. data/lib/rgeo/impl_helper/utils.rb +3 -9
  56. data/lib/rgeo/impl_helper/valid_op.rb +12 -16
  57. data/lib/rgeo/version.rb +1 -1
  58. data/lib/rgeo/wkrep/wkb_generator.rb +42 -47
  59. data/lib/rgeo/wkrep/wkb_parser.rb +17 -18
  60. data/lib/rgeo/wkrep/wkt_generator.rb +23 -16
  61. data/lib/rgeo/wkrep/wkt_parser.rb +23 -13
  62. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91ca209240d93482556f0aaf2b1dcb3beca7710af47a3cba6b12014a09a8b3be
4
- data.tar.gz: b22b62247f1c4f3d07d4e7e4c1552999ae42d1d0d94808cc2fa7805e48914acd
3
+ metadata.gz: dc0fdafb5f2260dd8e4310275cdb5d07be71c7cdeb39c86d5aa6931a454df3cf
4
+ data.tar.gz: 1b47209e5205243eb568ed50eea430279c629a1c16cb290253de809dd3a99ee2
5
5
  SHA512:
6
- metadata.gz: 803a18e2ccb670da3db22c630bda86bb6ad80643c8a3e4e6bae448a1e3003632904bdf90b2d7642601857c01b92ffbf4a5e354fd292fb85033db7c0e19cd49b3
7
- data.tar.gz: 142ada28031864f3a2960605b504aa3daf222db98d190fc208589b31841f328cefb5192391594a6237b48d1aab907eae2250e63c12824ef65d22f6ca01546057
6
+ metadata.gz: 40a807a8aa741e30715c5b7dc1a487ae9682c149ff3c94b7f370190fbf804c1f11ac034c0f697a923b49cef3f763121224c1e1cef6eafc5b9721a1ba0f6d4344
7
+ data.tar.gz: 72bec2c1432b56a2bb5ea50809f0d15d157c5c1e30379e756fb089c4dcd62a455d66783036e2d742c33ae552fe0f3a2ef40e53b07a26c6ccab21a2489f4f9214
data/README.md CHANGED
@@ -74,6 +74,14 @@ If you are using proj.4 extensions, include
74
74
  gem "rgeo-proj4"
75
75
  ```
76
76
 
77
+ ### Upgrading to Version 3.0
78
+
79
+ See [doc/Upgrading-to-v3.md](doc/Upgrading-to-v3.md) for a checklist of changes to make before upgrading to RGeo 3.0.
80
+
81
+ For a brief overview of the changes, see [NEWS.md](NEWS.md).
82
+
83
+ For a comprehensive list of all changes, see [History.md](History.md).
84
+
77
85
 
78
86
  ### Extensions
79
87
 
@@ -130,6 +138,7 @@ Here's the current list of available topics:
130
138
  - [Factory Compatibility](https://github.com/rgeo/rgeo/blob/main/doc/Factory-Compatibility.md)
131
139
  - [Which factory should I use?](https://github.com/rgeo/rgeo/blob/main/doc/Which-factory-should-I-use.md)
132
140
  - [Geometry validity handling](https://github.com/rgeo/rgeo/blob/main/doc/Geometry-Validity.md)
141
+ - [Upgrading to Version 3](https://github.com/rgeo/rgeo/blob/main/doc/Upgrading-to-v3.md)
133
142
  - [Examples](https://github.com/rgeo/rgeo/blob/main/doc/Examples.md)
134
143
  - [Who uses `rgeo`?](https://github.com/rgeo/rgeo/blob/main/doc/Gallery.md)
135
144
 
@@ -820,7 +820,7 @@ rgeo_wrap_geos_geometry_clone(VALUE factory,
820
820
  }
821
821
 
822
822
  const GEOSGeometry*
823
- rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
823
+ rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type, int* state)
824
824
  {
825
825
  VALUE object;
826
826
 
@@ -831,10 +831,28 @@ rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
831
831
  object =
832
832
  rb_funcall(rgeo_feature_module, rb_intern("cast"), 3, obj, factory, type);
833
833
  }
834
- if (NIL_P(object))
834
+ if (NIL_P(object)) {
835
+ rb_protect(
836
+ rb_exc_raise_value,
837
+ rb_exc_new_cstr(rb_eRGeoInvalidGeometry,
838
+ "Unable to cast the geometry to the GEOS Factory"),
839
+ state);
840
+ }
841
+
842
+ if (*state) {
843
+ return NULL;
844
+ }
845
+
846
+ if (!rgeo_is_geos_object(object)) {
847
+ rb_protect(rb_exc_raise_value,
848
+ rb_exc_new_cstr(rb_eRGeoError, "Not a GEOS Geometry object."),
849
+ state);
850
+ }
851
+
852
+ if (*state) {
835
853
  return NULL;
854
+ }
836
855
 
837
- Check_TypedStruct(object, &rgeo_geometry_type);
838
856
  return RGEO_GEOMETRY_DATA_PTR(object)->geom;
839
857
  }
840
858
 
@@ -849,6 +867,7 @@ rgeo_convert_to_detached_geos_geometry(VALUE obj,
849
867
  GEOSGeometry* geom;
850
868
  RGeo_GeometryData* object_data;
851
869
  const GEOSPreparedGeometry* prep;
870
+
852
871
  if (klasses) {
853
872
  *klasses = Qnil;
854
873
  }
@@ -862,7 +881,24 @@ rgeo_convert_to_detached_geos_geometry(VALUE obj,
862
881
  type,
863
882
  ID2SYM(rb_intern("force_new")),
864
883
  ID2SYM(rb_intern("keep_subtype")));
865
- if (*state || NIL_P(object)) {
884
+
885
+ if (NIL_P(object)) {
886
+ rb_protect(
887
+ rb_exc_raise_value,
888
+ rb_exc_new_cstr(rb_eRGeoInvalidGeometry,
889
+ "Unable to cast the geometry to the GEOS Factory"),
890
+ state);
891
+ }
892
+ if (*state) {
893
+ return NULL;
894
+ }
895
+
896
+ if (!rgeo_is_geos_object(object)) {
897
+ rb_protect(rb_exc_raise_value,
898
+ rb_exc_new_cstr(rb_eRGeoError, "Not a GEOS Geometry object."),
899
+ state);
900
+ }
901
+ if (*state) {
866
902
  return NULL;
867
903
  }
868
904
 
@@ -1023,7 +1059,7 @@ rgeo_geos_coordseq_hash(const GEOSGeometry* geom, st_index_t hash)
1023
1059
  for (i = 0; i < len; ++i) {
1024
1060
  if (GEOSCoordSeq_getX(cs, i, &hash_struct.x)) {
1025
1061
  if (GEOSCoordSeq_getY(cs, i, &hash_struct.y)) {
1026
- if (!GEOSCoordSeq_getY(cs, i, &hash_struct.z)) {
1062
+ if (!GEOSCoordSeq_getZ(cs, i, &hash_struct.z)) {
1027
1063
  hash_struct.z = 0;
1028
1064
  }
1029
1065
  hash_struct.seed_hash = hash;
@@ -154,9 +154,18 @@ rgeo_wrap_geos_geometry_clone(VALUE factory,
154
154
  specified by an appropriate feature module. Passing Qnil for the type
155
155
  disables this auto-cast. The returned GEOS geometry is owned by rgeo,
156
156
  and you should not dispose it or take ownership of it yourself.
157
+
158
+ The state parameter is given to follow `rb_protect*` ruby methods: this
159
+ method calls `#cast`, and this call may raise. if it does raise, state
160
+ will be set to a non-zero value, and you'll have access to the error
161
+ in `rb_errinfo()`. IT IS THE CALLER'S RESPONSIBILITY TO PROPAGATE THE
162
+ ERROR. You could also discard the error with `rb_set_errinfo(Qnil)`,
163
+ this will just ignore the error altogether. The error can be raised
164
+ with `rb_jump_tag(state)` which is helpful if you need to free data
165
+ before you raise the error.
157
166
  */
158
167
  const GEOSGeometry*
159
- rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type);
168
+ rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type, int* state);
160
169
 
161
170
  /*
162
171
  Gets a GEOS geometry for a given ruby Geometry object. You must provide
@@ -179,7 +188,9 @@ rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type);
179
188
  will be set to a non-zero value, and you'll have access to the error
180
189
  in `rb_errinfo()`. IT IS THE CALLER'S RESPONSIBILITY TO PROPAGATE THE
181
190
  ERROR. You could also discard the error with `rb_set_errinfo(Qnil)`,
182
- this will just ignore the error altogether.
191
+ this will just ignore the error altogether. The error can be raised
192
+ with `rb_jump_tag(state)` which is helpful if you need to free data
193
+ before you raise the error.
183
194
  */
184
195
  GEOSGeometry*
185
196
  rgeo_convert_to_detached_geos_geometry(VALUE obj,
@@ -367,7 +367,6 @@ method_geometry_equals(VALUE self, VALUE rhs)
367
367
  RGeo_GeometryData* self_data;
368
368
  const GEOSGeometry* self_geom;
369
369
  const GEOSGeometry* rhs_geom;
370
- char val;
371
370
 
372
371
  // Shortcut when self and rhs are the same object.
373
372
  if (self == rhs) {
@@ -385,12 +384,7 @@ method_geometry_equals(VALUE self, VALUE rhs)
385
384
  if (GEOSisEmpty(self_geom) == 1 && GEOSisEmpty(rhs_geom) == 1) {
386
385
  result = Qtrue;
387
386
  } else {
388
- val = GEOSEquals(self_geom, rhs_geom);
389
- if (val == 0) {
390
- result = Qfalse;
391
- } else if (val == 1) {
392
- result = Qtrue;
393
- }
387
+ result = GEOSEquals(self_geom, rhs_geom) ? Qtrue : Qfalse;
394
388
  }
395
389
  }
396
390
  }
@@ -411,7 +405,7 @@ method_geometry_disjoint(VALUE self, VALUE rhs)
411
405
  RGeo_GeometryData* self_data;
412
406
  const GEOSGeometry* self_geom;
413
407
  const GEOSGeometry* rhs_geom;
414
- char val;
408
+ int state = 0;
415
409
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
416
410
  const GEOSPreparedGeometry* prep;
417
411
  #endif
@@ -420,21 +414,18 @@ method_geometry_disjoint(VALUE self, VALUE rhs)
420
414
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
421
415
  self_geom = self_data->geom;
422
416
  if (self_geom) {
423
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
424
- if (rhs_geom) {
417
+ rhs_geom =
418
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
419
+ if (state) {
420
+ rb_jump_tag(state);
421
+ }
425
422
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
426
- prep = rgeo_request_prepared_geometry(self_data);
427
- if (prep)
428
- val = GEOSPreparedDisjoint(prep, rhs_geom);
429
- else
423
+ prep = rgeo_request_prepared_geometry(self_data);
424
+ if (prep)
425
+ result = GEOSPreparedDisjoint(prep, rhs_geom) ? Qtrue : Qfalse;
426
+ else
430
427
  #endif
431
- val = GEOSDisjoint(self_geom, rhs_geom);
432
- if (val == 0) {
433
- result = Qfalse;
434
- } else if (val == 1) {
435
- result = Qtrue;
436
- }
437
- }
428
+ result = GEOSDisjoint(self_geom, rhs_geom) ? Qtrue : Qfalse;
438
429
  }
439
430
  return result;
440
431
  }
@@ -447,6 +438,7 @@ method_geometry_intersects(VALUE self, VALUE rhs)
447
438
  const GEOSGeometry* self_geom;
448
439
  const GEOSGeometry* rhs_geom;
449
440
  char val;
441
+ int state = 0;
450
442
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED1
451
443
  const GEOSPreparedGeometry* prep;
452
444
  #endif
@@ -455,20 +447,22 @@ method_geometry_intersects(VALUE self, VALUE rhs)
455
447
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
456
448
  self_geom = self_data->geom;
457
449
  if (self_geom) {
458
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
459
- if (rhs_geom) {
450
+ rhs_geom =
451
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
452
+ if (state) {
453
+ rb_jump_tag(state);
454
+ }
460
455
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED1
461
- prep = rgeo_request_prepared_geometry(self_data);
462
- if (prep)
463
- val = GEOSPreparedIntersects(prep, rhs_geom);
464
- else
456
+ prep = rgeo_request_prepared_geometry(self_data);
457
+ if (prep)
458
+ val = GEOSPreparedIntersects(prep, rhs_geom);
459
+ else
465
460
  #endif
466
- val = GEOSIntersects(self_geom, rhs_geom);
467
- if (val == 0) {
468
- result = Qfalse;
469
- } else if (val == 1) {
470
- result = Qtrue;
471
- }
461
+ val = GEOSIntersects(self_geom, rhs_geom);
462
+ if (val == 0) {
463
+ result = Qfalse;
464
+ } else if (val == 1) {
465
+ result = Qtrue;
472
466
  }
473
467
  }
474
468
  return result;
@@ -482,6 +476,7 @@ method_geometry_touches(VALUE self, VALUE rhs)
482
476
  const GEOSGeometry* self_geom;
483
477
  const GEOSGeometry* rhs_geom;
484
478
  char val;
479
+ int state = 0;
485
480
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
486
481
  const GEOSPreparedGeometry* prep;
487
482
  #endif
@@ -490,20 +485,22 @@ method_geometry_touches(VALUE self, VALUE rhs)
490
485
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
491
486
  self_geom = self_data->geom;
492
487
  if (self_geom) {
493
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
494
- if (rhs_geom) {
488
+ rhs_geom =
489
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
490
+ if (state) {
491
+ rb_jump_tag(state);
492
+ }
495
493
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
496
- prep = rgeo_request_prepared_geometry(self_data);
497
- if (prep)
498
- val = GEOSPreparedTouches(prep, rhs_geom);
499
- else
494
+ prep = rgeo_request_prepared_geometry(self_data);
495
+ if (prep)
496
+ val = GEOSPreparedTouches(prep, rhs_geom);
497
+ else
500
498
  #endif
501
- val = GEOSTouches(self_geom, rhs_geom);
502
- if (val == 0) {
503
- result = Qfalse;
504
- } else if (val == 1) {
505
- result = Qtrue;
506
- }
499
+ val = GEOSTouches(self_geom, rhs_geom);
500
+ if (val == 0) {
501
+ result = Qfalse;
502
+ } else if (val == 1) {
503
+ result = Qtrue;
507
504
  }
508
505
  }
509
506
  return result;
@@ -517,6 +514,7 @@ method_geometry_crosses(VALUE self, VALUE rhs)
517
514
  const GEOSGeometry* self_geom;
518
515
  const GEOSGeometry* rhs_geom;
519
516
  char val;
517
+ int state = 0;
520
518
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
521
519
  const GEOSPreparedGeometry* prep;
522
520
  #endif
@@ -525,20 +523,22 @@ method_geometry_crosses(VALUE self, VALUE rhs)
525
523
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
526
524
  self_geom = self_data->geom;
527
525
  if (self_geom) {
528
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
529
- if (rhs_geom) {
526
+ rhs_geom =
527
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
528
+ if (state) {
529
+ rb_jump_tag(state);
530
+ }
530
531
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
531
- prep = rgeo_request_prepared_geometry(self_data);
532
- if (prep)
533
- val = GEOSPreparedCrosses(prep, rhs_geom);
534
- else
532
+ prep = rgeo_request_prepared_geometry(self_data);
533
+ if (prep)
534
+ val = GEOSPreparedCrosses(prep, rhs_geom);
535
+ else
535
536
  #endif
536
- val = GEOSCrosses(self_geom, rhs_geom);
537
- if (val == 0) {
538
- result = Qfalse;
539
- } else if (val == 1) {
540
- result = Qtrue;
541
- }
537
+ val = GEOSCrosses(self_geom, rhs_geom);
538
+ if (val == 0) {
539
+ result = Qfalse;
540
+ } else if (val == 1) {
541
+ result = Qtrue;
542
542
  }
543
543
  }
544
544
  return result;
@@ -552,6 +552,7 @@ method_geometry_within(VALUE self, VALUE rhs)
552
552
  const GEOSGeometry* self_geom;
553
553
  const GEOSGeometry* rhs_geom;
554
554
  char val;
555
+ int state = 0;
555
556
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
556
557
  const GEOSPreparedGeometry* prep;
557
558
  #endif
@@ -560,20 +561,22 @@ method_geometry_within(VALUE self, VALUE rhs)
560
561
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
561
562
  self_geom = self_data->geom;
562
563
  if (self_geom) {
563
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
564
- if (rhs_geom) {
564
+ rhs_geom =
565
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
566
+ if (state) {
567
+ rb_jump_tag(state);
568
+ }
565
569
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
566
- prep = rgeo_request_prepared_geometry(self_data);
567
- if (prep)
568
- val = GEOSPreparedWithin(prep, rhs_geom);
569
- else
570
+ prep = rgeo_request_prepared_geometry(self_data);
571
+ if (prep)
572
+ val = GEOSPreparedWithin(prep, rhs_geom);
573
+ else
570
574
  #endif
571
- val = GEOSWithin(self_geom, rhs_geom);
572
- if (val == 0) {
573
- result = Qfalse;
574
- } else if (val == 1) {
575
- result = Qtrue;
576
- }
575
+ val = GEOSWithin(self_geom, rhs_geom);
576
+ if (val == 0) {
577
+ result = Qfalse;
578
+ } else if (val == 1) {
579
+ result = Qtrue;
577
580
  }
578
581
  }
579
582
  return result;
@@ -587,6 +590,7 @@ method_geometry_contains(VALUE self, VALUE rhs)
587
590
  const GEOSGeometry* self_geom;
588
591
  const GEOSGeometry* rhs_geom;
589
592
  char val;
593
+ int state = 0;
590
594
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED1
591
595
  const GEOSPreparedGeometry* prep;
592
596
  #endif
@@ -595,20 +599,22 @@ method_geometry_contains(VALUE self, VALUE rhs)
595
599
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
596
600
  self_geom = self_data->geom;
597
601
  if (self_geom) {
598
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
599
- if (rhs_geom) {
602
+ rhs_geom =
603
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
604
+ if (state) {
605
+ rb_jump_tag(state);
606
+ }
600
607
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED1
601
- prep = rgeo_request_prepared_geometry(self_data);
602
- if (prep)
603
- val = GEOSPreparedContains(prep, rhs_geom);
604
- else
608
+ prep = rgeo_request_prepared_geometry(self_data);
609
+ if (prep)
610
+ val = GEOSPreparedContains(prep, rhs_geom);
611
+ else
605
612
  #endif
606
- val = GEOSContains(self_geom, rhs_geom);
607
- if (val == 0) {
608
- result = Qfalse;
609
- } else if (val == 1) {
610
- result = Qtrue;
611
- }
613
+ val = GEOSContains(self_geom, rhs_geom);
614
+ if (val == 0) {
615
+ result = Qfalse;
616
+ } else if (val == 1) {
617
+ result = Qtrue;
612
618
  }
613
619
  }
614
620
  return result;
@@ -622,6 +628,7 @@ method_geometry_overlaps(VALUE self, VALUE rhs)
622
628
  const GEOSGeometry* self_geom;
623
629
  const GEOSGeometry* rhs_geom;
624
630
  char val;
631
+ int state = 0;
625
632
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
626
633
  const GEOSPreparedGeometry* prep;
627
634
  #endif
@@ -630,20 +637,22 @@ method_geometry_overlaps(VALUE self, VALUE rhs)
630
637
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
631
638
  self_geom = self_data->geom;
632
639
  if (self_geom) {
633
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
634
- if (rhs_geom) {
640
+ rhs_geom =
641
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
642
+ if (state) {
643
+ rb_jump_tag(state);
644
+ }
635
645
  #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
636
- prep = rgeo_request_prepared_geometry(self_data);
637
- if (prep)
638
- val = GEOSPreparedOverlaps(prep, rhs_geom);
639
- else
646
+ prep = rgeo_request_prepared_geometry(self_data);
647
+ if (prep)
648
+ val = GEOSPreparedOverlaps(prep, rhs_geom);
649
+ else
640
650
  #endif
641
- val = GEOSOverlaps(self_geom, rhs_geom);
642
- if (val == 0) {
643
- result = Qfalse;
644
- } else if (val == 1) {
645
- result = Qtrue;
646
- }
651
+ val = GEOSOverlaps(self_geom, rhs_geom);
652
+ if (val == 0) {
653
+ result = Qfalse;
654
+ } else if (val == 1) {
655
+ result = Qtrue;
647
656
  }
648
657
  }
649
658
  return result;
@@ -657,19 +666,23 @@ method_geometry_relate(VALUE self, VALUE rhs, VALUE pattern)
657
666
  const GEOSGeometry* self_geom;
658
667
  const GEOSGeometry* rhs_geom;
659
668
  char val;
669
+ int state = 0;
660
670
 
661
671
  result = Qnil;
662
672
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
663
673
  self_geom = self_data->geom;
664
674
  if (self_geom) {
665
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
666
- if (rhs_geom) {
667
- val = GEOSRelatePattern(self_geom, rhs_geom, StringValuePtr(pattern));
668
- if (val == 0) {
669
- result = Qfalse;
670
- } else if (val == 1) {
671
- result = Qtrue;
672
- }
675
+ rhs_geom =
676
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
677
+ if (state) {
678
+ rb_jump_tag(state);
679
+ }
680
+
681
+ val = GEOSRelatePattern(self_geom, rhs_geom, StringValuePtr(pattern));
682
+ if (val == 0) {
683
+ result = Qfalse;
684
+ } else if (val == 1) {
685
+ result = Qtrue;
673
686
  }
674
687
  }
675
688
  return result;
@@ -683,16 +696,20 @@ method_geometry_distance(VALUE self, VALUE rhs)
683
696
  const GEOSGeometry* self_geom;
684
697
  const GEOSGeometry* rhs_geom;
685
698
  double dist;
699
+ int state = 0;
686
700
 
687
701
  result = Qnil;
688
702
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
689
703
  self_geom = self_data->geom;
690
704
  if (self_geom) {
691
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
692
- if (rhs_geom) {
693
- if (GEOSDistance(self_geom, rhs_geom, &dist)) {
694
- result = rb_float_new(dist);
695
- }
705
+ rhs_geom =
706
+ rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil, &state);
707
+ if (state) {
708
+ rb_jump_tag(state);
709
+ }
710
+
711
+ if (GEOSDistance(self_geom, rhs_geom, &dist)) {
712
+ result = rb_float_new(dist);
696
713
  }
697
714
  }
698
715
  return result;
@@ -816,17 +833,20 @@ method_geometry_intersection(VALUE self, VALUE rhs)
816
833
  const GEOSGeometry* self_geom;
817
834
  VALUE factory;
818
835
  const GEOSGeometry* rhs_geom;
836
+ int state = 0;
819
837
 
820
838
  result = Qnil;
821
839
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
822
840
  self_geom = self_data->geom;
823
841
  if (self_geom) {
824
842
  factory = self_data->factory;
825
- rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
826
- if (rhs_geom) {
827
- result = rgeo_wrap_geos_geometry(
828
- factory, GEOSIntersection(self_geom, rhs_geom), Qnil);
843
+ rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil, &state);
844
+ if (state) {
845
+ rb_jump_tag(state);
829
846
  }
847
+
848
+ result = rgeo_wrap_geos_geometry(
849
+ factory, GEOSIntersection(self_geom, rhs_geom), Qnil);
830
850
  }
831
851
  return result;
832
852
  }
@@ -839,17 +859,20 @@ method_geometry_union(VALUE self, VALUE rhs)
839
859
  const GEOSGeometry* self_geom;
840
860
  VALUE factory;
841
861
  const GEOSGeometry* rhs_geom;
862
+ int state = 0;
842
863
 
843
864
  result = Qnil;
844
865
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
845
866
  self_geom = self_data->geom;
846
867
  if (self_geom) {
847
868
  factory = self_data->factory;
848
- rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
849
- if (rhs_geom) {
850
- result =
851
- rgeo_wrap_geos_geometry(factory, GEOSUnion(self_geom, rhs_geom), Qnil);
869
+ rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil, &state);
870
+ if (state) {
871
+ rb_jump_tag(state);
852
872
  }
873
+
874
+ result =
875
+ rgeo_wrap_geos_geometry(factory, GEOSUnion(self_geom, rhs_geom), Qnil);
853
876
  }
854
877
  return result;
855
878
  }
@@ -880,17 +903,20 @@ method_geometry_difference(VALUE self, VALUE rhs)
880
903
  const GEOSGeometry* self_geom;
881
904
  VALUE factory;
882
905
  const GEOSGeometry* rhs_geom;
906
+ int state = 0;
883
907
 
884
908
  result = Qnil;
885
909
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
886
910
  self_geom = self_data->geom;
887
911
  if (self_geom) {
888
912
  factory = self_data->factory;
889
- rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
890
- if (rhs_geom) {
891
- result = rgeo_wrap_geos_geometry(
892
- factory, GEOSDifference(self_geom, rhs_geom), Qnil);
913
+ rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil, &state);
914
+ if (state) {
915
+ rb_jump_tag(state);
893
916
  }
917
+
918
+ result = rgeo_wrap_geos_geometry(
919
+ factory, GEOSDifference(self_geom, rhs_geom), Qnil);
894
920
  }
895
921
  return result;
896
922
  }
@@ -903,17 +929,20 @@ method_geometry_sym_difference(VALUE self, VALUE rhs)
903
929
  const GEOSGeometry* self_geom;
904
930
  VALUE factory;
905
931
  const GEOSGeometry* rhs_geom;
932
+ int state = 0;
906
933
 
907
934
  result = Qnil;
908
935
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
909
936
  self_geom = self_data->geom;
910
937
  if (self_geom) {
911
938
  factory = self_data->factory;
912
- rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
913
- if (rhs_geom) {
914
- result = rgeo_wrap_geos_geometry(
915
- factory, GEOSSymDifference(self_geom, rhs_geom), Qnil);
939
+ rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil, &state);
940
+ if (state) {
941
+ rb_jump_tag(state);
916
942
  }
943
+
944
+ result = rgeo_wrap_geos_geometry(
945
+ factory, GEOSSymDifference(self_geom, rhs_geom), Qnil);
917
946
  }
918
947
  return result;
919
948
  }
@@ -31,7 +31,6 @@ create_geometry_collection(VALUE module, int type, VALUE factory, VALUE array)
31
31
  VALUE result;
32
32
  unsigned int len;
33
33
  GEOSGeometry** geoms;
34
- RGeo_FactoryData* factory_data;
35
34
  VALUE klass;
36
35
  unsigned int i;
37
36
  unsigned int j;
@@ -49,7 +48,6 @@ create_geometry_collection(VALUE module, int type, VALUE factory, VALUE array)
49
48
  rb_raise(rb_eRGeoError, "not enough memory available");
50
49
  }
51
50
 
52
- factory_data = RGEO_FACTORY_DATA_PTR(factory);
53
51
  klasses = Qnil;
54
52
  cast_type = Qnil;
55
53
  switch (type) {
@@ -66,9 +64,14 @@ create_geometry_collection(VALUE module, int type, VALUE factory, VALUE array)
66
64
  for (i = 0; i < len; ++i) {
67
65
  geom = rgeo_convert_to_detached_geos_geometry(
68
66
  rb_ary_entry(array, i), factory, cast_type, &klass, &state);
69
- if (state || !geom) {
70
- break;
67
+ if (state) {
68
+ for (j = 0; j < i; j++) {
69
+ GEOSGeom_destroy(geoms[j]);
70
+ }
71
+ FREE(geoms);
72
+ rb_jump_tag(state);
71
73
  }
74
+
72
75
  geoms[i] = geom;
73
76
  if (!NIL_P(klass) && NIL_P(klasses)) {
74
77
  klasses = rb_ary_new2(len);
@@ -80,24 +83,19 @@ create_geometry_collection(VALUE module, int type, VALUE factory, VALUE array)
80
83
  rb_ary_push(klasses, klass);
81
84
  }
82
85
  }
83
- if (i != len) {
84
- for (j = 0; j < i; ++j) {
85
- GEOSGeom_destroy(geoms[j]);
86
- }
87
- } else {
88
- collection = GEOSGeom_createCollection(type, geoms, len);
89
- if (collection) {
90
- result = rgeo_wrap_geos_geometry(factory, collection, module);
91
- RGEO_GEOMETRY_DATA_PTR(result)->klasses = klasses;
92
- }
93
- // NOTE: We are assuming that GEOS will do its own cleanup of the
94
- // element geometries if it fails to create the collection, so we
95
- // are not doing that ourselves. If that turns out not to be the
96
- // case, this will be a memory leak.
86
+ collection = GEOSGeom_createCollection(type, geoms, len);
87
+ if (collection) {
88
+ result = rgeo_wrap_geos_geometry(factory, collection, module);
89
+ RGEO_GEOMETRY_DATA_PTR(result)->klasses = klasses;
97
90
  }
91
+
92
+ // NOTE: We are assuming that GEOS will do its own cleanup of the
93
+ // element geometries if it fails to create the collection, so we
94
+ // are not doing that ourselves. If that turns out not to be the
95
+ // case, this will be a memory leak.
98
96
  FREE(geoms);
99
97
  if (state) {
100
- rb_exc_raise(rb_errinfo()); // raise $!
98
+ rb_jump_tag(state);
101
99
  }
102
100
 
103
101
  return result;