Skip to content

Commit 0e2e695

Browse files
committed
Enable Feature by using a geometry field instead of separate x y z.
1 parent c886252 commit 0e2e695

File tree

4 files changed

+40
-39
lines changed

4 files changed

+40
-39
lines changed

src/geointerface.jl

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,38 @@ import GeoInterface as GI
22

33
GeoInterface.isgeometry(::Type{<:Point}) = true
44
GeoInterface.geomtrait(::Point) = PointTrait()
5-
# GeoInterface.trait(::Point) = FeatureTrait()
5+
GeoInterface.trait(::Point) = FeatureTrait()
66

77
GeoInterface.ncoord(::PointTrait, p::Point) = 3
8-
GeoInterface.getcoord(::PointTrait, p::Point) = [p.x, p.y, p.z]
9-
GeoInterface.getcoord(::PointTrait, p::Point, i) = getfield(p, i)
8+
GeoInterface.getcoord(::PointTrait, p::Point) = p.geometry
9+
GeoInterface.getcoord(::PointTrait, p::Point, i) = p.geometry[i]
1010

11-
GeoInterface.x(::PointTrait, p::Point) = p.x
12-
GeoInterface.y(::PointTrait, p::Point) = p.y
13-
GeoInterface.z(::PointTrait, p::Point) = p.z
11+
GeoInterface.x(::PointTrait, p::Point) = p.geometry[1]
12+
GeoInterface.y(::PointTrait, p::Point) = p.geometry[2]
13+
GeoInterface.z(::PointTrait, p::Point) = p.geometry[3]
1414

1515
GeoInterface.isfeature(feat::Type{<:Point}) = true
1616
GeoInterface.properties(feat::T) where {T<:Point} = NamedTuple(zip(fieldnames(T), getfield(feat, n) for n in fieldnames(T)))
17-
GeoInterface.geometry(feat::Point) = feat
17+
GeoInterface.geometry(feat::Point) = feat.geom
1818

1919
GeoInterface.isgeometry(::Type{<:Dataset}) = true
2020
GeoInterface.geomtrait(::Dataset) = MultiPointTrait()
21-
# GeoInterface.trait(::Dataset) = FeatureCollectionTrait()
21+
GeoInterface.trait(::Dataset) = FeatureCollectionTrait()
2222
GeoInterface.ngeom(::MultiPointTrait, ds::Dataset) = length(ds)
2323
GeoInterface.getgeom(::MultiPointTrait, ds::Dataset) = ds
2424
GeoInterface.getgeom(::MultiPointTrait, ds::Dataset, i) = ds[i]
2525

26-
# GeoInterface.crs(geomtrait(geom), geom::customgeom)::GeoFormatTypes.GeoFormat}
26+
# GeoInterface.crs(geomtrait(geom), geom::customgeom)::GeoFormatTypes.GeoFormat
2727
GeoInterface.extent(::MultiPointTrait, ds::Dataset) = Extent(X=(ds.header.min_x, ds.header.max_x), Y=(ds.header.min_y, ds.header.max_y), Z=(ds.header.min_z, ds.header.max_z))
2828

2929
GeoInterface.isfeaturecollection(::Type{Dataset}) = true
3030
GeoInterface.getfeature(::MultiPointTrait, ds::Dataset, i) = ds[i]
3131
GeoInterface.getfeature(::MultiPointTrait, ds::Dataset) = ds
3232
GeoInterface.nfeature(::MultiPointTrait, ds::Dataset) = length(ds)
33-
GeoInterface.geometrycolumns(::Dataset) = ()
33+
GeoInterface.geometrycolumns(::Dataset) = (:geometry,)
34+
35+
GeoInterface.isgeometry(::Type{<:AbstractVector{<:Point}}) = true
36+
GeoInterface.geomtrait(::AbstractVector{<:Point}) = MultiPointTrait()
37+
GeoInterface.ngeom(::MultiPointTrait, ds::AbstractVector{<:Point}) = length(ds)
38+
GeoInterface.getgeom(::MultiPointTrait, ds::AbstractVector{<:Point}) = ds
39+
GeoInterface.getgeom(::MultiPointTrait, ds::AbstractVector{<:Point}, i) = ds[i]

src/point.jl

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
abstract type Point end
22
struct Point0 <: Point
3-
x::Float64
4-
y::Float64
5-
z::Float64
3+
geometry::SVector{3,Float64}
64
intensity::UInt16
75
return_number::UInt8
86
number_of_returns::UInt8
@@ -17,9 +15,8 @@ struct Point0 <: Point
1715
end
1816

1917
function Point0(rp, am)
20-
x, y, z = am((rp.X, rp.Y, rp.Z))
2118
Point0(
22-
x, y, z, rp.intensity,
19+
am((rp.X, rp.Y, rp.Z)), rp.intensity,
2320
return_number(rp),
2421
number_of_returns(rp),
2522
scan_direction(rp),
@@ -33,9 +30,7 @@ function Point0(rp, am)
3330
end
3431

3532
struct Point1 <: Point
36-
x::Float64
37-
y::Float64
38-
z::Float64
33+
geometry::SVector{3,Float64}
3934
intensity::UInt16
4035
return_number::UInt8
4136
number_of_returns::UInt8
@@ -51,9 +46,8 @@ struct Point1 <: Point
5146
end
5247

5348
function Point1(rp, am)
54-
x, y, z = am((rp.X, rp.Y, rp.Z))
5549
Point1(
56-
x, y, z, rp.intensity,
50+
am((rp.X, rp.Y, rp.Z)), rp.intensity,
5751
return_number(rp),
5852
number_of_returns(rp),
5953
scan_direction(rp),
@@ -68,9 +62,7 @@ function Point1(rp, am)
6862
end
6963

7064
struct Point2 <: Point
71-
x::Float64
72-
y::Float64
73-
z::Float64
65+
geometry::SVector{3,Float64}
7466
intensity::UInt16
7567
return_number::UInt8
7668
number_of_returns::UInt8
@@ -88,9 +80,8 @@ struct Point2 <: Point
8880
end
8981

9082
function Point2(rp, am)
91-
x, y, z = am((rp.X, rp.Y, rp.Z))
9283
Point2(
93-
x, y, z, rp.intensity,
84+
am((rp.X, rp.Y, rp.Z)), rp.intensity,
9485
return_number(rp),
9586
number_of_returns(rp),
9687
scan_direction(rp),
@@ -108,9 +99,7 @@ end
10899

109100

110101
struct Point3 <: Point
111-
x::Float64
112-
y::Float64
113-
z::Float64
102+
geometry::SVector{3,Float64}
114103
intensity::UInt16
115104
return_number::UInt8
116105
number_of_returns::UInt8
@@ -129,9 +118,8 @@ struct Point3 <: Point
129118
end
130119

131120
function Point3(rp, am)
132-
x, y, z = am((rp.X, rp.Y, rp.Z))
133121
Point3(
134-
x, y, z, rp.intensity,
122+
am((rp.X, rp.Y, rp.Z)), rp.intensity,
135123
return_number(rp),
136124
number_of_returns(rp),
137125
scan_direction(rp),

src/table.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ function Base.setproperty!(p::RawPoint, name, value, header)
4848
p.return_number = UInt8(value) << 7 | UInt8(LasIO.scan_direction(p)) << 6 | LasIO.number_of_returns(p) << 3 | LasIO.return_number(p)
4949
elseif name == :point_source_id
5050
p.point_source_ID = value
51-
else
51+
elseif name == :geometry
52+
p.X = round(Int32, (value[1] - header.x_offset) / header.x_scale_factor)
53+
p.Y = round(Int32, (value[2] - header.y_offset) / header.y_scale_factor)
54+
p.Z = round(Int32, (value[3] - header.z_offset) / header.z_scale_factor)
55+
elseif name in fieldnames(typeof(p))
5256
setproperty!(p, name, value)
5357
end
5458
end
@@ -58,7 +62,7 @@ function write(fn::AbstractString, table, bbox; scalex=0.01, scaley=0.01, scalez
5862

5963
schema = Tables.schema(table)
6064
isnothing(schema) && error("A Schema is required")
61-
all(name in column_names for name in schema.names) || error("Can't map all columns to RawPoint")
65+
all(name in column_names for name in schema.names) || @warn("Can't map all columns to RawPoint")
6266

6367
rows = Tables.rows(table)
6468

test/testio.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ end
9292

9393
@test LazIO.readstring(ds.header.system_identifier) == "Laser shooter, pew pew!"
9494
@test length(ds) == 3
95-
@test first(ds).x == 11000.01
95+
@test first(ds).geometry[1] == 11000.01
9696
@test first(ds).classification == LazIO.classes.ground
9797
end
9898

@@ -169,9 +169,9 @@ end
169169
p2 = first(ds_out)
170170
header1 = ds.header
171171
header2 = ds_out.header
172-
@test p1.x === p2.x
173-
@test p1.y === p2.y
174-
@test p1.z === p2.z
172+
@test p1.geometry[1] === p2.geometry[1]
173+
@test p1.geometry[2] === p2.geometry[2]
174+
@test p1.geometry[3] === p2.geometry[3]
175175
@test p1.intensity === p2.intensity
176176
@test header1.number_of_point_records === header2.number_of_point_records
177177

@@ -197,9 +197,9 @@ end
197197
p2 = first(ds_out)
198198
header1 = ds.header
199199
header2 = ds_out.header
200-
@test p1.x === p2.x
201-
@test p1.y === p2.y
202-
@test p1.z === p2.z
200+
@test p1.geometry[1] === p2.geometry[1]
201+
@test p1.geometry[2] === p2.geometry[2]
202+
@test p1.geometry[3] === p2.geometry[3]
203203
@test p1.intensity === p2.intensity
204204
@test header1.number_of_point_records === header2.number_of_point_records
205205

@@ -212,6 +212,9 @@ end
212212
ds = LazIO.open(testfile_str)
213213
GeoInterface.testgeometry(ds)
214214
GeoInterface.testgeometry(ds[1])
215+
GeoInterface.testgeometry(collect(ds)[1:2])
215216
@test_broken GeoInterface.testfeature(ds[1])
216217
@test_broken GeoInterface.testfeaturecollection(ds)
218+
219+
@test GeoInterface.z(GeoInterface.getpoint(collect(ds)[1:2], 1)) == 846.66
217220
end

0 commit comments

Comments
 (0)