Skip to content

Commit 1f90501

Browse files
authored
expose clone (#145)
* change default context of operations from global context to operand context * add clone * add a comment to clone
1 parent 8d58689 commit 1f90501

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

src/geos_types.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and that shared context is returned. If contexts of some geometries differ,
1212
an error is thrown.
1313
"""
1414
function get_context end
15+
1516
function get_context(gs::AbstractVector)::GEOSContext
1617
if isempty(gs)
1718
get_global_context() # is this a good idea?
@@ -304,6 +305,18 @@ const Geometry = Union{
304305
GeometryCollection,
305306
}
306307

308+
"""
309+
clone(obj::Geometry, context=get_context(obj))
310+
311+
Create a deep copy of obj, optionally also moving it to a new context.
312+
"""
313+
function clone(obj::Geometry, context=get_context(obj))
314+
G = typeof(obj)
315+
# Note that all Geometry constructors
316+
# implicitly clone the pointer, in the following line
317+
GC.@preserve obj G(obj.ptr, context)::G
318+
end
319+
307320
get_context(obj::Geometry) = obj.context
308321
function destroyGeom(obj::Geometry)
309322
context = get_context(obj)

test/test_geos_types.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,39 @@ end
369369
return nothing
370370
end
371371
f91(91)
372+
@testset "clone" begin
373+
function f(n)
374+
# adapted from https://github.com/JuliaGeo/LibGEOS.jl/issues/91#issuecomment-1267732709
375+
contexts = [LibGEOS.GEOSContext() for i=1:Threads.nthreads()]
376+
p = LibGEOS.Polygon([[[-1.,-1],[+1,-1],[+1,+1],[-1,+1],[-1,-1]]])
377+
Threads.@threads :static for i=1:n
378+
ctx = contexts[Threads.threadid()]
379+
g1 = LibGEOS.clone(p,ctx)
380+
g2 = LibGEOS.clone(p,ctx)
381+
for j=1:n
382+
intersects(g1,g2)
383+
end
384+
end
385+
GC.gc(true)
386+
return nothing
387+
end
388+
f(91)
389+
end
390+
end
391+
392+
@testset "clone" begin
393+
geos = [
394+
readgeom("POINT(0 0)")
395+
readgeom("MULTIPOINT(0 0, 5 0, 10 0)")
396+
readgeom("LINESTRING (130 240, 650 240)")
397+
readgeom("POLYGON EMPTY")
398+
readgeom("POLYGON ((10 10, 20 40, 90 90, 90 10, 10 10))")
399+
readgeom("MULTILINESTRING ((5 0, 10 0), (0 0, 5 0))")
400+
readgeom("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)))")
401+
]
402+
for g1 in geos
403+
g2 = LibGEOS.clone(g1)
404+
@test g1 !== g2
405+
@test LibGEOS.equals(g1,g2)
406+
end
372407
end

test/test_misc.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,3 @@ end
3636
@test_throws ArgumentError LibGEOS.intersects(p1, q2)
3737
@test_throws ArgumentError LibGEOS.intersects(p2, q1)
3838
end
39-

0 commit comments

Comments
 (0)