1
+ using XML
2
+
3
+ import WellKnownGeometry
4
+ import GeoFormatTypes as GFT
5
+ import GeometryOps as GO
6
+ import GeoInterface as GI
7
+
8
+ """
9
+ jts_wkt_to_geom(wkt::String)
10
+
11
+ Convert a JTS WKT string to a GeometryOps geometry, via WellKnownGeometry.jl and GO.tuples.
12
+
13
+ The reason this exists is because WellKnownGeometry doesn't work well with newlines in subsidiary geometries,
14
+ so this sanitizes the input before parsing and converting.
15
+ """
16
+ function jts_wkt_to_geom (wkt:: String )
17
+ sanitized_wkt = join (strip .(split (wkt, " \n " )), " " )
18
+ geom = GFT. WellKnownText (GFT. Geom (), sanitized_wkt)
19
+ return GO. tuples (geom)
20
+ end
21
+
22
+ struct TestItem{T}
23
+ operation:: String
24
+ arg1:: GO.GI.Wrappers.WrapperGeometry
25
+ arg2:: GO.GI.Wrappers.WrapperGeometry
26
+ expected_result:: T
27
+ end
28
+
29
+ Base. show (io:: IO , :: MIME"text/plain" , item:: TestItem ) = print (io, " TestItem(operation = $(item. operation) , expects $(GI. trait (item. expected_result)) )" )
30
+ Base. show (io:: IO , item:: TestItem ) = show (io, MIME " text/plain" (), item)
31
+
32
+ struct Case
33
+ description:: String
34
+ geom_a:: GO.GI.Wrappers.WrapperGeometry
35
+ geom_b:: GO.GI.Wrappers.WrapperGeometry
36
+ items:: Vector{TestItem}
37
+ end
38
+
39
+ function load_test_cases (filepath:: String )
40
+ doc = read (filepath, XML. Node) # lazy parsing
41
+ run = only (children (doc))
42
+ test_cases = Case[]
43
+ for case in children (run)
44
+ if tag (case) != " case"
45
+ continue
46
+ end
47
+ push! (test_cases, parse_case (case))
48
+ end
49
+ return test_cases
50
+ end
51
+
52
+ function parse_case (case:: XML.Node )
53
+ description = value (only (children (case. children[1 ])))
54
+ a = jts_wkt_to_geom (value (only (children (case. children[2 ]))))
55
+ b = jts_wkt_to_geom (value (only (children (case. children[3 ]))))
56
+
57
+ items = TestItem[]
58
+ for item in children (case)[4 : end ]
59
+ ops = children (item)
60
+ for op in ops
61
+ op_attrs = XML. attributes (op)
62
+ operation = op_attrs[" name" ]
63
+ arg1 = op_attrs[" arg1" ]
64
+ arg2 = op_attrs[" arg2" ]
65
+ expected_result = jts_wkt_to_geom (value (only (op. children)))
66
+ push! (items, TestItem (operation, lowercase (arg1) == " a" ? a : b, lowercase (arg2) == " a" ? a : b, expected_result))
67
+ end
68
+ end
69
+ return Case (description, a, b, items)
70
+ end
71
+
72
+
73
+ testfile = " /Users/anshul/.julia/dev/geo/jts/modules/tests/src/test/resources/testxml/general/TestOverlayAA.xml"
74
+
75
+ cases = load_test_cases (testfile)
76
+
77
+ using Test
78
+
79
+ for case in cases
80
+ @testset " $(case. description) " begin
81
+ for item in case. items
82
+ @testset " $(item. operation) " begin
83
+ result = if item. operation == " union"
84
+ GO. union (item. arg1, item. arg2; target = GO. PolygonTrait ())
85
+ elseif item. operation == " difference"
86
+ GO. difference (item. arg1, item. arg2; target = GO. PolygonTrait ())
87
+ elseif item. operation == " intersection"
88
+ GO. intersection (item. arg1, item. arg2; target = GO. PolygonTrait ())
89
+ elseif item. operation == " symdifference"
90
+ continue
91
+ else
92
+ continue
93
+ end
94
+
95
+ finalresult = if length (result) == 0
96
+ nothing
97
+ elseif length (result) == 1
98
+ only (result)
99
+ else
100
+ GI. MultiPolygon (result)
101
+ end
102
+
103
+ if isnothing (finalresult)
104
+ @warn (" No result" )
105
+ continue
106
+ end
107
+
108
+ if GI. geomtrait (item. expected_result) isa Union{GI. MultiPolygonTrait, GI. PolygonTrait}
109
+ difference_in_areas = GO. area (GO. difference (finalresult, item. expected_result; target = GO. PolygonTrait ()))
110
+ if difference_in_areas > 1
111
+ @warn (" Difference in areas: $(difference_in_areas) " )
112
+ f, a, p = poly (finalresult; label = " Final result (GO)" , axis = (; title = " $(case. description) - $(item. operation) " ))
113
+ poly! (a, item. expected_result; label = " Expected result (JTS)" )
114
+ display (f)
115
+ end
116
+ # @test difference_in_areas < 1
117
+ else
118
+ @test_broken GO. equals (finalresult, item. expected_result)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
0 commit comments