import pytest
from shapely import geometry

from tiletanic.tilecover import cover_geometry
from tiletanic.tileschemes import DGTiling, WebMercator


@pytest.fixture
def tiler():
    return DGTiling()


@pytest.fixture
def wmtiler():
    return WebMercator()


@pytest.fixture
def pt():
    return geometry.Point(-94.39453125, 15.908203125)


@pytest.fixture
def mpt():
    return geometry.MultiPoint([(-94.39453125, 15.908203125),
                                (-94.306640625, 15.908203125),
                                (-94.306640625, 15.8203125),
                                (-94.39453125, 15.8203125)])


@pytest.fixture
def ls():
    return geometry.shape({"coordinates": [[-123.12515258789061, 45.70809729528788], [-122.4755859375, 45.615958580368364], [-123.32977294921874, 45.44664375276733], [-122.25173950195311, 45.334771196762766], [-123.3819580078125, 45.11133093583217], [-122.23388671874999, 45.04829981381567], [-122.57995605468749, 45.74740199642105], [-122.6348876953125, 44.961882876810925], [-122.80654907226562, 45.75315158411652], [-122.98645019531249, 44.998795943614084], [-123.05648803710938, 45.744526980468436], [-123.33938598632812, 45.031803280058554]], "type": "LineString"})


@pytest.fixture
def mls():
    return geometry.shape({'type': 'MultiLineString', 'coordinates': (((-0.9709167480468749, 35.18840002173177), (-0.9832763671875, 34.83296838321102), (-0.954437255859375, 35.02774729487063), (-0.850067138671875, 35.02662273458687), (-0.833587646484375, 34.838604318635014), (-0.8074951171874999, 35.185032937998294)), ((-0.0823974609375, 35.191766965947394), (-0.111236572265625, 34.83071390101431), (0.048065185546875, 34.829586636768205), (0.067291259765625, 35.192889249680945), (-0.06591796875, 35.191766965947394)), ((-0.28564453125, 35.19064466671118), (-0.34606933593749994, 34.84085858477277), (-0.18402099609375, 34.831841149828676)), ((-0.48614501953124994, 35.183910545750834), (-0.517730712890625, 34.854382885097905), (-0.391387939453125, 34.84874803007872)), ((-0.553436279296875, 35.183910545750834), (-0.7347106933593749, 35.185032937998294), (-0.751190185546875, 35.05922870088872), (-0.591888427734375, 35.0502352513963), (-0.758056640625, 35.03336986422378), (-0.767669677734375, 34.86227103378598), (-0.597381591796875, 34.85550980979319)))})


@pytest.fixture
def poly():
    return geometry.shape({'type': 'Polygon', 'coordinates': (((74.5751953125, 46.86019101567027), (73.916015625, 46.45299704748289), (73.564453125, 46.21785176740299), (73.32275390625, 45.920587344733654), (73.289794921875, 45.56021795715051), (73.465576171875, 45.27488643704894), (74.036865234375, 44.96479793033104), (74.256591796875, 45.07352060670971), (74.322509765625, 45.48324350868221), (74.46533203125, 45.91294412737392), (74.849853515625, 46.057985244793024), (74.99267578125, 46.354510837365254), (75.465087890625, 46.40756396630067), (76.102294921875, 46.42271253466719), (76.904296875, 46.34692761055676), (77.376708984375, 46.27863122156088), (78.2666015625, 46.195042108660154), (78.94775390625, 46.31658418182218), (79.29931640625, 46.5286346952717), (79.398193359375, 46.77749276376827), (79.12353515625, 47.017716353979225), (78.42041015625, 46.912750956378915), (77.574462890625, 46.76244305208004), (76.46484375, 46.81509864599243), (76.036376953125, 46.98025235521883), (75.399169921875, 46.830133640447386), (74.893798828125, 46.93526088057719), (74.5751953125, 46.86019101567027)),)})


@pytest.fixture
def poly_w_hole():
    return geometry.shape({'type': 'Polygon', 'coordinates': (((31.794433593749996, -28.979312036722447), (31.289062500000004, -29.401319510041485), (31.036376953125, -29.897805610155864), (30.377197265625, -30.845647420182598), (29.278564453125, -31.886886525780806), (26.74072265625, -31.94283997285307), (23.9501953125, -31.184609135743237), (23.917236328125, -28.98892237190413), (25.5322265625, -27.615406013399603), (27.894287109374996, -27.019984007982554), (30.377197265625, -27.32297494724568), (31.794433593749996, -28.979312036722447)), ((28.652343749999996, -28.584521719370393), (28.399658203125, -28.632746799225856), (28.3282470703125, -28.724313406473463), (28.1634521484375, -28.729130483430154), (28.015136718749996, -28.8831596093235), (27.745971679687496, -28.92163128242129), (27.531738281249996, -29.200123477644983), (27.410888671874996, -29.382175075145277), (27.257080078125, -29.54956657394792), (26.987915039062496, -29.640320395351402), (27.1966552734375, -30.002516938570686), (27.31201171875, -30.140376821599734), (27.3834228515625, -30.14987731644208), (27.366943359375, -30.249577240467637), (27.39990234375, -30.334953881988564), (27.454833984375, -30.33021268543272), (27.745971679687496, -30.60954979719083), (27.8997802734375, -30.619004797647793), (28.108520507812496, -30.680439786468128), (28.1744384765625, -30.50075098029068), (28.14697265625, -30.462879341709876), (28.229370117187496, -30.410781790845878), (28.2513427734375, -30.29701788337205), (28.3612060546875, -30.202113679097216), (28.71826171875, -30.135626231134587), (28.9544677734375, -30.026299582223675), (29.179687499999996, -29.912090918781477), (29.1192626953125, -29.831113764737136), (29.141235351562504, -29.67850809103362), (29.256591796874996, -29.640320395351402), (29.300537109374996, -29.492206334848714), (29.410400390625, -29.40610505570927), (29.443359375, -29.31993078977759), (29.393920898437496, -29.195328267099118), (29.2950439453125, -29.08977693862319), (29.091796875, -28.936054482136658), (28.976440429687496, -28.90239722855847), (28.916015625, -28.762843805266016), (28.800659179687496, -28.772474183943018), (28.789672851562496, -28.6905876542507), (28.7017822265625, -28.656851034203406), (28.652343749999996, -28.584521719370393)))})


