{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# OTB Guided Tour - JURSE 2019 Vannes France - May 21th\n", "## Yannick TANGUY and David YOUSSEFI (CNES, French Space Agency)\n", "\n", "
\n", "\n", " Press SHIFT+ENTER to execute the notebook interactively cell by cell \n", "\n", "## Step 4 : Filter shapefile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Polygonize with GDAL" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "import subprocess\n", "from osgeo import ogr, osr\n", "\n", "import ogr_io\n", "\n", "# Data directory\n", "DATA_DIR = \"data\"\n", "\n", "# Output directory\n", "OUTPUT_DIR = \"output\"\n", "\n", "# Input / Output filenames\n", "envelope_fname = os.path.join(DATA_DIR, \"morbihan.sqlite\")\n", "ndwi_thres_fname = os.path.join(OUTPUT_DIR, \"ndwi_threshold30.tif\")\n", "watermask_fname = os.path.join(OUTPUT_DIR, \"watermask.sqlite\")\n", "results_fname = os.path.join(OUTPUT_DIR, \"results.sqlite\")\n", "geojson_fname = os.path.join(OUTPUT_DIR, \"geojson.json\")\n", "\n", "# Get SQLite driver\n", "outDriver = ogr.GetDriverByName(\"SQLite\")\n", "\n", "# Remove results if it already exists\n", "if os.path.exists(results_fname):\n", " outDriver.DeleteDataSource(results_fname)\n", " \n", "# Remove watermask if it already exists\n", "if os.path.exists(watermask_fname):\n", " outDriver.DeleteDataSource(watermask_fname)\n", "\n", "# Convert the TIF file in a shapefile with polygons\n", "try:\n", " subprocess.call([\"gdal_polygonize.py\", ndwi_thres_fname,\"-f\", \"SQLite\", watermask_fname])\n", " print (\"Converting \",ndwi_thres_fname, \" into a shapefile \", watermask_fname)\n", "except:\n", " print(\"Error during conversion\")\n", " exit(-1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Read shapefile with ogr\n", "watermask = ogr_io.openToRead(watermask_fname)\n", "envelope = ogr_io.openToRead(envelope_fname)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Crop Islands\n", "\n", "Crop the \"watermask\" shapefile with envelope shape (~ Morbihan gulf) and also filter the smallest areas and the two biggest (main land and sea)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# create the spatial reference, WGS84\n", "srs = osr.SpatialReference()\n", "srs.ImportFromEPSG(32630)\n", "\n", "# Create the output shapefile\n", "outDataSource = outDriver.CreateDataSource(results_fname)\n", "outLayer = outDataSource.CreateLayer(\"islands\", srs, geom_type=ogr.wkbPolygon)\n", "\n", "# Collect all islands inside the envelope\n", "geomcol = ogr.Geometry(ogr.wkbGeometryCollection)\n", "inLayer = watermask.GetLayer()\n", "layer_envelope = envelope.GetLayer()\n", "\n", "for shape in layer_envelope:\n", " inLayer.SetSpatialFilter(shape.GetGeometryRef())\n", " print(\"Nb features (before filtering): \",inLayer.GetFeatureCount())\n", " for feature in inLayer:\n", " outLayer.CreateFeature(feature)\n", "\n", "featureDefn = outLayer.GetLayerDefn()\n", "\n", "areaMax = 0\n", "index = 1\n", "biggestFeature = 0\n", "for feature in outLayer:\n", " area = feature.GetGeometryRef().GetArea()\n", " # Our features contain : \n", " # - some land (because the cropping shape is not very precise\n", " # - the sea !\n", " # - some very small submarine dark areas : these are supposely rocks\n", " # --> we eliminate every feature larger than 4 km² (\"ile aux moines\" area) \n", " # and also smaller than 10000 m² (1 Ha)\n", " if (area > 4000000.0):\n", " #print(\"Del too large feature area = \",str(area))\n", " outLayer.DeleteFeature(feature.GetFID())\n", " if (area < 10000.0):\n", " #print(\"Del too small feature area = \",str(area))\n", " outLayer.DeleteFeature(feature.GetFID())\n", "\n", "print (\"Nb islands (after filtering): \", outLayer.GetFeatureCount())\n", " \n", "# unload the driver -> writes the file\n", "outDriver = None" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import rasterio\n", "from glob import glob\n", "import display_api\n", "import json\n", "\n", "# Convert sqlite to geojson EPSG:4326\n", "try:\n", " subprocess.call([\"ogr2ogr\", \"-f\", \"GeoJSON\", geojson_fname, results_fname, \"-t_srs\", \"EPSG:4326\"])\n", " print (\"Converting sqlite to geojson EPSG:4326\")\n", "except:\n", " print(\"Error during conversion\")\n", " exit(-1)\n", " \n", "with open(geojson_fname, 'r') as f:\n", " fc = json.load(f)\n", "\n", "DATE = \"20180805\"\n", "raster = rasterio.open(glob(os.path.join(DATA_DIR, \"SENTINEL2?_{0}-*.tif\".format(DATE)))[0])\n", "m, dc = display_api.rasters_on_map([raster], OUTPUT_DIR, [DATE], geojson_data=fc)\n", "m" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.6" } }, "nbformat": 4, "nbformat_minor": 2 }