Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't clone geometry when given a pointer #198

Merged
merged 1 commit into from
Jan 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 110 additions & 39 deletions src/geos_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@
mutable struct Point <: AbstractGeometry
ptr::GEOSGeom
context::GEOSContext
function Point(obj::Point, context::GEOSContext = get_global_context())
point = new(cloneGeom(obj, context), context)
finalizer(destroyGeom, point)
point
end
# create a point from a pointer - only makese sense if it is a pointer to a point, otherwise error
function Point(obj::Union{Point,GEOSGeom}, context::GEOSContext = get_global_context())
function Point(obj::GEOSGeom, context::GEOSContext = get_global_context())
id = LibGEOS.geomTypeId(obj, context)
point = if id == GEOS_POINT
point = new(cloneGeom(obj, context), context)
point = new(obj, context)
else
open_issue_if_conversion_makes_sense(Point, id)
end
Expand All @@ -52,15 +57,25 @@
mutable struct MultiPoint <: AbstractMultiGeometry
ptr::GEOSGeom
context::GEOSContext
function MultiPoint(obj::Point, context::GEOSContext = get_global_context())
multipoint = new(
createCollection(GEOS_MULTIPOINT, [cloneGeom(obj, context)], context),
context,
)
finalizer(destroyGeom, multipoint)
multipoint
end
function MultiPoint(obj::MultiPoint, context::GEOSContext = get_global_context())
multipoint = new(cloneGeom(obj, context), context)
finalizer(destroyGeom, multipoint)
multipoint
end
# create a multipoint from a pointer - only makes sense if it is a pointer to a multipoint
# or to a point, otherwise error
function MultiPoint(
obj::Union{Point,MultiPoint,GEOSGeom},
context::GEOSContext = get_global_context(),
)
function MultiPoint(obj::GEOSGeom, context::GEOSContext = get_global_context())
id = LibGEOS.geomTypeId(obj, context)
multipoint = if id == GEOS_MULTIPOINT
new(cloneGeom(obj, context), context)
new(obj, context)
elseif id == GEOS_POINT
new(createCollection(GEOS_MULTIPOINT, [cloneGeom(obj, context)], context), context)
else
Expand All @@ -83,20 +98,25 @@
)
# create a multipoint from a list of points
MultiPoint(points::Vector{LibGEOS.Point}, context::GEOSContext = get_context(points)) =
MultiPoint(createCollection(GEOS_MULTIPOINT, points, context), context)
MultiPoint(
createCollection(GEOS_MULTIPOINT, cloneGeom.(points, Ref(context)), context),
context,
)
end

mutable struct LineString <: AbstractGeometry
ptr::GEOSGeom
context::GEOSContext
function LineString(obj::LineString, context::GEOSContext = get_global_context())
line = new(cloneGeom(obj, context), context)
finalizer(destroyGeom, line)
line
end
# create a linestring from a linestring pointer, otherwise error
function LineString(
obj::Union{LineString,GEOSGeom},
context::GEOSContext = get_global_context(),
)
function LineString(obj::GEOSGeom, context::GEOSContext = get_global_context())
id = LibGEOS.geomTypeId(obj, context)
line = if id == GEOS_LINESTRING
new(cloneGeom(obj, context), context)
new(obj, context)
else
open_issue_if_conversion_makes_sense(LineString, id)
end
Expand All @@ -122,14 +142,27 @@
mutable struct MultiLineString <: AbstractMultiGeometry
ptr::GEOSGeom
context::GEOSContext
# create a multiline string from a multilinestring or a linestring pointer, else error
function MultiLineString(
obj::Union{LineString,MultiLineString,GEOSGeom},
obj::MultiLineString,
context::GEOSContext = get_global_context(),
)
multiline = new(cloneGeom(obj, context), context)
finalizer(destroyGeom, multiline)
multiline
end
function MultiLineString(obj::LineString, context::GEOSContext = get_global_context())
multiline = new(

Check warning on line 154 in src/geos_types.jl

View check run for this annotation

Codecov / codecov/patch

src/geos_types.jl#L153-L154

Added lines #L153 - L154 were not covered by tests
createCollection(GEOS_MULTILINESTRING, [cloneGeom(obj, context)], context),
context,
)
finalizer(destroyGeom, multiline)
multiline

Check warning on line 159 in src/geos_types.jl

View check run for this annotation

Codecov / codecov/patch

src/geos_types.jl#L158-L159

