ffi-geos 2.3.1 → 2.5.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.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +2 -2
- data/.rbenv-vars +1 -0
- data/.rubocop-minitest.yml +40 -17
- data/.rubocop.yml +664 -120
- data/.rubocop_todo.yml +30 -19
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -0
- data/ffi-geos.gemspec +2 -2
- data/lib/ffi-geos/coordinate_sequence.rb +2 -1
- data/lib/ffi-geos/geojson_reader.rb +35 -0
- data/lib/ffi-geos/geojson_writer.rb +49 -0
- data/lib/ffi-geos/geometry.rb +101 -1
- data/lib/ffi-geos/geometry_collection.rb +1 -1
- data/lib/ffi-geos/line_string.rb +1 -1
- data/lib/ffi-geos/point.rb +9 -0
- data/lib/ffi-geos/polygon.rb +1 -1
- data/lib/ffi-geos/prepared_geometry.rb +20 -0
- data/lib/ffi-geos/version.rb +1 -1
- data/lib/ffi-geos/wkb_writer.rb +12 -0
- data/lib/ffi-geos.rb +156 -3
- data/test/coordinate_sequence_tests.rb +22 -4
- data/test/geojson_reader_tests.rb +174 -0
- data/test/geojson_writer_tests.rb +103 -0
- data/test/geometry/area_tests.rb +18 -0
- data/test/geometry/boundary_tests.rb +36 -0
- data/test/geometry/buffer_tests.rb +116 -0
- data/test/geometry/build_area_tests.rb +20 -0
- data/test/geometry/centroid_tests.rb +37 -0
- data/test/geometry/clip_by_rect_tests.rb +56 -0
- data/test/geometry/clone_tests.rb +29 -0
- data/test/geometry/concave_hull_of_polygons_tests.rb +28 -0
- data/test/geometry/concave_hull_tests.rb +38 -0
- data/test/geometry/convex_hull_tests.rb +26 -0
- data/test/geometry/coord_seq_tests.rb +27 -0
- data/test/geometry/delaunay_triangulation_tests.rb +82 -0
- data/test/geometry/densify_tests.rb +95 -0
- data/test/geometry/difference_tests.rb +108 -0
- data/test/geometry/dimensions_tests.rb +46 -0
- data/test/geometry/distance_tests.rb +29 -0
- data/test/geometry/dump_points_tests.rb +60 -0
- data/test/geometry/dup_tests.rb +29 -0
- data/test/geometry/empty_tests.rb +23 -0
- data/test/geometry/envelope_tests.rb +26 -0
- data/test/geometry/equal_identical_tests.rb +78 -0
- data/test/geometry/equal_tests.rb +62 -0
- data/test/geometry/exterior_ring_tests.rb +27 -0
- data/test/geometry/extract_unique_points_tests.rb +41 -0
- data/test/geometry/frecet_distance_tests.rb +24 -0
- data/test/geometry/get_geometry_n_tests.rb +21 -0
- data/test/geometry/hausdorff_distance_tests.rb +46 -0
- data/test/geometry/hilbert_code_tests.rb +45 -0
- data/test/geometry/interior_ring_n_tests.rb +64 -0
- data/test/geometry/interior_rings_tests.rb +36 -0
- data/test/geometry/interpolate_tests.rb +49 -0
- data/test/geometry/intersection_tests.rb +49 -0
- data/test/geometry/largest_empty_circle_tests.rb +26 -0
- data/test/geometry/length_tests.rb +18 -0
- data/test/geometry/line_merge_directed_tests.rb +28 -0
- data/test/geometry/line_merge_tests.rb +25 -0
- data/test/geometry/line_string_enumerator_tests.rb +20 -0
- data/test/geometry/line_substring_tests.rb +76 -0
- data/test/geometry/make_valid_tests.rb +27 -0
- data/test/geometry/maximum_inscribed_circle_tests.rb +21 -0
- data/test/geometry/minimum_bounding_circle_tests.rb +23 -0
- data/test/geometry/minimum_clearance_tests.rb +58 -0
- data/test/geometry/minimum_rotated_rectangle_tests.rb +28 -0
- data/test/geometry/minimum_width_tests.rb +26 -0
- data/test/geometry/misc_tests.rb +24 -0
- data/test/geometry/nearest_points_tests.rb +46 -0
- data/test/geometry/node_tests.rb +22 -0
- data/test/geometry/normalize_tests.rb +34 -0
- data/test/geometry/num_coordinates_tests.rb +39 -0
- data/test/geometry/num_goemetries_tests.rb +35 -0
- data/test/geometry/num_interior_rings_tests.rb +28 -0
- data/test/geometry/orient_polygons_tests.rb +101 -0
- data/test/geometry/point_on_surface_tests.rb +37 -0
- data/test/geometry/polygon_hull_simplify_tests.rb +55 -0
- data/test/geometry/polygonize_tests.rb +173 -0
- data/test/geometry/precision_tests.rb +42 -0
- data/test/geometry/project_tests.rb +56 -0
- data/test/geometry/relate_tests.rb +73 -0
- data/test/geometry/relationships_tests.rb +138 -0
- data/test/geometry/reverse_tests.rb +44 -0
- data/test/geometry/ring_tests.rb +18 -0
- data/test/geometry/shared_path_tests.rb +31 -0
- data/test/geometry/simple_tests.rb +18 -0
- data/test/geometry/simplify_tests.rb +21 -0
- data/test/geometry/snap_tests.rb +20 -0
- data/test/geometry/srid_copy_policy_tests.rb +94 -0
- data/test/geometry/start_and_end_point_tests.rb +24 -0
- data/test/geometry/sym_difference_tests.rb +114 -0
- data/test/geometry/topology_preserve_simplify_tests.rb +21 -0
- data/test/geometry/union_tests.rb +216 -0
- data/test/geometry/valid_tests.rb +56 -0
- data/test/geometry/voronoi_diagram_tests.rb +62 -0
- data/test/geometry_collection_tests.rb +14 -2
- data/test/interrupt_tests.rb +1 -1
- data/test/line_string_tests.rb +24 -3
- data/test/misc_tests.rb +1 -1
- data/test/point/has_m_tests.rb +43 -0
- data/test/point/x_y_z_m_tests.rb +51 -0
- data/test/point_tests.rb +25 -3
- data/test/polygon_tests.rb +14 -1
- data/test/prepared_geometry_tests.rb +31 -0
- data/test/strtree_tests.rb +11 -18
- data/test/test_helper.rb +2 -0
- data/test/tools_tests.rb +7 -0
- data/test/utils_tests.rb +14 -3
- data/test/wkb_reader_tests.rb +1 -0
- data/test/wkb_writer_tests.rb +46 -5
- data/test/wkt_reader_tests.rb +2 -0
- data/test/wkt_writer_tests.rb +20 -2
- metadata +160 -7
- data/test/geometry_tests.rb +0 -2096
data/lib/ffi-geos.rb
CHANGED
@@ -15,6 +15,10 @@ module Geos
|
|
15
15
|
File.join(GEOS_BASE, 'wkb_reader')
|
16
16
|
autoload :WkbWriter,
|
17
17
|
File.join(GEOS_BASE, 'wkb_writer')
|
18
|
+
autoload :GeoJSONReader,
|
19
|
+
File.join(GEOS_BASE, 'geojson_reader')
|
20
|
+
autoload :GeoJSONWriter,
|
21
|
+
File.join(GEOS_BASE, 'geojson_writer')
|
18
22
|
autoload :CoordinateSequence,
|
19
23
|
File.join(GEOS_BASE, 'coordinate_sequence')
|
20
24
|
autoload :Geometry,
|
@@ -50,7 +54,7 @@ module Geos
|
|
50
54
|
|
51
55
|
module FFIGeos
|
52
56
|
def self.search_paths
|
53
|
-
@search_paths ||=
|
57
|
+
@search_paths ||=
|
54
58
|
if ENV['GEOS_LIBRARY_PATH']
|
55
59
|
[ENV['GEOS_LIBRARY_PATH']]
|
56
60
|
elsif FFI::Platform::IS_WINDOWS
|
@@ -77,7 +81,7 @@ module Geos
|
|
77
81
|
end
|
78
82
|
|
79
83
|
def self.geos_library_path
|
80
|
-
@geos_library_path ||=
|
84
|
+
@geos_library_path ||=
|
81
85
|
# On MingW the libraries have version numbers
|
82
86
|
find_lib('{lib,}geos_c{,-?}')
|
83
87
|
end
|
@@ -104,6 +108,11 @@ module Geos
|
|
104
108
|
:ndr, 1 # Little Endian
|
105
109
|
])
|
106
110
|
|
111
|
+
Geos::Flavors = enum(:flavor, [
|
112
|
+
:extended, 1,
|
113
|
+
:iso, 2
|
114
|
+
])
|
115
|
+
|
107
116
|
Geos::BufferCapStyles = enum(:buffer_cap_style, [
|
108
117
|
:round, 1,
|
109
118
|
:flat, 2,
|
@@ -144,6 +153,11 @@ module Geos
|
|
144
153
|
:keep_collapsed, 1 << 1
|
145
154
|
])
|
146
155
|
|
156
|
+
Geos::PolygonHullSimplifyModes = enum(:polygon_hull_simplify_mode, [
|
157
|
+
:vertex_ratio, 1,
|
158
|
+
:area_ratio, 2
|
159
|
+
])
|
160
|
+
|
147
161
|
FFI_LAYOUT = {
|
148
162
|
#### Utility functions ####
|
149
163
|
|
@@ -430,6 +444,11 @@ module Geos
|
|
430
444
|
:pointer, :pointer, :pointer, :double, :int, :buffer_cap_style, :buffer_join_style, :double
|
431
445
|
],
|
432
446
|
|
447
|
+
GEOSDensify_r: [
|
448
|
+
# *geom, *handle, *geom, tolerence
|
449
|
+
:pointer, :pointer, :pointer, :double
|
450
|
+
],
|
451
|
+
|
433
452
|
# Deprecated in GEOS 3.3.0.
|
434
453
|
GEOSSingleSidedBuffer_r: [
|
435
454
|
# *geom, *handle, *geom, width, quad_segs, buffer_join_style, mitre_limit, is_left
|
@@ -446,6 +465,26 @@ module Geos
|
|
446
465
|
:pointer, :pointer, :pointer
|
447
466
|
],
|
448
467
|
|
468
|
+
GEOSConcaveHull_r: [
|
469
|
+
# *geom, *handle, *geom, ratio, allow_holes
|
470
|
+
:pointer, :pointer, :pointer, :double, :uint
|
471
|
+
],
|
472
|
+
|
473
|
+
GEOSConcaveHullByLength_r: [
|
474
|
+
# *geom, *handle, *geom, length, allow_holes
|
475
|
+
:pointer, :pointer, :pointer, :double, :uint
|
476
|
+
],
|
477
|
+
|
478
|
+
GEOSPolygonHullSimplify_r: [
|
479
|
+
# *geom, *handle, *geom, is_outer, vertex_num_fraction
|
480
|
+
:pointer, :pointer, :pointer, :uint, :double
|
481
|
+
],
|
482
|
+
|
483
|
+
GEOSPolygonHullSimplifyMode_r: [
|
484
|
+
# *geom, *handle, *geom, is_outer, parameter_mode, parameter
|
485
|
+
:pointer, :pointer, :pointer, :uint, :uint, :double
|
486
|
+
],
|
487
|
+
|
449
488
|
GEOSDifference_r: [
|
450
489
|
# *geom, *handle, *geom_a, *geom_b
|
451
490
|
:pointer, :pointer, :pointer, :pointer
|
@@ -486,6 +525,11 @@ module Geos
|
|
486
525
|
:pointer, :pointer, :pointer
|
487
526
|
],
|
488
527
|
|
528
|
+
GEOSDisjointSubsetUnion_r: [
|
529
|
+
# *geom, *handle, *geom
|
530
|
+
:pointer, :pointer, :pointer
|
531
|
+
],
|
532
|
+
|
489
533
|
GEOSUnaryUnion_r: [
|
490
534
|
# *geom, *handle, *geom
|
491
535
|
:pointer, :pointer, :pointer
|
@@ -522,6 +566,11 @@ module Geos
|
|
522
566
|
:pointer, :pointer, :pointer
|
523
567
|
],
|
524
568
|
|
569
|
+
GEOSHilbertCode_r: [
|
570
|
+
# int, *handler, *geom, *extent, level, *code
|
571
|
+
:int, :pointer, :pointer, :pointer, :uint, :pointer
|
572
|
+
],
|
573
|
+
|
525
574
|
GEOSMinimumBoundingCircle_r: [
|
526
575
|
# *geom, *handle, *geom, *double radius, **geom center
|
527
576
|
:pointer, :pointer, :pointer, :pointer, :pointer
|
@@ -537,6 +586,16 @@ module Geos
|
|
537
586
|
:pointer, :pointer, :pointer
|
538
587
|
],
|
539
588
|
|
589
|
+
GEOSLineMergeDirected_r: [
|
590
|
+
# *geom, *handle, *geom
|
591
|
+
:pointer, :pointer, :pointer
|
592
|
+
],
|
593
|
+
|
594
|
+
GEOSLineSubstring_r: [
|
595
|
+
# *geom, *handle, *geom, start_fraction, end_fraction
|
596
|
+
:pointer, :pointer, :pointer, :double, :double
|
597
|
+
],
|
598
|
+
|
540
599
|
GEOSGeom_getXMin_r: [
|
541
600
|
# 0 on exception, *handle, (double *) value
|
542
601
|
:int, :pointer, :pointer, :pointer
|
@@ -587,6 +646,11 @@ module Geos
|
|
587
646
|
:pointer, :pointer, :pointer, :double, :int
|
588
647
|
],
|
589
648
|
|
649
|
+
GEOSConstrainedDelaunayTriangulation_r: [
|
650
|
+
# *geom, *handle, *geom
|
651
|
+
:pointer, :pointer, :pointer
|
652
|
+
],
|
653
|
+
|
590
654
|
GEOSVoronoiDiagram_r: [
|
591
655
|
# *geom, *handle, *geom, *envelope, tolerance, only_edges
|
592
656
|
:pointer, :pointer, :pointer, :pointer, :double, :int
|
@@ -667,6 +731,11 @@ module Geos
|
|
667
731
|
:char, :pointer, :pointer, :pointer, :double
|
668
732
|
],
|
669
733
|
|
734
|
+
GEOSEqualsIdentical_r: [
|
735
|
+
# (2 on exception, 1 on true, 2 on false), *handle, *geom_a, *geom_b
|
736
|
+
:char, :pointer, :pointer, :pointer
|
737
|
+
],
|
738
|
+
|
670
739
|
GEOSisEmpty_r: [
|
671
740
|
# (2 on exception, 1 on true, 2 on false), *handle, *geom
|
672
741
|
:char, :pointer, :pointer
|
@@ -702,6 +771,11 @@ module Geos
|
|
702
771
|
:char, :pointer, :pointer
|
703
772
|
],
|
704
773
|
|
774
|
+
GEOSHasM_r: [
|
775
|
+
# (2 on exception, 1 on true, 2 on false), *handle, *geom
|
776
|
+
:char, :pointer, :pointer
|
777
|
+
],
|
778
|
+
|
705
779
|
GEOSisClosed_r: [
|
706
780
|
# (2 on exception, 1 on true, 2 on false), *handle, *geom
|
707
781
|
:char, :pointer, :pointer
|
@@ -727,6 +801,11 @@ module Geos
|
|
727
801
|
:int, :pointer, :pointer, :pointer, :pointer
|
728
802
|
],
|
729
803
|
|
804
|
+
GEOSDistanceWithin_r: [
|
805
|
+
# (0 on exception, 1 otherwise), *handle, *geom_a, *geom_b, double distance
|
806
|
+
:char, :pointer, :pointer, :pointer, :double
|
807
|
+
],
|
808
|
+
|
730
809
|
GEOSHausdorffDistance_r: [
|
731
810
|
# (0 on exception, 1 otherwise), *handle, *geom_a, *geom_b, (double *) distance
|
732
811
|
:int, :pointer, :pointer, :pointer, :pointer
|
@@ -757,6 +836,11 @@ module Geos
|
|
757
836
|
:int, :pointer, :pointer
|
758
837
|
],
|
759
838
|
|
839
|
+
GEOSOrientPolygons_r: [
|
840
|
+
# -1 on exception, *handle, *geom, exterior_cw
|
841
|
+
:int, :pointer, :pointer, :int
|
842
|
+
],
|
843
|
+
|
760
844
|
GEOSGetInteriorRingN_r: [
|
761
845
|
# *geom, *handle, *geom, n
|
762
846
|
:pointer, :pointer, :pointer, :int
|
@@ -787,6 +871,11 @@ module Geos
|
|
787
871
|
:int, :pointer, :pointer, :pointer
|
788
872
|
],
|
789
873
|
|
874
|
+
GEOSGeomGetM_r: [
|
875
|
+
# -1 on exception, *handle, *geom, *point
|
876
|
+
:int, :pointer, :pointer, :pointer
|
877
|
+
],
|
878
|
+
|
790
879
|
GEOSGeomGetPointN_r: [
|
791
880
|
# *point, *handle, *geom, n
|
792
881
|
:pointer, :pointer, :pointer, :int
|
@@ -812,6 +901,11 @@ module Geos
|
|
812
901
|
:double, :pointer, :pointer
|
813
902
|
],
|
814
903
|
|
904
|
+
GEOSConcaveHullOfPolygons_r: [
|
905
|
+
# *geom, *handle, *geom, length_ratio, tight, allow_holes
|
906
|
+
:pointer, :pointer, :pointer, :double, :uint, :uint
|
907
|
+
],
|
908
|
+
|
815
909
|
GEOSMinimumRotatedRectangle_r: [
|
816
910
|
# *geom, *handle, *geom
|
817
911
|
:pointer, :pointer, :pointer
|
@@ -955,6 +1049,21 @@ module Geos
|
|
955
1049
|
# (2 on exception, 1 on true, 0 on false), *handle, *prepared, *geom
|
956
1050
|
:char, :pointer, :pointer, :pointer
|
957
1051
|
],
|
1052
|
+
|
1053
|
+
GEOSPreparedDistance_r: [
|
1054
|
+
# (1 on success, 0 on failure), *handle, *prepared, *geom, *distance
|
1055
|
+
:int, :pointer, :pointer, :pointer, :pointer
|
1056
|
+
],
|
1057
|
+
|
1058
|
+
GEOSPreparedDistanceWithin_r: [
|
1059
|
+
# (1 on true, 0 on false), *handle, *prepared, *geom, max_distance
|
1060
|
+
:char, :pointer, :pointer, :pointer, :double
|
1061
|
+
],
|
1062
|
+
|
1063
|
+
GEOSPreparedNearestPoints_r: [
|
1064
|
+
# *coord_seq, *handle, *prepared, *geom
|
1065
|
+
:pointer, :pointer, :pointer, :pointer
|
1066
|
+
],
|
958
1067
|
#### /PreparedGeometry functions ####
|
959
1068
|
|
960
1069
|
#### WktReader functions ####
|
@@ -1088,8 +1197,52 @@ module Geos
|
|
1088
1197
|
# void, *handle, *geom, bool
|
1089
1198
|
:void, :pointer, :pointer, :char
|
1090
1199
|
],
|
1200
|
+
|
1201
|
+
GEOSWKBWriter_getFlavor_r: [
|
1202
|
+
# flavor, *handle, *geom
|
1203
|
+
:flavor, :pointer, :pointer
|
1204
|
+
],
|
1205
|
+
|
1206
|
+
GEOSWKBWriter_setFlavor_r: [
|
1207
|
+
# void, *handle, *geom, flavor
|
1208
|
+
:void, :pointer, :pointer, :flavor
|
1209
|
+
],
|
1091
1210
|
#### /WkbWriter functions ####
|
1092
1211
|
|
1212
|
+
#### GeoJSONReader functions ####
|
1213
|
+
GEOSGeoJSONReader_create_r: [
|
1214
|
+
# *geojson_reader, *handle
|
1215
|
+
:pointer, :pointer
|
1216
|
+
],
|
1217
|
+
|
1218
|
+
GEOSGeoJSONReader_readGeometry_r: [
|
1219
|
+
# *geom, *handle, *geojson_reader, string
|
1220
|
+
:pointer, :pointer, :pointer, :string
|
1221
|
+
],
|
1222
|
+
|
1223
|
+
GEOSGeoJSONReader_destroy_r: [
|
1224
|
+
# void, *handle, *geojson_reader
|
1225
|
+
:void, :pointer, :pointer
|
1226
|
+
],
|
1227
|
+
#### /GeoJSONReader functions ###
|
1228
|
+
|
1229
|
+
#### GeoJSONWriter functions ####
|
1230
|
+
GEOSGeoJSONWriter_create_r: [
|
1231
|
+
# *geojson_writer, *handle
|
1232
|
+
:pointer, :pointer
|
1233
|
+
],
|
1234
|
+
|
1235
|
+
GEOSGeoJSONWriter_destroy_r: [
|
1236
|
+
# void, *handle, *geojson_writer
|
1237
|
+
:void, :pointer, :pointer
|
1238
|
+
],
|
1239
|
+
|
1240
|
+
GEOSGeoJSONWriter_writeGeometry_r: [
|
1241
|
+
# string, *handle, *geojson_writer, :geom, :indent
|
1242
|
+
:string, :pointer, :pointer, :pointer, :int
|
1243
|
+
],
|
1244
|
+
#### /GeoJSONWriter functions ####
|
1245
|
+
|
1093
1246
|
#### Linearref functions ####
|
1094
1247
|
GEOSProject_r: [
|
1095
1248
|
# distance, *handle, *geom_a, *geom_b
|
@@ -1252,7 +1405,7 @@ module Geos
|
|
1252
1405
|
end
|
1253
1406
|
|
1254
1407
|
def default_error_handler(*args)
|
1255
|
-
raise Geos::GEOSException, args[0]
|
1408
|
+
raise Geos::GEOSException, sprintf(args[0], *args[1])
|
1256
1409
|
end
|
1257
1410
|
end
|
1258
1411
|
|
@@ -12,16 +12,19 @@ class CoordinateSequenceTests < Minitest::Test
|
|
12
12
|
|
13
13
|
def test_set_and_get_x
|
14
14
|
@cs.set_x(0, 10.01)
|
15
|
+
|
15
16
|
assert_in_delta(10.01, @cs.get_x(0), TOLERANCE)
|
16
17
|
end
|
17
18
|
|
18
19
|
def test_set_and_get_y
|
19
20
|
@cs.set_y(0, 20.02)
|
21
|
+
|
20
22
|
assert_in_delta(20.02, @cs.get_y(0), TOLERANCE)
|
21
23
|
end
|
22
24
|
|
23
25
|
def test_set_and_get_z
|
24
26
|
@cs.set_z(0, 20.02)
|
27
|
+
|
25
28
|
assert_in_delta(20.02, @cs.get_z(0), TOLERANCE)
|
26
29
|
end
|
27
30
|
|
@@ -53,7 +56,7 @@ class CoordinateSequenceTests < Minitest::Test
|
|
53
56
|
[0, 0]
|
54
57
|
])
|
55
58
|
|
56
|
-
|
59
|
+
assert_predicate(cs, :counter_clockwise?)
|
57
60
|
|
58
61
|
cs = Geos::CoordinateSequence.new([
|
59
62
|
[0, 0],
|
@@ -62,7 +65,7 @@ class CoordinateSequenceTests < Minitest::Test
|
|
62
65
|
[0, 0]
|
63
66
|
])
|
64
67
|
|
65
|
-
|
68
|
+
refute_predicate(cs, :counter_clockwise?)
|
66
69
|
end
|
67
70
|
|
68
71
|
def test_check_bounds
|
@@ -115,6 +118,7 @@ class CoordinateSequenceTests < Minitest::Test
|
|
115
118
|
|
116
119
|
def test_with_no_arguments
|
117
120
|
cs = Geos::CoordinateSequence.new
|
121
|
+
|
118
122
|
assert_equal(0, cs.size)
|
119
123
|
assert_equal(3, cs.dimensions)
|
120
124
|
end
|
@@ -153,6 +157,7 @@ class CoordinateSequenceTests < Minitest::Test
|
|
153
157
|
|
154
158
|
def test_to_point
|
155
159
|
cs = Geos::CoordinateSequence.new([5, 7])
|
160
|
+
|
156
161
|
assert_equal('POINT (5 7)', write(cs.to_point, trim: true))
|
157
162
|
end
|
158
163
|
|
@@ -170,9 +175,11 @@ class CoordinateSequenceTests < Minitest::Test
|
|
170
175
|
|
171
176
|
def test_empty
|
172
177
|
cs = Geos::CoordinateSequence.new
|
178
|
+
|
173
179
|
assert_geom_empty(cs)
|
174
180
|
|
175
181
|
cs = Geos::CoordinateSequence.new([4, 1])
|
182
|
+
|
176
183
|
refute_geom_empty(cs)
|
177
184
|
end
|
178
185
|
|
@@ -219,11 +226,13 @@ class CoordinateSequenceTests < Minitest::Test
|
|
219
226
|
|
220
227
|
def test_to_s_2d
|
221
228
|
cs = Geos::CoordinateSequence.new([[1, 2], [10, 11]])
|
229
|
+
|
222
230
|
assert_equal('1.0 2.0, 10.0 11.0', cs.to_s)
|
223
231
|
end
|
224
232
|
|
225
233
|
def test_to_s_3d
|
226
234
|
cs = Geos::CoordinateSequence.new([[1, 2, 3], [10, 11, 12]])
|
235
|
+
|
227
236
|
assert_equal('1.0 2.0 3.0, 10.0 11.0 12.0', cs.to_s)
|
228
237
|
end
|
229
238
|
|
@@ -358,37 +367,45 @@ class CoordinateSequenceTests < Minitest::Test
|
|
358
367
|
|
359
368
|
def test_x_max
|
360
369
|
cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
|
370
|
+
|
361
371
|
assert_equal(10, cs.x_max)
|
362
372
|
end
|
363
373
|
|
364
374
|
def test_x_min
|
365
375
|
cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
|
376
|
+
|
366
377
|
assert_equal(-10, cs.x_min)
|
367
378
|
end
|
368
379
|
|
369
380
|
def test_y_max
|
370
381
|
cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
|
382
|
+
|
371
383
|
assert_equal(20, cs.y_max)
|
372
384
|
end
|
373
385
|
|
374
386
|
def test_y_min
|
375
387
|
cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
|
388
|
+
|
376
389
|
assert_equal(-15, cs.y_min)
|
377
390
|
end
|
378
391
|
|
379
392
|
def test_z_max
|
380
393
|
cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
|
381
|
-
|
394
|
+
|
395
|
+
assert_predicate(cs.z_max, :nan?, ' Expected NaN')
|
382
396
|
|
383
397
|
cs = Geos::CoordinateSequence.new([-10, -15, -20], [0, 5, 10], [10, 20, 30])
|
398
|
+
|
384
399
|
assert_equal(30, cs.z_max)
|
385
400
|
end
|
386
401
|
|
387
402
|
def test_z_min
|
388
403
|
cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
|
389
|
-
|
404
|
+
|
405
|
+
assert_predicate(cs.z_min, :nan?, ' Expected NaN')
|
390
406
|
|
391
407
|
cs = Geos::CoordinateSequence.new([-10, -15, -20], [0, 5, 10], [10, 20, 30])
|
408
|
+
|
392
409
|
assert_equal(-20, cs.z_min)
|
393
410
|
end
|
394
411
|
|
@@ -422,6 +439,7 @@ class CoordinateSequenceTests < Minitest::Test
|
|
422
439
|
|
423
440
|
cs = Geos::CoordinateSequence.new(*coordinates)
|
424
441
|
snapped = cs.snap_to_grid(10 ** -i)
|
442
|
+
|
425
443
|
assert_equal(coordinates, cs.to_a)
|
426
444
|
assert_equal(expected[i].inspect, snapped.to_a.inspect)
|
427
445
|
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class GeoJSONReaderTests < Minitest::Test
|
6
|
+
include TestHelper
|
7
|
+
|
8
|
+
attr_reader :json_reader
|
9
|
+
|
10
|
+
def setup
|
11
|
+
super
|
12
|
+
|
13
|
+
skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSGeoJSONReader_create_r)
|
14
|
+
|
15
|
+
@json_reader = Geos::GeoJSONReader.new
|
16
|
+
|
17
|
+
@writer.rounding_precision = 3
|
18
|
+
end
|
19
|
+
|
20
|
+
def json_read(*args, **options)
|
21
|
+
json_reader.read(*args, **options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def geojson_tester(expected, json, **options)
|
25
|
+
assert_equal(expected, write(json_read(json, **options)))
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_point
|
29
|
+
geojson_tester(
|
30
|
+
'POINT (-117.000 33.000)',
|
31
|
+
'{"type":"Point","coordinates":[-117.0,33.0]}'
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_line_string
|
36
|
+
geojson_tester(
|
37
|
+
'LINESTRING (102.000 0.000, 103.000 1.000, 104.000 0.000, 105.000 1.000)',
|
38
|
+
'{"type":"LineString","coordinates":[[102.0,0.0],[103.0,1.0],[104.0,0.0],[105.0,1.0]]}'
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_polygon
|
43
|
+
geojson_tester(
|
44
|
+
'POLYGON ((30.000 10.000, 40.000 40.000, 20.000 40.000, 10.000 20.000, 30.000 10.000))',
|
45
|
+
'{"type":"Polygon","coordinates":[[[30,10],[40,40],[20,40],[10,20],[30,10]]]}'
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_polygon_with_inner_ring
|
50
|
+
geojson_tester(
|
51
|
+
'POLYGON ((35.000 10.000, 45.000 45.000, 15.000 40.000, 10.000 20.000, 35.000 10.000), (20.000 30.000, 35.000 35.000, 30.000 20.000, 20.000 30.000))',
|
52
|
+
'{"type":"Polygon","coordinates":[[[35,10],[45,45],[15,40],[10,20],[35,10]],[[20,30],[35,35],[30,20],[20,30]]]}'
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_multi_point
|
57
|
+
geojson_tester(
|
58
|
+
if Geos::GEOS_NICE_VERSION >= '031200'
|
59
|
+
'MULTIPOINT ((10.000 40.000), (40.000 30.000), (20.000 20.000), (30.000 10.000))'
|
60
|
+
else
|
61
|
+
'MULTIPOINT (10.000 40.000, 40.000 30.000, 20.000 20.000, 30.000 10.000)'
|
62
|
+
end,
|
63
|
+
'{"type":"MultiPoint","coordinates":[[10, 40], [40, 30], [20, 20], [30, 10]]}'
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_multi_line_string
|
68
|
+
geojson_tester(
|
69
|
+
'MULTILINESTRING ((10.000 10.000, 20.000 20.000, 10.000 40.000), (40.000 40.000, 30.000 30.000, 40.000 20.000, 30.000 10.000))',
|
70
|
+
'{"type":"MultiLineString","coordinates":[[[10, 10], [20, 20], [10, 40]],[[40, 40], [30, 30], [40, 20], [30, 10]]]}'
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_multi_polygon
|
75
|
+
geojson_tester(
|
76
|
+
'MULTIPOLYGON (((40.000 40.000, 20.000 45.000, 45.000 30.000, 40.000 40.000)), ((20.000 35.000, 10.000 30.000, 10.000 10.000, 30.000 5.000, 45.000 20.000, 20.000 35.000), (30.000 20.000, 20.000 15.000, 20.000 25.000, 30.000 20.000)))',
|
77
|
+
'{"type": "MultiPolygon", "coordinates": [[[[40, 40], [20, 45], [45, 30], [40, 40]]], [[[20, 35], [10, 30], [10, 10], [30, 5], [45, 20], [20, 35]], [[30, 20], [20, 15], [20, 25], [30, 20]]]]}'
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_geometry_collection
|
82
|
+
geojson_tester(
|
83
|
+
'GEOMETRYCOLLECTION (POINT (40.000 10.000), LINESTRING (10.000 10.000, 20.000 20.000, 10.000 40.000), POLYGON ((40.000 40.000, 20.000 45.000, 45.000 30.000, 40.000 40.000)))',
|
84
|
+
'{"type": "GeometryCollection","geometries": [{"type": "Point","coordinates": [40, 10]},{"type": "LineString","coordinates": [[10, 10], [20, 20], [10, 40]]},{"type": "Polygon","coordinates": [[[40, 40], [20, 45], [45, 30], [40, 40]]]}]}'
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_feature_collection
|
89
|
+
geojson_tester(
|
90
|
+
'GEOMETRYCOLLECTION (POINT (-117.000 33.000), POINT (-122.000 45.000))',
|
91
|
+
'{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-117.0,33.0]}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-122.0,45.0]}}]}'
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_empty_point
|
96
|
+
geojson_tester(
|
97
|
+
'POINT EMPTY',
|
98
|
+
'{"type":"Point","coordinates":[]}'
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_empty_line_string
|
103
|
+
geojson_tester(
|
104
|
+
'LINESTRING EMPTY',
|
105
|
+
'{"type":"LineString","coordinates":[]}'
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_empty_polygon
|
110
|
+
geojson_tester(
|
111
|
+
'POLYGON EMPTY',
|
112
|
+
'{"type":"Polygon","coordinates":[]}'
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_empty_multi_point
|
117
|
+
geojson_tester(
|
118
|
+
'MULTIPOINT EMPTY',
|
119
|
+
'{"type":"MultiPoint","coordinates":[]}'
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_empty_multi_line_string
|
124
|
+
geojson_tester(
|
125
|
+
'MULTILINESTRING EMPTY',
|
126
|
+
'{"type":"MultiLineString","coordinates":[]}'
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_empty_multi_polygon
|
131
|
+
geojson_tester(
|
132
|
+
'MULTIPOLYGON EMPTY',
|
133
|
+
'{"type": "MultiPolygon", "coordinates": []}'
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_empty_geometry_collection
|
138
|
+
geojson_tester(
|
139
|
+
'GEOMETRYCOLLECTION EMPTY',
|
140
|
+
'{"type": "GeometryCollection","geometries": []}'
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_incomplete_geojson
|
145
|
+
assert_raises(Geos::GeoJSONReader::ParseError) do
|
146
|
+
json_reader.read('{"type":"Point","coordinates":[-117.0]}')
|
147
|
+
end
|
148
|
+
|
149
|
+
assert_raises(Geos::GeoJSONReader::ParseError) do
|
150
|
+
json_reader.read('{"type":"LineString","coordinates":[[1,2],[2]]}')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_broken_geojson
|
155
|
+
assert_raises(Geos::GeoJSONReader::ParseError) do
|
156
|
+
json_reader.read('<gml>NOT_GEO_JSON</gml>')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_incompatible_type
|
161
|
+
assert_raises(Geos::GeoJSONReader::ParseError) do
|
162
|
+
json_reader.read('{"type":"Line","coordinates":[[1,2],[2,3]]}')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_srid_from_options
|
167
|
+
geom = json_reader.read(
|
168
|
+
'{"type":"Point","coordinates":[-117.0,33.0]}',
|
169
|
+
srid: 3857
|
170
|
+
)
|
171
|
+
|
172
|
+
assert_equal(3857, geom.srid)
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class GeoJSONWriterTests < Minitest::Test
|
6
|
+
include TestHelper
|
7
|
+
|
8
|
+
attr_reader :json_writer
|
9
|
+
|
10
|
+
def setup
|
11
|
+
super
|
12
|
+
|
13
|
+
skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSGeoJSONWriter_create_r)
|
14
|
+
|
15
|
+
@json_writer = Geos::GeoJSONWriter.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def json_write(*args, **options)
|
19
|
+
json_writer.write(*args, **options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def geojson_tester(expected, geom, **options)
|
23
|
+
assert_equal(expected, json_write(read(geom), **options))
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_point
|
27
|
+
geojson_tester('{"type":"Point","coordinates":[-117.0,33.0]}', 'POINT(-117 33)')
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_line_string
|
31
|
+
geojson_tester('{"type":"LineString","coordinates":[[102.0,0.0],[103.0,1.0],[104.0,0.0],[105.0,1.0]]}', 'LINESTRING(102.0 0.0, 103.0 1.0, 104.0 0.0, 105.0 1.0)')
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_polygon
|
35
|
+
geojson_tester('{"type":"Polygon","coordinates":[[[30.0,10.0],[40.0,40.0],[20.0,40.0],[10.0,20.0],[30.0,10.0]]]}', 'POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))')
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_polygon_with_inner_ring
|
39
|
+
geojson_tester('{"type":"Polygon","coordinates":[[[35.0,10.0],[45.0,45.0],[15.0,40.0],[10.0,20.0],[35.0,10.0]],[[20.0,30.0],[35.0,35.0],[30.0,20.0],[20.0,30.0]]]}', 'POLYGON((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))')
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_multi_point
|
43
|
+
geojson_tester('{"type":"MultiPoint","coordinates":[[10.0,40.0],[40.0,30.0],[20.0,20.0],[30.0,10.0]]}', 'MULTIPOINT ((10 40), (40 30), (20 20), (30 10))')
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_multi_line_string
|
47
|
+
geojson_tester('{"type":"MultiLineString","coordinates":[[[10.0,10.0],[20.0,20.0],[10.0,40.0]],[[40.0,40.0],[30.0,30.0],[40.0,20.0],[30.0,10.0]]]}', 'MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))')
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_multi_polygon
|
51
|
+
geojson_tester('{"type":"MultiPolygon","coordinates":[[[[30.0,20.0],[45.0,40.0],[10.0,40.0],[30.0,20.0]]],[[[15.0,5.0],[40.0,10.0],[10.0,20.0],[5.0,10.0],[15.0,5.0]]]]}', 'MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))')
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_geometry_collection
|
55
|
+
geojson_tester('{"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[1.0,1.0]},{"type":"Point","coordinates":[2.0,2.0]}]}', 'GEOMETRYCOLLECTION(POINT(1 1),POINT(2 2))')
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_write_with_indentation
|
59
|
+
geojson_tester(<<~JSON.strip, 'LINESTRING(102.0 0.0, 103.0 1.0, 104.0 0.0, 105.0 1.0)', indentation: 2)
|
60
|
+
{
|
61
|
+
"type": "LineString",
|
62
|
+
"coordinates": [
|
63
|
+
[
|
64
|
+
102.0,
|
65
|
+
0.0
|
66
|
+
],
|
67
|
+
[
|
68
|
+
103.0,
|
69
|
+
1.0
|
70
|
+
],
|
71
|
+
[
|
72
|
+
104.0,
|
73
|
+
0.0
|
74
|
+
],
|
75
|
+
[
|
76
|
+
105.0,
|
77
|
+
1.0
|
78
|
+
]
|
79
|
+
]
|
80
|
+
}
|
81
|
+
JSON
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_empty_point
|
85
|
+
geojson_tester('{"type":"Point","coordinates":[]}', 'POINT EMPTY')
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_empty_line_string
|
89
|
+
geojson_tester('{"type":"LineString","coordinates":[]}', 'LINESTRING EMPTY')
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_empty_polygon
|
93
|
+
geojson_tester('{"type":"Polygon","coordinates":[[]]}', 'POLYGON EMPTY')
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_empty_geometry_collection
|
97
|
+
geojson_tester('{"type":"GeometryCollection","geometries":[]}', 'GEOMETRYCOLLECTION EMPTY')
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_linear_ring
|
101
|
+
geojson_tester('{"type":"LineString","coordinates":[[0.0,0.0],[1.0,1.0],[1.0,0.0],[0.0,0.0]]}', 'LINEARRING (0 0, 1 1, 1 0, 0 0)')
|
102
|
+
end
|
103
|
+
end
|