<run>
  <precisionModel scale="1.0" offsetx="0.0" offsety="0.0"/>

<case>
  <desc>P - point</desc>
  <a>
    POINT(10 10)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>mP - multipoint with repeated points</desc>
  <a>
    MULTIPOINT ((80 280), (80 220), (160 220), (80 220))
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>mP - multipoint with no repeated points</desc>
  <a>
    MULTIPOINT ((80 280), (80 220), (160 220))
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>mP - empty</desc>
  <a>
    MULTIPOINT EMPTY
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>mP - with empty element</desc>
  <a>
    MULTIPOINT (EMPTY, (80 220), (160 220))
  </a>
<test><op name="isSimple" arg1="A"> true </op></test>
</case>

<case>
  <desc>L - simple line</desc>
  <a>
    LINESTRING(10 10, 20 20)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - simple line - repeated start point</desc>
  <a>
    LINESTRING(10 10, 10 10, 20 20)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - simple line - repeated end point</desc>
  <a>
    LINESTRING(10 10, 20 20, 20 20)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - simple line - repeated points at both ends</desc>
  <a>
    LINESTRING(10 10, 10 10, 20 20, 20 20)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - simple line - zerolength</desc>
  <a>
    LINESTRING(10 10, 10 10, 10 10)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - simple ring - repeated start point</desc>
  <a>
    LINESTRING (10 10, 2 2, 20 2, 10 10, 10 10)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - simple ring - repeated end point</desc>
  <a>
    LINESTRING (10 10, 10 10, 10 10, 2 2, 20 2, 10 10, 10 10)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - simple ring - repeated all points</desc>
  <a>
    LINESTRING (10 10, 10 10, 10 10)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - non-simple, proper interior intersection</desc>
  <a>
    LINESTRING (20 60, 160 60, 80 160, 80 20)
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>L - non-simple, two equal segments (out-and-back)</desc>
  <a>
    LINESTRING (10 10, 20 20, 10 10)
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>L - non-simple, interior intersection at vertices</desc>
  <a>
    LINESTRING (20 80, 80 20, 80 80, 140 60, 80 20, 160 20)
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>L - non-simple, interior intersection at Bdy/non-vertex</desc>
  <a>
    LINESTRING (20 60, 100 60, 60 100, 60 60)
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>L - non-simple, interior intersection at Bdy/vertex</desc>
  <a>
    LINESTRING (20 60, 60 60, 100 60, 60 100, 60 60)
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>L - simple, intersection at Bdy/Bdy (ring)</desc>
  <a>
    LINESTRING (20 20, 80 20, 80 80, 20 20)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>L - non-simple, intersection at Bdy/Bdy + non-vertex</desc>
  <a>
    LINESTRING (80 80, 20 20, 20 80, 140 80, 140 140, 80 80)
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>L - empty</desc>
  <a>
    LINESTRING EMPTY
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>


<case>
  <desc>mL - intersection between elements at non-vertex</desc>
  <a>
    MULTILINESTRING(
  (40 140, 160 40), 
  (160 140, 40 40))
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>mL - no intersection between elements</desc>
  <a>
    MULTILINESTRING(
  (20 160, 20 20), 
  (100 160, 100 20))
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>mL - mutual intersection at endpoints only</desc>
  <a>
    MULTILINESTRING ((60 140, 20 80, 60 40), 
  (60 40, 100 80, 60 140))
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>mL - one element is non-simple</desc>
  <a>
    MULTILINESTRING ((60 40, 140 40, 100 120, 100 0), 
  (100 200, 200 120))
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>mL - proper intersection between elements at vertex</desc>
  <a>
    MULTILINESTRING ((40 120, 100 60), 
  (160 120, 100 60), 
  (40 60, 160 60))
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>mL - intersection between closed lines</desc>
  <a>
    MULTILINESTRING ((80 160, 40 220, 40 100, 80 160), 
  (80 160, 120 220, 120 100, 80 160))
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>mL - intersection between closed and open lines</desc>
  <a>
    MULTILINESTRING ((80 160, 40 220), 
  (80 160, 120 220, 120 100, 80 160), 
  (40 100, 80 160))
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>mL - non-simple: two equal lines</desc>
  <a>
    MULTILINESTRING ((0 0, 100 100), (100 100, 0 0))
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>mL - with empty element</desc>
  <a>
    MULTILINESTRING ((0 0, 100 100), EMPTY)
  </a>
