Skip to content

Commit 8a9b17b

Browse files
authored
Provide Support for Prepared Geometries (#59)
* consolidate tests * support prepared geometries * add tests for some reason `crosses`, `overlaps` and `touches` are always returning false on my local machine * allow failures on nightly
1 parent 35c3487 commit 8a9b17b

File tree

4 files changed

+61
-127
lines changed

4 files changed

+61
-127
lines changed

appveyor.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ platform:
99

1010
# # Uncomment the following lines to allow failures on nightly julia
1111
# # (tests will run but not make your overall status red)
12-
# matrix:
13-
# allow_failures:
14-
# - julia_version: nightly
12+
matrix:
13+
allow_failures:
14+
- julia_version: nightly
1515

1616
branches:
1717
only:

src/geos_operations.jl

Lines changed: 14 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -131,99 +131,22 @@ for g1 in (:Point, :MultiPoint, :LineString, :MultiLineString, :LinearRing, :Pol
131131
end
132132

133133
# # -----
134-
# # Prepared Geometry Binary predicates - return 2 on exception, 1 on true, 0 on false
134+
# # Prepared Geometry Binary predicates
135135
# # -----
136136

137-
# # GEOSGeometry ownership is retained by caller
138-
# function prepareGeom(ptr::GEOSGeom)
139-
# result = GEOSPrepare(ptr)
140-
# if result == C_NULL
141-
# error("LibGEOS: Error in GEOSPrepare")
142-
# end
143-
# result
144-
# end
145-
146-
# destroyPreparedGeom(ptr::Ptr{GEOSPreparedGeometry}) = GEOSPreparedGeom_destroy(ptr)
147-
148-
# function prepcontains(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
149-
# result = GEOSPreparedContains(g1, g2)
150-
# if result == 0x02
151-
# error("LibGEOS: Error in GEOSPreparedContains")
152-
# end
153-
# bool(result)
154-
# end
155-
156-
# function prepcontainsproperly(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
157-
# result = GEOSPreparedContainsProperly(g1, g2)
158-
# if result == 0x02
159-
# error("LibGEOS: Error in GEOSPreparedContainsProperly")
160-
# end
161-
# bool(result)
162-
# end
163-
164-
# function prepcoveredby(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
165-
# result = GEOSPreparedCoveredBy(g1, g2)
166-
# if result == 0x02
167-
# error("LibGEOS: Error in GEOSPreparedCoveredBy")
168-
# end
169-
# bool(result)
170-
# end
171-
172-
# function prepcovers(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
173-
# result = GEOSPreparedCovers(g1, g2)
174-
# if result == 0x02
175-
# error("LibGEOS: Error in GEOSPreparedCovers")
176-
# end
177-
# bool(result)
178-
# end
179-
180-
# function prepcrosses(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
181-
# result = GEOSPreparedCrosses(g1, g2)
182-
# if result == 0x02
183-
# error("LibGEOS: Error in GEOSPreparedCrosses")
184-
# end
185-
# bool(result)
186-
# end
187-
188-
# function prepdisjoint(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
189-
# result = GEOSPreparedDisjoint(g1, g2)
190-
# if result == 0x02
191-
# error("LibGEOS: Error in GEOSPreparedDisjoint")
192-
# end
193-
# bool(result)
194-
# end
195-
196-
# function prepintersects(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
197-
# result = GEOSPreparedIntersects(g1, g2)
198-
# if result == 0x02
199-
# error("LibGEOS: Error in GEOSPreparedIntersects")
200-
# end
201-
# bool(result)
202-
# end
203-
204-
# function prepoverlaps(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
205-
# result = GEOSPreparedOverlaps(g1, g2)
206-
# if result == 0x02
207-
# error("LibGEOS: Error in GEOSPreparedOverlaps")
208-
# end
209-
# bool(result)
210-
# end
211-
212-
# function preptouches(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
213-
# result = GEOSPreparedTouches(g1, g2)
214-
# if result == 0x02
215-
# error("LibGEOS: Error in GEOSPreparedTouches")
216-
# end
217-
# bool(result)
218-
# end
219-
220-
# function prepwithin(g1::Ptr{GEOSPreparedGeometry}, g2::GEOSGeom)
221-
# result = GEOSPreparedWithin(g1, g2)
222-
# if result == 0x02
223-
# error("LibGEOS: Error in GEOSPreparedWithin")
224-
# end
225-
# bool(result)
226-
# end
137+
for geom in (:Point, :MultiPoint, :LineString, :MultiLineString, :LinearRing, :Polygon, :MultiPolygon, :GeometryCollection)
138+
@eval prepareGeom(obj::$geom, context::GEOSContext = _context) = PreparedGeometry(prepareGeom(obj.ptr, context), obj)
139+
@eval contains(obj1::PreparedGeometry, obj2::$geom) = prepcontains(obj1.ptr, obj2.ptr)
140+
@eval containsproperly(obj1::PreparedGeometry, obj2::$geom) = prepcontainsproperly(obj1.ptr, obj2.ptr)
141+
@eval coveredby(obj1::PreparedGeometry, obj2::$geom) = prepcoveredby(obj1.ptr, obj2.ptr)
142+
@eval covers(obj1::PreparedGeometry, obj2::$geom) = prepcovers(obj1.ptr, obj2.ptr)
143+
@eval crosses(obj1::PreparedGeometry, obj2::$geom) = prepcrosses(obj1.ptr, obj2.ptr)
144+
@eval disjoint(obj1::PreparedGeometry, obj2::$geom) = prepdisjoint(obj1.ptr, obj2.ptr)
145+
@eval intersects(obj1::PreparedGeometry, obj2::$geom) = prepintersects(obj1.ptr, obj2.ptr)
146+
@eval overlaps(obj1::PreparedGeometry, obj2::$geom) = prepoverlaps(obj1.ptr, obj2.ptr)
147+
@eval touches(obj1::PreparedGeometry, obj2::$geom) = preptouches(obj1.ptr, obj2.ptr)
148+
@eval within(obj1::PreparedGeometry, obj2::$geom) = prepwithin(obj1.ptr, obj2.ptr)
149+
end
227150

228151
# # -----
229152
# # STRtree functions

src/geos_types.jl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,19 @@ end
107107

108108
for geom in (:Point, :MultiPoint, :LineString, :MultiLineString, :LinearRing, :Polygon, :MultiPolygon, :GeometryCollection)
109109
@eval begin
110-
function destroyGeom(obj::$geom)
111-
destroyGeom(obj.ptr)
110+
function destroyGeom(obj::$geom, context::GEOSContext = _context)
111+
destroyGeom(obj.ptr, context)
112112
obj.ptr = C_NULL
113113
end
114114
end
115115
end
116+
117+
mutable struct PreparedGeometry{G <: GeoInterface.AbstractGeometry} <: GeoInterface.AbstractGeometry
118+
ptr::Ptr{GEOSPreparedGeometry}
119+
ownedby::G
120+
end
121+
122+
function destroyGeom(obj::PreparedGeometry, context::GEOSContext = _context)
123+
destroyPreparedGeom(obj.ptr, context)
124+
obj.ptr = C_NULL
125+
end

test/test_geos_operations.jl

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ end
1919

2020
function factcheck(f::Function, g1::String, g2::String, expected::Bool)
2121
@test f(readgeom(g1),readgeom(g2)) == expected
22+
@test f(prepareGeom(readgeom(g1)),readgeom(g2)) == expected
2223
end
2324

2425
@testset "GEOS operations" begin
@@ -35,22 +36,6 @@ end
3536
@test equals(interpolate(ls, test_dist), dest)
3637
end
3738

38-
g1 = readgeom("POLYGON EMPTY")
39-
g2 = readgeom("POLYGON EMPTY")
40-
@test !LibGEOS.contains(g1, g2)
41-
@test !LibGEOS.contains(g2, g1)
42-
43-
g1 = readgeom("POLYGON((1 1,1 5,5 5,5 1,1 1))")
44-
g2 = readgeom("POINT(2 2)")
45-
@test LibGEOS.contains(g1, g2)
46-
@test !LibGEOS.contains(g2, g1)
47-
48-
g1 = readgeom("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))")
49-
g2 = readgeom("POLYGON((1 1,1 2,2 2,2 1,1 1))")
50-
@test LibGEOS.contains(g1, g2)
51-
@test !LibGEOS.contains(g2, g1)
52-
53-
5439
# GEOSConvexHullTest
5540
input = readgeom("MULTIPOINT (130 240, 130 240, 130 240, 570 240, 570 240, 570 240, 650 240)")
5641
expected = readgeom("LINESTRING (130 240, 650 240)")
@@ -114,14 +99,6 @@ end
11499
"POLYGON((0 1,0 2,10 2,10 1,0 1))",
115100
"GEOMETRYCOLLECTION (LINESTRING (1 2, 2 2), LINESTRING (2 1, 1 1), POLYGON ((0.5 1, 1 2, 1 1, 0.5 1)), POLYGON ((9 2, 9.5 1, 2 1, 2 2, 9 2)))")
116101

117-
# GEOSIntersectsTest
118-
test_intersects(g1::String, g2::String, expected::Bool) = factcheck(intersects, g1, g2, expected)
119-
test_intersects("POLYGON EMPTY", "POLYGON EMPTY", false)
120-
test_intersects("POLYGON((1 1,1 5,5 5,5 1,1 1))", "POINT(2 2)", true)
121-
test_intersects("POINT(2 2)", "POLYGON((1 1,1 5,5 5,5 1,1 1))", true)
122-
test_intersects("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", "POLYGON((1 1,1 2,2 2,2 1,1 1))", true)
123-
test_intersects("POLYGON((1 1,1 2,2 2,2 1,1 1))", "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", true)
124-
125102
# LineString_PointTest
126103
g1 = readgeom("LINESTRING(0 0, 5 5, 10 10)")
127104
@test !isClosed(g1)
@@ -232,13 +209,37 @@ end
232209
test_unaryunion("GEOMETRYCOLLECTION (MULTILINESTRING((5 7, 12 7), (4 5, 6 5), (5.5 7.5, 6.5 7.5)), POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(5 6, 7 6, 7 8, 5 8, 5 6)), MULTIPOINT(6 6.5, 6 1, 12 2, 6 1))",
233210
"GEOMETRYCOLLECTION (POINT (6 6.5), POINT (12 2), LINESTRING (5 7, 7 7), LINESTRING (10 7, 12 7), LINESTRING (5.5 7.5, 6.5 7.5), POLYGON ((10 7, 10 0, 0 0, 0 10, 10 10, 10 7), (5 6, 7 6, 7 7, 7 8, 5 8, 5 7, 5 6)))")
234211

235-
# GEOSWithinTest
236-
test_within(g1::String, g2::String, expected::Bool) = factcheck(within, g1, g2, expected)
237-
test_within("POLYGON EMPTY", "POLYGON EMPTY", false)
238-
test_within("POLYGON((1 1,1 5,5 5,5 1,1 1))", "POINT(2 2)", false)
239-
test_within("POINT(2 2)", "POLYGON((1 1,1 5,5 5,5 1,1 1))", true)
240-
test_within("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", "POLYGON((1 1,1 2,2 2,2 1,1 1))", false)
241-
test_within("POLYGON((1 1,1 2,2 2,2 1,1 1))", "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", true)
212+
for (g1, g2, testvalue) in (
213+
("POLYGON EMPTY", "POLYGON EMPTY", false),
214+
("POLYGON((1 1,1 5,5 5,5 1,1 1))", "POINT(2 2)", false),
215+
("POINT(2 2)", "POLYGON((1 1,1 5,5 5,5 1,1 1))", true),
216+
("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", "POLYGON((1 1,1 2,2 2,2 1,1 1))", false),
217+
("POLYGON((1 1,1 2,2 2,2 1,1 1))", "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", true),
218+
("LINESTRING (100 200, 300 200)", "LINESTRING (100 300, 200 201, 300 300)", false),
219+
("LINESTRING (100 200, 300 200)", "LINESTRING (100 300, 200 200, 300 300)", false),
220+
("LINESTRING (100 200, 300 200)", "LINESTRING (100 300, 300 100)", false)
221+
)
222+
for f in (within, coveredby)
223+
factcheck(f, g1, g2, testvalue)
224+
end
225+
for f in (contains, covers)
226+
factcheck(f, g2, g1, testvalue)
227+
end
228+
end
229+
230+
for (g1, g2, testvalue) in (
231+
("POLYGON EMPTY", "POLYGON EMPTY", false),
232+
("POLYGON((1 1,1 5,5 5,5 1,1 1))", "POINT(2 2)", true),
233+
("POINT(2 2)", "POLYGON((1 1,1 5,5 5,5 1,1 1))", true),
234+
("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", "POLYGON((1 1,1 2,2 2,2 1,1 1))", true),
235+
("POLYGON((1 1,1 2,2 2,2 1,1 1))", "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)))", true),
236+
("LINESTRING (100 200, 300 200)", "LINESTRING (100 300, 200 201, 300 300)", false),
237+
("LINESTRING (100 200, 300 200)", "LINESTRING (100 300, 200 200, 300 300)", true),
238+
("LINESTRING (100 200, 300 200)", "LINESTRING (100 300, 300 100)", true)
239+
)
240+
factcheck(intersects, g1, g2, testvalue)
241+
factcheck(disjoint, g1, g2, !testvalue)
242+
end
242243

243244
# GEOSisClosedTest
244245
@test !isClosed(readgeom("LINESTRING(0 0, 1 0, 1 1)"))

0 commit comments

Comments
 (0)