rgeo 3.0.0.pre.rc.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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;