import numpy as np

from spandex import spatialtoolz

# Sanity checks for spatialtoolz. These tests don't ensure correct results,
# but rather check that results "make sense" and are within bounds.
# In the future, we may want to test for prior known values in the results.


def get_srids(loader):
    """Build list of unique geometry column SRIDs."""
    # This deliberately uses raw SQL instead of ORM to provide redundancy
    # against spatialtoolz.conform_srids, which iterates over the ORM.
    srids = []
    with loader.database.cursor() as cur:
        cur.execute("SELECT DISTINCT srid from geometry_columns;")
        for (srid,) in cur:
            srids.append(srid)
    assert len(srids) > 0
    return srids


def get_tables(loader):
    """Build list of table ORM classes."""
    tables = []
    for (key, value) in loader.database.tables.sample.__dict__.items():
        if not key.startswith('_'):
            tables.append(value)
    assert len(tables) > 1
    return tables


def test_tag(loader):
    # Tag parcels with block group ID.
    parcels = loader.database.tables.sample.heather_farms
    bg = loader.database.tables.sample.hf_bg
    assert not hasattr(parcels, 'bg_id')
    spatialtoolz.tag(parcels, 'bg_id', bg, 'objectid')
    assert hasattr(parcels, 'bg_id')

    # Build DataFrame from parcels and block groups tables.
    parcels_df = spatialtoolz.db_to_df(parcels, index_name='parcel_id')
    bg_df = spatialtoolz.db_to_df(bg, index_name='objectid')

    # Assert that all parcels have integer block groups.
    assert not parcels_df.bg_id.isnull().any()
    assert parcels_df.bg_id.dtype == int

    # Assert that there are at least 10 unique parcel block groups.
    parcels_bg_ids = parcels_df.bg_id.unique()
    assert len(parcels_bg_ids) >= 10

    # Assert that parcel block groups are a subset of all block groups.
    assert np.all([bg_id in bg_df.index for bg_id in parcels_bg_ids])


def test_reproject(loader):

    # Assert that SRIDs need to be reprojected.
    srids = get_srids(loader)
    assert srids != [loader.srid]

    # Reproject all non-conforming SRIDs into project SRID.
    spatialtoolz.conform_srids(schema='sample')

    # Assert that all SRIDs are consistent and match defined project SRID.
    srids = get_srids(loader)
    tables = get_tables(loader)
    assert len(srids) == 1
    assert spatialtoolz.srid_equality(tables)
    assert loader.srid and type(loader.srid) == int
    assert srids == [loader.srid]

@@ -11,16 +11,44 @@
 py as np
+%0Afrom sqlalchemy import func
 %0A%0Afrom s
@@ -1962,16 +1962,1655 @@
 ef test_
+proportion_overlap(loader):%0A    # Calculate proportion of each parcel overlapped by water.%0A    parcels = loader.database.tables.sample.heather_farms%0A    water = loader.database.tables.sample.hf_water%0A    assert not hasattr(parcels, 'proportion_water')%0A    spatialtoolz.proportion_overlap(parcels, water, 'proportion_water')%0A    assert hasattr(parcels, 'proportion_water')%0A%0A    # Build DataFrame from columns of parcels table.%0A    columns = %5Bparcels.parcel_id, parcels.geom.ST_Area(),%0A               parcels.proportion_water%5D%0A    parcels_df = spatialtoolz.db_to_df(columns, index_name='parcel_id')%0A%0A    # Assert that proportion overlap values are between 0 and 1.%0A    assert parcels_df.proportion_water.dtype == float%0A    assert not (parcels_df.proportion_water %3C 0).any()%0A    assert not (parcels_df.proportion_water %3E 1).any()%0A%0A    # Assert that sum of overlapped parcel area is %3C= total water area.%0A    with loader.database.session() as sess:%0A        overlapped_area = sess.query(%0A            func.sum(parcels.proportion_water * parcels.geom.ST_Area())%0A        ).scalar()%0A        water_area = sess.query(func.sum(water.geom.ST_Area())).scalar()%0A    assert overlapped_area %3C= water_area%0A%0A%0Adef test_invalid(loader):%0A    # There are currently no invalid geometries in the sample data, so this%0A    # is not a great test.%0A    parcels = loader.database.tables.sample.heather_farms%0A    invalid = spatialtoolz.invalid_geometry_diagnostic(parcels,%0A                                                       parcels.parcel_id)%0A    assert invalid.empty%0A    invalid = spatialtoolz.invalid_geometry_diagnostic(parcels)%0A    assert invalid.empty%0A%0A%0Adef test_
 reprojec
@@ -3619,17 +3619,16 @@
 loader):
-%0A
 %0A    # A

Add tests for proportion_overlap and invalid geometry