diff --git a/src/writer.jl b/src/writer.jl index 1966a06..bdbabcf 100644 --- a/src/writer.jl +++ b/src/writer.jl @@ -121,7 +121,7 @@ function write(path::AbstractString, o::Writer; force=false) # Detect the shape type code from the first available geometry # There can only be one shape type in the file. # If all values are missing, the shape type is Missing - if iterate(skipmissing(geoms)) == nothing + if isnothing(iterate(skipmissing(geoms))) trait = Missing hasz = hasm = false else @@ -295,7 +295,7 @@ function _write(io::IO, trait::GI.AbstractGeometryTrait, geom; kw...) end # write x/y part of points for point in GI.getpoint(geom) - x, y = GI.x(point), GI.y(point) + x, y = Float64(GI.x(point)), Float64(GI.y(point)) bytes += Base.write(io, x) bytes += Base.write(io, y) end @@ -334,7 +334,7 @@ function _calc_mbr(geom) low_x = low_y = Inf high_x = high_y = -Inf for point in GI.getpoint(geom) - x, y = GI.x(point), GI.y(point) + x, y = Float64(GI.x(point)), Float64(GI.y(point)) low_x = min(low_x, x) high_x = max(high_x, x) low_y = min(low_y, y) @@ -350,14 +350,14 @@ function _write_others(io, geom; bytes = 0 # TODO what to do when hasm == false but hasz == true if hasz - b, zrange = _write_others(GI.z, io, geom) + b, zrange = _write_others(p -> Float64(GI.z(p)), io, geom) bytes += b else zrange = Interval(0.0, 0.0) end if hasm - b, mrange = _write_others(GI.m, io, geom) + b, mrange = _write_others(p -> Float64(GI.m(p)), io, geom) bytes += b else mrange = Interval(0.0, 0.0) diff --git a/test/writer.jl b/test/writer.jl index ea19da8..5c49a62 100644 --- a/test/writer.jl +++ b/test/writer.jl @@ -34,6 +34,39 @@ t = Shapefile.Table(file) @test only(t.geometry) == Polygon(box, [0], ps) + # Float32 coordinates + struct Point32 + x::Float32 + y::Float32 + end + + struct LineString32 + points::Vector{Point32} + end + + # basic GI interface implementation + GI.isgeometry(::Type{Point32}) = true + GI.geomtrait(::Point32) = GI.PointTrait() + GI.ncoord(::GI.PointTrait, p::Point32) = 2 + GI.getcoord(::GI.PointTrait, p::Point32, i) = getfield(p, i) + + GI.isgeometry(::Type{LineString32}) = true + GI.geomtrait(::LineString32) = GI.LineStringTrait() + GI.ncoord(::GI.LineStringTrait, p::LineString32) = 2 + GI.ngeom(::GI.LineStringTrait, l::LineString32) = length(l.points) + GI.getgeom(::GI.LineStringTrait, l::LineString32, i) = getindex(l.points, i) + + file = tempname() + Shapefile.write(file, Point32(0, 0)) + t = Shapefile.Table(file) + @test only(t.geometry) == Point(0, 0) + + file = tempname() + geom = LineString32([Point32(0, 0), Point32(1, 0), Point32(1, 1), Point32(0, 1)]) + Shapefile.write(file, geom) + t = Shapefile.Table(file) + @test only(t.geometry) == Polyline(Rect(0, 0, 1, 1), [0], [Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)]) + # feature struct F end GI.trait(::F) = GI.FeatureCollectionTrait()