@@ -131,6 +131,105 @@ using GeometryBasics: attributes
131
131
end
132
132
end
133
133
134
+ @testset " embedding MetaT" begin
135
+ @testset " MetaT{Polygon}" begin
136
+ polys = [Polygon (rand (Point{2 , Float32}, 20 )) for i in 1 : 10 ]
137
+ multipol = MultiPolygon (polys)
138
+ pnames = [randstring (4 ) for i in 1 : 10 ]
139
+ numbers = LinRange (0.0 , 1.0 , 10 )
140
+ bin = rand (Bool, 10 )
141
+ # create a polygon
142
+ poly = MetaT (polys[1 ], name = pnames[1 ], value = numbers[1 ], category = bin[1 ])
143
+ # create a MultiPolygon with the right type & meta information!
144
+ multipoly = MetaT (multipol, name = pnames, value = numbers, category = bin)
145
+ @test multipoly isa MetaT
146
+ @test poly isa MetaT
147
+
148
+ @test GeometryBasics. getcolumn (poly, :name ) == pnames[1 ]
149
+ @test GeometryBasics. getcolumn (multipoly, :name ) == pnames
150
+
151
+ meta_p = MetaT (polys[1 ], boundingbox= Rect (0 , 0 , 2 , 2 ))
152
+ @test meta_p. boundingbox === Rect (0 , 0 , 2 , 2 )
153
+ @test GeometryBasics. metafree (meta_p) == polys[1 ]
154
+ @test GeometryBasics. metafree (poly) == polys[1 ]
155
+ @test GeometryBasics. metafree (multipoly) == multipol
156
+ @test GeometryBasics. meta (meta_p) == (boundingbox = GeometryBasics. HyperRectangle {2,Int64} ([0 , 0 ], [2 , 2 ]),)
157
+ @test GeometryBasics. meta (poly) == (name = pnames[1 ], value = 0.0 , category = bin[1 ])
158
+ @test GeometryBasics. meta (multipoly) == (name = pnames, value = numbers, category = bin)
159
+ end
160
+
161
+ @testset " MetaT{Point}" begin
162
+ p = Point (1.1 , 2.2 )
163
+ @test p isa AbstractVector{Float64}
164
+ pm = MetaT (Point (1.1 , 2.2 ); a= 1 , b= 2 )
165
+ p1 = Point (2.2 , 3.6 )
166
+ p2 = [p, p1]
167
+ @test coordinates (p2) == p2
168
+ @test pm. meta === (a= 1 , b= 2 )
169
+ @test pm. main === p
170
+ @test propertynames (pm) == (:main , :a , :b )
171
+ @test GeometryBasics. metafree (pm) == p
172
+ @test GeometryBasics. meta (pm) == (a = 1 , b = 2 )
173
+ end
174
+
175
+ @testset " MetaT{MultiPoint}" begin
176
+ p = collect (Point {2, Float64} (x, x+ 1 ) for x in 1 : 5 )
177
+ @test p isa AbstractVector
178
+ mpm = MetaT (MultiPoint (p); a= 1 , b= 2 )
179
+ @test coordinates (mpm. main) == Point{2 , Float64}[(x, x+ 1 ) for x in 1 : 5 ]
180
+ @test mpm. meta === (a= 1 , b= 2 )
181
+ @test mpm. main == p
182
+ @test propertynames (mpm) == (:main , :a , :b )
183
+ @test GeometryBasics. metafree (mpm) == p
184
+ @test GeometryBasics. meta (mpm) == (a = 1 , b = 2 )
185
+ end
186
+
187
+ @testset " MetaT{LineString}" begin
188
+ linestring = MetaT (LineString (Point{2 , Int}[(10 , 10 ), (20 , 20 ), (10 , 40 )]), a = 1 , b = 2 )
189
+ @test linestring isa MetaT
190
+ @test linestring. meta === (a = 1 , b = 2 )
191
+ @test propertynames (linestring) == (:main , :a , :b )
192
+ @test GeometryBasics. metafree (linestring) == LineString (Point{2 , Int}[(10 , 10 ), (20 , 20 ), (10 , 40 )])
193
+ @test GeometryBasics. meta (linestring) == (a = 1 , b = 2 )
194
+ end
195
+
196
+ @testset " MetaT{MultiLineString}" begin
197
+ linestring1 = LineString (Point{2 , Int}[(10 , 10 ), (20 , 20 ), (10 , 40 )])
198
+ linestring2 = LineString (Point{2 , Int}[(40 , 40 ), (30 , 30 ), (40 , 20 ), (30 , 10 )])
199
+ multilinestring = MultiLineString ([linestring1, linestring2])
200
+ multilinestringmeta = MetaT (MultiLineString ([linestring1, linestring2]); boundingbox = Rect (1.0 , 1.0 , 2.0 , 2.0 ))
201
+ @test multilinestringmeta isa MetaT
202
+ @test multilinestringmeta. meta === (boundingbox = Rect (1.0 , 1.0 , 2.0 , 2.0 ),)
203
+ @test multilinestringmeta. main == multilinestring
204
+ @test propertynames (multilinestringmeta) == (:main , :boundingbox )
205
+ @test GeometryBasics. metafree (multilinestringmeta) == multilinestring
206
+ @test GeometryBasics. meta (multilinestringmeta) == (boundingbox = GeometryBasics. HyperRectangle {2,Float64} ([1.0 , 1.0 ], [2.0 , 2.0 ]),)
207
+ end
208
+
209
+ #=
210
+ So mesh works differently for MetaT
211
+ since `MetaT{Point}` not subtyped to `AbstractPoint`
212
+ =#
213
+
214
+ @testset " MetaT{Mesh}" begin
215
+ @testset " per vertex attributes" begin
216
+ points = rand (Point{3 , Float64}, 8 )
217
+ tfaces = TetrahedronFace{Int}[(1 , 2 , 3 , 4 ), (5 , 6 , 7 , 8 )]
218
+ normals = rand (SVector{3 , Float64}, 8 )
219
+ stress = LinRange (0 , 1 , 8 )
220
+ mesh_nometa = Mesh (points, tfaces)
221
+ mesh = MetaT (mesh_nometa, normals = normals, stress = stress)
222
+
223
+ @test hasproperty (mesh, :stress )
224
+ @test hasproperty (mesh, :normals )
225
+ @test mesh. stress == stress
226
+ @test mesh. normals == normals
227
+ @test GeometryBasics. faces (mesh. main) == tfaces
228
+ @test propertynames (mesh) == (:main , :normals , :stress )
229
+ end
230
+ end
231
+ end
232
+
134
233
@testset " view" begin
135
234
@testset " TupleView" begin
136
235
x = [1 , 2 , 3 , 4 , 5 , 6 ]
505
604
@test < (x, x1)
506
605
end
507
606
607
+ @testset " MetaT and heterogeneous data" begin
608
+ ls = [LineString ([Point (i, (i+ 1 )^ 2 / 6 ), Point (i* 0.86 ,i+ 5 ), Point (i/ 3 , i/ 7 )]) for i in 1 : 10 ]
609
+ mls = MultiLineString ([LineString ([Point (i+ 1 , (i)^ 2 / 6 ), Point (i* 0.75 ,i+ 8 ), Point (i/ 2.5 , i/ 6.79 )]) for i in 5 : 10 ])
610
+ poly = Polygon (Point{2 , Int}[(40 , 40 ), (20 , 45 ), (45 , 30 ), (40 , 40 )])
611
+ geom = [ls... , mls, poly]
612
+ prop = Any[(country_states = " India$(i) " , rainfall = (i* 9 )/ 2 ) for i in 1 : 11 ]
613
+ push! (prop, (country_states = 12 , rainfall = 1000 )) # a pinch of heterogeneity
614
+
615
+ feat = [MetaT (i, j) for (i,j) = zip (geom, prop)]
616
+ sa = meta_table (feat)
617
+
618
+ @test nameof (eltype (feat)) == :MetaT
619
+ @test eltype (sa) === MetaT{Any,(:country_states , :rainfall ),Tuple{Any,Float64}}
620
+ @test propertynames (sa) === (:main , :country_states , :rainfall )
621
+ @test getproperty (sa, :country_states ) isa Array{Any}
622
+ @test getproperty (sa, :main ) == geom
623
+
624
+ @test GeometryBasics. getnamestypes (typeof (feat[1 ])) ==
625
+ (LineString{2 ,Float64,Point{2 ,Float64},Base. ReinterpretArray{GeometryBasics. Ngon{2 ,Float64,2 ,Point{2 ,Float64}},1 ,Tuple{Point{2 ,Float64},Point{2 ,Float64}},TupleView{Tuple{Point{2 ,Float64},Point{2 ,Float64}},2 ,1 ,Array{Point{2 ,Float64},1 }}}},
626
+ (:country_states , :rainfall ), Tuple{String,Float64})
627
+
628
+ @test StructArrays. staticschema (typeof (feat[1 ])) ==
629
+ NamedTuple{(:main , :country_states , :rainfall ),Tuple{LineString{2 ,Float64,Point{2 ,Float64},Base. ReinterpretArray{GeometryBasics. Ngon{2 ,Float64,2 ,Point{2 ,Float64}},1 ,Tuple{Point{2 ,Float64},Point{2 ,Float64}},TupleView{Tuple{Point{2 ,Float64},Point{2 ,Float64}},2 ,1 ,Array{Point{2 ,Float64},1 }}}},
630
+ String,Float64}}
631
+
632
+ @test StructArrays. createinstance (typeof (feat[1 ]), LineString ([Point (1 , (2 )^ 2 / 6 ), Point (1 * 0.86 ,6 ), Point (1 / 3 , 1 / 7 )]), " Mumbai" , 100 ) isa typeof (feat[1 ])
633
+
634
+ @test Base. getindex (feat[1 ], 1 ) isa Line
635
+ @test Base. size (feat[1 ]) == (2 ,)
636
+ end
637
+
508
638
@testset " Tests from GeometryTypes" begin
509
639
include (" geometrytypes.jl" )
510
640
end
0 commit comments