@pytest.fixture
def mpoly():
    return geometry.shape({'type': 'MultiPolygon', 'coordinates': [(((-155.60651896977458, 20.13795556629634), (-155.16804273408488, 19.946827215003964), (-154.81406356568098, 19.50657921146143), (-155.67475562357313, 18.906117143691233), (-155.9039060717078, 19.069459067981597), (-156.0601639283226, 19.73122055328588), (-155.83545761767488, 19.975703442260055), (-155.88048255092895, 20.252020575289293), (-155.60651896977458, 20.13795556629634)),), (((-156.91373752666547, 20.73472409144364), (-156.96228010324413, 20.73238773010962), (-157.05521360182624, 20.911371030348732), (-156.81633843277243, 20.841704170311175), (-156.91373752666547, 20.73472409144364)),), (((-156.53412841109724, 20.531787476211036), (-156.6792613032665, 20.504712931856318), (-156.7005618241688, 20.525426565083876), (-156.5826214116488, 20.59995670154052), (-156.53412841109724, 20.531787476211036)),), (((-156.5895997046626, 21.027738813695294), (-156.24290930851774, 20.941555080502553), (-155.98469586911904, 20.717591061278426), (-156.40765319493894, 20.587206654063834), (-156.68490668409615, 20.881887778698), (-156.5895997046626, 21.027738813695294)),), (((-157.24884316468027, 21.22171060725873), (-156.96576900873274, 21.213324286186833), (-156.70572493545737, 21.15654296368683), (-157.2730606762092, 21.087347723418702), (-157.24884316468027, 21.22171060725873)),), (((-157.89376363688228, 21.598381702453594), (-157.72570752668096, 21.45898509818369), (-157.69321165049723, 21.262742044309903), (-157.9609268868663, 21.388820705311275), (-158.0988663403093, 21.29539622635474), (-158.27893301424717, 21.575264710198212), (-157.98264568694884, 21.7098504289541), (-157.89376363688228, 21.598381702453594)),), (((-161.9451798172947, 23.03986237235057), (-161.94477291633697, 23.04621002837007), (-161.94041907528006, 23.045599677383166), (-161.94090735588972, 23.041978257690403), (-161.9451798172947, 23.03986237235057)),), (((-164.7043350900923, 23.5793317732427), (-164.69908606656867, 23.570542710577627), (-164.70848548112002, 23.574530341402124), (-164.7043350900923, 23.5793317732427)),), (((-167.99616451697884, 25.004339911058025), (-168.00279700357882, 25.014797268279267), (-167.99986731722288, 25.01642487211012), (-167.99555416599193, 25.011664130095483), (-167.99616451697884, 25.004339911058025)),), (((-171.72280839828892, 25.773016669183903), (-171.72935950433762, 25.7519391954375), (-171.7390844392954, 25.756293036494412), (-171.74067135330029, 25.769029039258726), (-171.72280839828892, 25.773016669183903)),), (((-173.9591772130579, 26.059637762073066), (-173.96564693855532, 26.05857982030244), (-173.96499589774245, 26.07135651199343), (-173.96051998630827, 26.063137111388585), (-173.9591772130579, 26.059637762073066)),), (((-178.2983970579778, 28.387372162295435), (-178.3043661632678, 28.387912197090202), (-178.29038113887842, 28.401678575605786), (-178.28790478098082, 28.39298946089491), (-178.2983970579778, 28.387372162295435)),), (((-160.198240306345, 21.783883779013195), (-160.23442352432616, 21.874455639016503), (-160.05996362062456, 22.000562970404758), (-160.07221432223315, 21.910834052149767), (-160.198240306345, 21.783883779013195)),), (((-159.38818451870054, 22.228789014401457), (-159.29470434293106, 22.107627229413083), (-159.43731532294376, 21.868769246403588), (-159.78721108632254, 22.019270121718705), (-159.38818451870054, 22.228789014401457)),)]})


@pytest.fixture
def donut():
    return geometry.shape({'type': 'Polygon', 'coordinates': (((-8478680.853644049, 5697329.705967457), (-8475876.604351476, 5693825.364227657), (-8478353.796980098, 5691831.500531353), (-8479056.000328023, 5691230.9688630225), (-8482763.718607875, 5687921.707011377), (-8484066.71324761, 5689357.283425693), (-8484132.72570565, 5689458.9609730365), (-8485603.924095975, 5691119.276002927), (-8489564.56025891, 5695499.188019603), (-8487563.926370371, 5695598.554369273), (-8487020.909894282, 5696010.158685913), (-8486833.002593823, 5696653.397796723), (-8486272.50895768, 5701826.232722361), (-8485641.661403354, 5702462.741808833), (-8483894.05671739, 5703160.777664438), (-8481629.706955165, 5700827.320925154), (-8479652.672798675, 5698504.158803017), (-8478680.853644049, 5697329.705967457)), ((-8485619.620144177, 5698875.087400831), (-8486120.001255292, 5698515.59130402), (-8486124.231395943, 5698419.68577629), (-8486086.494088564, 5698217.5571292695), (-8485962.48417582, 5697920.644304513), (-8485402.101859165, 5696988.529093507), (-8485168.776206464, 5696640.697662884), (-8482860.1212869, 5694044.057728255), (-8482570.690610839, 5694045.16866679), (-8482441.560001519, 5694099.446117623), (-8481249.550894104, 5695150.144684806), (-8483046.692753471, 5697250.959475276), (-8484276.773126736, 5698761.869977695), (-8484799.30681652, 5699340.04017765), (-8484900.050955689, 5699521.073411321), (-8485474.014250219, 5699024.669980715), (-8485499.951691575, 5698955.594911603), (-8485619.620144177, 5698875.087400831)))})


def test_cover_geometry_empty_geoms(tiler):
    """Empty geometries should return empty iterators."""
    assert not cover_geometry(tiler, geometry.Point(), 0) == True
    assert not cover_geometry(tiler, geometry.Point(), [0, 1]) == True
    assert not cover_geometry(tiler, geometry.MultiPoint(), 0) == True
    assert not cover_geometry(tiler, geometry.MultiPoint(), [0, 1]) == True
    assert not cover_geometry(tiler, geometry.LineString(), 0) == True
    assert not cover_geometry(tiler, geometry.LineString(), [0, 1]) == True
    assert not cover_geometry(tiler, geometry.MultiLineString(), 0) == True
    assert not cover_geometry(tiler, geometry.MultiLineString(), [0, 1]) == True
    assert not cover_geometry(tiler, geometry.Polygon(), 0) == True
    assert not cover_geometry(tiler, geometry.Polygon(), [0, 1]) == True
    assert not cover_geometry(tiler, geometry.MultiPolygon(), 0) == True
    assert not cover_geometry(tiler, geometry.MultiPolygon(), [0, 1]) == True
    assert not cover_geometry(tiler, geometry.GeometryCollection(), 0) == True
    assert not cover_geometry(tiler, geometry.GeometryCollection(), [0, 1]) == True


def test_cover_geometry_nonshapely_geom(tiler):
    """Only accept shapely geometries."""
    with pytest.raises(ValueError):
        for _ in cover_geometry(tiler, None, 0):
            pass

    with pytest.raises(ValueError):
        for _ in cover_geometry(tiler, None, [0, 1]):
            pass


