Skip to content

Commit 1844202

Browse files
rafaqzasinghvi17
andauthored
add coordtype (#167)
Closes #128 Currently on a GI.MultiPolygon this takes 4ns. Its not a compile time operation. We could put this in the type parameters of the wrapper geometries at construction so its instant. A lot of packages will be able to set this absolutely to a single type, e.g. Shapefile.jl, GeoJSON.jl and LibGEOS.jl can return Float64 Co-authored-by: Anshul Singhvi <[email protected]>
1 parent 88da506 commit 1844202

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

src/fallbacks.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ const default_coord_names = (:X, :Y, :Z, :M)
88

99
coordnames(t::AbstractGeometryTrait, geom) = default_coord_names[1:ncoord(t, geom)]
1010

11+
@inline coordtype(::FeatureCollectionTrait, fc) = coordtype(getfeature(fc, 1))
12+
@inline coordtype(::FeatureTrait, feature) = coordtype(geometry(feature))
13+
@inline coordtype(::AbstractGeometryTrait, geom) = coordtype(getgeom(geom, 1))
14+
@inline coordtype(::PointTrait, geom) = typeof(x(geom))
15+
1116
# Maybe hardcode dimension order? At least for X and Y?
1217
x(t::AbstractPointTrait, geom) = getcoord(t, geom, findfirst(isequal(:X), coordnames(geom)))
1318
y(t::AbstractPointTrait, geom) = getcoord(t, geom, findfirst(isequal(:Y), coordnames(geom)))

src/interface.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,15 @@ Returns a geometric object that represents the convex hull of the given `geom`.
597597
"""
598598
convexhull(geom) = convexhull(geomtrait(geom), geom)
599599

600+
"""
601+
coordtype(geom) -> Type
602+
603+
Return the type of the coordinates in the geom.
604+
605+
Usually `<: AbstractFloat` but can be any `Number`.
606+
"""
607+
coordtype(geom) = coordtype(trait(geom), geom)
608+
600609
"""
601610
x(geom) -> Number
602611

src/wrappers.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,11 @@ convert(::Type{Point}, ::PointTrait, geom) = Point(geom)
434434
convert(::Type{Point}, ::PointTrait, geom::Point) = geom
435435
extent(trait::PointTrait, geom::Point) = extent(trait, parent(geom))
436436

437+
coordtype(::Point{<:Any,<:Any,<:AbstractArray{T}}) where T = T
438+
coordtype(::Point{<:Any,<:Any,<:NTuple{<:Any,T}}) where T = T
439+
coordtype(::Point{<:Any,<:Any,<:NamedTuple{<:Any,<:NTuple{<:Any,T}}}) where T = T
440+
coordtype(p::Point) = coordtype(parent(p))
441+
437442
x(trait::PointTrait, geom::Point) = x(trait, parent(geom))
438443
y(trait::PointTrait, geom::Point) = y(trait, parent(geom))
439444
z(trait::PointTrait, geom::Point{true}) = z(trait, parent(geom))

test/test_wrappers.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ GI.getcoord(point, 1)
2323
@test !GI.ismeasured(point)
2424
@test !GI.is3d(point)
2525
@test GI.ncoord(point) == 2
26+
@test GI.coordtype(point) == Int
2627
@test GI.extent(point) == Extent(X=(1, 1), Y=(2, 2))
2728
@test point == GI.Point(point)
2829
@test (GI.x(point), GI.y(point)) == (1, 2)
@@ -42,6 +43,7 @@ pointz = GI.Point(1, 2, 3)
4243
@test !GI.ismeasured(pointz)
4344
@test GI.is3d(pointz)
4445
@test GI.ncoord(pointz) == 3
46+
@test GI.coordtype(pointz) == Int
4547
@test (GI.x(pointz), GI.y(pointz), GI.z(pointz)) == (1, 2, 3)
4648
@test GI.testgeometry(pointz)
4749
@test GI.convert(GI, pointz) === pointz
@@ -55,6 +57,7 @@ pointzm = GI.Point(; X=1, Y=2, Z=3, M=4)
5557
@test GI.ismeasured(pointzm)
5658
@test GI.is3d(pointzm)
5759
@test GI.ncoord(pointzm) == 4
60+
@test GI.coordtype(pointzm) == Int
5861
@test pointzm == GI.Point(pointzm)
5962
@test point != GI.Point(pointzm)
6063
@test (GI.x(pointzm), GI.y(pointzm), GI.z(pointzm), GI.m(pointzm)) == (1, 2, 3, 4)
@@ -71,6 +74,7 @@ pointm = GI.Point((X=1, Y=2, M=3))
7174
@test GI.ismeasured(pointm)
7275
@test !GI.is3d(pointm)
7376
@test GI.ncoord(pointm) == 3
77+
@test GI.coordtype(pointm) == Int
7478
@test pointm == GI.Point(pointm)
7579
@test point != GI.Point(pointm)
7680
@test (GI.x(pointm), GI.y(pointm), GI.m(pointm)) == (1, 2, 3)
@@ -88,6 +92,7 @@ pointtm = GI.Point{false,true}(1, 2, 3)
8892
@test GI.ismeasured(pointtm)
8993
@test !GI.is3d(pointtm)
9094
@test GI.ncoord(pointtm) == 3
95+
@test GI.coordtype(pointtm) == Int
9196
@test (GI.x(pointtm), GI.y(pointtm), GI.m(pointtm)) == (1, 2, 3)
9297
@test_throws ArgumentError GI.z(pointtm)
9398
@test GI.testgeometry(pointtm)
@@ -102,6 +107,7 @@ pointa = GI.Point([1, 2])
102107
@test !GI.ismeasured(pointa)
103108
@test !GI.is3d(pointa)
104109
@test GI.ncoord(pointa) == 2
110+
@test GI.coordtype(pointa) == Int
105111
@test (GI.x(pointa), GI.y(pointa)) == (1, 2)
106112
@test GI.testgeometry(pointa)
107113
test_display(pointa, "Point{false, false}((1, 2))", "Point((1,2))")
@@ -159,6 +165,7 @@ linestring = GI.LineString([(1, 2), (3, 4)])
159165
@test GI.testgeometry(linestring)
160166
@test !GI.is3d(linestring)
161167
@test GI.ncoord(linestring) == 2
168+
@test GI.coordtype(linestring) == Int
162169
test_display(linestring, "LineString{false, false}([(1, 2), (3, 4)])", "LineString([(1,2),(3,4)])")
163170
@test @inferred(GI.extent(linestring)) == Extent(X=(1, 3), Y=(2, 4))
164171
@test_throws ArgumentError GI.LineString([(1, 2)])
@@ -242,6 +249,7 @@ collection = GI.GeometryCollection(geoms)
242249
@test GI.testgeometry(collection)
243250
@test !GI.is3d(collection)
244251
@test GI.ncoord(collection) == 2
252+
@test GI.coordtype(collection) == Int
245253
@test GI.extent(collection) == reduce(Extents.union, map(GI.extent, geoms))
246254
test_display(collection, "GeometryCollection{false, false}([Line([(1, 2), (3, 4)]), … (3) … , (1, 2)])",
247255
"GeometryCollection([Line([(1,2),(3,4)]),LineString([(1,2),(3,4)]),…(2)…,(1,2)])")
@@ -259,6 +267,7 @@ multicurve = GI.MultiCurve([linestring, linearring])
259267
@test GI.getgeom(multicurve, 1) === linestring
260268
@test !GI.is3d(multicurve)
261269
@test GI.ncoord(multicurve) == 2
270+
@test GI.coordtype(multicurve) == Int
262271
@test GI.extent(multicurve) == Extent(X=(1, 5), Y=(2, 6))
263272
@test_throws ArgumentError GI.MultiCurve([pointz, polygon])
264273
@test GI.testgeometry(multicurve)
@@ -278,6 +287,7 @@ multipolygon = GI.MultiPolygon([polygon])
278287
@test GI.getgeom(multipolygon, 1) === polygon
279288
@test !GI.is3d(multipolygon)
280289
@test GI.ncoord(multipolygon) == 2
290+
@test GI.coordtype(multipolygon) == Int
281291
test_display(multipolygon, "MultiPolygon{false, false}([Polygon([LinearRing([(1, 2), … (2) … , (1, 2)]), LinearRing([(1, 2), … (2) … , (1, 2)])])])",
282292
"MultiPolygon([Polygon([LinearRing([(1,2),…(2)…,(1,2)]),LinearRing([(1,2),…(2)…,(1,2)])])])")
283293
# MultiPolygon extent does not infer, maybe due to nesting
@@ -297,6 +307,7 @@ polyhedralsurface = GI.PolyhedralSurface([polygon, polygon])
297307
@test GI.PolyhedralSurface(polygon) == GI.PolyhedralSurface(polygon)
298308
@test !GI.is3d(polyhedralsurface)
299309
@test GI.ncoord(polyhedralsurface) == 2
310+
@test GI.coordtype(polyhedralsurface) == Int
300311
@test @inferred(GI.extent(polyhedralsurface)) == Extent(X=(1, 5), Y=(2, 6))
301312
@test GI.getgeom(polyhedralsurface, 1) === polygon
302313
@test collect(GI.getgeom(polyhedralsurface)) == [polygon, polygon]
@@ -315,6 +326,7 @@ test_display(polyhedralsurface_crs, "PolyhedralSurface{false, false}([Polygon([L
315326
multipolygon_coords = [[[[1, 2], [3, 4], [3, 2], [1, 4]]]]
316327
multipolygon = GI.MultiPolygon(multipolygon_coords)
317328
@test GI.coordinates(multipolygon) == multipolygon_coords
329+
@test GI.coordtype(multipolygon) == Int
318330
test_display(multipolygon, "MultiPolygon{false, false}([Polygon([LinearRing([[1, 2], [3, 4], [3, 2], [1, 4]])])])",
319331
"MultiPolygon([Polygon([LinearRing([[1,2],[3,4],[3,2],[1,4]])])])")
320332

@@ -345,6 +357,7 @@ test_display(feature, "Feature(MultiPolygon{false, false}([Polygon([LinearRing([
345357
@test GI.crs(feature) == EPSG(4326)
346358
@test GI.extent(feature) == GI.extent(multipolygon)
347359
@test GI.testfeature(feature)
360+
@test GI.coordtype(feature) == Int
348361
@test_throws ArgumentError GI.Feature(:not_a_feature; properties=(x=1, y=2, z=3))
349362
@test GI.properties(GI.Feature(multipolygon)) == NamedTuple()
350363

@@ -364,6 +377,7 @@ test_display(fc, "FeatureCollection([Feature(MultiPolygon{false, false}([Polygon
364377
@test_throws ArgumentError GI.FeatureCollection([1])
365378
vecfc = GI.FeatureCollection([(geometry=(1,2), a=1, b=2)])
366379
@test GI.getfeature(vecfc, 1) == (geometry=(1,2), a=1, b=2)
380+
@test GI.coordtype(vecfc) == Int
367381

368382

369383

0 commit comments

Comments
 (0)