{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Creating a polygon from a list of points\n", "\n", "For many of those working with geo data it is a common task being asked to create a polygon from a list of points. More specific, to create a polygon that wraps around those points in a meaningful manner. So, there are several sources in the web explaining how to create the shape (see sources at end of document). This example notebook is the application of those solutions to folium maps." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Helpers" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Imports\n", "import random\n", "\n", "import folium\n", "from scipy.spatial import ConvexHull\n", "\n", "\n", "# Function to create a list of some random points\n", "def randome_points(amount, LON_min, LON_max, LAT_min, LAT_max):\n", "\n", " points = []\n", " for _ in range(amount):\n", " points.append(\n", " (random.uniform(LON_min, LON_max), random.uniform(LAT_min, LAT_max))\n", " )\n", "\n", " return points\n", "\n", "\n", "# Function to draw points in the map\n", "def draw_points(map_object, list_of_points, layer_name, line_color, fill_color, text):\n", "\n", " fg = folium.FeatureGroup(name=layer_name)\n", "\n", " for point in list_of_points:\n", " fg.add_child(\n", " folium.CircleMarker(\n", " point,\n", " radius=1,\n", " color=line_color,\n", " fill_color=fill_color,\n", " popup=(folium.Popup(text)),\n", " )\n", " )\n", "\n", " map_object.add_child(fg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Convex hull\n", "\n", "The convex hull is probably the most common approach - its goal is to create the smallest polygon that contains all points from a given list. The scipy.spatial package provides this algorithm (https://docs.scipy.org/doc/scipy-0.19.0/reference/generated/scipy.spatial.ConvexHull.html, accessed 29.12.2018)." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Function that takes a map and a list of points (LON,LAT tupels) and\n", "# returns a map with the convex hull polygon from the points as a new layer\n", "\n", "\n", "def create_convexhull_polygon(\n", " map_object, list_of_points, layer_name, line_color, fill_color, weight, text\n", "):\n", "\n", " # Since it is pointless to draw a convex hull polygon around less than 3 points check len of input\n", " if len(list_of_points) < 3:\n", " return\n", "\n", " # Create the convex hull using scipy.spatial\n", " form = [list_of_points[i] for i in ConvexHull(list_of_points).vertices]\n", "\n", " # Create feature group, add the polygon and add the feature group to the map\n", " fg = folium.FeatureGroup(name=layer_name)\n", " fg.add_child(\n", " folium.vector_layers.Polygon(\n", " locations=form,\n", " color=line_color,\n", " fill_color=fill_color,\n", " weight=weight,\n", " popup=(folium.Popup(text)),\n", " )\n", " )\n", " map_object.add_child(fg)\n", "\n", " return map_object" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "