# Copyright (C) 2004,2006 by Intevation GmbH        vim:encoding=latin-1:
# Authors:
# Nina Hüffmeyer <nhueffme@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with the software for details.

__version__ = "$Revision: 2713 $"
# $Source$
# $Id: test_OGRShapestore.py 2713 2006-10-26 16:37:42Z bernhard $

"""Tests for ogrshapes"""

import os
import sys
import unittest

try:
    import ogr
    ogr_imported = True
except ImportError:
    # No ogr available. The tests will
    # be skipped completely.
    ogr_imported = False

# If run directly as a script, add Thuban's test directory to the path
# as well as the extensions own directory (i.e. parent).
# Otherwise we assume that the importing code has already done it.
if __name__ == "__main__":
    sys.path.append(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])),
                                 "..", "..", "test"))
    sys.path.append(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])),
                                 ".."))

import support
support.initthuban()

from Extensions.ogr.ogrshapes import OGRShapeStore, OGRShape, \
     SHAPETYPE_POINT, SHAPETYPE_ARC, SHAPETYPE_POLYGON
from Thuban.Model.data import RAW_PYTHON
from Thuban.Model.table import FIELDTYPE_INT
from Thuban.Model.session import Session


def skip_if_no_ogr():
    if not ogr_imported:
        raise support.SkipTest( \
            "Can't run ogr tests because ogr couldn't be imported.")

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

    def setUp(self):
        """Initialize self.session and open shapefile, if ogr could be
        imported.
        """
        skip_if_no_ogr()
        self.session = Session("TestSession")
        self.filename_arc = os.path.join("..", "Data", "iceland",
                                        "roads-line.shp")
        self.store_arc = OGRShapeStore(self.session, self.filename_arc,
                                        "roads-line")

        self.filename_point = os.path.join("..", "Data", "iceland",
                                        "cultural_landmark-point.shp")
        self.store_point = OGRShapeStore(self.session, self.filename_point,
                                        "cultural_landmark-point")

        self.filename_poly = os.path.join("..", "Data", "iceland",
                                        "political.shp")
        self.store_poly = OGRShapeStore(self.session, self.filename_poly,
                                        "political")

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

    def test_shape_type(self):
        """Test OGRShapeStore.ShapeType() with arc shapes"""
        self.assertEquals(self.store_arc.ShapeType(), SHAPETYPE_ARC)
        self.assertEquals(self.store_point.ShapeType(), SHAPETYPE_POINT)
        self.assertEquals(self.store_poly.ShapeType(), SHAPETYPE_POLYGON)

    def test_raw_format(self):
        """Test OGRShapeStore.RawShapeFormat() with ogr file"""
        self.assertEquals(self.store_arc.RawShapeFormat(), RAW_PYTHON)
        self.assertEquals(self.store_point.RawShapeFormat(), RAW_PYTHON)
        self.assertEquals(self.store_poly.RawShapeFormat(), RAW_PYTHON)

    def test_boundingbox(self):
        """Test OGRShapeStore.BoundingBox() with arc shapes"""
        self.assertFloatSeqEqual(self.store_arc.BoundingBox(),
                                [-24.450359344482422, 63.426830291748047,
                                -13.55668830871582, 66.520111083984375])
        self.assertFloatSeqEqual(self.store_point.BoundingBox(),
                                [-23.806047439575195, 63.405960083007812,
                                -15.12291431427002, 66.36572265625])
        self.assertFloatSeqEqual(self.store_poly.BoundingBox(),
                                [-24.546524047851562, 63.286754608154297,
                                -13.495815277099609, 66.563774108886719])

    def test_num_shapes(self):
        """Test OGRShapeStore.NumShapes() with arc shapes"""
        self.assertEquals(self.store_arc.NumShapes(), 839)
        self.assertEquals(self.store_point.NumShapes(), 34)
        self.assertEquals(self.store_poly.NumShapes(), 156)

    def test_shapes_in_region(self):
        """Test OGRShapeStore.ShapesInRegion() with arc shapes"""
        shapes_arc = self.store_arc.ShapesInRegion((-22.78, 63.96, 
                                                    -22.72, 64.0))
        self.assertEquals([s.ShapeID() for s in shapes_arc], [769, 771])

        shapes_point = self.store_point.ShapesInRegion((-23.0, 63.0, 
                                                        -22.0, 64.0))
        self.assertEquals([s.ShapeID() for s in shapes_point], [29, 31])

        shapes_poly = self.store_poly.ShapesInRegion((-23.0, 63.0, -22.0, 64.0))
        self.assertEquals([s.ShapeID() for s in shapes_poly], [144])

    def test_all_shapes(self):
        """Test OGRShapeStore.AllShapes()"""
        self.assertEquals([s.ShapeID() for s in self.store_arc.AllShapes()],
                            range(self.store_arc.NumShapes()))
        self.assertEquals([s.ShapeID() for s in self.store_point.AllShapes()],
                            range(self.store_point.NumShapes()))
        self.assertEquals([s.ShapeID() for s in self.store_poly.AllShapes()],
                            range(self.store_poly.NumShapes()))

    def test_shape_Points(self):
        """Test OGRShapeStore.Shape() with arc shapes"""
        self.assertPointListEquals(self.store_arc.Shape(32).Points(),
                                [[(-15.08217430114746, 66.2773818969726),
                                (-15.02635002136230, 66.2733917236328)]])
        self.assertPointListEquals(self.store_point.Shape(13).Points(),
                                [[(-15.364621162414551, 65.6103515625)]])
        self.assertPointListEquals(self.store_poly.Shape(20).Points(),
                                [[(-22.233562469482422, 64.4395751953125),
                                (-22.244234085083008, 64.441192626953125),
                                (-22.233894348144531, 64.446701049804688),
                                (-22.226711273193359, 64.44439697265625),
                                (-22.23356246948242, 64.4395751953125)]])

    def test_shape_shapeid(self):
        """Test OGRShapeStore.Shape(i).ShapeID()"""
        self.assertEquals(self.store_arc.Shape(5).ShapeID(), 5)
        self.assertEquals(self.store_point.Shape(13).ShapeID(), 13)
        self.assertEquals(self.store_point.Shape(20).ShapeID(), 20)

    def test_shape_compute_bbox(self):
        """Test bbox of one shape"""
        self.assertFloatSeqEqual(self.store_arc.Shape(32).compute_bbox(),
                                (-15.08217430114746, 66.2733917236328,
                                -15.02635002136230, 66.2773818969726))
        self.assertFloatSeqEqual(self.store_point.Shape(13).compute_bbox(),
                                (-15.364621162414551, 65.6103515625,
                                -15.364621162414551, 65.6103515625))
        self.assertFloatSeqEqual(self.store_poly.Shape(20).compute_bbox(),
                                (-22.244234085083008, 64.4395751953125,
                                -22.226711273193359, 64.446701049804688))


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

    def setUp(self):
        """Initialize"""
        skip_if_no_ogr()
        self.session = Session("TestSession")
        self.filename = os.path.join("..","Data", "iceland","roads-line.shp")
        self.store_arc = OGRShapeStore(self.session, self.filename,
                                        "roads-line")
        self.table = self.store_arc.Table()

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

    def test_Dependencies(self):
        """Test dependencies, which is always ()"""
        self.assertEquals(self.table.Dependencies(), ())

    def test_NumColumns(self):
        """Test number of columns"""
        self.assertEquals(self.table.NumColumns(), 9)

    def test_Columns(self):
        """Test columns, which are instances of OGRColumn"""
        self.assertEquals(len(self.table.Columns()), 9)
        self.assertEquals(self.table.Columns()[0].name, "FNODE_")
        self.assertEquals(self.table.Columns()[0].type, FIELDTYPE_INT)
        self.assertEquals(self.table.Columns()[0].index, 0)

    def test_Column(self):
        """Test column, which is instance of OGRColumn"""
        self.assertEquals(self.table.Column(0).name, "FNODE_")
        self.assertEquals(self.table.Column(0).type, FIELDTYPE_INT)
        self.assertEquals(self.table.Column(0).index, 0)
        self.assertEquals(self.table.Column("FNODE_").type, FIELDTYPE_INT)
        self.assertEquals(self.table.Column("FNODE_").index, 0)

    def test_HasColumn(self):
        """Test HasColumn(), which can be called either with an integer or 
        a string"""
        self.assert_(self.table.HasColumn(0))
        self.assert_(self.table.HasColumn("FNODE_"))

    def test_NumRows(self):
        """Test number of rows, which equals the number of features"""
        self.assertEquals(self.table.NumRows(), 839)

    def test_RowIdToOrdinal(self):
        self.assertEqual(self.table.RowIdToOrdinal(5),5)

    def test_RowOrdinalToId(self):
        self.assertEqual(self.table.RowOrdinalToId(5),5)

    def test_ReadRowAsDict(self):
        """Test ReadRowAsDict()"""
        self.assertEquals(len(self.table.ReadRowAsDict(0)), 9)
        self.assertEquals(self.table.ReadRowAsDict(0, row_is_ordinal = 1),
                        {"FNODE_": 3,
                        "TNODE_": 1,
                        "LPOLY_": 146,
                        "RPOLY_": 146,
                        "LENGTH": 0.156,
                        "RDLINE_": 1,
                        "RDLINE_ID": 879,
                        "RDLNTYPE": 3,
                        "RDLNSTAT": 1})

    def test_ReadValue(self):
        """Test ReadValue()"""
        self.assertEquals(self.table.ReadValue(0,0,0), 3)
        self.assertEquals(self.table.ReadValue(0,"FNODE_",0),3)

    def test_ValueRange(self):
        """Test ValueRange()"""
        self.assertEquals(self.table.ValueRange("FNODE_"), (1, 733))

    def test_UniqueValues(self):
        """Test UniqueValues()"""
        self.assertFloatSeqEqual(self.table.UniqueValues("RDLNTYPE"), [2,3,8])

    def test_SimpleQuery(self):
        """Test SimpleQuery()"""
        self.assertEquals(self.table.SimpleQuery(self.table.Column("LENGTH"),
                        "==", 0.156),[0, 24, 317])



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