def test_cover_geometry_point1(tiler, pt):
    """A Point geometry."""
    tiles = [tile for tile in cover_geometry(tiler, pt, 4)]
    assert len(tiles) == 1
    assert set(tiles) == {(3, 4, 4)}


def test_cover_geometry_point2(tiler, pt):
    """A Point geometry."""
    tiles = [tile for tile in cover_geometry(tiler, pt, 12)]
    assert len(tiles) == 4
    assert set(tiles) == {(973, 1204, 12), (973, 1205, 12), (974, 1204, 12), (974, 1205, 12)}


def test_cover_geometry_point3(tiler, pt):
    """A Point geometry."""
    tiles = [tile for tile in cover_geometry(tiler, pt, [3, 4])]
    assert len(tiles) == 1
    assert set(tiles) == {(1, 2, 3)}


def test_cover_geometry_point4(tiler, pt):
    """A Point geometry."""
    tiles = [tile for tile in cover_geometry(tiler, pt, [11, 12])]
    assert len(tiles) == 2
    assert set(tiles) == {(487, 602, 11), (486, 602, 11)}


def test_cover_geometry_multipoint1(tiler, mpt):
    """A MultiPoint geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mpt, 4)]
    assert len(tiles) == 1


def test_cover_geometry_multipoint2(tiler, mpt):
    """A MultiPoint geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mpt, 12)]
    assert len(tiles) == 9
    assert set(tiles) == {(973, 1203, 12), (974, 1203, 12), (975, 1203, 12),
                          (973, 1204, 12), (973, 1205, 12), (974, 1204, 12),
                          (975, 1204, 12), (974, 1205, 12), (975, 1205, 12)}


def test_cover_geometry_multipoint3(tiler, mpt):
    """A MultiPoint geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mpt, [3, 4])]
    assert len(tiles) == 1


def test_cover_geometry_multipoint4(tiler, mpt):
    """A MultiPoint geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mpt, [11, 12])]
    assert len(tiles) == 4
    assert set(tiles) == {(486, 601, 11), (487, 601, 11),
                          (487, 602, 11), (486, 602, 11)}

                           
def test_cover_geometry_linestring1(tiler, ls):
    """A LineString geometry."""
    tiles = [tile for tile in cover_geometry(tiler, ls, 4)]
    assert len(tiles) == 2
    assert set(tiles) == {(2, 5, 4), (2, 6, 4)}


def test_cover_geometry_linestring2(tiler, ls):
    """A LineString geometry."""
    tiles = [tile for tile in cover_geometry(tiler, ls, 11)]
    assert len(tiles) == 30
    assert set(tiles) == {(322, 768, 11), (322, 769, 11), (322, 770, 11), (323, 768, 11),
                          (323, 769, 11), (323, 770, 11), (323, 771, 11), (323, 772, 11),
                          (324, 767, 11), (324, 768, 11), (324, 769, 11), (324, 770, 11),
                          (324, 771, 11), (325, 768, 11), (325, 769, 11), (325, 770, 11),
                          (325, 771, 11), (325, 772, 11), (326, 767, 11), (326, 768, 11),
                          (326, 769, 11), (326, 770, 11), (326, 771, 11), (326, 772, 11),
                          (327, 768, 11), (327, 769, 11), (327, 770, 11), (327, 771, 11),
                          (328, 768, 11), (328, 769, 11)}


def test_cover_geometry_linestring3(tiler, ls):
    """A LineString geometry."""
    tiles = [tile for tile in cover_geometry(tiler, ls, [3, 4])]
    assert len(tiles) == 2
    assert set(tiles) == {(1, 3, 3), (1, 2, 3)}


def test_cover_geometry_linestring4(tiler, ls):
    """A LineString geometry."""
    tiles = [tile for tile in cover_geometry(tiler, ls, [10, 11])]
    assert len(tiles) == 12
    assert set(tiles) == {(161, 384, 10), (163, 385, 10), (162, 386, 10), (163, 386, 10),
                          (161, 386, 10), (164, 384, 10), (162, 383, 10), (163, 383, 10),
                          (163, 384, 10), (162, 384, 10), (162, 385, 10), (161, 385, 10)}


def test_cover_geometry_multilinestring1(tiler, mls):
    """A MultiLineString geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mls, 8)]
    assert len(tiles) == 4
    assert set(tiles) == {(127, 88, 8), (127, 89, 8), (128, 88, 8), (128, 89, 8)}


def test_cover_geometry_multilinestring2(tiler, mls):
    """A MultiLineString geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mls, 12)]
    assert len(tiles) == 47
    assert set(tiles) == {(2036, 1420, 12), (2036, 1421, 12), (2036, 1422, 12), (2036, 1423, 12),
                          (2036, 1424, 12), (2037, 1421, 12), (2037, 1422, 12), (2038, 1420, 12),
                          (2038, 1421, 12), (2038, 1422, 12), (2038, 1423, 12), (2038, 1424, 12),
                          (2039, 1420, 12), (2039, 1421, 12), (2039, 1422, 12), (2039, 1423, 12),
                          (2039, 1424, 12), (2040, 1420, 12), (2040, 1422, 12), (2040, 1424, 12),
                          (2041, 1420, 12), (2041, 1422, 12), (2041, 1424, 12), (2042, 1420, 12),
                          (2042, 1421, 12), (2042, 1422, 12), (2042, 1423, 12), (2042, 1424, 12),
                          (2043, 1420, 12), (2044, 1420, 12), (2044, 1421, 12), (2044, 1422, 12),
                          (2044, 1423, 12), (2044, 1424, 12), (2045, 1420, 12), (2046, 1420, 12),
                          (2046, 1421, 12), (2046, 1422, 12), (2046, 1423, 12), (2047, 1420, 12),
                          (2047, 1423, 12), (2047, 1424, 12), (2048, 1420, 12), (2048, 1421, 12),
                          (2048, 1422, 12), (2048, 1423, 12), (2048, 1424, 12)}


def test_cover_geometry_multilinestring3(tiler, mls):
    """A MultiLineString geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mls, [7, 8])]
    assert len(tiles) == 2
    assert set(tiles) == {(63, 44, 7), (64, 44, 7)}


def test_cover_geometry_multilinestring4(tiler, mls):
    """A MultiLineString geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mls, [11, 12])]
    assert len(tiles) == 21
    assert set(tiles) == {(1022, 712, 11), (1019, 710, 11), (1024, 712, 11), (1020, 710, 11),
                          (1023, 710, 11), (1020, 711, 11), (1018, 712, 11), (1018, 711, 11),
                          (1023, 712, 11), (1024, 711, 11), (1022, 710, 11), (1024, 710, 11),
                          (1019, 711, 11), (1018, 710, 11), (1019, 712, 11), (1021, 711, 11),
                          (1021, 710, 11), (1023, 711, 11), (1020, 712, 11), (1022, 711, 11),
                          (1021, 712, 11)}


