Skip to content

Commit

Permalink
Enable Feature by using a geometry field instead of separate x y z.
Browse files Browse the repository at this point in the history
  • Loading branch information
evetion committed Jan 10, 2023
1 parent c886252 commit 0e2e695
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 39 deletions.
26 changes: 16 additions & 10 deletions src/geointerface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,38 @@ import GeoInterface as GI

GeoInterface.isgeometry(::Type{<:Point}) = true
GeoInterface.geomtrait(::Point) = PointTrait()
# GeoInterface.trait(::Point) = FeatureTrait()
GeoInterface.trait(::Point) = FeatureTrait()

GeoInterface.ncoord(::PointTrait, p::Point) = 3
GeoInterface.getcoord(::PointTrait, p::Point) = [p.x, p.y, p.z]
GeoInterface.getcoord(::PointTrait, p::Point, i) = getfield(p, i)
GeoInterface.getcoord(::PointTrait, p::Point) = p.geometry
GeoInterface.getcoord(::PointTrait, p::Point, i) = p.geometry[i]

GeoInterface.x(::PointTrait, p::Point) = p.x
GeoInterface.y(::PointTrait, p::Point) = p.y
GeoInterface.z(::PointTrait, p::Point) = p.z
GeoInterface.x(::PointTrait, p::Point) = p.geometry[1]
GeoInterface.y(::PointTrait, p::Point) = p.geometry[2]
GeoInterface.z(::PointTrait, p::Point) = p.geometry[3]

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

GeoInterface.isgeometry(::Type{<:Dataset}) = true
GeoInterface.geomtrait(::Dataset) = MultiPointTrait()
# GeoInterface.trait(::Dataset) = FeatureCollectionTrait()
GeoInterface.trait(::Dataset) = FeatureCollectionTrait()
GeoInterface.ngeom(::MultiPointTrait, ds::Dataset) = length(ds)
GeoInterface.getgeom(::MultiPointTrait, ds::Dataset) = ds
GeoInterface.getgeom(::MultiPointTrait, ds::Dataset, i) = ds[i]

# GeoInterface.crs(geomtrait(geom), geom::customgeom)::GeoFormatTypes.GeoFormat}
# GeoInterface.crs(geomtrait(geom), geom::customgeom)::GeoFormatTypes.GeoFormat
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))

GeoInterface.isfeaturecollection(::Type{Dataset}) = true
GeoInterface.getfeature(::MultiPointTrait, ds::Dataset, i) = ds[i]
GeoInterface.getfeature(::MultiPointTrait, ds::Dataset) = ds
GeoInterface.nfeature(::MultiPointTrait, ds::Dataset) = length(ds)
GeoInterface.geometrycolumns(::Dataset) = ()
GeoInterface.geometrycolumns(::Dataset) = (:geometry,)

GeoInterface.isgeometry(::Type{<:AbstractVector{<:Point}}) = true
GeoInterface.geomtrait(::AbstractVector{<:Point}) = MultiPointTrait()
GeoInterface.ngeom(::MultiPointTrait, ds::AbstractVector{<:Point}) = length(ds)
GeoInterface.getgeom(::MultiPointTrait, ds::AbstractVector{<:Point}) = ds
GeoInterface.getgeom(::MultiPointTrait, ds::AbstractVector{<:Point}, i) = ds[i]
28 changes: 8 additions & 20 deletions src/point.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
abstract type Point end
struct Point0 <: Point
x::Float64
y::Float64
z::Float64
geometry::SVector{3,Float64}
intensity::UInt16
return_number::UInt8
number_of_returns::UInt8
Expand All @@ -17,9 +15,8 @@ struct Point0 <: Point
end

