geos/swig/ruby/test/test_helper.rb

248 строки
11 KiB
Ruby

#!/usr/bin/env ruby
require 'geos'
require "rexml/document"
XmlTest = Struct.new(:case_id, :test_id,
:operation, :expected,
:geom1, :geom2,
:arg1, :arg2, :arg3)
class GeosTestHelper
def create_point(x, y)
cs = Geos::CoordinateSequence.new(1,2)
cs.set_x(0, x)
cs.set_y(0, y)
Geos.create_point(cs)
end
def create_ushaped_linestring(xoffset, yoffset, side)
cs = Geos::CoordinateSequence.new(4,2)
cs.set_x(0, xoffset)
cs.set_y(0, yoffset)
cs.set_x(1, xoffset)
cs.set_y(1, yoffset + side)
cs.set_x(2, xoffset + side)
cs.set_y(2, yoffset + side)
cs.set_x(3, xoffset + side)
cs.set_y(3, yoffset)
Geos.create_line_string(cs)
end
# This function will create a LinearRing geometry
# representing a square with the given origin and side
def create_square_linear_ring(xoffset, yoffset, side)
cs = Geos::CoordinateSequence.new(5,2)
cs.set_x(0, xoffset)
cs.set_y(0, yoffset)
cs.set_x(1, xoffset)
cs.set_y(1, yoffset + side)
cs.set_x(2, xoffset + side)
cs.set_y(2, yoffset + side)
cs.set_x(3, xoffset + side)
cs.set_y(3, yoffset)
cs.set_x(4, xoffset)
cs.set_y(4, yoffset)
Geos.create_linear_ring(cs)
end
# This function will create a Polygon
# geometry representing a square with the given origin
# and side and with a central hole 1/3 sided.
def create_square_polygon(xoffset, yoffset, side)
# We need a LinearRing for the polygon shell
outer = create_square_linear_ring(xoffset,yoffset,side);
# And another for the hole
inner = create_square_linear_ring(xoffset+(side/3), yoffset+(side/3),(side/3));
Geos.create_polygon(outer, [inner])
end
def create_simple_collection(geoms)
# This function creates a GeometryCollection
# containing copies of all Geometries in given vector.
#@geom_factory.create_geometry_collection(geoms)
wkt = "GEOMETRYCOLLECTION (POLYGON ((0.00 250.00, 0.00 550.00, 300.00 550.00, 300.00 250.00, 0.00 250.00), (100.00 350.00, 200.00 350.00, 200.00 450.00, 100.00 450.00, 100.00 350.00)), POLYGON ((0.00 200.00, 0.00 500.00, 300.00 500.00, 300.00 200.00, 0.00 200.00), (100.00 300.00, 200.00 300.00, 200.00 400.00, 100.00 400.00, 100.00 300.00)), LINEARRING (0.00 0.00, 0.00 100.00, 100.00 100.00, 100.00 0.00, 0.00 0.00), LINEARRING (0.00 0.00, 0.00 100.00, 100.00 100.00, 100.00 0.00, 0.00 0.00), LINESTRING (60.00 60.00, 60.00 160.00, 160.00 160.00, 160.00 60.00), POINT (150.00 350.00))"
reader = Geos::WktReader.new
reader.read(wkt)
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()
wkt = "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))"
reader = Geos::WktReader.new
reader.read(wkt)
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()
wkt = "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))"
reader = Geos::WktReader.new
reader.read(wkt)
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()
wkt = "POLYGON ((#{llX} #{llY}, #{llX} #{llY + height}, #{llX+width} #{llY+height}, #{llX+width} #{llY}, #{llX} #{llY}))"
reader = Geos::WktReader.new
reader.read(wkt)
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)
wkt = "LINESTRING (5.00 20.00, 5.00 20.00, 5.00 20.00, 5.50 20.00, 5.50 20.00, 5.50 20.00, 5.50 20.00, 5.50 20.00, 5.50 20.00, 6.00 20.00, 6.00 20.00, 6.00 20.00, 6.00 20.00, 6.00 20.00, 6.00 19.50, 6.00 19.50, 6.50 19.50, 6.50 19.50, 6.50 19.50, 6.50 19.50, 6.50 19.50, 6.50 19.50, 7.00 19.50, 7.00 19.50, 7.00 19.00, 7.00 19.00, 7.00 19.00, 7.00 19.00, 7.00 19.00, 7.50 19.00, 7.50 19.00, 7.50 19.00, 7.50 18.50, 7.50 18.50, 7.50 18.50, 7.50 18.50, 7.50 18.50, 8.00 18.50, 8.00 18.00, 8.00 18.00, 8.00 18.00, 8.00 18.00, 8.00 18.00, 8.00 17.50, 8.00 17.50, 8.50 17.50, 8.50 17.50, 8.50 17.50, 8.50 17.00, 8.50 17.00, 8.50 17.00, 8.50 17.00, 8.50 16.50, 9.00 16.50, 9.00 16.50, 9.00 16.50, 9.00 16.50, 9.00 16.00, 9.00 16.00, 9.00 16.00, 9.00 16.00, 9.00 15.50, 9.00 15.50, 9.00 15.50, 9.50 15.00, 9.50 15.00, 9.50 15.00, 9.50 15.00, 9.50 14.50, 9.50 14.50, 9.50 14.50, 9.50 14.50, 9.50 14.00, 9.50 14.00, 9.50 14.00, 9.50 13.50, 9.50 13.50, 9.50 13.50, 9.50 13.00, 10.00 13.00, 10.00 13.00, 10.00 13.00, 10.00 12.50, 10.00 12.50, 10.00 12.50, 10.00 12.00, 10.00 12.00, 10.00 12.00, 10.00 11.50, 10.00 11.50, 10.00 11.50, 10.00 11.50, 10.00 11.00, 10.00 11.00, 10.00 11.00, 10.00 10.50, 10.00 10.50, 10.00 10.50, 10.00 10.00, 10.00 10.00)"
reader = Geos::WktReader.new
reader.read(wkt)
end
def create_geoms
geoms = Array.new
geoms.push(create_point(150, 350))
geoms.push(create_square_linear_ring(0,0,100))
geoms.push(create_ushaped_linestring(60,60,100))
geoms.push(create_square_linear_ring(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
def print_geoms(geoms)
geoms.each do |geom|
wkt = Geos.geom_to_wkt(geom)
STDOUT << wkt << "\n"
end
end
# ----- xml support ---------
def load_tests(file_name)
current_path = File.expand_path(__FILE__)
xml_path = File.join(current_path, "..", "..", "..", "..", "tests", "xmltester")
file_path = File.expand_path(File.join(xml_path, file_name))
file = File.new(file_path)
result = nil
begin
doc = REXML::Document.new(file)
result = load_cases(doc)
ensure
file.close
end
result
end
def parse_geometry(value)
value.strip!
if value.match(/\A[0-9A-F]/)
reader = Geos::WkbReader.new
reader.read_hex(value)
else
reader = Geos::WktReader.new
reader.read(value)
end
end
def load_cases(doc)
case_id = 1
result = Array.new
# get the run element
run_element = doc.elements["run"]
# Iterate over each case
run_element.elements.each("case") do |case_element|
test_id = 1
# Get geometry a
a_element = case_element.elements["a"]
geom1 = parse_geometry(a_element.text) if a_element
# Get geometry b
b_element = case_element.elements["b"]
geom2 = parse_geometry(b_element.text) if b_element
# Iterate over each test in this case
case_element.elements.each("test") do |test_element|
operation_element = test_element.elements["op"]
# Get operation name and result
operation = operation_element.attributes['name'].strip!
expected = operation_element.text.strip!
# Figure arguments
arg1 = operation_element.attributes['arg1']
arg2 = operation_element.attributes['arg2']
arg3 = operation_element.attributes['arg3']
arg1.strip! if arg1
arg2.strip! if arg2
arg3.strip! if arg3
# Create test
test = XmlTest.new(case_id, test_id,
operation, expected,
geom1, geom2,
arg1, arg2, arg3)
result.push(test)
test_id += 1
end
case_id += 1
end
result
end
end