from matplotlib import pyplot as plt
from matplotlib import gridspec
from matplotlib.path import Path
from matplotlib.patches import PathPatch

import numpy
import geopandas as gpd
from shapely.wkt import loads
import cartagen as c4

polygons = [
    loads('POLYGON ((1671684.33503583236597478 6640184.87185448687523603, 1724447.128384675597772 6583302.91520072147250175, 1807675.66023935214616358 6567999.29454971756786108, 1800732.27912595611996949 6519788.22479292284697294, 1861203.54860731679946184 6483723.52156444173306227, 1877822.79304525954648852 6528767.98236426338553429, 1954165.46972782840020955 6509230.9596130782738328, 1964727.23254820168949664 6454772.7628742316737771, 2047489.80427844799123704 6444306.75609370414167643, 2098722.40758904768154025 6359484.52348314877599478, 2065529.93946618982590735 6359276.38694169837981462, 2048277.90967408777214587 6328480.39713238924741745, 2022730.6391483333427459 6321057.98019515164196491, 2015436.34979308373294771 6282327.7659193268045783, 1994122.98854608600959182 6274266.32072173245251179, 1991114.38181675248779356 6258499.00520261935889721, 1953101.23981400835327804 6240996.67944358009845018, 1903784.25034828507341444 6243861.71769171394407749, 1888010.63724726741202176 6206752.35448146238923073, 1836691.74502473813481629 6238595.33550586365163326, 1784412.16958270827308297 6229829.65464682783931494, 1698002.45317483716644347 6281494.0716727701947093, 1658821.53456396167166531 6268823.27473133336752653, 1596198.79487844975665212 6199740.11397837288677692, 1513493.74908948852680624 6254045.68297867570072412, 1450640.90563882724381983 6327125.96815799176692963, 1393834.03861747751943767 6368261.95801091752946377, 1382052.72584180976264179 6440929.82312062196433544, 1362562.9369336215313524 6492529.25899334810674191, 1443461.66816615662537515 6530535.26974879391491413, 1484794.0569811831228435 6574240.93839095253497362, 1564732.10499421739950776 6608376.46468910202383995, 1592649.44430101430043578 6642063.30602050386369228, 1622004.93213999713771045 6621707.54285569116473198, 1671684.33503583236597478 6640184.87185448687523603))'),
    loads('POLYGON ((2511160.39624350657686591 6289421.88415267504751682, 2480291.9761486635543406 6245285.86227862630039454, 2458558.67553026648238301 6177394.29184130672365427, 2434806.21437268331646919 6160252.62019212543964386, 2315589.45364858116954565 6211276.64375811535865068, 2279106.50168408406898379 6201009.10541653726249933, 2253001.22952784225344658 6161524.39819812495261431, 2200727.40667994366958737 6140641.90748390555381775, 2188692.9797626081854105 6151325.22547416016459465, 2134480.53269332181662321 6125404.35667907632887363, 2090248.83643740555271506 6120468.96252772491425276, 2081286.2947848211042583 6087072.57074050977826118, 1987846.90835162531584501 6066759.6873060492798686, 1946807.90183716453611851 6084834.17564896773546934, 1890167.86004554736427963 6127424.98463182244449854, 1879071.10597119806334376 6185407.56891869008541107, 1888010.63724726741202176 6206752.35448146238923073, 1903784.25034828507341444 6243861.71769171394407749, 1953101.23981400835327804 6240996.67944358009845018, 1991114.38181675248779356 6258499.00520261935889721, 1994122.98854608600959182 6274266.32072173245251179, 2015436.34979308373294771 6282327.7659193268045783, 2022730.6391483333427459 6321057.98019515164196491, 2048277.90967408777214587 6328480.39713238924741745, 2065529.93946618982590735 6359276.38694169837981462, 2098722.40758904768154025 6359484.52348314877599478, 2105004.24037763429805636 6349141.51502863317728043, 2150771.87926592584699392 6372407.96002371795475483, 2206911.44536834349855781 6311783.64968566969037056, 2272680.85404227767139673 6348389.63234757352620363, 2325236.5540024871006608 6330832.41577770467847586, 2405370.19021589728072286 6355008.51234229560941458, 2511160.39624350657686591 6289421.88415267504751682))'),
    loads('POLYGON ((1890167.86004554736427963 6127424.98463182244449854, 1881717.29927042033523321 6059549.04954236466437578, 1819025.52845536242239177 6059224.15690211486071348, 1840586.25124989869073033 6023441.2183494558557868, 1803631.58656684262678027 5918012.90224720165133476, 1782410.26682590576820076 5890583.33705814555287361, 1685053.3637910345569253 5886542.51436578296124935, 1628879.28212384390644729 5849820.35350786987692118, 1536929.81756999320350587 5862344.93113766983151436, 1377744.03283937857486308 5904215.98938171658664942, 1352875.56842081714421511 5960929.5571554834023118, 1242862.95830270904116333 5932543.56686825677752495, 1229919.62151303188875318 5901583.47386971954256296, 1162476.20794763439334929 5924715.38833865709602833, 1105675.09352041035890579 5929144.45848092995584011, 1055305.3793291246984154 5958871.45044063683599234, 1072333.05795020959340036 5998997.15651112701743841, 1068024.364947778172791 6028202.01937216892838478, 1101625.26725377538241446 6037296.55646637547761202, 1157954.66896244045346975 5991588.28833879996091127, 1173808.81838125828653574 6035019.89345597103238106, 1271982.58978241379372776 6027989.04741630330681801, 1351569.72955359076149762 6057599.87731378898024559, 1404936.5452859525103122 6052523.83873935882002115, 1439653.45085292495787144 6018742.60321075934916735, 1450031.13066118024289608 6046772.04193465318530798, 1434251.76496603363193572 6155093.91244305856525898, 1474243.79934906726703048 6176362.82620277721434832, 1513493.74908948852680624 6254045.68297867570072412, 1596198.79487844975665212 6199740.11397837288677692, 1658821.53456396167166531 6268823.27473133336752653, 1698002.45317483716644347 6281494.0716727701947093, 1784412.16958270827308297 6229829.65464682783931494, 1836691.74502473813481629 6238595.33550586365163326, 1888010.63724726741202176 6206752.35448146238923073, 1879071.10597119806334376 6185407.56891869008541107, 1890167.86004554736427963 6127424.98463182244449854))'),
    loads('POLYGON ((2458558.67553026648238301 6177394.29184130672365427, 2520364.54684949433431029 6131885.84035125561058521, 2528124.79632917419075966 6087278.42942925076931715, 2460134.88632154325023293 6052532.3817491652444005, 2407452.62929050298407674 5941133.58206644840538502, 2340153.03057832270860672 5831148.03518426697701216, 2250901.53267085319384933 5800799.796680080704391, 2181421.70078387716785073 5807911.88544869143515825, 2096127.98763698199763894 5765758.80827368516474962, 2096126.50766928563825786 5765757.95812190324068069, 2054519.47430377569980919 5741889.31820260360836983, 1962570.00974992499686778 5772623.55225606728345156, 1879352.98308350634761155 5841556.9635159932076931, 1843986.03437998471781611 5861446.44341410044580698, 1822356.28045590617693961 5916212.98435185104608536, 1803631.58656684262678027 5918012.90224720165133476, 1840586.25124989869073033 6023441.2183494558557868, 1819025.52845536242239177 6059224.15690211486071348, 1881717.29927042033523321 6059549.04954236466437578, 1890167.86004554736427963 6127424.98463182244449854, 1946807.90183716453611851 6084834.17564896773546934, 1987846.90835162531584501 6066759.6873060492798686, 2081286.2947848211042583 6087072.57074050977826118, 2090248.83643740555271506 6120468.96252772491425276, 2134480.53269332181662321 6125404.35667907632887363, 2188692.9797626081854105 6151325.22547416016459465, 2200727.40667994366958737 6140641.90748390555381775, 2253001.22952784225344658 6161524.39819812495261431, 2279106.50168408406898379 6201009.10541653726249933, 2315589.45364858116954565 6211276.64375811535865068, 2434806.21437268331646919 6160252.62019212543964386, 2458558.67553026648238301 6177394.29184130672365427))')
]