def test_cover_geometry_poly1(tiler, poly):
    """A Polygon geometry."""
    tiles = [tile for tile in cover_geometry(tiler, poly, 7)]
    assert len(tiles) == 4
    assert set(tiles) == {(90, 47, 7), (90, 48, 7), (91, 48, 7), (92, 48, 7)}


def test_cover_geometry_poly2(tiler, poly):
    """A Polygon geometry."""
    tiles = [tile for tile in cover_geometry(tiler, poly, [7, 8])]
    assert len(tiles) == 5
    assert set(tiles) == {(90, 48, 7), (91, 48, 7),
                          (180, 95, 8), (184, 97, 8), (184, 96, 8)}


def test_cover_geometry_poly3(tiler, poly):
    """A Polygon geometry."""
    tiles = [tile for tile in cover_geometry(tiler, poly, [8, 9, 10])]
    assert len(tiles) == 25
    assert set(tiles) == {(180, 96, 8),
                          (362, 194, 9), (363, 194, 9), (364, 194, 9), (365, 194, 9), (366, 194, 9), (367, 194, 9), (368, 194, 9), (722, 383, 10),
                          (722, 388, 10), (723, 388, 10), (723, 389, 10), (724, 386, 10), (724, 387, 10), (725, 387, 10), (726, 387, 10), (728, 387, 10), (729, 387, 10), (730, 387, 10), (731, 387, 10), (732, 387, 10), (733, 387, 10), (734, 387, 10), (735, 387, 10), (736, 387, 10), }


def test_cover_geometry_poly_w_hole1(tiler, poly_w_hole):
    """A Polygon geometry with a hole in it."""
    tiles = [tile for tile in cover_geometry(tiler, poly_w_hole, 7)]
    assert len(tiles) == 11
    assert set(tiles) == set([(72, 22, 7), (74, 21, 7), (75, 22, 7), (73, 20, 7), (74, 22, 7), (73, 22, 7), (74, 20, 7), (73, 21, 7), (75, 21, 7), (72, 21, 7), (72, 20, 7)])


def test_cover_geometry_poly_w_hole2(tiler, poly_w_hole):
    """A Polygon geometry with a hole in it."""
    tiles = [tile for tile in cover_geometry(tiler, poly_w_hole, 9)]
    assert len(tiles) == 77
    assert set(tiles) == set([(297, 82, 9), (301, 87, 9), (294, 87, 9), (299, 88, 9), (300, 85, 9), (292, 83, 9), (296, 83, 9), (298, 89, 9), (295, 82, 9), (290, 86, 9), (291, 87, 9), (297, 88, 9), (292, 87, 9), (298, 86, 9), (298, 84, 9), (294, 84, 9), (294, 88, 9), (299, 89, 9), (292, 85, 9), (300, 86, 9), (294, 82, 9), (290, 85, 9), (298, 82, 9), (295, 84, 9), (296, 87, 9), (293, 84, 9), (299, 85, 9), (291, 85, 9), (299, 86, 9), (296, 85, 9), (297, 85, 9), (296, 89, 9), (293, 89, 9), (292, 86, 9), (293, 87, 9), (291, 88, 9), (298, 88, 9), (298, 87, 9), (295, 87, 9), (296, 88, 9), (293, 83, 9), (301, 86, 9), (291, 86, 9), (297, 86, 9), (297, 89, 9), (292, 88, 9), (294, 86, 9), (294, 85, 9), (292, 82, 9), (300, 87, 9), (295, 89, 9), (290, 87, 9), (296, 82, 9), (298, 85, 9), (297, 83, 9), (291, 83, 9), (295, 83, 9), (300, 88, 9), (293, 86, 9), (299, 83, 9), (299, 84, 9), (297, 87, 9), (294, 83, 9), (297, 84, 9), (298, 83, 9), (293, 82, 9), (294, 89, 9), (296, 84, 9), (290, 84, 9), (293, 88, 9), (290, 83, 9), (295, 86, 9), (293, 85, 9), (295, 88, 9), (292, 84, 9), (291, 84, 9), (299, 87, 9)])


def test_cover_geometry_poly_w_hole3(tiler, poly_w_hole):
    """A Polygon geometry with a hole in it."""
    tiles = [tile for tile in cover_geometry(tiler, poly_w_hole, [6, 7])]
    assert len(tiles) == 8
    assert set(tiles) == set([(36, 10, 6),
                              (72, 22, 7), (74, 21, 7), (75, 22, 7), (74, 22, 7), (73, 22, 7), (74, 20, 7), (75, 21, 7)])


def test_cover_geometry_poly_w_hole4(tiler, poly_w_hole):
    """A Polygon geometry with a hole in it."""
    tiles = [tile for tile in cover_geometry(tiler, poly_w_hole, [8, 9])]
    assert len(tiles) == 32
    assert set(tiles) == set([(148, 42, 8), (146, 43, 8), (147, 43, 8), (145, 42, 8), (148, 44, 8), (147, 41, 8), (149, 43, 8), (149, 44, 8), (145, 43, 8), (146, 41, 8), (149, 42, 8), (150, 43, 8), (147, 44, 8), (148, 41, 8), (146, 42, 8),
                              (299, 83, 9), (293, 89, 9), (298, 82, 9), (300, 85, 9), (295, 84, 9), (296, 87, 9), (291, 88, 9), (300, 88, 9), (297, 87, 9), (292, 88, 9), (293, 88, 9), (294, 85, 9), (298, 83, 9), (290, 83, 9), (291, 83, 9), (297, 86, 9), (294, 84, 9)])