function Point0(rp, am)
x, y, z = am((rp.X, rp.Y, rp.Z))
Point0(
x, y, z, rp.intensity,
am((rp.X, rp.Y, rp.Z)), rp.intensity,
return_number(rp),
number_of_returns(rp),
scan_direction(rp),
Expand All @@ -33,9 +30,7 @@ function Point0(rp, am)
end

struct Point1 <: Point
x::Float64
y::Float64
z::Float64
geometry::SVector{3,Float64}
intensity::UInt16
return_number::UInt8
number_of_returns::UInt8
Expand All @@ -51,9 +46,8 @@ struct Point1 <: Point
end

function Point1(rp, am)
x, y, z = am((rp.X, rp.Y, rp.Z))
Point1(
x, y, z, rp.intensity,
am((rp.X, rp.Y, rp.Z)), rp.intensity,
return_number(rp),
number_of_returns(rp),
scan_direction(rp),
Expand All @@ -68,9 +62,7 @@ function Point1(rp, am)
end

struct Point2 <: Point
x::Float64
y::Float64
z::Float64
geometry::SVector{3,Float64}
intensity::UInt16
return_number::UInt8
number_of_returns::UInt8
Expand All @@ -88,9 +80,8 @@ struct Point2 <: Point
end

function Point2(rp, am)
x, y, z = am((rp.X, rp.Y, rp.Z))
Point2(
x, y, z, rp.intensity,
am((rp.X, rp.Y, rp.Z)), rp.intensity,
return_number(rp),
number_of_returns(rp),
scan_direction(rp),
Expand All @@ -108,9 +99,7 @@ end


struct Point3 <: Point
x::Float64
y::Float64
z::Float64
geometry::SVector{3,Float64}
intensity::UInt16
return_number::UInt8
number_of_returns::UInt8
Expand All @@ -129,9 +118,8 @@ struct Point3 <: Point
end

function Point3(rp, am)
x, y, z = am((rp.X, rp.Y, rp.Z))
Point3(
x, y, z, rp.intensity,
am((rp.X, rp.Y, rp.Z)), rp.intensity,
return_number(rp),
number_of_returns(rp),
scan_direction(rp),
Expand Down
8 changes: 6 additions & 2 deletions src/table.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ function Base.setproperty!(p::RawPoint, name, value, header)
p.return_number = UInt8(value) << 7 | UInt8(LasIO.scan_direction(p)) << 6 | LasIO.number_of_returns(p) << 3 | LasIO.return_number(p)
elseif name == :point_source_id
p.point_source_ID = value
else
elseif name == :geometry
p.X = round(Int32, (value[1] - header.x_offset) / header.x_scale_factor)
p.Y = round(Int32, (value[2] - header.y_offset) / header.y_scale_factor)
p.Z = round(Int32, (value[3] - header.z_offset) / header.z_scale_factor)
elseif name in fieldnames(typeof(p))
setproperty!(p, name, value)
end
end
Expand All @@ -58,7 +62,7 @@ function write(fn::AbstractString, table, bbox; scalex=0.01, scaley=0.01, scalez

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

rows = Tables.rows(table)

Expand Down
17 changes: 10 additions & 7 deletions test/testio.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ end

@test LazIO.readstring(ds.header.system_identifier) == "Laser shooter, pew pew!"
@test length(ds) == 3
@test first(ds).x == 11000.01
@test first(ds).geometry[1] == 11000.01
@test first(ds).classification == LazIO.classes.ground
end

Expand Down Expand Up @@ -169,9 +169,9 @@ end
p2 = first(ds_out)
header1 = ds.header
header2 = ds_out.header
@test p1.x === p2.x
@test p1.y === p2.y
@test p1.z === p2.z
@test p1.geometry[1] === p2.geometry[1]
@test p1.geometry[2] === p2.geometry[2]
@test p1.geometry[3] === p2.geometry[3]
@test p1.intensity === p2.intensity
@test header1.number_of_point_records === header2.number_of_point_records

Expand All @@ -197,9 +197,9 @@ end
p2 = first(ds_out)
header1 = ds.header
header2 = ds_out.header
@test p1.x === p2.x
@test p1.y === p2.y
@test p1.z === p2.z
@test p1.geometry[1] === p2.geometry[1]
@test p1.geometry[2] === p2.geometry[2]
@test p1.geometry[3] === p2.geometry[3]
@test p1.intensity === p2.intensity
@test header1.number_of_point_records === header2.number_of_point_records

Expand All @@ -212,6 +212,9 @@ end
ds = LazIO.open(testfile_str)
GeoInterface.testgeometry(ds)
GeoInterface.testgeometry(ds[1])
GeoInterface.testgeometry(collect(ds)[1:2])
@test_broken GeoInterface.testfeature(ds[1])
@test_broken GeoInterface.testfeaturecollection(ds)

@test GeoInterface.z(GeoInterface.getpoint(collect(ds)[1:2], 1)) == 846.66
end

2 comments on commit 0e2e695

@evetion
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/75463

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.4.0 -m "<description of version>" 0e2e69518147e2edb7513e67453c8a3708d5ac00
git push origin v0.4.0

Please sign in to comment.