# Copyright (C) 2003 by Intevation GmbH
# Authors:
# Bernhard Herzog <bh@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with the software for details.

"""Test cases for ShapefileStore"""

__version__ = "$Revision: 1675 $"
# $Source$
# $Id: test_shapefilestore.py 1675 2003-08-28 13:09:48Z bh $

import os
import unittest

import support
support.initthuban()

from Thuban.Model.data import ShapefileStore
from Thuban.Model.session import Session
from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
from Thuban.Model.data import RAW_SHAPEFILE


class TestShapefileStore(unittest.TestCase):

    """Test cases for ShapefileStore"""

    def setUp(self):
        """Initialize self.session"""
        self.session = Session("Test Session")
        self.filename = os.path.join("..", "Data", "iceland",
                                "roads-line.shp")
        self.store = ShapefileStore(self.session, self.filename)

    def tearDown(self):
        """Call self.session.Destroy() and reset self.session to None"""
        self.session.Destroy()
        self.session = None

    def test_accessors(self):
        """Test ShapefileStore accessors"""
        self.assertEquals(self.store.FileName(),
                          os.path.abspath(self.filename))

        # The filetype of a shapefile is "shapefile"
        self.assertEquals(self.store.FileType(), "shapefile")

    def test_raw_format(self):
        """Test ShapefileStore raw shape format"""
        self.assertEquals(self.store.RawShapeFormat(), RAW_SHAPEFILE)

        # For shapefiles the raw format means just the shape id as an
        # int
        self.assertEquals(self.store.Shape(5).RawData(), 5)

    def test_dependencies(self):
        """Test ShapefileStore and ShapeTable dependencies"""
        # The shapestore itself depends on nothing else
        self.assertEquals(self.store.Dependencies(), ())

        # The shapestore's table depends on the shapestore
        self.assertEquals(self.store.Table().Dependencies(), (self.store,))


    def test_orig_shapestore(self):
        """Test ShapefileStore.OrigShapeStore()"""
        self.assertEquals(self.store.OrigShapeStore(), None)



class ShapefileStoreTests(unittest.TestCase, support.FloatComparisonMixin):

    """Base class for the ShapefileStore tests"""


class TestShapefileStoreArc(ShapefileStoreTests):

    """Test cases for ShapefileStore with arc shapes"""

    def setUp(self):
        """Initialize self.session"""
        self.session = Session("Test Session")
        self.filename = os.path.join("..", "Data", "iceland",
                                "roads-line.shp")
        self.store = ShapefileStore(self.session, self.filename)

    def tearDown(self):
        """Call self.session.Destroy() and reset self.session to None"""
        self.session.Destroy()
        self.session = None

    def test_shape_type(self):
        """Test ShapefileStore.ShapeType() with arc shapes"""
        self.assertEquals(self.store.ShapeType(), SHAPETYPE_ARC)

    def test_boundingbox(self):
        """Test ShapefileStore.BoundingBox() with arc shapes"""
        self.assertFloatSeqEqual(self.store.BoundingBox(),
                                 [-24.450359344482422, 63.426830291748047,
                                  -13.55668830871582, 66.520111083984375])

    def test_num_shapes(self):
        """Test ShapefileStore.NumShapes() with arc shapes"""
        self.assertEquals(self.store.NumShapes(), 839)

    def test_shapes_in_region(self):
        """Test ShapefileStore.ShapesInRegion() with arc shapes"""
        shapes = self.store.ShapesInRegion((-24.0, 64.0, -23.75, 64.25))
        self.assertEquals([s.ShapeID() for s in shapes], [613, 726, 838])

    def test_shape(self):
        """Test ShapefileStore.Shape() with arc shapes"""
        self.assertPointListEquals(self.store.Shape(32).Points(),
                                   [[(-15.0821743011474, 66.2773818969726),
                                     (-15.0263500213623, 66.2733917236328)]])

    def test_shape_shapeid(self):
        """Test ShapefileStore.Shape(i).ShapeID()"""
        self.assertEquals(self.store.Shape(5).ShapeID(), 5)