def test_cover_geometry_poly_w_hole5(tiler, poly_w_hole):
    """A Polygon geometry with a hole in it."""
    tiles = [tile for tile in cover_geometry(tiler, poly_w_hole, [8, 9, 11])]
    assert len(tiles) == 318
    assert set(tiles) == set([(145, 42, 8), (146, 42, 8), (146, 43, 8), (149, 43, 8),
                              (290, 86, 9), (291, 86, 9), (291, 87, 9), (292, 83, 9), (293, 83, 9), (293, 88, 9), (294, 83, 9), (294, 84, 9), (294, 86, 9), (294, 87, 9), (294, 88, 9), (295, 83, 9), (295, 87, 9), (295, 88, 9), (296, 83, 9), (296, 84, 9), (296, 88, 9), (297, 83, 9), (297, 84, 9), (297, 87, 9), (297, 88, 9), (298, 84, 9), (298, 85, 9), (298, 88, 9), (299, 85, 9),
                              (1160, 334, 11), (1160, 335, 11), (1161, 334, 11), (1161, 335, 11), (1161, 348, 11), (1162, 333, 11), (1162, 334, 11), (1162, 335, 11), (1162, 348, 11), (1162, 349, 11), (1163, 333, 11), (1163, 334, 11), (1163, 335, 11), (1163, 348, 11), (1163, 349, 11), (1163, 350, 11), (1164, 333, 11), (1164, 334, 11), (1164, 335, 11), (1165, 333, 11), (1165, 334, 11), (1165, 335, 11), (1165, 352, 11), (1166, 332, 11), (1166, 333, 11), (1166, 334, 11), (1166, 335, 11), (1166, 352, 11), (1167, 332, 11), (1167, 333, 11), (1167, 334, 11), (1167, 335, 11), (1167, 352, 11), (1167, 353, 11), (1168, 352, 11), (1168, 353, 11), (1168, 354, 11), (1169, 331, 11), (1169, 352, 11), (1169, 353, 11), (1169, 354, 11), (1169, 355, 11), (1170, 331, 11), (1170, 352, 11), (1170, 353, 11), (1170, 354, 11), (1170, 355, 11), (1171, 331, 11), (1171, 352, 11), (1171, 353, 11), (1171, 354, 11), (1171, 355, 11), (1172, 331, 11), (1173, 330, 11), (1173, 331, 11), (1173, 356, 11), (1174, 330, 11), (1174, 331, 11), (1174, 356, 11), (1175, 330, 11), (1175, 331, 11), (1175, 356, 11), (1176, 330, 11), (1176, 331, 11), (1176, 340, 11), (1176, 341, 11), (1176, 342, 11), (1176, 343, 11), (1176, 356, 11), (1177, 330, 11), (1177, 331, 11), (1177, 340, 11), (1177, 341, 11), (1177, 342, 11), (1177, 343, 11), (1177, 356, 11), (1177, 357, 11), (1178, 330, 11), (1178, 331, 11), (1178, 340, 11), (1178, 341, 11), (1178, 342, 11), (1178, 343, 11), (1178, 356, 11), (1178, 357, 11), (1179, 330, 11), (1179, 331, 11), (1179, 340, 11), (1179, 343, 11), (1179, 356, 11), (1179, 357, 11), (1180, 330, 11), (1180, 331, 11), (1180, 336, 11), (1180, 337, 11), (1180, 338, 11), (1180, 339, 11), (1180, 344, 11), (1180, 345, 11), (1180, 346, 11), (1180, 347, 11), (1180, 356, 11), (1180, 357, 11), (1181, 330, 11), (1181, 331, 11), (1181, 336, 11), (1181, 337, 11), (1181, 338, 11), (1181, 346, 11), (1181, 347, 11), (1181, 356, 11), (1181, 357, 11), (1181, 358, 11), (1182, 330, 11), (1182, 331, 11), (1182, 336, 11), (1182, 337, 11), (1182, 347, 11), (1182, 356, 11), (1182, 357, 11), (1182, 358, 11), (1183, 330, 11), (1183, 331, 11), (1183, 336, 11), (1183, 337, 11), (1183, 347, 11), (1183, 356, 11), (1183, 357, 11), (1183, 358, 11), (1184, 330, 11), (1184, 331, 11), (1184, 348, 11), (1184, 349, 11), (1184, 350, 11), (1184, 351, 11), (1184, 356, 11), (1184, 357, 11), (1184, 358, 11), (1185, 330, 11), (1185, 331, 11), (1185, 340, 11), (1185, 348, 11), (1185, 349, 11), (1185, 350, 11), (1185, 351, 11), (1185, 356, 11), (1185, 357, 11), (1185, 358, 11), (1186, 330, 11), (1186, 331, 11), (1186, 340, 11), (1186, 349, 11), (1186, 350, 11), (1186, 351, 11), (1186, 356, 11), (1186, 357, 11), (1187, 330, 11), (1187, 331, 11), (1187, 340, 11), (1187, 348, 11), (1187, 349, 11), (1187, 350, 11), (1187, 351, 11), (1187, 356, 11), (1187, 357, 11), (1188, 330, 11), (1188, 331, 11), (1188, 340, 11), (1188, 341, 11), (1188, 347, 11), (1188, 356, 11), (1188, 357, 11), (1189, 330, 11), (1189, 331, 11), (1189, 340, 11), (1189, 341, 11), (1189, 342, 11), (1189, 343, 11), (1189, 347, 11), (1189, 356, 11), (1189, 357, 11), (1190, 330, 11), (1190, 331, 11), (1190, 340, 11), (1190, 341, 11), (1190, 342, 11), (1190, 343, 11), (1190, 344, 11), (1190, 346, 11), (1190, 347, 11), (1190, 356, 11), (1190, 357, 11), (1191, 331, 11), (1191, 340, 11), (1191, 341, 11), (1191, 342, 11), (1191, 343, 11), (1191, 344, 11), (1191, 345, 11), (1191, 346, 11), (1191, 347, 11), (1191, 356, 11), (1191, 357, 11), (1192, 331, 11), (1192, 332, 11), (1192, 333, 11), (1192, 334, 11), (1192, 335, 11), (1192, 356, 11), (1192, 357, 11), (1193, 332, 11), (1193, 333, 11), (1193, 334, 11), (1193, 335, 11), (1193, 356, 11), (1193, 357, 11), (1194, 333, 11), (1194, 334, 11), (1194, 335, 11), (1194, 356, 11), (1195, 334, 11), (1195, 335, 11), (1195, 356, 11), (1196, 335, 11), (1196, 336, 11), (1196, 337, 11), (1196, 338, 11), (1196, 339, 11), (1196, 352, 11), (1196, 353, 11), (1196, 354, 11), (1196, 355, 11), (1196, 356, 11), (1197, 336, 11), (1197, 337, 11), (1197, 338, 11), (1197, 339, 11), (1197, 352, 11), (1197, 353, 11), (1197, 354, 11), (1197, 355, 11), (1197, 356, 11), (1198, 338, 11), (1198, 339, 11), (1198, 352, 11), (1198, 353, 11), (1198, 354, 11), (1198, 355, 11), (1199, 339, 11), (1199, 352, 11), (1199, 353, 11), (1199, 354, 11), (1200, 341, 11), (1200, 342, 11), (1200, 343, 11), (1200, 344, 11), (1200, 345, 11), (1200, 346, 11), (1200, 347, 11), (1200, 348, 11), (1200, 349, 11), (1200, 350, 11), (1200, 351, 11), (1200, 352, 11), (1201, 342, 11), (1201, 343, 11), (1201, 344, 11), (1201, 345, 11), (1201, 346, 11), (1201, 347, 11), (1201, 348, 11), (1201, 349, 11), (1201, 350, 11), (1201, 351, 11), (1202, 344, 11), (1202, 345, 11), (1202, 346, 11), (1202, 347, 11), (1202, 348, 11), (1202, 349, 11), (1202, 350, 11), (1203, 345, 11), (1203, 346, 11), (1203, 347, 11), (1203, 348, 11), (1203, 349, 11), (1204, 346, 11), (1204, 347, 11), (1204, 348, 11) ])


def test_cover_geometry_multipoly1(tiler, mpoly):
    """A MultiPolygon geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mpoly, 7)]
    assert len(tiles) == 8
    assert set(tiles) == set([(8, 38, 7), (4, 40, 7), (2, 41, 7), (0, 42, 7), (5, 40, 7), (7, 39, 7), (8, 39, 7), (6, 40, 7)])


def test_cover_geometry_multipoly2(tiler, mpoly):
    """A MultiPolygon geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mpoly, 10)]
    assert len(tiles) == 44
    assert set(tiles) == set([(23, 329, 10), (56, 318, 10), (70, 310, 10), (64, 315, 10), (67, 315, 10), (68, 310, 10), (63, 316, 10), (62, 316, 10), (71, 311, 10), (65, 314, 10), (68, 311, 10), (57, 318, 10), (70, 313, 10), (62, 317, 10), (4, 336, 10), (67, 314, 10), (64, 316, 10), (69, 310, 10), (66, 314, 10), (69, 313, 10), (68, 312, 10), (17, 330, 10), (63, 317, 10), (69, 312, 10), (58, 319, 10), (71, 312, 10), (68, 313, 10), (70, 311, 10), (69, 309, 10), (51, 321, 10), (70, 312, 10), (56, 317, 10), (61, 317, 10), (65, 315, 10), (65, 316, 10), (43, 323, 10), (68, 309, 10), (58, 318, 10), (34, 327, 10), (68, 314, 10), (66, 315, 10), (69, 311, 10), (68, 315, 10), (66, 316, 10)])


