[geos-devel] Ruby Test Suite

Charlie Savage cfis at interserv.com
Tue Jan 10 03:55:26 EST 2006


In case people are interested, I developed a set of unit tests to make 
sure the Ruby bindings were working correctly.  I did this by running 
the example C++ program, noted down the results, and made sure the Ruby 
bindings match them.  So no guarantee the results are actually correct, 
but it would be quite easy to see if they change in the future.  Patch 
is below.

One thing I did notice of interest - I can't round trip one of the 
polygons via either the WKT or WKB format (by roundtrip I mean take a 
geometry, output it to WKT/WKB, then reimport it).  The geometry of 
interest is this one:

Geom In: <Geos::Geometry POLYGON ((5.00 0.00, 4.99 0.31, 4.96 0.63, 4.91 
0.94, etc. >>

It comes back as this:

Geom Out: <Geos::Geometry POLYGON ((5.00 0.00, 5.00 0.50, 5.00 0.50, 
5.00 1.00, etc. >>

Should this be happening - is it a precision issue.  I'm creating the 
geometry the same way as in the C++ code, so like this:

    pm = Geos::PrecisionModel.new(2.0, 0, 0)
    @geom_factory = Geos::GeometryFactory.new(pm, -1)

Thanks,

Charlie
 
----------------------------------------------------

--- /dev/null    Tue Jan 10 01:46:19 2006
+++ geos_tests.rb    Mon Jan  9 19:00:06 2006
@@ -0,0 +1,7 @@
+# Runs the test cases that have been developed for GEOS
+
+require 'test_simple'
+require 'test_io'
+require 'test_operations'
+require 'test_relations'
+require 'test_combinations'
--- /dev/null    Tue Jan 10 01:46:34 2006
+++ test_simple.rb    Mon Jan  9 18:56:26 2006
@@ -0,0 +1,30 @@
+#!/usr/bin/env ruby
+
+require 'test/unit'
+require 'geos'
+require 'test_helper'
+
+class TestGeosSimple < Test::Unit::TestCase
+  def setup
+    @test_helper = GeosTestHelper.new()
+  end
+  
+  def test_create_coord
+    coord = @test_helper.create_coord(5,6)
+    assert_equal(5, coord.x)
+    assert_equal(6, coord.y)
+  end
+  
+  def test_create_point
+    point = @test_helper.create_point(5,6)
+    assert_equal(5, point.x)
+    assert_equal(6, point.y)
+  end
+
+  def test_envelope
+    in_envelope = Geos::Envelope.new(3.1,3.3, 7.215, 8.392)
+    str = in_envelope.to_string()
+    out_envelope = Geos::Envelope.new(str)
+    assert(out_envelope.equals(in_envelope))
+  end
+end
\ No newline at end of file
--- /dev/null    Tue Jan 10 01:46:41 2006
+++ test_io.rb    Tue Jan 10 01:09:09 2006
@@ -0,0 +1,67 @@
+#!/usr/bin/env ruby
+
+require 'test/unit'
+require 'geos'
+require 'test_helper'
+
+class TestGeosIO < Test::Unit::TestCase
+  def setup
+    @test_helper = GeosTestHelper.new()
+  end
+
+  def run_test(message, &block)
+    # This function tests writing and reading geometries to
+    # the well-known binary hex format
+    geoms = @test_helper.create_geoms()
+
+    STDOUT << "\n" << "-------- #{message} ----------" << "\n"
+    geoms.each do |geom_in|
+      geom_out = yield(geom_in)
+
+      begin
+        ## Geometries should be equal
+        assert(geom_out.equals(geom_in),
+               "Geom In: #{geom_in}\nGeom Out: #{geom_out}")
+      rescue Geos::IllegalArgumentException => error
+        # this is ok
+      end
+
+      ## Check precision model
+      geom_in.normalize()
+      geom_out.normalize()
+
+      ## This seems to always fail
+     # assert_equal(0, geom_in.compare_to(geom_out))
+    end
+  end
+  
+  def test_wkb_hex()
+    wkb_writer = Geos::WKBWriter.new()
+    wkb_reader = Geos::WKBReader.new(@test_helper.geom_factory)
+
+    self.run_test("TESTING WKB HEX IO") do |geom_in|
+      value = wkb_writer.write_hex(geom_in)
+      geom_out = wkb_reader.read_hex(value)
+    end     
+  end
+  
+  def test_wkb()
+    wkb_writer = Geos::WKBWriter.new()
+    wkb_reader = Geos::WKBReader.new(@test_helper.geom_factory)
+
+    self.run_test("TESTING WKB IO") do |geom_in|
+      value = wkb_writer.write(geom_in)
+      geom_out = wkb_reader.read(value)
+    end     
+  end
+  
+  def test_wkt()
+    wkt_writer = Geos::WKTWriter.new()
+    wkt_reader = Geos::WKTReader.new(@test_helper.geom_factory)
+
+    self.run_test("TESTING WKT IO") do |geom_in|
+      value = wkt_writer.write(geom_in)
+      geom_out = wkt_reader.read(value)
+    end     
+  end
+end
\ No newline at end of file
--- /dev/null    Tue Jan 10 01:46:48 2006
+++ test_operations.rb    Mon Jan  9 18:51:31 2006
@@ -0,0 +1,85 @@
+#!/usr/bin/env ruby
+
+require 'test/unit'
+require 'geos'
+require 'test_helper'
+
+class TestGeosOperations < Test::Unit::TestCase
+  def setup
+    @test_helper = GeosTestHelper.new()
+    @wkt_reader = Geos::WKTReader.new(@test_helper.geom_factory)
+  end
+
+  def run_operation(results, &block)
+    geoms = @test_helper.create_geoms()
+
+    geoms.each_with_index do |geom_in, i|
+      # Get expected result
+      expected = @wkt_reader.read(results[i])
+      
+      # Get the actual result
+      actual = yield(geom_in)
+
+      assert(actual.equals(expected),
+             "Expected: #{expected}\nActual: #{actual}")
+    end
+  end
+
+  def test_centroid()
+    results = Array.new()
+    results[0]  = "POINT (150.00 350.00)"
+    results[1]  = "POINT (110.00 126.50)"
+    results[2]  = "POINT (50.00 50.00)"
+    results[3]  = "POINT (150.00 350.00)"
+    results[4]  = "POINT (150.00 400.00)"
+    results[5]  = "POINT (150.00 375.00)"
+    results[6]  = "POINT (-0.00 -0.00)"
+    results[7]  = "POINT (-0.00 0.00)"
+    results[8]  = "POINT (-0.00 -0.00)"
+    results[9]  = "POINT (-0.00 5.00)"
+    results[10] = "POINT (8.50 16.00)"
+
+    run_operation(results) do |geom|
+      geom.get_centroid()
+    end
+  end
+
+  def test_buffer()
+    results = Array.new()
+    results[0]  = "POLYGON ((140.00 348.00, 140.00 350.00, 140.00 
352.00, 141.00 354.00, 141.50 355.50, 143.00 357.00, 144.50 358.50, 
146.00 359.00, 148.00 360.00, 150.00 360.00, 152.00 360.00, 154.00 
359.00, 155.50 358.50, 157.00 357.00, 158.50 355.50, 159.00 354.00, 
160.00 352.00, 160.00 350.00, 160.00 348.00, 159.00 346.00, 158.50 
344.50, 157.00 343.00, 155.50 341.50, 154.00 341.00, 152.00 340.00, 
150.00 340.00, 148.00 340.00, 146.00 341.00, 144.50 341.50, 143.00 
343.00, 141.50 344.50, 141.00 346.00, 140.00 348.00))"
+    results[1]  = "POLYGON ((50.00 58.00, 50.00 60.00, 50.00 160.00, 
50.00 162.00, 51.00 164.00, 51.50 165.50, 53.00 167.00, 54.50 168.50, 
56.00 169.00, 58.00 170.00, 60.00 170.00, 160.00 170.00, 162.00 170.00, 
164.00 169.00, 165.50 168.50, 167.00 167.00, 168.50 165.50, 169.00 
164.00, 170.00 162.00, 170.00 160.00, 170.00 60.00, 170.00 58.00, 169.00 
56.00, 168.50 54.50, 167.00 53.00, 165.50 51.50, 164.00 51.00, 162.00 
50.00, 160.00 50.00, 158.00 50.00, 156.00 51.00, 154.50 51.50, 153.00 
53.00, 151.50 54.50, 151.00 56.00, 150.00 58.00, 150.00 60.00, 150.00 
150.00, 70.00 150.00, 70.00 60.00, 70.00 58.00, 69.00 56.00, 68.50 
54.50, 67.00 53.00, 65.50 51.50, 64.00 51.00, 62.00 50.00, 60.00 50.00, 
58.00 50.00, 56.00 51.00, 54.50 51.50, 53.00 53.00, 51.50 54.50, 51.00 
56.00, 50.00 58.00))"
+    results[2]  = "POLYGON ((-10.00 -2.00, -10.00 0.00, -10.00 2.00, 
-10.00 100.00, -10.00 102.00, -9.00 104.00, -8.50 105.50, -7.00 107.00, 
-5.50 108.50, -4.00 109.00, -2.00 110.00, 0.00 110.00, 100.00 110.00, 
102.00 110.00, 104.00 109.00, 105.50 108.50, 107.00 107.00, 108.50 
105.50, 109.00 104.00, 110.00 102.00, 110.00 100.00, 110.00 0.00, 110.00 
-2.00, 109.00 -4.00, 108.50 -5.50, 107.00 -7.00, 105.50 -8.50, 104.00 
-9.00, 102.00 -10.00, 100.00 -10.00, 2.00 -10.00, 0.00 -10.00, -2.00 
-10.00, -4.00 -9.00, -5.50 -8.50, -7.00 -7.00, -8.50 -5.50, -9.00 -4.00, 
-10.00 -2.00), (10.00 10.00, 90.00 10.00, 90.00 90.00, 10.00 90.00, 
10.00 10.00))"
+    results[3]  = "POLYGON ((-10.00 198.00, -10.00 200.00, -10.00 
500.00, -10.00 502.00, -9.00 504.00, -8.50 505.50, -7.00 507.00, -5.50 
508.50, -4.00 509.00, -2.00 510.00, 0.00 510.00, 300.00 510.00, 302.00 
510.00, 304.00 509.00, 305.50 508.50, 307.00 507.00, 308.50 505.50, 
309.00 504.00, 310.00 502.00, 310.00 500.00, 310.00 200.00, 310.00 
198.00, 309.00 196.00, 308.50 194.50, 307.00 193.00, 305.50 191.50, 
304.00 191.00, 302.00 190.00, 300.00 190.00, 0.00 190.00, -2.00 190.00, 
-4.00 191.00, -5.50 191.50, -7.00 193.00, -8.50 194.50, -9.00 196.00, 
-10.00 198.00), (110.00 310.00, 190.00 310.00, 190.00 390.00, 110.00 
390.00, 110.00 310.00))"
+    results[4]  = "POLYGON ((-10.00 248.00, -10.00 250.00, -10.00 
550.00, -10.00 552.00, -9.00 554.00, -8.50 555.50, -7.00 557.00, -5.50 
558.50, -4.00 559.00, -2.00 560.00, 0.00 560.00, 300.00 560.00, 302.00 
560.00, 304.00 559.00, 305.50 558.50, 307.00 557.00, 308.50 555.50, 
309.00 554.00, 310.00 552.00, 310.00 550.00, 310.00 250.00, 310.00 
248.00, 309.00 246.00, 308.50 244.50, 307.00 243.00, 305.50 241.50, 
304.00 241.00, 302.00 240.00, 300.00 240.00, 0.00 240.00, -2.00 240.00, 
-4.00 241.00, -5.50 241.50, -7.00 243.00, -8.50 244.50, -9.00 246.00, 
-10.00 248.00), (110.00 360.00, 190.00 360.00, 190.00 440.00, 110.00 
440.00, 110.00 360.00))"
+    results[5]  = "MULTIPOLYGON (((-10.00 -2.00, -10.00 0.00, -10.00 
2.00, -10.00 100.00, -10.00 102.00, -9.00 104.00, -8.50 105.50, -7.00 
107.00, -5.50 108.50, -4.00 109.00, -2.00 110.00, 0.00 110.00, 50.00 
110.00, 50.00 160.00, 50.00 162.00, 51.00 164.00, 51.50 165.50, 53.00 
167.00, 54.50 168.50, 56.00 169.00, 58.00 170.00, 60.00 170.00, 160.00 
170.00, 162.00 170.00, 164.00 169.00, 165.50 168.50, 167.00 167.00, 
168.50 165.50, 169.00 164.00, 170.00 162.00, 170.00 160.00, 170.00 
60.00, 170.00 58.00, 169.00 56.00, 168.50 54.50, 167.00 53.00, 165.50 
51.50, 164.00 51.00, 162.00 50.00, 160.00 50.00, 158.00 50.00, 156.00 
51.00, 154.50 51.50, 153.00 53.00, 151.50 54.50, 151.00 56.00, 150.00 
58.00, 150.00 60.00, 150.00 150.00, 70.00 150.00, 70.00 110.00, 100.00 
110.00, 102.00 110.00, 104.00 109.00, 105.50 108.50, 107.00 107.00, 
108.50 105.50, 109.00 104.00, 110.00 102.00, 110.00 100.00, 110.00 0.00, 
110.00 -2.00, 109.00 -4.00, 108.50 -5.50, 107.00 -7.00, 105.50 -8.50, 
104.00 -9.00, 102.00 -10.00, 100.00 -10.00, 2.00 -10.00, 0.00 -10.00, 
-2.00 -10.00, -4.00 -9.00, -5.50 -8.50, -7.00 -7.00, -8.50 -5.50, -9.00 
-4.00, -10.00 -2.00), (10.00 10.00, 90.00 10.00, 90.00 90.00, 70.00 
90.00, 70.00 60.00, 70.00 58.00, 69.00 56.00, 68.50 54.50, 67.00 53.00, 
65.50 51.50, 64.00 51.00, 62.00 50.00, 60.00 50.00, 58.00 50.00, 56.00 
51.00, 54.50 51.50, 53.00 53.00, 51.50 54.50, 51.00 56.00, 50.00 58.00, 
50.00 60.00, 50.00 90.00, 10.00 90.00, 10.00 10.00)), ((-10.00 198.00, 
-10.00 200.00, -10.00 248.00, -10.00 250.00, -10.00 500.00, -10.00 
502.00, -10.00 550.00, -10.00 552.00, -9.00 554.00, -8.50 555.50, -7.00 
557.00, -5.50 558.50, -4.00 559.00, -2.00 560.00, 0.00 560.00, 300.00 
560.00, 302.00 560.00, 304.00 559.00, 305.50 558.50, 307.00 557.00, 
308.50 555.50, 309.00 554.00, 310.00 552.00, 310.00 550.00, 310.00 
502.00, 310.00 500.00, 310.00 250.00, 310.00 248.00, 310.00 200.00, 
310.00 198.00, 309.00 196.00, 308.50 194.50, 307.00 193.00, 305.50 
191.50, 304.00 191.00, 302.00 190.00, 300.00 190.00, 0.00 190.00, -2.00 
190.00, -4.00 191.00, -5.50 191.50, -7.00 193.00, -8.50 194.50, -9.00 
196.00, -10.00 198.00), (110.00 360.00, 148.00 360.00, 150.00 360.00, 
152.00 360.00, 190.00 360.00, 190.00 390.00, 110.00 390.00, 110.00 
360.00)))"
+    results[6]  = "POLYGON ((-15.00 -2.50, -15.00 -2.00, -15.00 -1.50, 
-15.00 -0.50, -15.00 0.50, -15.00 1.50, -15.00 2.00, -15.00 2.50, -14.50 
3.00, -14.50 3.50, -14.50 4.00, -14.50 4.50, -14.00 5.00, -14.00 6.00, 
-13.50 6.00, -13.50 6.50, -13.50 7.00, -13.00 7.50, -13.00 8.00, -12.50 
8.50, -12.00 9.00, -12.00 9.50, -11.50 10.00, -11.00 10.00, -10.50 
10.50, -10.00 11.00, -10.00 11.50, -9.50 12.00, -9.00 12.00, -8.50 
12.50, -8.00 13.00, -7.50 13.00, -7.00 13.50, -6.50 13.50, -6.00 13.50, 
-6.00 14.00, -5.00 14.00, -4.50 14.50, -4.00 14.50, -3.50 14.50, -3.00 
14.50, -2.50 15.00, -2.00 15.00, -1.50 15.00, -0.50 15.00, 0.50 15.00, 
1.50 15.00, 2.00 15.00, 2.50 15.00, 3.00 14.50, 3.50 14.50, 4.00 14.50, 
4.50 14.50, 5.00 14.00, 6.00 14.00, 6.00 13.50, 6.50 13.50, 7.00 13.50, 
7.50 13.00, 8.00 13.00, 8.50 12.50, 9.00 12.00, 9.50 12.00, 10.00 11.50, 
10.00 11.00, 10.50 10.50, 11.00 10.00, 11.50 10.00, 12.00 9.50, 12.00 
9.00, 12.50 8.50, 13.00 8.00, 13.00 7.50, 13.50 7.00, 13.50 6.50, 13.50 
6.00, 14.00 6.00, 14.00 5.00, 14.50 4.50, 14.50 4.00, 14.50 3.50, 14.50 
3.00, 15.00 2.50, 15.00 2.00, 15.00 1.50, 15.00 0.50, 15.00 -0.50, 15.00 
-1.50, 15.00 -2.00, 15.00 -2.50, 14.50 -3.00, 14.50 -3.50, 14.50 -4.00, 
14.50 -4.50, 14.00 -5.00, 14.00 -6.00, 13.50 -6.00, 13.50 -6.50, 13.50 
-7.00, 13.00 -7.50, 13.00 -8.00, 12.50 -8.50, 12.00 -9.00, 12.00 -9.50, 
11.50 -10.00, 11.00 -10.00, 10.50 -10.50, 10.00 -11.00, 10.00 -11.50, 
9.50 -12.00, 9.00 -12.00, 8.50 -12.50, 8.00 -13.00, 7.50 -13.00, 7.00 
-13.50, 6.50 -13.50, 6.00 -13.50, 6.00 -14.00, 5.00 -14.00, 4.50 -14.50, 
4.00 -14.50, 3.50 -14.50, 3.00 -14.50, 2.50 -15.00, 2.00 -15.00, 1.50 
-15.00, 0.50 -15.00, -0.50 -15.00, -1.50 -15.00, -2.00 -15.00, -2.50 
-15.00, -3.00 -14.50, -3.50 -14.50, -4.00 -14.50, -4.50 -14.50, -5.00 
-14.00, -6.00 -14.00, -6.00 -13.50, -6.50 -13.50, -7.00 -13.50, -7.50 
-13.00, -8.00 -13.00, -8.50 -12.50, -9.00 -12.00, -9.50 -12.00, -10.00 
-11.50, -10.00 -11.00, -10.50 -10.50, -11.00 -10.00, -11.50 -10.00, 
-12.00 -9.50, -12.00 -9.00, -12.50 -8.50, -13.00 -8.00, -13.00 -7.50, 
-13.50 -7.00, -13.50 -6.50, -13.50 -6.00, -14.00 -6.00, -14.00 -5.00, 
-14.50 -4.50, -14.50 -4.00, -14.50 -3.50, -14.50 -3.00, -15.00 -2.50))"
+    results[7]  = "POLYGON ((-14.00 -3.00, -14.00 -2.50, -14.00 -2.00, 
-14.00 -1.50, -14.00 -1.00, -14.00 -0.50, -14.00 -0.00, -14.00 0.50, 
-14.00 1.00, -14.00 1.50, -14.00 2.00, -14.00 2.50, -14.00 3.00, -13.50 
3.50, -13.50 4.00, -13.50 4.50, -13.50 5.00, -13.00 5.50, -13.00 6.00, 
-13.00 6.50, -12.50 7.00, -12.50 7.50, -12.00 8.00, -12.00 8.50, -11.50 
9.00, -11.00 9.50, -11.00 10.00, -10.50 10.50, -10.00 11.00, -10.00 
11.50, -9.50 12.00, -9.00 12.50, -8.50 12.50, -8.00 13.00, -8.00 13.50, 
-7.00 14.00, -6.00 14.50, -5.00 15.00, -4.00 15.50, -3.00 15.50, -2.00 
16.00, -1.50 16.00, -0.50 16.00, 0.50 16.00, 1.50 16.00, 2.00 16.00, 
3.00 15.50, 4.00 15.50, 5.00 15.00, 6.00 14.50, 7.00 14.00, 8.00 13.50, 
8.00 13.00, 8.50 12.50, 9.00 12.50, 9.50 12.00, 10.00 11.50, 10.00 
11.00, 10.50 10.50, 11.00 10.00, 11.00 9.50, 11.50 9.00, 12.00 8.50, 
12.00 8.00, 12.50 7.50, 12.50 7.00, 13.00 6.50, 13.00 6.00, 13.00 5.50, 
13.50 5.00, 13.50 4.50, 13.50 4.00, 13.50 3.50, 14.00 3.00, 14.00 2.50, 
14.00 2.00, 14.00 1.50, 14.00 1.00, 14.00 0.50, 14.00 0.00, 14.00 -0.50, 
14.00 -1.00, 14.00 -1.50, 14.00 -2.00, 14.00 -2.50, 14.00 -3.00, 13.50 
-3.50, 13.50 -4.00, 13.50 -4.50, 13.50 -5.00, 13.00 -5.50, 13.00 -6.00, 
13.00 -6.50, 12.50 -7.00, 12.50 -7.50, 12.00 -8.00, 12.00 -8.50, 11.50 
-9.00, 11.00 -9.50, 11.00 -10.00, 10.50 -10.50, 10.00 -11.00, 10.00 
-11.50, 9.50 -12.00, 9.00 -12.50, 8.50 -12.50, 8.00 -13.00, 8.00 -13.50, 
7.00 -14.00, 6.00 -14.50, 5.00 -15.00, 4.00 -15.50, 3.00 -15.50, 2.00 
-16.00, 1.50 -16.00, 0.50 -16.00, -0.50 -16.00, -1.50 -16.00, -2.00 
-16.00, -3.00 -15.50, -4.00 -15.50, -5.00 -15.00, -6.00 -14.50, -7.00 
-14.00, -8.00 -13.50, -8.00 -13.00, -8.50 -12.50, -9.00 -12.50, -9.50 
-12.00, -10.00 -11.50, -10.00 -11.00, -10.50 -10.50, -11.00 -10.00, 
-11.00 -9.50, -11.50 -9.00, -12.00 -8.50, -12.00 -8.00, -12.50 -7.50, 
-12.50 -7.00, -13.00 -6.50, -13.00 -6.00, -13.00 -5.50, -13.50 -5.00, 
-13.50 -4.50, -13.50 -4.00, -13.50 -3.50, -14.00 -3.00))"
+    results[8]  = "POLYGON ((-15.00 -7.00, -15.00 -5.00, -15.00 5.00, 
-15.00 7.00, -14.00 9.00, -13.50 10.50, -12.00 12.00, -10.50 13.50, 
-9.00 14.00, -7.00 15.00, -5.00 15.00, 5.00 15.00, 7.00 15.00, 9.00 
14.00, 10.50 13.50, 12.00 12.00, 13.50 10.50, 14.00 9.00, 15.00 7.00, 
15.00 5.00, 15.00 -5.00, 15.00 -7.00, 14.00 -9.00, 13.50 -10.50, 12.00 
-12.00, 10.50 -13.50, 9.00 -14.00, 7.00 -15.00, 5.00 -15.00, -5.00 
-15.00, -7.00 -15.00, -9.00 -14.00, -10.50 -13.50, -12.00 -12.00, -13.50 
-10.50, -14.00 -9.00, -15.00 -7.00))"
+    results[9]  = "POLYGON ((-15.00 -7.00, -15.00 -5.00, -15.00 15.00, 
-15.00 17.00, -14.00 19.00, -13.50 20.50, -12.00 22.00, -10.50 23.50, 
-9.00 24.00, -7.00 25.00, -5.00 25.00, 5.00 25.00, 7.00 25.00, 9.00 
24.00, 10.50 23.50, 12.00 22.00, 13.50 20.50, 14.00 19.00, 15.00 17.00, 
15.00 15.00, 15.00 -5.00, 15.00 -7.00, 14.00 -9.00, 13.50 -10.50, 12.00 
-12.00, 10.50 -13.50, 9.00 -14.00, 7.00 -15.00, 5.00 -15.00, -5.00 
-15.00, -7.00 -15.00, -9.00 -14.00, -10.50 -13.50, -12.00 -12.00, -13.50 
-10.50, -14.00 -9.00, -15.00 -7.00))"
+    results[10] = "POLYGON ((-5.00 18.00, -5.00 20.00, -5.00 22.00, 
-4.00 24.00, -3.50 25.50, -2.00 27.00, -0.50 28.50, 1.00 29.00, 3.00 
30.00, 5.00 30.00, 6.00 30.00, 8.00 30.00, 9.00 29.50, 10.00 29.00, 
11.50 28.50, 12.00 28.00, 12.50 28.00, 13.00 27.50, 13.50 27.00, 14.00 
26.50, 14.50 26.00, 15.00 25.50, 15.50 25.00, 16.00 24.50, 16.50 24.00, 
17.00 23.00, 17.00 22.50, 17.00 22.00, 17.50 22.00, 18.00 20.50, 18.50 
19.50, 19.00 18.50, 19.00 18.00, 19.50 17.00, 19.50 16.00, 20.00 15.00, 
20.00 13.00, 20.00 10.00, 20.00 8.00, 19.00 6.00, 18.50 4.50, 17.00 
3.00, 15.50 1.50, 14.00 1.00, 12.00 0.00, 10.00 0.00, 8.00 0.00, 6.00 
1.00, 4.50 1.50, 3.00 3.00, 1.50 4.50, 1.00 6.00, 0.00 8.00, 0.00 10.00, 
-0.50 11.00, -0.50 11.50, -2.00 13.00, -3.50 14.50, -4.00 16.00, -5.00 
18.00))"
+
+    # Note - this test is quite slow
+    run_operation(results) do |geom|
+      geom.buffer(10)
+    end
+  end
+  
+  def test_convex_hull()
+    results = Array.new()
+    results[0]  = "POINT (150.00 350.00)"
+    results[1]  = "POLYGON ((60.00 60.00, 60.00 160.00, 160.00 160.00, 
160.00 60.00, 60.00 60.00))"
+    results[2]  = "POLYGON ((0.00 0.00, 0.00 100.00, 100.00 100.00, 
100.00 0.00, 0.00 0.00))"
+    results[3]  = "POLYGON ((0.00 200.00, 0.00 500.00, 300.00 500.00, 
300.00 200.00, 0.00 200.00))"
+    results[4]  = "POLYGON ((0.00 250.00, 0.00 550.00, 300.00 550.00, 
300.00 250.00, 0.00 250.00))"
+    results[5]  = "POLYGON ((0.00 0.00, 0.00 550.00, 300.00 550.00, 
300.00 200.00, 100.00 0.00, 0.00 0.00))"
+    results[6]  = "POLYGON ((-5.00 0.00, -4.99 0.31, -4.96 0.63, -4.91 
0.94, -4.84 1.24, -4.76 1.55, -4.65 1.84, -4.52 2.13, -4.38 2.41, -4.22 
2.68, -4.05 2.94, -3.85 3.19, -3.64 3.42, -3.42 3.64, -3.19 3.85, -2.94 
4.05, -2.68 4.22, -2.41 4.38, -2.13 4.52, -1.84 4.65, -1.55 4.76, -1.24 
4.84, -0.94 4.91, -0.63 4.96, -0.31 4.99, 0.00 5.00, 0.31 4.99, 0.63 
4.96, 0.94 4.91, 1.24 4.84, 1.55 4.76, 1.84 4.65, 2.13 4.52, 2.41 4.38, 
2.68 4.22, 2.94 4.05, 3.19 3.85, 3.42 3.64, 3.64 3.42, 3.85 3.19, 4.05 
2.94, 4.22 2.68, 4.38 2.41, 4.52 2.13, 4.65 1.84, 4.76 1.55, 4.84 1.24, 
4.91 0.94, 4.96 0.63, 4.99 0.31, 5.00 0.00, 4.99 -0.31, 4.96 -0.63, 4.91 
-0.94, 4.84 -1.24, 4.76 -1.55, 4.65 -1.84, 4.52 -2.13, 4.38 -2.41, 4.22 
-2.68, 4.05 -2.94, 3.85 -3.19, 3.64 -3.42, 3.42 -3.64, 3.19 -3.85, 2.94 
-4.05, 2.68 -4.22, 2.41 -4.38, 2.13 -4.52, 1.84 -4.65, 1.55 -4.76, 1.24 
-4.84, 0.94 -4.91, 0.63 -4.96, 0.31 -4.99, -0.00 -5.00, -0.31 -4.99, 
-0.63 -4.96, -0.94 -4.91, -1.24 -4.84, -1.55 -4.76, -1.84 -4.65, -2.13 
-4.52, -2.41 -4.38, -2.68 -4.22, -2.94 -4.05, -3.19 -3.85, -3.42 -3.64, 
-3.64 -3.42, -3.85 -3.19, -4.05 -2.94, -4.22 -2.68, -4.38 -2.41, -4.52 
-2.13, -4.65 -1.84, -4.76 -1.55, -4.84 -1.24, -4.91 -0.94, -4.96 -0.63, 
-4.99 -0.31, -5.00 0.00))"
+    results[7]  = "POLYGON ((-4.00 0.00, -3.99 0.38, -3.97 0.75, -3.93 
1.12, -3.87 1.49, -3.80 1.85, -3.72 2.21, -3.62 2.55, -3.51 2.89, -3.38 
3.21, -3.24 3.53, -3.08 3.82, -2.92 4.11, -2.74 4.37, -2.55 4.62, -2.35 
4.85, -2.14 5.07, -1.93 5.26, -1.70 5.43, -1.47 5.58, -1.24 5.71, -0.99 
5.81, -0.75 5.89, -0.50 5.95, -0.25 5.99, 0.00 6.00, 0.25 5.99, 0.50 
5.95, 0.75 5.89, 0.99 5.81, 1.24 5.71, 1.47 5.58, 1.70 5.43, 1.93 5.26, 
2.14 5.07, 2.35 4.85, 2.55 4.62, 2.74 4.37, 2.92 4.11, 3.08 3.82, 3.24 
3.53, 3.38 3.21, 3.51 2.89, 3.62 2.55, 3.72 2.21, 3.80 1.85, 3.87 1.49, 
3.93 1.12, 3.97 0.75, 3.99 0.38, 4.00 0.00, 3.99 -0.38, 3.97 -0.75, 3.93 
-1.12, 3.87 -1.49, 3.80 -1.85, 3.72 -2.21, 3.62 -2.55, 3.51 -2.89, 3.38 
-3.21, 3.24 -3.53, 3.08 -3.82, 2.92 -4.11, 2.74 -4.37, 2.55 -4.62, 2.35 
-4.85, 2.14 -5.07, 1.93 -5.26, 1.70 -5.43, 1.47 -5.58, 1.24 -5.71, 0.99 
-5.81, 0.75 -5.89, 0.50 -5.95, 0.25 -5.99, -0.00 -6.00, -0.25 -5.99, 
-0.50 -5.95, -0.75 -5.89, -0.99 -5.81, -1.24 -5.71, -1.47 -5.58, -1.70 
-5.43, -1.93 -5.26, -2.14 -5.07, -2.35 -4.85, -2.55 -4.62, -2.74 -4.37, 
-2.92 -4.11, -3.08 -3.82, -3.24 -3.53, -3.38 -3.21, -3.51 -2.89, -3.62 
-2.55, -3.72 -2.21, -3.80 -1.85, -3.87 -1.49, -3.93 -1.12, -3.97 -0.75, 
-3.99 -0.38, -4.00 0.00))"
+    results[8]  = "POLYGON ((-5.00 -5.00, -5.00 5.00, 5.00 5.00, 5.00 
-5.00, -5.00 -5.00))"
+    results[9]  = "POLYGON ((-5.00 -5.00, -5.00 15.00, 5.00 15.00, 5.00 
-5.00, -5.00 -5.00))"
+    results[10] = "POLYGON ((5.00 20.00, 6.00 20.00, 7.00 19.50, 8.00 
18.50, 9.00 16.50, 9.50 15.00, 10.00 13.00, 10.00 10.00, 5.00 20.00))"
+
+    run_operation(results) do |geom|
+      geom.convex_hull()
+    end
+  end
+end
\ No newline at end of file
--- /dev/null    Tue Jan 10 01:46:58 2006
+++ test_relations.rb    Tue Jan 10 01:12:31 2006
@@ -0,0 +1,329 @@
+#!/usr/bin/env ruby
+
+# These tests evaluate the geos relational operators
+
+
+require 'test/unit'
+require 'geos'
+require 'test_helper'
+
+class TestGeosRelations < Test::Unit::TestCase
+  X = Geos::IllegalArgumentException
+  
+  def setup
+    @test_helper = GeosTestHelper.new()
+  end
+
+  def get_expected_result(results, row, column)
+    value = results[row][column]
+
+    # 0 is false and 1 is true
+    case
+      when value == 0
+        return false
+      when value == 1
+        return true
+      when value == X
+        return X
+      else
+        raise ArgumentError, "Unknown result value"
+    end
+  end
+  
+  def run_relational_operation(operation, results, &block)
+    STDOUT << "\n" << "------ #{operation} RELATION  ------" << "\n"
+    STDOUT.flush()  
+
+    # Create the geometries
+    geoms = @test_helper.create_geoms()
+
+    # Loop through the the geometries the first time
+    row = 0
+    geoms.each do |geom1|
+      # Loop through the the geometries the second time
+      column = 0
+      geoms.each do |geom2|
+        # Get the expected result
+        expected = self.get_expected_result(results, row, column)
+
+        begin
+          # Get the actual result from the provided block
+          result = yield(geom1, geom2)
+
+          if result
+            STDOUT << "1\t"
+          else
+            STDOUT << "0\t"
+          end
+
+          # Did this work?
+          assert_equal(expected, result, "#{operation} failure")
+
+        # Geometry Collection is not a valid argument
+        rescue Geos::IllegalArgumentException => error
+          # This is probably ok but check
+          assert_equal(expected, Geos::IllegalArgumentException)
+          STDOUT << "X\t"
+        end
+        STDOUT.flush()
+        column += 1
+      end
+      STDOUT << "\n"
+      STDOUT.flush()
+      row += 1
+    end
+  end
+
+  def test_contains()
+    # Setup the expected results
+
+    # CONTAINS Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[1] =  [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[2] =  [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[3] =  [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
+    results[4] =  [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
+    results[5] =  [X, X, X, X, X, X, 0, 0, 0, 0, X]
+    results[6] =  [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
+    results[7] =  [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
+    results[8] =  [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0]
+    results[9] =  [0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0]
+    results[10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
+    
+    self.run_relational_operation("CONTAINS", results) do |geom1, geom2|
+      geom1.contains(geom2)
+    end
+  end
+  
+  def test_crosses()
+    # Setup the expected results
+
+    # CROSSES Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[1] =  [0, 0, 1, 0, 0, X, 0, 0, 0, 0, 0]
+    results[2] =  [0, 1, 0, 0, 0, X, 1, 1, 1, 1, 0]
+    results[3] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[4] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[5] =  [X, X, X, X, X, X, X, X, X, X, X]
+    results[6] =  [0, 0, 1, 0, 0, X, 0, 0, 0, 0, 0]
+    results[7] =  [0, 0, 1, 0, 0, X, 0, 0, 0, 0, 0]
+    results[8] =  [0, 0, 1, 0, 0, X, 0, 0, 0, 0, 0]
+    results[9] =  [0, 0, 1, 0, 0, X, 0, 0, 0, 0, 0]
+    results[10] = [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    
+    self.run_relational_operation("CROSSES", results) do |geom1, geom2|
+      geom1.crosses(geom2)
+    end
+  end
+  
+  def test_disjoint()
+    # Setup the expected results
+
+    # DISJOINT Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [0, 1, 1, 1, 0, X, 1, 1, 1, 1, 1]
+    results[1] =  [1, 0, 0, 1, 1, X, 1, 1, 1, 1, 1]
+    results[2] =  [1, 0, 0, 1, 1, X, 0, 0, 0, 0, 0]
+    results[3] =  [1, 1, 1, 0, 0, X, 1, 1, 1, 1, 1]
+    results[4] =  [0, 1, 1, 0, 0, X, 1, 1, 1, 1, 1]
+    results[5] =  [X, X, X, X, X, X, X, X, X, X, X]
+    results[6] =  [1, 1, 0, 1, 1, X, 0, 0, 0, 0, 1]
+    results[7] =  [1, 1, 0, 1, 1, X, 0, 0, 0, 0, 1]
+    results[8] =  [1, 1, 0, 1, 1, X, 0, 0, 0, 0, 1]
+    results[9] =  [1, 1, 0, 1, 1, X, 0, 0, 0, 0, 1]
+    results[10] = [1, 1, 0, 1, 1, X, 1, 1, 1, 1, 0]
+    
+    self.run_relational_operation("DISJOINT", results) do |geom1, geom2|
+      geom1.disjoint(geom2)
+    end
+  end
+
+  def test_equals()
+    # Setup the expected results
+
+    # EQUALS Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[1] =  [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[2] =  [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[3] =  [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
+    results[4] =  [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
+    results[5] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[6] =  [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
+    results[7] =  [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
+    results[8] =  [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
+    results[9] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
+    results[10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
+    
+    self.run_relational_operation("EQUALS", results) do |geom1, geom2|
+      geom1.equals(geom2)
+    end
+  end
+
+  def test_equals_exact()
+    # Setup the expected results
+
+    # EQUALS_EXACT Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[1] =  [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[2] =  [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[3] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[4] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[5] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[6] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[7] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[8] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[9] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    results[10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
+    
+    self.run_relational_operation("EQUALS_EXACT", results) do |geom1, 
geom2|
+      geom1.equals_exact(geom2)
+    end
+  end
+  
+  def test_intersects()
+    # Setup the expected results
+
+    # INTERSECTS Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [1, 0, 0, 0, 1, X, 0, 0, 0, 0, 0]
+    results[1] =  [0, 1, 1, 0, 0, X, 0, 0, 0, 0, 0]
+    results[2] =  [0, 1, 1, 0, 0, X, 1, 1, 1, 1, 1]
+    results[3] =  [0, 0, 0, 1, 1, X, 0, 0, 0, 0, 0]
+    results[4] =  [1, 0, 0, 1, 1, X, 0, 0, 0, 0, 0]
+    results[5] =  [X, X, X, X, X, X, X, X, X, X, X]
+    results[6] =  [0, 0, 1, 0, 0, X, 1, 1, 1, 1, 0]
+    results[7] =  [0, 0, 1, 0, 0, X, 1, 1, 1, 1, 0]
+    results[8] =  [0, 0, 1, 0, 0, X, 1, 1, 1, 1, 0]
+    results[9] =  [0, 0, 1, 0, 0, X, 1, 1, 1, 1, 0]
+    results[10] = [0, 0, 1, 0, 0, X, 0, 0, 0, 0, 1]
+    
+    self.run_relational_operation("INTERSECTS", results) do |geom1, geom2|
+      geom1.intersects(geom2)
+    end
+  end
+
+  def test_is_within_distance()
+    # Setup the expected results
+
+    # IS_WITHIN_DISTANCE Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0]
+    results[1] =  [0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0]
+    results[2] =  [0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]
+    results[3] =  [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0]
+    results[4] =  [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0]
+    results[5] =  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
+    results[6] =  [0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0]
+    results[7] =  [0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0]
+    results[8] =  [0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0]
+    results[9] =  [0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0]
+    results[10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
+    
+    self.run_relational_operation("IS_WITHIN_DISTANCE", results) do 
|geom1, geom2|
+      geom1.is_within_distance(geom2, 2)
+    end
+  end
+  
+  def test_overlaps()
+    # Setup the expected results
+
+    # OVERLAPS Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[1] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[2] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 1]
+    results[3] =  [0, 0, 0, 0, 1, X, 0, 0, 0, 0, 0]
+    results[4] =  [0, 0, 0, 1, 0, X, 0, 0, 0, 0, 0]
+    results[5] =  [X, X, X, X, X, X, X, X, X, X, X]
+    results[6] =  [0, 0, 0, 0, 0, X, 0, 1, 0, 0, 0]
+    results[7] =  [0, 0, 0, 0, 0, X, 1, 0, 1, 1, 0]
+    results[8] =  [0, 0, 0, 0, 0, X, 0, 1, 0, 0, 0]
+    results[9] =  [0, 0, 0, 0, 0, X, 0, 1, 0, 0, 0]
+    results[10] = [0, 0, 1, 0, 0, X, 0, 0, 0, 0, 0]
+    
+    self.run_relational_operation("OVERLAPS", results) do |geom1, geom2|
+      geom1.overlaps(geom2)
+    end
+  end
+
+  def test_relate()
+    # Setup the expected results
+
+    # RELATE Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[1] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[2] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[3] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[4] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[5] =  [X, X, X, X, X, X, X, X, X, X, X]
+    results[6] =  [0, 0, 0, 0, 0, X, 0, 1, 0, 0, 0]
+    results[7] =  [0, 0, 0, 0, 0, X, 1, 0, 1, 1, 0]
+    results[8] =  [0, 0, 0, 0, 0, X, 0, 1, 0, 0, 0]
+    results[9] =  [0, 0, 0, 0, 0, X, 0, 1, 0, 0, 0]
+    results[10] = [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    
+    self.run_relational_operation("RELATE", results) do |geom1, geom2|
+      geom1.relate(geom2, "212101212")
+    end
+  end
+
+  def test_touches()
+    # Setup the expected results
+
+    # TOUCHES Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [0, 0, 0, 0, 1, X, 0, 0, 0, 0, 0]
+    results[1] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[2] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[3] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[4] =  [1, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[5] =  [X, X, X, X, X, X, X, X, X, X, X]
+    results[6] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[7] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[8] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[9] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[10] = [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    
+    self.run_relational_operation("TOUCHES", results) do |geom1, geom2|
+      geom1.touches(geom2)
+    end
+  end
+
+  def test_within()
+    # Setup the expected results
+
+    # WITHIN Results
+    #             [0][1][2][3][4][5][6][7][8][9][10]
+    results = Array.new()
+    results[0] =  [1, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[1] =  [0, 1, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[2] =  [0, 0, 1, 0, 0, X, 0, 0, 0, 0, 0]
+    results[3] =  [0, 0, 0, 1, 0, X, 0, 0, 0, 0, 0]
+    results[4] =  [0, 0, 0, 0, 1, X, 0, 0, 0, 0, 0]
+    results[5] =  [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 0]
+    results[6] =  [0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0]
+    results[7] =  [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
+    results[8] =  [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]
+    results[9] =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
+    results[10] = [0, 0, 0, 0, 0, X, 0, 0, 0, 0, 1]
+    
+    self.run_relational_operation("WITHIN", results) do |geom1, geom2|
+      geom1.within(geom2)
+    end
+  end
+end
\ No newline at end of file
--- /dev/null    Tue Jan 10 01:47:05 2006
+++ test_combinations.rb    Tue Jan 10 01:13:38 2006
@@ -0,0 +1,55 @@
+#!/usr/bin/env ruby
+
+require 'test/unit'
+require 'geos'
+require 'test_helper'
+
+class TestGeosCombinations < Test::Unit::TestCase
+  def setup
+    @test_helper = GeosTestHelper.new()
+  end
+  
+  def run_combination(message, &block)
+    STDOUT << "\n" << "-------- #{message} COMBINATION  ------" << "\n"
+    STDOUT.flush()
+
+    geoms = @test_helper.create_geoms()
+
+    geoms.each do |geom1|
+      geoms.each do |geom2|
+        begin
+          # Get the actual result from the provided block
+          result = yield(geom1, geom2)
+          puts result
+        # Geometry Collection is not a valid argument
+        rescue Geos::IllegalArgumentException => error
+          # This is ok
+        end
+      end
+    end
+  end
+
+  def test_union()
+    run_combination("UNION") do |geom1, geom2|
+      geom1.union(geom2)
+    end
+  end
+
+  def test_intersection()
+    run_combination("INTERSECTION") do |geom1, geom2|
+      geom1.intersection(geom2)
+    end
+  end
+  
+  def test_difference()
+    run_combination("DIFFERENCE") do |geom1, geom2|
+      geom1.difference(geom2)
+    end
+  end
+  
+  def test_symdifference()
+    run_combination("SYMDIFFERENCE") do |geom1, geom2|
+      geom1.sym_difference(geom2)
+    end
+  end
+end
\ No newline at end of file
--- /dev/null    Tue Jan 10 01:47:13 2006
+++ test_helper.rb    Mon Jan  9 18:10:59 2006
@@ -0,0 +1,172 @@
+#!/usr/bin/env ruby
+
+require 'geos'
+
+class GeosTestHelper
+  attr_reader :geom_factory
+  
+  def initialize
+    # Define a precision model using 0,0 as the reference origin
+    # and 2.0 as coordinates scale.
+    pm = Geos::PrecisionModel.new(2.0, 0, 0)
+    @geom_factory = Geos::GeometryFactory.new(pm, -1)
+  end
+  
+  def create_coord(x, y)
+    Geos::Coordinate.new(x, y)
+  end
+
+  def create_point(x, y)
+    coord = create_coord(x, y)
+    @geom_factory.create_point(coord)
+  end
+  
+  def create_ushaped_linestring(xoffset, yoffset, side)
+    # We will use a coordinate list to build the linestring
+    cl = Geos::DefaultCoordinateSequence.new()
+    cl.add(Geos::Coordinate.new(xoffset, yoffset))
+    cl.add(Geos::Coordinate.new(xoffset, yoffset+side))
+    cl.add(Geos::Coordinate.new(xoffset+side, yoffset+side))
+    cl.add(Geos::Coordinate.new(xoffset+side, yoffset))
+
+    # Now that we have a CoordinateSequence we can create the linestring.
+    # The newly created LineString will take ownership of the 
CoordinateSequence.
+    @geom_factory.create_line_string!(cl)
+
+    # This is what you do if you want the new LineString
+    # to make a copy of your CoordinateSequence:
+    @geom_factory.create_line_string(cl)
+  end
+    
+  # This function will create a LinearRing geometry
+  # representing a square with the given origin and side
+  def create_square_linearring(xoffset, yoffset, side)
+    # We will use a coordinate list to build the linearring
+    cl = Geos::DefaultCoordinateSequence.new()
+    cl.add(Geos::Coordinate.new(xoffset, yoffset))
+    cl.add(Geos::Coordinate.new(xoffset, yoffset+side))
+    cl.add(Geos::Coordinate.new(xoffset+side, yoffset+side))
+    cl.add(Geos::Coordinate.new(xoffset+side, yoffset))
+    cl.add(Geos::Coordinate.new(xoffset, yoffset))
+
+    # Create the line string The newly created LinearRing will
+    # take ownership of the CoordinateSequence.
+    @geom_factory.create_linear_ring!(cl)
+
+    # To make a copy of your CoordinateSequence
+    @geom_factory.create_linear_ring(cl)
+  end
+
+  def create_square_polygon(xoffset, yoffset, side)
+    # This function will create a Polygon
+    # geometry rapresenting a square with the given origin
+    # and side and with a central hole 1/3 sided.
+
+    # We need a LinearRing for the polygon shell
+    outer = create_square_linearring(xoffset,yoffset,side);
+
+    # And another for the hole
+    inner = create_square_linearring(xoffset+(side/3), 
yoffset+(side/3),(side/3));
+  
+    # Specify hole as vector of Geometries
+    holes = Geos::GeometryVector.new()
+
+    # Add the newly created geometry to the vector of holes.
+    holes.push(inner)
+
+    # Finally we call the polygon constructor. Both the outer LinearRing
+    # and the vector of holes will be referenced by the resulting
+    # Polygon object.
+    poly = @geom_factory.create_polygon(outer, holes)
+  end
+  
+  def create_simple_collection(geoms)
+    # To transfer ownership of the vector and its
+    # elements you can do this
+    # @geom_factory.create_geometry_collection!(geoms)
+
+    # This function creates a GeometryCollection
+    # containing copies of all Geometries in given vector.
+    @geom_factory.create_geometry_collection(geoms)
+  end
+
+  def create_circle(centerX, centerY, radius)
+    # Use a GeometricShapeFactory to render
+    # a circle having the specified center and radius
+
+    shapefactory = Geos::GeometricShapeFactory.new(@geom_factory)
+    shapefactory.set_centre(Geos::Coordinate.new(centerX, centerY))
+    shapefactory.set_size(radius);
+    # same as:
+    #   shapefactory.set_height(radius)
+    #   shapefactory.set_width(radius)
+    
+    shapefactory.create_circle()
+  end
+
+  def create_ellipse(centerX, centerY, width, height)
+    # Use a GeometricShapeFactory to render
+    # a circle having the specified center and radius
+
+    shapefactory = Geos::GeometricShapeFactory.new(@geom_factory)
+    shapefactory.set_centre(Geos::Coordinate.new(centerX, centerY))
+    shapefactory.set_height(width)
+    shapefactory.set_width(height)
+    
+    shapefactory.create_circle()
+  end
+
+  def create_rectangle(llX, llY, width, height)
+    # This function uses GeometricShapeFactory to render
+    # a rectangle having lower-left corner at given coordinates
+    # and given sizes.
+
+    shapefactory = Geos::GeometricShapeFactory.new(@geom_factory)
+    shapefactory.set_base(Geos::Coordinate.new(llX, llY))
+    shapefactory.set_height(height)
+    shapefactory.set_width(width)
+    
+    # we don't need more then 4 points for a rectangle...
+    shapefactory.set_num_points(4)
+    # can use setSize for a square
+    shapefactory.create_rectangle()
+  end
+  
+  def create_arc(llX, llY, width, height, startang, endang)
+    # This function uses GeometricShapeFactory to render
+    # an arc having lower-left corner at given coordinates,
+    # given sizes and given angles.
+
+    shapefactory = Geos::GeometricShapeFactory.new(@geom_factory)
+    shapefactory.set_base(Geos::Coordinate.new(llX, llY))
+    shapefactory.set_height(height)
+    shapefactory.set_width(width)
+    # the default (100 pts)
+    shapefactory.set_num_points(100)
+    
+    shapefactory.create_arc(startang, endang)
+  end
+  
+  def create_geoms
+    geoms = Geos::GeometryVector.new()
+
+    geoms.push(create_point(150, 350))
+    geoms.push(create_ushaped_linestring(60,60,100))
+    geoms.push(create_square_linearring(0,0,100))
+    geoms.push(create_square_polygon(0,200,300))
+    geoms.push(create_square_polygon(0,250,300))
+    geoms.push(create_simple_collection(geoms))
+
+    # These ones use a GeometricShapeFactory
+    geoms.push(create_circle(0, 0, 10))
+    geoms.push(create_ellipse(0, 0, 8, 12))
+    # A square
+    geoms.push(create_rectangle(-5, -5, 10, 10))
+    # A rectangle
+    geoms.push(create_rectangle(-5, -5, 10, 20))
+    # The upper-right quarter of a vertical ellipse
+    geoms.push(create_arc(0, 0, 10, 20, 0, Math::PI/2))
+
+    return geoms
+  end
+end
\ No newline at end of file

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 2781 bytes
Desc: S/MIME Cryptographic Signature
Url : http://lists.osgeo.org/pipermail/geos-devel/attachments/20060110/57e45656/smime.bin


More information about the geos-devel mailing list