class TestShapefileStorePolygon(ShapefileStoreTests):

    """Test cases for ShapefileStore with plygon shapes"""

    def setUp(self):
        """Initialize self.session"""
        self.session = Session("Test Session")
        """Test ShapeStore with polygon shapes"""
        self.filename = os.path.join("..", "Data", "iceland",
                                "political.shp")
        self.store = ShapefileStore(self.session, self.filename)

    def tearDown(self):
        """Call self.session.Destroy() and reset self.session to None"""
        self.session.Destroy()
        self.session = None

    def test_shape_type(self):
        """Test ShapeStore.ShapeType() with polygon shapes"""
        self.assertEquals(self.store.ShapeType(), SHAPETYPE_POLYGON)

    def test_boundingbox(self):
        """Test ShapefileStore.BoundingBox() with polygon shapes"""
        self.assertFloatSeqEqual(self.store.BoundingBox(),
                                 [-24.546524047851562, 63.286754608154297,
                                  -13.495815277099609, 66.563774108886719])

    def test_num_shapes(self):
        """Test ShapefileStore.NumShapes() with polygon shapes"""
        self.assertEquals(self.store.NumShapes(), 156)

    def test_shapes_in_region(self):
        """Test ShapefileStore.ShapesInRegion() with polygon shapes"""
        shapes = self.store.ShapesInRegion((-24.0, 64.0, -23.9, 64.1))
        self.assertEquals([s.ShapeID() for s in shapes],
                          [91, 92, 144, 146, 148, 150, 152, 153])

    def test_shape(self):
        """Test ShapefileStore.Shape() with polygon shapes"""
        self.assertPointListEquals(self.store.Shape(4).Points(),
                                   [[(-22.40639114379882, 64.714111328125),
                                     (-22.41621208190918, 64.716003417968),
                                     (-22.40605163574218, 64.719200134277),
                                     (-22.40639114379882, 64.714111328125)]])

class TestShapefileStorePoint(ShapefileStoreTests):

    """Test cases for ShapefileStore with plygon shapes"""

    def setUp(self):
        """Initialize self.session"""
        self.session = Session("Test Session")
        """Test ShapeStore with point shapes"""
        self.filename = os.path.join("..", "Data", "iceland",
                                "cultural_landmark-point.shp")
        self.store = ShapefileStore(self.session, self.filename)

    def tearDown(self):
        """Call self.session.Destroy() and reset self.session to None"""
        self.session.Destroy()
        self.session = None

    def test_shape_type(self):
        """Test ShapeStore.ShapeType() with point shapes"""
        self.assertEquals(self.store.ShapeType(), SHAPETYPE_POINT)

    def test_boundingbox(self):
        """Test ShapefileStore.BoundingBox() with point shapes"""
        self.assertFloatSeqEqual(self.store.BoundingBox(),
                                 [-23.806047439575195, 63.405960083007812,
                                  -15.12291431427002, 66.36572265625])

    def test_num_shapes(self):
        """Test ShapefileStore.NumShapes() with point shapes"""
        self.assertEquals(self.store.NumShapes(), 34)

    def test_shapes_in_region(self):
        """Test ShapefileStore.ShapesInRegion() with point shapes"""
        shapes = self.store.ShapesInRegion((-24.0, 64.0, -23.80, 64.1))
        self.assertEquals([s.ShapeID() for s in shapes],
                          [0, 1, 2, 3, 4, 5, 27, 28, 29, 30, 31])

    def test_all_shapes(self):
        """Test ShapefileStore.AllShapes()"""
        # This test is probably not needed for other shape types as it's
        # not specific to the type or the data at all.
        self.assertEquals([s.ShapeID() for s in self.store.AllShapes()],
                          range(self.store.NumShapes()))

    def test_shape(self):
        """Test ShapefileStore.Shape() with point shapes"""
        self.assertPointListEquals(self.store.Shape(0).Points(),
                                   [[(-22.711074829101562, 66.36572265625)]])

if __name__ == "__main__":
    support.run_tests()