def test_cover_geometry_multipoly3(tiler, mpoly):
    """A MultiPolygon geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mpoly, [9, 10])]
    assert len(tiles) == 32
    assert set(tiles) == set([(31, 158, 9), (33, 157, 9), (34, 155, 9), (34, 156, 9),
                              (4, 336, 10), (17, 330, 10), (23, 329, 10), (34, 327, 10), (43, 323, 10), (51, 321, 10), (56, 317, 10), (56, 318, 10), (57, 318, 10), (58, 318, 10), (58, 319, 10), (61, 317, 10), (64, 315, 10), (64, 316, 10), (65, 314, 10), (65, 315, 10), (65, 316, 10), (66, 316, 10), (68, 309, 10), (68, 314, 10), (68, 315, 10), (69, 309, 10), (70, 310, 10), (70, 311, 10), (70, 312, 10), (70, 313, 10), (71, 311, 10), (71, 312, 10) ])


def test_cover_geometry_multipoly4(tiler, mpoly):
    """A MultiPolygon geometry."""
    tiles = [tile for tile in cover_geometry(tiler, mpoly, [9, 10, 11])]
    assert len(tiles) == 58
    assert set(tiles) == set([(34, 155, 9),
                              (58, 318, 10), (62, 317, 10), (66, 314, 10), (66, 315, 10), (67, 315, 10), (68, 312, 10), (69, 312, 10), (70, 311, 10), (70, 312, 10), (71, 311, 10), 
                              (9, 673, 11), (34, 660, 11), (46, 658, 11), (47, 658, 11), (68, 654, 11), (86, 646, 11), (87, 646, 11), (102, 643, 11), (112, 635, 11), (112, 636, 11), (113, 636, 11), (113, 637, 11), (114, 637, 11), (115, 636, 11), (115, 637, 11), (116, 638, 11), (117, 638, 11), (123, 634, 11), (124, 633, 11), (125, 633, 11), (126, 632, 11), (126, 633, 11), (126, 634, 11), (129, 631, 11), (129, 632, 11), (130, 630, 11), (130, 632, 11), (131, 629, 11), (131, 630, 11), (131, 632, 11), (132, 632, 11), (134, 629, 11), (135, 629, 11), (136, 629, 11), (136, 630, 11), (137, 619, 11), (137, 626, 11), (137, 627, 11), (138, 619, 11), (138, 626, 11), (139, 619, 11), (139, 626, 11), (140, 620, 11), (140, 621, 11), (140, 626, 11), (141, 621, 11), (142, 624, 11) ])


def test_cover_donut_webmercator(wmtiler, donut):
    tiles = [tile for tile in cover_geometry(wmtiler, donut, 16)]
    assert len(tiles) == 310
    assert set(tiles) == set([(18899, 23458, 16), (18896, 23451, 16), (18888, 23457, 16), (18898, 23457, 16), (18890, 23442, 16), (18894, 23449, 16), (18888, 23454, 16), (18900, 23457, 16), (18898, 23458, 16), (18890, 23447, 16), (18894, 23450, 16), (18895, 23459, 16), (18891, 23460, 16), (18896, 23450, 16), (18900, 23462, 16), (18898, 23463, 16), (18898, 23449, 16), (18894, 23447, 16), (18895, 23462, 16), (18891, 23459, 16), (18892, 23459, 16), (18898, 23464, 16), (18893, 23442, 16), (18898, 23450, 16), (18887, 23453, 16), (18896, 23446, 16), (18892, 23456, 16), (18893, 23445, 16), (18898, 23455, 16), (18887, 23456, 16), (18896, 23466, 16), (18896, 23443, 16), (18905, 23457, 16), (18892, 23461, 16), (18888, 23456, 16), (18893, 23448, 16), (18896, 23458, 16), (18897, 23460, 16), (18897, 23446, 16), (18891, 23447, 16), (18897, 23463, 16), (18893, 23454, 16), (18894, 23460, 16), (18891, 23442, 16), (18887, 23455, 16), (18897, 23458, 16), (18897, 23452, 16), (18901, 23449, 16), (18907, 23456, 16), (18894, 23457, 16), (18903, 23452, 16), (18895, 23450, 16), (18892, 23441, 16), (18897, 23455, 16), (18901, 23452, 16), (18889, 23457, 16), (18885, 23454, 16), (18890, 23457, 16), (18902, 23460, 16), (18891, 23452, 16), (18895, 23449, 16), (18897, 23464, 16), (18892, 23446, 16), (18897, 23450, 16), (18901, 23455, 16), (18889, 23452, 16), (18901, 23457, 16), (18890, 23458, 16), (18902, 23457, 16), (18891, 23451, 16), (18889, 23455, 16), (18901, 23460, 16), (18886, 23456, 16), (18902, 23458, 16), (18899, 23454, 16), (18895, 23443, 16), (18892, 23448, 16), (18889, 23450, 16), (18890, 23446, 16), (18902, 23453, 16), (18890, 23448, 16), (18886, 23455, 16), (18899, 23453, 16), (18895, 23446, 16), (18892, 23453, 16), (18889, 23445, 16), (18893, 23458, 16), (18902, 23454, 16), (18890, 23453, 16), (18899, 23448, 16), (18903, 23453, 16), (18899, 23462, 16), (18900, 23450, 16), (18893, 23461, 16), (18902, 23451, 16), (18890, 23454, 16), (18899, 23447, 16), (18895, 23464, 16), (18899, 23461, 16), (18900, 23455, 16), (18888, 23458, 16), (18884, 23453, 16), (18898, 23454, 16), (18893, 23464, 16), (18890, 23443, 16), (18894, 23454, 16), (18899, 23456, 16), (18900, 23452, 16), (18888, 23455, 16), (18900, 23458, 16), (18898, 23459, 16), (18898, 23445, 16), (18890, 23444, 16), (18895, 23458, 16), (18888, 23452, 16), (18898, 23460, 16), (18898, 23446, 16), (18894, 23444, 16), (18895, 23457, 16), (18891, 23458, 16), (18893, 23455, 16), (18893, 23441, 16), (18898, 23451, 16), (18894, 23441, 16), (18895, 23460, 16), (18891, 23457, 16), (18896, 23447, 16), (18892, 23457, 16), (18904, 23458, 16), (18893, 23444, 16), (18898, 23452, 16), (18904, 23456, 16), (18902, 23450, 16), (18896, 23462, 16), (18896, 23444, 16), (18905, 23456, 16), (18892, 23462, 16), (18893, 23447, 16), (18896, 23459, 16), (18903, 23460, 16), (18897, 23451, 16), (18897, 23445, 16), (18894, 23464, 16), (18903, 23458, 16), (18896, 23456, 16), (18891, 23446, 16), (18897, 23462, 16), (18893, 23453, 16), (18906, 23455, 16), (18894, 23461, 16), (18891, 23445, 16), (18887, 23454, 16), (18897, 23457, 16), (18896, 23448, 16), (18894, 23462, 16), (18903, 23455, 16), (18892, 23452, 16), (18892, 23442, 16), (18897, 23454, 16), (18901, 23451, 16), (18889, 23456, 16), (18885, 23453, 16), (18894, 23459, 16), (18891, 23455, 16), (18895, 23448, 16), (18904, 23459, 16), (18892, 23447, 16), (18897, 23449, 16), (18901, 23454, 16), (18901, 23456, 16), (18890, 23459, 16), (18891, 23450, 16), (18895, 23455, 16), (18892, 23444, 16), (18903, 23456, 16), (18889, 23454, 16), (18901, 23459, 16), (18890, 23460, 16), (18902, 23459, 16), (18899, 23457, 16), (18895, 23442, 16), (18905, 23455, 16), (18889, 23449, 16), (18890, 23449, 16), (18899, 23452, 16), (18892, 23454, 16), (18903, 23457, 16), (18889, 23444, 16), (18893, 23457, 16), (18902, 23455, 16), (18890, 23450, 16), (18899, 23451, 16), (18895, 23444, 16), (18900, 23451, 16), (18896, 23461, 16), (18889, 23447, 16), (18893, 23460, 16), (18890, 23455, 16), (18904, 23452, 16), (18899, 23446, 16), (18899, 23460, 16), (18900, 23448, 16), (18884, 23454, 16), (18893, 23463, 16), (18894, 23455, 16), (18903, 23459, 16), (18899, 23459, 16), (18900, 23453, 16), (18896, 23460, 16), (18900, 23459, 16), (18898, 23456, 16), (18890, 23445, 16), (18894, 23448, 16), (18891, 23462, 16), (18904, 23453, 16), (18888, 23453, 16), (18900, 23456, 16), (18898, 23461, 16), (18906, 23457, 16), (18898, 23447, 16), (18894, 23445, 16), (18895, 23456, 16), (18891, 23461, 16), (18900, 23447, 16), (18900, 23461, 16), (18898, 23462, 16), (18898, 23448, 16), (18894, 23446, 16), (18904, 23457, 16), (18895, 23463, 16), (18891, 23456, 16), (18895, 23445, 16), (18892, 23458, 16), (18893, 23443, 16), (18898, 23453, 16), (18894, 23443, 16), (18896, 23463, 16), (18896, 23445, 16), (18892, 23463, 16), (18893, 23446, 16), (18894, 23458, 16), (18887, 23457, 16), (18905, 23458, 16), (18892, 23460, 16), (18897, 23444, 16), (18893, 23449, 16), (18894, 23465, 16), (18896, 23457, 16), (18896, 23455, 16), (18897, 23461, 16), (18897, 23447, 16), (18904, 23455, 16), (18896, 23464, 16), (18900, 23454, 16), (18903, 23451, 16), (18891, 23444, 16), (18896, 23452, 16), (18897, 23456, 16), (18894, 23463, 16), (18903, 23454, 16), (18891, 23443, 16), (18896, 23449, 16), (18897, 23459, 16), (18892, 23443, 16), (18897, 23453, 16), (18901, 23450, 16), (18894, 23456, 16), (18895, 23461, 16), (18894, 23442, 16), (18891, 23454, 16), (18895, 23451, 16), (18897, 23448, 16), (18901, 23453, 16), (18889, 23458, 16), (18885, 23455, 16), (18890, 23456, 16), (18891, 23453, 16), (18897, 23465, 16), (18892, 23445, 16), (18889, 23453, 16), (18901, 23458, 16), (18902, 23456, 16), (18891, 23448, 16), (18905, 23454, 16), (18889, 23448, 16), (18901, 23461, 16), (18886, 23453, 16), (18899, 23455, 16), (18892, 23455, 16), (18889, 23451, 16), (18893, 23456, 16), (18902, 23452, 16), (18890, 23451, 16), (18886, 23454, 16), (18899, 23450, 16), (18895, 23447, 16), (18900, 23460, 16), (18889, 23446, 16), (18893, 23459, 16), (18906, 23456, 16), (18890, 23452, 16), (18899, 23449, 16), (18895, 23466, 16), (18899, 23463, 16), (18900, 23449, 16), (18904, 23454, 16), (18893, 23462, 16), (18889, 23459, 16), (18896, 23465, 16), (18895, 23465, 16)])


def test_cover_donut_webmercator2(wmtiler, donut):
    tiles = [tile for tile in cover_geometry(wmtiler, donut, [14, 16, 17])]
    assert len(tiles) == 281
    assert set(tiles) == set([(4723, 5861, 14), (4723, 5864, 14), (4724, 5862, 14), (4724, 5864, 14), (4725, 5863, 14), (4725, 5864, 14), (18885, 23454, 16),
                              (18886, 23454, 16), (18886, 23455, 16), (18887, 23454, 16), (18887, 23455, 16), (18887, 23456, 16), (18888, 23453, 16), (18888, 23454, 16), (18888, 23455, 16), (18888, 23456, 16), (18888, 23457, 16), (18889, 23449, 16), (18889, 23450, 16), (18889, 23451, 16), (18889, 23452, 16), (18889, 23453, 16), (18889, 23454, 16), (18889, 23455, 16), (18889, 23456, 16), (18889, 23457, 16), (18889, 23458, 16), (18890, 23443, 16), (18890, 23444, 16), (18890, 23445, 16), (18890, 23446, 16), (18890, 23447, 16), (18890, 23448, 16), (18890, 23450, 16), (18890, 23451, 16), (18890, 23452, 16), (18890, 23453, 16), (18890, 23454, 16), (18890, 23455, 16), (18890, 23456, 16), (18890, 23457, 16), (18890, 23458, 16), (18890, 23459, 16), (18891, 23442, 16), (18891, 23443, 16), (18891, 23444, 16), (18891, 23445, 16), (18891, 23446, 16), (18891, 23447, 16), (18891, 23451, 16), (18891, 23452, 16), (18891, 23453, 16), (18891, 23454, 16), (18891, 23455, 16), (18891, 23456, 16), (18891, 23457, 16), (18891, 23458, 16), (18891, 23459, 16), (18891, 23460, 16), (18892, 23442, 16), (18892, 23443, 16), (18892, 23453, 16), (18892, 23454, 16), (18892, 23455, 16), (18892, 23460, 16), (18892, 23461, 16), (18892, 23462, 16), (18893, 23442, 16), (18893, 23443, 16), (18893, 23448, 16), (18893, 23454, 16), (18893, 23455, 16), (18893, 23460, 16), (18893, 23461, 16), (18893, 23462, 16), (18893, 23463, 16), (18894, 23442, 16), (18894, 23443, 16), (18894, 23448, 16), (18894, 23449, 16), (18894, 23455, 16), (18894, 23460, 16), (18894, 23461, 16), (18894, 23462, 16), (18894, 23463, 16), (18894, 23464, 16), (18895, 23443, 16), (18895, 23448, 16), (18895, 23449, 16), (18895, 23450, 16), (18895, 23460, 16), (18895, 23461, 16), (18895, 23462, 16), (18895, 23463, 16), (18895, 23464, 16), (18895, 23465, 16), (18896, 23444, 16), (18896, 23445, 16), (18896, 23446, 16), (18896, 23447, 16), (18896, 23460, 16), (18896, 23461, 16), (18896, 23462, 16), (18896, 23463, 16), (18896, 23464, 16), (18896, 23465, 16), (18897, 23445, 16), (18897, 23446, 16), (18897, 23447, 16), (18897, 23452, 16), (18897, 23453, 16), (18897, 23455, 16), (18897, 23460, 16), (18897, 23461, 16), (18897, 23462, 16), (18897, 23463, 16), (18897, 23464, 16), (18898, 23446, 16), (18898, 23447, 16), (18898, 23452, 16), (18898, 23453, 16), (18898, 23454, 16), (18898, 23455, 16), (18898, 23460, 16), (18898, 23461, 16), (18898, 23462, 16), (18898, 23463, 16), (18899, 23447, 16), (18899, 23452, 16), (18899, 23453, 16), (18899, 23454, 16), (18899, 23455, 16), (18899, 23460, 16), (18899, 23461, 16), (18899, 23462, 16), (18900, 23449, 16), (18900, 23450, 16), (18900, 23451, 16), (18900, 23460, 16), (18900, 23461, 16), (18901, 23450, 16), (18901, 23451, 16), (18901, 23460, 16), (18902, 23451, 16), (18904, 23453, 16), (18904, 23454, 16), (18904, 23455, 16), (18904, 23456, 16), (18904, 23457, 16), (18904, 23458, 16), (18905, 23455, 16), (18905, 23456, 16), (18905, 23457, 16), (18906, 23456, 16),
                              (37769, 46907, 17), (37769, 46908, 17), (37770, 46907, 17), (37771, 46907, 17), (37771, 46910, 17), (37772, 46907, 17), (37773, 46907, 17), (37773, 46912, 17), (37774, 46907, 17), (37774, 46914, 17), (37775, 46907, 17), (37775, 46914, 17), (37775, 46915, 17), (37776, 46916, 17), (37777, 46905, 17), (37777, 46916, 17), (37777, 46917, 17), (37778, 46918, 17), (37779, 46889, 17), (37779, 46890, 17), (37779, 46891, 17), (37779, 46892, 17), (37779, 46893, 17), (37779, 46894, 17), (37779, 46895, 17), (37779, 46896, 17), (37779, 46897, 17), (37779, 46918, 17), (37779, 46919, 17), (37780, 46898, 17), (37780, 46899, 17), (37780, 46920, 17), (37781, 46885, 17), (37781, 46899, 17), (37781, 46920, 17), (37781, 46921, 17), (37782, 46896, 17), (37782, 46897, 17), (37782, 46901, 17), (37782, 46922, 17), (37783, 46896, 17), (37783, 46922, 17), (37783, 46923, 17), (37783, 46924, 17), (37784, 46904, 17), (37784, 46905, 17), (37785, 46883, 17), (37785, 46896, 17), (37785, 46905, 17), (37785, 46926, 17), (37786, 46883, 17), (37786, 46906, 17), (37786, 46907, 17), (37787, 46882, 17), (37787, 46883, 17), (37787, 46898, 17), (37787, 46907, 17), (37787, 46928, 17), (37788, 46882, 17), (37788, 46883, 17), (37788, 46908, 17), (37788, 46909, 17), (37789, 46883, 17), (37789, 46900, 17), (37789, 46901, 17), (37789, 46909, 17), (37789, 46930, 17), (37790, 46884, 17), (37790, 46885, 17), (37790, 46902, 17), (37790, 46911, 17), (37791, 46885, 17), (37791, 46902, 17), (37791, 46903, 17), (37791, 46932, 17), (37792, 46886, 17), (37792, 46887, 17), (37792, 46904, 17), (37792, 46932, 17), (37793, 46904, 17), (37793, 46905, 17), (37793, 46911, 17), (37794, 46889, 17), (37794, 46930, 17), (37795, 46908, 17), (37795, 46909, 17), (37796, 46891, 17), (37796, 46928, 17), (37798, 46893, 17), (37798, 46926, 17), (37798, 46927, 17), (37799, 46926, 17), (37800, 46895, 17), (37800, 46896, 17), (37800, 46897, 17), (37800, 46924, 17), (37800, 46925, 17), (37801, 46897, 17), (37801, 46924, 17), (37802, 46898, 17), (37802, 46899, 17), (37802, 46922, 17), (37802, 46923, 17), (37803, 46899, 17), (37803, 46922, 17), (37804, 46900, 17), (37804, 46901, 17), (37804, 46920, 17), (37804, 46921, 17), (37805, 46901, 17), (37805, 46920, 17), (37806, 46903, 17), (37806, 46920, 17), (37808, 46905, 17), (37808, 46918, 17), (37810, 46908, 17), (37810, 46909, 17), (37810, 46916, 17), (37811, 46909, 17), (37811, 46916, 17), (37812, 46910, 17), (37812, 46911, 17), (37812, 46914, 17), (37812, 46915, 17), (37813, 46911, 17), (37813, 46914, 17), (37814, 46913, 17) ])