{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "2b52862b-c3ef-700c-a09c-cbeaa0504494"
      },
      "source": [
        "## Description\n",
        "\n",
        "One polygon in image 6060_2_3 is invalid.  This causes errors when performing some actions like intersection etc.\n",
        "\n",
        "In this kernel, we will find, and fix, all such invalid polygons."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "64ef8efb-74f5-1704-765d-d81c762c091b"
      },
      "outputs": [],
      "source": [
        "import numpy as np # linear algebra\n",
        "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n",
        "\n",
        "import shapely\n",
        "from shapely.wkt import loads as wkt_loads"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "360664eb-5f67-378a-f26a-8d050ad0fd7c"
      },
      "outputs": [],
      "source": [
        "# Read the training data from WKT format\n",
        "inDir = '../input'\n",
        "df = pd.read_csv(inDir + '/train_wkt_v4.csv',\n",
        "        names=['SceneId', 'ClassType', 'MultipolygonWKT'], skiprows=1)\n",
        "trainSceneIds = np.sort(df.SceneId.unique())\n",
        "classes = range(1,11)\n",
        "\n",
        "# Function to load polygons\n",
        "def get_polygons(sceneId):\n",
        "    '''\n",
        "    Parameters\n",
        "    ----------\n",
        "    sceneId : str\n",
        "        sceneId like \"6010_0_4\"\n",
        "\n",
        "    Returns\n",
        "    -------\n",
        "    polygonsList : dict\n",
        "        Keys are CLASSES\n",
        "        Values are shapely polygons\n",
        "        None if sceneId is missing from df\n",
        "    '''\n",
        "    df_scene = df[df.SceneId == sceneId]\n",
        "    if len(df_scene) == 0:\n",
        "        return None\n",
        "    polygonsList = {}\n",
        "    for cType in classes:\n",
        "        polygonsList[cType] = wkt_loads(df_scene[df_scene.ClassType == cType].MultipolygonWKT.values[0])\n",
        "    return polygonsList"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "8a0d3dbc-a73d-5a9f-145e-5f0ef2f18477"
      },
      "outputs": [],
      "source": [
        "# Locate invalid polygons in the training data\n",
        "for sceneId in trainSceneIds:\n",
        "    pl = get_polygons(sceneId)\n",
        "    for cType in classes:\n",
        "        if not pl[cType].is_valid:\n",
        "            # One of the polygons in this MultiPolygon is invalid\n",
        "            for i, poly in enumerate(pl[cType]):\n",
        "                if not poly.is_valid:\n",
        "                    print('Scene {} Class {} Polygon {} is invalid'.format(sceneId, cType, i))\n",
        "                    fixed_poly = poly.buffer(0)  # Fix invalid polygon\n",
        "                    print('Polygon fixed? :', fixed_poly.is_valid)                   "
      ]
    }
  ],
  "metadata": {
    "_change_revision": 0,
    "_is_fork": false,
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.5.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}