<test><op name="isSimple" arg1="A"> true </op></test>
</case>

<case>
  <desc>LR - valid ring</desc>
  <a>
    LINEARRING (100 300, 200 300, 200 200, 100 200, 100 300)
  </a>
<test>
  <op name="isSimple" arg1="A">
    true
  </op>
</test>
</case>

<case>
  <desc>LR - ring with self-intersection</desc>
  <a>
    LINEARRING (100 300, 200 300, 100 200, 200 200, 100 300)
  </a>
<test>
  <op name="isSimple" arg1="A">
    false
  </op>
</test>
</case>

<case>
  <desc>A - valid polygon</desc>
  <a>
    POLYGON ((180 260, 80 300, 40 180, 160 120, 180 260))
  </a>
<test>
  <op name="isSimple" arg1="A"> true </op>
</test>
</case>

<case>
  <desc>A - invalid bowtie polygon</desc>
  <a>
    POLYGON ((100 100, 100 200, 200 100, 200 200, 100 100))
  </a>
<test>
  <op name="isSimple" arg1="A"> false </op>
</test>
</case>

<case>
   <desc>A - polygon with too few points </desc>
   <a>POLYGON ((0 0, 10 10, 0 0))</a>
   <test>
      <op name="isSimple" arg1="A"> false </op>
   </test>
</case>
  
<case>
   <desc>A - polygon with equal segments </desc>
   <a>POLYGON ((50 90, 90 90, 90 50, 50 50, 10 10, 50 50, 50 90))</a>
   <test>
      <op name="isSimple" arg1="A"> false </op>
   </test>
</case>
  
<case>
  <desc>A - empty</desc>
  <a>
    POLYGON EMPTY
  </a>
<test>
  <op name="isSimple" arg1="A"> true </op>
</test>
</case>

<case>
  <desc>mA - valid polygon</desc>
  <a>
    MULTIPOLYGON (((240 160, 140 220, 80 60, 220 40, 240 160)), 
  ((160 380, 100 240, 20 380, 160 380), 
    (120 340, 60 360, 80 320, 120 340)))
  </a>
<test>
  <op name="isSimple" arg1="A"> true </op>
</test>
</case>

<case>
  <desc>mA - with touching elements</desc>
  <a>
    MULTIPOLYGON (((240 160, 100 240, 80 60, 220 40, 240 160)), 
  ((160 380, 100 240, 20 380, 160 380), 
    (120 340, 60 360, 80 320, 120 340)))
  </a>
<test>
  <op name="isSimple" arg1="A"> true </op>
</test>
</case>

<case>
  <desc>mA - with an invalid bowtie element</desc>
  <a>
MULTIPOLYGON (((100 100, 100 200, 200 100, 200 200, 100 100)), ((100 400, 200 400, 200 300, 100 300, 100 400)))
</a>
<test>
  <op name="isSimple" arg1="A"> false </op>
</test>
</case>

<case>
  <desc>mA - with empty element</desc>
  <a>
MULTIPOLYGON (((0 10, 10 10, 10 0, 0 0, 0 10)), EMPTY)
</a>
<test><op name="isSimple" arg1="A"> true </op></test>
</case>

<case>
  <desc>GC - all components simple</desc>
  <a>
GEOMETRYCOLLECTION (POLYGON ((100 200, 200 200, 200 100, 100 100, 100 200)), 
  LINESTRING (100 300, 200 250), 
  POINT (250 250), 
  POINT (250 150))</a>
<test>
  <op name="isSimple" arg1="A"> true </op>
</test>
</case>

<case>
  <desc>GC - one non-simple component</desc>
  <a>
GEOMETRYCOLLECTION (POLYGON ((100 100, 100 200, 200 100, 200 200, 100 100)), 
  LINESTRING (100 300, 200 250), 
  POINT (250 250), 
  POINT (250 150))</a>
<test>
  <op name="isSimple" arg1="A"> false </op>
</test>
</case>

<case>
  <desc>GC - with empty element</desc>
  <a>
GEOMETRYCOLLECTION (POLYGON ((0 10, 10 10, 10 0, 0 0, 0 10)), 
  LINESTRING (100 300, 200 250), 
  POINT EMPTY)</a>
<test><op name="isSimple" arg1="A"> true </op></test>
</case>

</run>
