/
TestValid.xml
630 lines (553 loc) · 20.7 KB
/
TestValid.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
<run>
<precisionModel scale="1.0" offsetx="0.0" offsety="0.0"/>
<case>
<desc>P - point (valid)</desc>
<a>
POINT(10 10)
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>P - empty point (valid)</desc>
<a>
POINT EMPTY
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mP - no repeated points (valid)</desc>
<a>
MULTIPOINT((10 10), (20 20), (30 30))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mP - repeated points (valid)</desc>
<a>
MULTIPOINT((10 10), (20 20), (30 30), (10 10))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>L - empty (valid)</desc>
<a>
LINESTRING EMPTY
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>L - no repeated points (valid)</desc>
<a>
LINESTRING (40 180, 120 120, 140 200, 200 140, 240 200)
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>L - repeated points (valid)</desc>
<a>
LINESTRING (40 180, 120 120, 140 200, 140 200, 200 140, 240 200)
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>L - linestring bowtie (valid)</desc>
<a>LINESTRING(0 0, 100 100, 100 0, 0 100, 0 0)</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mL - MultiLinestring with empty component (valid)</desc>
<a>MULTILINESTRING((1 1, 0 0), EMPTY)</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>LR - linear-ring (valid)</desc>
<a>LINEARRING (100 200, 200 200, 200 100, 100 100, 100 200)</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - polygon with repeated point (valid) </desc>
<a>POLYGON ((107 246, 107 246, 250 285, 294 137, 151 90, 15 125, 157 174, 107 246))</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - with hole (valid)</desc>
<a>POLYGON ((0 60, 0 0, 60 0, 60 60, 0 60), (20 40, 20 20, 40 20, 40 40, 20 40))</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - shell has repeated points (valid)</desc>
<a>POLYGON ((0 60, 0 0, 0 0, 60 0, 60 60, 0 60), (20 40, 20 20, 40 20, 40 40, 20 40))</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - shell touches hole (valid)</desc>
<a>POLYGON ((0 60, 0 0, 60 0, 60 60, 0 60), (20 40, 20 20, 60 20, 20 40))</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - non-empty shell and empty hole (valid)</desc>
<a>POLYGON ((60 280, 260 180, 60 80, 60 280), EMPTY)</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - empty shell and holes (valid)</desc>
<a>POLYGON (EMPTY, EMPTY, EMPTY)</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - hole with repeated points (valid) </desc>
<a>
POLYGON ((40 260, 40 60, 120 60, 180 160, 240 60, 300 60, 300 260, 40 260),
(70 230, 80 230, 80 220, 80 220, 70 230)) </a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - hole touches hole (valid) </desc>
<a>POLYGON ((0 120, 0 0, 140 0, 140 120, 0 120), (100 100, 100 20, 120 20, 120 100, 100 100), (20 100, 20 40, 100 40, 20 100))</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - hole touches shell at non-vertex (valid)</desc>
<a>
POLYGON ((240 260, 40 260, 40 80, 240 80, 240 260),
(140 180, 40 180, 140 240, 140 180))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - hole touches shell at vertex (valid)</desc>
<a>
POLYGON ((240 260, 40 260, 40 80, 240 80, 240 260),
(140 180, 40 260, 140 240, 140 180))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - holes do not overlap, first point is identical (valid) </desc>
<a>
POLYGON ((20 320, 240 320, 240 40, 20 40, 20 320),
(140 180, 60 120, 60 240, 140 180),
(140 180, 200 120, 200 240, 140 180))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - holes touch at one point (valid) </desc>
<a>
POLYGON ((190 190, 360 20, 20 20, 190 190),
(90 50, 150 110, 190 50, 90 50),
(190 50, 230 110, 290 50, 190 50))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>A - multiple holes touch at one point (valid) </desc>
<a>
POLYGON ((10 90, 90 90, 90 10, 10 10, 10 90), (40 80, 60 80, 50 50, 40 80), (20 60, 20 40, 50 50, 20 60), (40 20, 60 20, 50 50, 40 20), (80 60, 80 40, 50 50, 80 60))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mA - shell inside hole, no touch (valid) </desc>
<a>
MULTIPOLYGON (((60 320, 60 80, 300 80, 60 320),
(80 280, 80 100, 260 100, 80 280)),
((120 160, 140 160, 140 140, 120 160)))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mA - shell inside hole, all shell vertices touch (valid) </desc>
<a>
MULTIPOLYGON (((20 380, 420 380, 420 20, 20 20, 20 380),
(220 340, 180 240, 60 200, 180 160, 340 60, 240 220, 220 340)),
((180 240, 180 160, 240 220, 180 240)))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mA - shells touch, disconnected exterior (valid) </desc>
<a>
MULTIPOLYGON (((100 20, 180 20, 180 100, 100 100, 100 20)),
((20 100, 100 100, 100 180, 20 180, 20 100)),
((100 180, 180 180, 180 260, 100 260, 100 180)),
((180 100, 260 100, 260 180, 180 180, 180 100)))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mA - shells touch at one point (valid) </desc>
<a>
MULTIPOLYGON (((110 110, 70 200, 150 200, 110 110)),
((110 110, 150 20, 70 20, 110 110)))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mA - shell touches other shell at all vertices (valid) </desc>
<a>
MULTIPOLYGON (((180 60, 240 160, 300 60, 180 60)),
((80 80, 180 60, 160 140, 240 160, 360 140, 300 60, 420 100, 320 280, 120 260, 80 80)))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mA - shell is inside hole (valid) </desc>
<a>
MULTIPOLYGON (((0 0, 0 8, 8 8, 8 0, 0 0),
(3 3, 7 3, 7 7, 3 7, 3 3),
(1 1, 2 1, 2 2, 1 2, 1 1)),
((4 4, 4 6, 6 6, 6 4, 4 4)))
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<case>
<desc>mA - non-empty and empty polygon (valid) </desc>
<a> MULTIPOLYGON (((30 10, 40 40, 20 40, 10 20, 30 10)), EMPTY)
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
<!-- ================================================ -->
<case>
<desc>P - invalid NaN X ordinate</desc>
<a>
POINT(NaN 10)
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>P - invalid NaN Y ordinate</desc>
<a>
POINT(10 NaN)
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mP - NaN ordinate</desc>
<a>
MULTIPOINT((10 10), (20 20), (30 30), (10 NaN))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>L - NaN ordinate</desc>
<a>
LINESTRING (40 180, 120 120, 140 200, 200 140, NaN 200)
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>L - linestring with two identical points (too few distinct points) </desc>
<a>LINESTRING(0 0, 0 0)</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mL - MultiLinestring with two identical points in first component (too few distinct points)</desc>
<a>MULTILINESTRING((0 0, 0 0), (1 1, 0 0))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mL - MultiLinestring with two identical points in second component (too few distinct points)</desc>
<a>MULTILINESTRING((1 1, 0 0), (0 0, 0 0))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mL - MultiLinestring with invalid point</desc>
<a>MULTILINESTRING((1 1, 2 NaN, 0 0))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>LR - linear-ring bowtie (self-intersection)</desc>
<a>LINEARRING(0 0, 100 100, 100 0, 0 100, 0 0)</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - zero-area polygon (too few distinct points) </desc>
<a>POLYGON ((0 0, 0 0, 0 0, 0 0, 0 0))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - zero-area polygon with multiple points (self-intersection) </desc>
<a>POLYGON ((0 0, 10 0, 20 0, 0 0, 0 0))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - polygon with too few points (too few distinct points) </desc>
<a>POLYGON ((0 0, 10 10, 0 0))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - polygon with invalid point </desc>
<a>POLYGON ((0 0, 10 NaN, 20 0, 0 10, 0 0))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - polygon with degenerate hole ring A-B-C-B--A (self-intersection) </desc>
<a>POLYGON ((0 0, 0 240, 260 240, 260 0, 0 0),
(220 200, 40 200, 40 20, 40 200, 220 200, 220 200))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mA - multipolygon with component with too few points (too few distinct points) </desc>
<a>MULTIPOLYGON ( ((100 20, 180 20, 180 100, 100 100, 100 20)),
((20 100, 100 100, 100 180, 20 180, 20 100)),
((100 180, 180 180, 180 260, 100 260, 100 180)),
((180 100, 180 180, 180 180, 180 100)))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - shell self-touches at vertex (self-intersection) </desc>
<a>
POLYGON ((340 320, 340 200, 200 280, 200 80, 340 200, 340 20, 60 20, 60 340, 340 320))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - shell self-touches at non-vertex (self-intersection) </desc>
<a>
POLYGON ((300 320, 300 220, 260 260, 180 220, 360 220, 360 140, 120 140, 120 320, 300 320)) </a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - shell self-crosses at non-vertex (self-intersection)</desc>
<a>POLYGON ((0 40, 0 0, 40 40, 40 0, 0 40))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - shell self-crosses at vertex (self-intersection)</desc>
<a>MULTIPOLYGON ( ((0 40, 20 20, 40 0, 40 40, 20 20, 0 0, 0 40)) ) </a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - shell self-crosses at vertex/non-vertex (self-intersection)</desc>
<a>POLYGON ((0 40, 20 20, 40 0, 40 40, 0 0, 0 40))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole self-crosses at non-vertex (self-intersection)</desc>
<a>POLYGON ((-10 50, 50 50, 50 -10, -10 -10, -10 50), (0 40, 0 0, 40 40, 40 0, 0 40))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole self-crosses at vertex (self-intersection)</desc>
<a>POLYGON ((-10 50, 50 50, 50 -10, -10 -10, -10 50), (0 40, 20 20, 40 0, 40 40, 20 20, 0 0, 0 40))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole self-crosses at vertex/non-vertex (self-intersection)</desc>
<a>POLYGON ((-10 50, 50 50, 50 -10, -10 -10, -10 50), (0 40, 20 20, 40 0, 40 40, 0 0, 0 40))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole adjacent to hole (self-intersection)</desc>
<a>POLYGON ((0 120, 0 0, 140 0, 140 120, 0 120),
(100 100, 100 20, 120 20, 120 100, 100 100),
(20 100, 20 40, 100 40, 100 80, 20 100))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - spike (self-intersection))</desc>
<a>POLYGON ((0 60, 0 0, 60 0, 60 20, 100 20, 60 20, 60 60, 0 60))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - gore (self-intersection)</desc>
<a>POLYGON ((0 60, 0 0, 60 0, 60 20, 20 20, 60 20, 60 60, 0 60))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole crossing shell at non-vertex (self-intersection)</desc>
<a>POLYGON ((60 280, 260 180, 60 80, 60 280), (140 80, 120 180, 200 180, 140 80)) </a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - shell self-overlaps (self-intersection) </desc>
<a>
POLYGON ((60 340, 60 100, 340 100, 340 280, 340 200, 340 340, 60 340))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole outside, adjacent (self-intersection)</desc>
<a>
POLYGON ((40 260, 40 60, 120 60, 180 160, 240 60, 300 60, 300 260, 40 260),
(180 160, 240 60, 120 60, 180 160)) </a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole outside, disjoint (hole outside shell)</desc>
<a>
POLYGON ((20 180, 20 20, 140 20, 140 180, 20 180), (160 120, 180 100, 160 80, 160 120))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole outside, all vertices touch (hole outside shell)</desc>
<a>
POLYGON ((10 10, 30 10, 30 50, 70 50, 70 10, 90 10, 90 90, 10 90, 10 10), (50 50, 30 10, 70 10, 50 50))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole identical to shell (self-intersection) </desc>
<a>
POLYGON ((20 180, 20 20, 140 20, 140 180, 20 180),
(20 180, 20 20, 140 20, 140 180, 20 180))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole self-touch at vertex-segment (self-intersection) </desc>
<a>
POLYGON ((380 340, 40 340, 40 20, 380 20, 380 340),
(120 300, 300 280, 320 200, 160 140, 200 80, 320 120, 320 200, 360 60, 120 40, 120 300))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole inside hole, disjoint (nested holes)</desc>
<a>POLYGON ((0 140, 0 0, 180 0, 180 140, 0 140), (20 20, 160 20, 160 120, 20 120, 20 20), (40 100, 40 40, 140 40, 140 100, 40 100))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole inside hole, first point is identical (nested holes) </desc>
<a>
POLYGON ((20 320, 260 320, 260 20, 20 20, 20 320),
(140 280, 80 100, 200 100, 140 280),
(140 280, 40 80, 240 80, 140 280))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole inside hole, all vertices touch (nested holes) </desc>
<a>
POLYGON ((10 90, 90 90, 90 10, 10 10, 10 90), (20 80, 80 80, 80 20, 20 20, 20 80), (50 80, 20 50, 50 20, 80 50, 50 80))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - duplicate holes (self-intersection) </desc>
<a>
POLYGON ((100 200, 200 200, 200 100, 100 100, 100 200), (120 180, 180 180, 180 120, 120 120, 120 180), (120 180, 180 180, 180 120, 120 120, 120 180))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole touches shell twice (interior disconnected)</desc>
<a>POLYGON ((0 60, 0 0, 60 0, 60 60, 0 60), (0 40, 20 20, 60 20, 0 40))</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - chain of holes surrounds area (interior disconnected) </desc>
<a>
POLYGON ((40 300, 40 20, 280 20, 280 300, 40 300),
(120 240, 80 180, 160 220, 120 240),
(220 240, 160 220, 220 160, 220 240),
(160 100, 80 180, 100 80, 160 100),
(160 100, 220 160, 240 100, 160 100)) </a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - chain of holes splits polygon, touches at vertices (interior disconnected) </desc>
<a>
POLYGON ((40 320, 340 320, 340 20, 40 20, 40 320),
(100 120, 40 20, 180 100, 100 120),
(200 200, 180 100, 240 160, 200 200),
(260 260, 240 160, 300 200, 260 260),
(300 300, 300 200, 340 320, 300 300))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - chain of holes splits polygon, touches at non-vertex (interior disconnected) </desc>
<a>
POLYGON ((40 320, 340 320, 340 20, 40 20, 40 320),
(100 120, 40 20, 180 100, 100 120),
(200 200, 180 100, 240 160, 200 200),
(260 260, 240 160, 300 200, 260 260),
(300 300, 300 200, 340 260, 300 300))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole touches hole at all vertices (interior disconnected) </desc>
<a>
POLYGON( (0 0, 0 5, 6 5, 6 0, 0 0), (2 1, 4 1, 3 2, 2 1), (2 1, 1 4, 5 4, 4 1, 4 3, 3 2, 2 3, 2 1) )
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole touches hole at two vertices (interior disconnected) </desc>
<a>
POLYGON ((0 0, 0 5, 6 5, 6 0, 0 0),
(2.5 1, 3.5 1, 3.5 2, 2.5 2, 2.5 1),
(2.5 1.5, 1 4, 5 4, 3.5 1.5, 4 3, 3 2, 2 3, 2.5 1.5))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>A - hole touches shell at all vertices (interior disconnected) </desc>
<a>
POLYGON ((0 0, 10 10, 10 0, 0 0),
(5 5, 5 0, 10 5, 5 5))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mA - shells adjacent, same vertices (self-intersection) </desc>
<a>
MULTIPOLYGON (((40 120, 140 120, 140 40, 40 40, 40 120)),
((140 120, 40 120, 40 200, 140 200, 140 120)))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mA - shells adjacent, different vertices (self-intersection) </desc>
<a>
MULTIPOLYGON (((40 120, 140 120, 140 40, 40 40, 40 120)),
((160 120, 60 120, 40 200, 140 200, 160 120)))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mA - duplicate shells (self-intersection) </desc>
<a>
MULTIPOLYGON (((60 300, 320 220, 260 60, 60 100, 60 300)),
((60 300, 320 220, 260 60, 60 100, 60 300)))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mA - shell inside shell, disjoint (nested shells) </desc>
<a>
MULTIPOLYGON (((80 260, 240 260, 240 100, 80 100, 80 260)),
((120 240, 220 240, 220 140, 120 140, 120 240)))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mA - shell inside shell, all vertices touch (nested shells)</desc>
<a>
MULTIPOLYGON (((10 10, 20 30, 10 90, 90 90, 80 30, 90 10, 50 20, 10 10)), ((80 30, 20 30, 50 20, 80 30)))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mA - shell inside shell, hole overlapped, all vertices touch hole (self-intersection) </desc>
<a>
MULTIPOLYGON (((20 380, 420 380, 420 20, 20 20, 20 380),
(220 340, 180 240, 60 200, 140 100, 340 60, 300 240, 220 340)),
((60 200, 340 60, 220 340, 60 200)))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
<case>
<desc>mA - shell inside shell, all vertices touch hole (nested shells)</desc>
<a>
MULTIPOLYGON (((20 380, 420 380, 420 20, 20 20, 20 380),
(220 340, 180 240, 60 200, 200 180, 340 60, 240 220, 220 340)),
((60 200, 340 60, 220 340, 60 200)))
</a>
<test> <op name="isValid" arg1="A"> false </op> </test>
</case>
</run>