Added lines #L158 - L159 were not covered by tests
end
# create a multiline string from a multilinestring or a linestring pointer, else error
function MultiLineString(obj::GEOSGeom, context::GEOSContext = get_global_context())
id = LibGEOS.geomTypeId(obj, context)
multiline = if id == GEOS_MULTILINESTRING
new(cloneGeom(obj, context), context)
new(obj, context)
elseif id == GEOS_LINESTRING
new(
createCollection(GEOS_MULTILINESTRING, [cloneGeom(obj, context)], context),
Expand Down Expand Up @@ -159,7 +192,7 @@
) = MultiLineString(
createCollection(
GEOS_MULTILINESTRING,
GEOSGeom[ls.ptr for ls in multiline],
GEOSGeom[cloneGeom(ls, context) for ls in multiline],
context,
),
context,
Expand All @@ -169,14 +202,16 @@
mutable struct LinearRing <: AbstractGeometry
ptr::GEOSGeom
context::GEOSContext
function LinearRing(obj::LinearRing, context::GEOSContext = get_global_context())
ring = new(cloneGeom(obj, context), context)
finalizer(destroyGeom, ring)
ring
end
# create a linear ring from a linear ring pointer, otherwise error
function LinearRing(
obj::Union{LinearRing,GEOSGeom},
context::GEOSContext = get_global_context(),
)
function LinearRing(obj::GEOSGeom, context::GEOSContext = get_global_context())
id = LibGEOS.geomTypeId(obj, context)
ring = if id == GEOS_LINEARRING
new(cloneGeom(obj, context), context)
new(obj, context)
else
open_issue_if_conversion_makes_sense(LinearRing, id)
end
Expand All @@ -198,16 +233,23 @@
mutable struct Polygon <: AbstractGeometry
ptr::GEOSGeom
context::GEOSContext
function Polygon(obj::Polygon, context::GEOSContext = get_global_context())
polygon = new(cloneGeom(obj, context), context)
finalizer(destroyGeom, polygon)
polygon
end
function Polygon(obj::LinearRing, context::GEOSContext = get_global_context())
polygon = new(createPolygon(cloneGeom(obj, context), context), context)
finalizer(destroyGeom, polygon)
polygon
end
# create polygon using GEOSGeom pointer - only makes sense if pointer points to a polygon or a linear ring to start with.
function Polygon(
obj::Union{Polygon,LinearRing,GEOSGeom},
context::GEOSContext = get_global_context(),
)
function Polygon(obj::GEOSGeom, context::GEOSContext = get_global_context())
id = LibGEOS.geomTypeId(obj, context)
polygon = if id == GEOS_POLYGON
new(cloneGeom(obj, context), context)
new(obj, context)
elseif id == GEOS_LINEARRING
new(cloneGeom(createPolygon(obj, context), context), context)
new(createPolygon(obj, context), context)

Check warning on line 252 in src/geos_types.jl

View check run for this annotation

Codecov / codecov/patch

src/geos_types.jl#L252

Added line #L252 was not covered by tests
else
open_issue_if_conversion_makes_sense(Polygon, id)
end
Expand All @@ -231,20 +273,37 @@
exterior::LinearRing,
holes::Vector{LinearRing},
context::GEOSContext = get_context(exterior),
) = Polygon(createPolygon(exterior, holes, context), context)
) = Polygon(
createPolygon(
cloneGeom(exterior, context),
cloneGeom.(holes, Ref(context)),
context,
),
context,
)
end

mutable struct MultiPolygon <: AbstractMultiGeometry
ptr::GEOSGeom
context::GEOSContext
function MultiPolygon(obj::MultiPolygon, context::GEOSContext = get_global_context())
multipolygon = new(cloneGeom(obj, context), context)
finalizer(destroyGeom, multipolygon)
multipolygon
end
function MultiPolygon(obj::Polygon, context::GEOSContext = get_global_context())
multipolygon = new(
createCollection(GEOS_MULTIPOLYGON, [cloneGeom(obj, context)], context),
context,
)
finalizer(destroyGeom, multipolygon)
multipolygon
end
# create multipolygon using a multipolygon or polygon pointer, else error
function MultiPolygon(
obj::Union{Polygon,MultiPolygon,GEOSGeom},
context::GEOSContext = get_global_context(),
)
function MultiPolygon(obj::GEOSGeom, context::GEOSContext = get_global_context())
id = LibGEOS.geomTypeId(obj, context)
multipolygon = if id == GEOS_MULTIPOLYGON
new(cloneGeom(obj, context), context)
new(obj, context)
elseif id == GEOS_POLYGON
new(
createCollection(GEOS_MULTIPOLYGON, [cloneGeom(obj, context)], context),
Expand All @@ -259,7 +318,14 @@

# create multipolygon from list of Polygon objects
MultiPolygon(polygons::Vector{Polygon}, context::GEOSContext = get_context(polygons)) =
MultiPolygon(createCollection(GEOS_MULTIPOLYGON, polygons, context), context)
MultiPolygon(
createCollection(
GEOS_MULTIPOLYGON,
cloneGeom.(polygons, Ref(context)),
context,
),
context,
)

# create multipolygon using list of polygon coordinates - note that each polygon can have holes as explained above in Polygon comments
MultiPolygon(
Expand All @@ -284,14 +350,19 @@
mutable struct GeometryCollection <: AbstractMultiGeometry
ptr::GEOSGeom
context::GEOSContext
# create a geometric collection from a pointer to a geometric collection, else error
function GeometryCollection(
obj::Union{GeometryCollection,GEOSGeom},
obj::GeometryCollection,
context::GEOSContext = get_global_context(),
)
geometrycollection = new(cloneGeom(obj, context), context)
finalizer(destroyGeom, geometrycollection)
geometrycollection
end
# create a geometric collection from a pointer to a geometric collection, else error
function GeometryCollection(obj::GEOSGeom, context::GEOSContext = get_global_context())
id = LibGEOS.geomTypeId(obj, context)
geometrycollection = if id == GEOS_GEOMETRYCOLLECTION
new(cloneGeom(obj, context), context)
new(obj, context)
else
open_issue_if_conversion_makes_sense(GeometryCollection, id)
end
Expand All @@ -312,7 +383,7 @@
) = GeometryCollection(
createCollection(
GEOS_GEOMETRYCOLLECTION,
GEOSGeom[geom.ptr for geom in collection],
GEOSGeom[cloneGeom(geom, context) for geom in collection],
context,
),
context,
Expand Down