diff --git a/README.md b/README.md index 0944cb63..9ad8e5c2 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,11 @@ julia> metafree(poi) 3 1 +# for other geometries metatypes are predefined +julia> multipoi = MultiPointMeta([p1], city="Abuja", rainfall=1221.2) +1-element MultiPointMeta{Point{2,Int64},MultiPoint{2,Int64,Point{2,Int64},Array{Point{2,Int64},1}},(:city, :rainfall),Tuple{String,Float64}}: +[3, 1] + # connect the points with lines julia> l1 = Line(p1, p2) Line([3, 1] => [1, 3]) diff --git a/src/GeometryBasics.jl b/src/GeometryBasics.jl index a2f5def4..9dcef8b2 100644 --- a/src/GeometryBasics.jl +++ b/src/GeometryBasics.jl @@ -29,7 +29,7 @@ module GeometryBasics export OffsetInteger, ZeroIndex, OneIndex, GLIndex export FaceView, SimpleFaceView export AbstractPoint, PointMeta, PointWithUV - export PolygonMeta, MultiPointMeta, MultiLineStringMeta, MeshMeta + export PolygonMeta, MultiPointMeta, MultiLineStringMeta, MeshMeta, LineStringMeta, MultiPolygonMeta export decompose, coordinates, faces, normals, decompose_uv, decompose_normals, texturecoordinates export Tesselation, pointmeta, Normal, UV, UVW export GLTriangleFace, GLNormalMesh3D, GLPlainTriangleMesh, GLUVMesh3D, GLUVNormalMesh3D diff --git a/src/metadata.jl b/src/metadata.jl index dbb51196..16983a73 100644 --- a/src/metadata.jl +++ b/src/metadata.jl @@ -171,6 +171,10 @@ Base.getindex(x::SimplexFaceMeta, idx::Int) = getindex(metafree(x), idx) @meta_type(Polygon, polygon, AbstractPolygon, N, T) +@meta_type(LineString, lines, AbstractVector, P <: Line) +Base.getindex(x::LineStringMeta, idx::Int) = getindex(metafree(x), idx) +Base.size(x::LineStringMeta) = size(metafree(x)) + @meta_type(MultiPoint, points, AbstractVector, P <: AbstractPoint) Base.getindex(x::MultiPointMeta, idx::Int) = getindex(metafree(x), idx) Base.size(x::MultiPointMeta) = size(metafree(x)) @@ -179,6 +183,10 @@ Base.size(x::MultiPointMeta) = size(metafree(x)) Base.getindex(x::MultiLineStringMeta, idx::Int) = getindex(metafree(x), idx) Base.size(x::MultiLineStringMeta) = size(metafree(x)) +@meta_type(MultiPolygon, polygons, AbstractVector, P <: Polygon) +Base.getindex(x::MultiPolygonMeta, idx::Int) = getindex(metafree(x), idx) +Base.size(x::MultiPolygonMeta) = size(metafree(x)) + @meta_type(Mesh, mesh, AbstractMesh, Element <: Polytope) Base.getindex(x::MeshMeta, idx::Int) = getindex(metafree(x), idx) Base.size(x::MeshMeta) = size(metafree(x)) diff --git a/test/runtests.jl b/test/runtests.jl index 6ea81c9b..6e4ff6aa 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -56,38 +56,31 @@ using GeometryBasics: attributes end end + @testset "polygon with metadata" begin polys = [Polygon(rand(Point{2, Float32}, 20)) for i in 1:10] pnames = [randstring(4) for i in 1:10] numbers = LinRange(0.0, 1.0, 10) bin = rand(Bool, 10) - # create just an array - plain = meta(polys, name = pnames, value = numbers, category = bin) + # create a polygon + poly = PolygonMeta(polys[1], name = pnames[1], value = numbers[1], category = bin[1]) # create a MultiPolygon with the right type & meta information! - multipoly = MultiPolygon(polys; name = pnames, value = numbers, category = bin) - for x in (plain, multipoly) - for (mp, p, n, num, b) in zip(x, polys, pnames, numbers, bin) - @test mp.polygon == p - @test mp.name == n - @test mp.value == num - @test mp.category == b - end - - filtered = filter(i -> i.value < 0.7, x) - @test length(filtered) == 7 - end - @test GeometryBasics.getcolumn(plain, :name) == pnames - @test GeometryBasics.MetaType(Polygon) == PolygonMeta - @test_throws ErrorException GeometryBasics.meta(plain) + multipoly = MultiPolygonMeta(polys, name = pnames, value = numbers, category = bin) + @test multipoly isa AbstractVector + @test poly isa GeometryBasics.AbstractPolygon + + @test GeometryBasics.getcolumn(poly, :name) == pnames[1] @test GeometryBasics.MetaFree(PolygonMeta) == Polygon + @test GeometryBasics.getcolumn(multipoly, :name) == pnames + @test GeometryBasics.MetaFree(MultiPolygonMeta) == MultiPolygon + meta_p = meta(polys[1], boundingbox=Rect(0, 0, 2, 2)) @test meta_p.boundingbox === Rect(0, 0, 2, 2) @test metafree(meta_p) === polys[1] attributes(meta_p) == Dict{Symbol, Any}(:boundingbox => meta_p.boundingbox, :polygon => polys[1]) end - @testset "point with metadata" begin p = Point(1.1, 2.2) @test p isa AbstractVector{Float64} @@ -99,8 +92,26 @@ using GeometryBasics: attributes @test metafree(pm) === p @test propertynames(pm) == (:position, :a, :b) end + + @testset "MultiPoint with metadata" begin + p = collect(Point{2, Float64}(x, x+1) for x in 1:5) + @test p isa AbstractVector + mpm = MultiPointMeta(p, a=1, b=2) + @test coordinates(mpm) == mpm + @test meta(mpm) === (a=1, b=2) + @test metafree(mpm) == p + @test propertynames(mpm) == (:points, :a, :b) + end + + @testset "LineString with metadata" begin + linestring = LineStringMeta(Point{2, Int}[(10, 10), (20, 20), (10, 40)], a = 1, b = 2) + @test linestring isa AbstractVector + @test meta(linestring) === (a = 1, b = 2) + @test metafree(linestring) == linestring + @test propertynames(linestring) == (:lines, :a, :b) + end - @testset "MultiLineString with metadata" begin + @testset "MultiLineString with metadata" begin linestring1 = LineString(Point{2, Int}[(10, 10), (20, 20), (10, 40)]) linestring2 = LineString(Point{2, Int}[(40, 40), (30, 30), (40, 20), (30, 10)]) multilinestring = MultiLineString([linestring1, linestring2])