gdf = gpd.GeoDataFrame(geometry=polygons)

simplified = c4.generalize_boundaries(gdf, c4.smooth_snake, 5, 0.1, 0.1, 1.0, 0.8)
simplified = c4.generalize_boundaries(gdf, c4.smooth_snake, 5, 0.1, 0.1, 1.0, 0.8)
simplified = c4.generalize_boundaries(gdf, c4.smooth_snake, 5, 0.1, 0.1, 1.0, 0.8)

fig = plt.figure(1, (12, 12))
gs = gridspec.GridSpec(3, 4)

sub1 = fig.add_subplot(gs[0, 1:3])
sub1.set_aspect('equal')
sub1.set_title("a) Original polygons", pad=10, family='sans-serif')
sub1.axes.get_xaxis().set_visible(False)
sub1.axes.get_yaxis().set_visible(False)

for polygon in polygons:
    poly1 = Path.make_compound_path(Path(numpy.asarray(polygon.exterior.coords)[:, :2]),*[Path(numpy.asarray(ring.coords)[:, :2]) for ring in polygon.interiors])
    sub1.add_patch(PathPatch(poly1, facecolor="lightgrey", edgecolor='black'))

generalized = c4.generalize_boundaries(gdf, c4.simplify_douglas_peucker, 20000)

sub2 = fig.add_subplot(gs[1, 0:2])
sub2.set_aspect('equal')
sub2.set_title("b) Douglas-Peucker simplification", pad=10, family='sans-serif')
sub2.axes.get_xaxis().set_visible(False)
sub2.axes.get_yaxis().set_visible(False)

for polygon in generalized.geometry:
    poly1 = Path.make_compound_path(Path(numpy.asarray(polygon.exterior.coords)[:, :2]),*[Path(numpy.asarray(ring.coords)[:, :2]) for ring in polygon.interiors])
    sub2.add_patch(PathPatch(poly1, facecolor="lightgrey", edgecolor='red'))

generalized = c4.generalize_boundaries(gdf, c4.simplify_raposo, 1_000_000, 2_000_000)

sub3 = fig.add_subplot(gs[1, 2:4])
sub3.set_aspect('equal')
sub3.set_title("c) Raposo simplification", pad=10, family='sans-serif')
sub3.axes.get_xaxis().set_visible(False)
sub3.axes.get_yaxis().set_visible(False)

for polygon in generalized.geometry:
    poly1 = Path.make_compound_path(Path(numpy.asarray(polygon.exterior.coords)[:, :2]),*[Path(numpy.asarray(ring.coords)[:, :2]) for ring in polygon.interiors])
    sub3.add_patch(PathPatch(poly1, facecolor="lightgrey", edgecolor='red'))

generalized = c4.generalize_boundaries(gdf, c4.smooth_gaussian, 5000, 2000)

sub4 = fig.add_subplot(gs[2, 0:2])
sub4.set_aspect('equal')
sub4.set_title("d) Gaussian smoothing", pad=10, family='sans-serif')
sub4.axes.get_xaxis().set_visible(False)
sub4.axes.get_yaxis().set_visible(False)

for polygon in generalized.geometry:
    poly1 = Path.make_compound_path(Path(numpy.asarray(polygon.exterior.coords)[:, :2]),*[Path(numpy.asarray(ring.coords)[:, :2]) for ring in polygon.interiors])
    sub4.add_patch(PathPatch(poly1, facecolor="lightgrey", edgecolor='red'))

generalized = c4.generalize_boundaries(gdf, c4.smooth_snake, 5, 0.1, 0.1, 1.0, 0.6)

sub5 = fig.add_subplot(gs[2, 2:4])
sub5.set_aspect('equal')
sub5.set_title("e) Snake smoothing", pad=10, family='sans-serif')
sub5.axes.get_xaxis().set_visible(False)
sub5.axes.get_yaxis().set_visible(False)

for polygon in generalized.geometry:
    poly1 = Path.make_compound_path(Path(numpy.asarray(polygon.exterior.coords)[:, :2]),*[Path(numpy.asarray(ring.coords)[:, :2]) for ring in polygon.interiors])
    sub5.add_patch(PathPatch(poly1, facecolor="lightgrey", edgecolor='red'))

sub1.autoscale_view()
sub2.autoscale_view()
sub3.autoscale_view()
sub4.autoscale_view()
sub5.autoscale_view()

plt.tight_layout()
plt.show()