{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial 4: Trajectory aggregation (flow maps)\n", "\n", "\n", "\n", "This tutorial covers trajectory generalization and aggregation using flow maps. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import urllib\n", "import os\n", "import numpy as np\n", "import pandas as pd\n", "from geopandas import GeoDataFrame, read_file\n", "from shapely.geometry import Point, LineString, Polygon, MultiPoint\n", "from datetime import datetime, timedelta\n", "\n", "import sys\n", "sys.path.append(\"..\")\n", "import movingpandas as mpd\n", "\n", "import warnings\n", "warnings.simplefilter(\"ignore\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ship movements (AIS data)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df = read_file('data/demodata_ais.gpkg')\n", "df['t'] = pd.to_datetime(df['Timestamp'], format='%d/%m/%Y %H:%M:%S')\n", "df = df.set_index('t')\n", "df = df[df.SOG>0]\n", "df.size" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "MIN_LENGTH = 100 # meters\n", "traj_collection = mpd.TrajectoryCollection(df, 'MMSI', min_length=MIN_LENGTH)\n", "print(\"Finished creating {} trajectories\".format(len(traj_collection)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "trips = mpd.ObservationGapSplitter(traj_collection).split(gap=timedelta(minutes=5))\n", "print(\"Extracted {} individual trips from {} continuous vessel tracks\".format(len(trips), len(traj_collection)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Generalizing the trip trajectories significantly speeds up the following aggregation step." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "generalized = mpd.MinDistanceGeneralizer(trips).generalize(tolerance=100)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "aggregator = mpd.TrajectoryCollectionAggregator(generalized, max_distance=1000, min_distance=100, min_stop_duration=timedelta(minutes=5))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "pts = aggregator.get_significant_points_gdf()\n", "clusters = aggregator.get_clusters_gdf()\n", "( pts.hvplot(geo=True, tiles='OSM', frame_width=800) * \n", " clusters.hvplot(geo=True, color='red') )" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "flows = aggregator.get_flows_gdf()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "( #trips.hvplot(color='gray') *\n", " flows.hvplot(geo=True, hover_cols=['weight'], line_width='weight', alpha=0.5, color='#1f77b3', tiles='OSM') * \n", " clusters.hvplot(geo=True, color='red', size='n') )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Comparison of generalized vs. original trajectories" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "aggregator_original = mpd.TrajectoryCollectionAggregator(trips, max_distance=1000, min_distance=100, min_stop_duration=timedelta(minutes=5))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "( aggregator_original.get_flows_gdf().hvplot(title='Original', geo=True, tiles='OSM', hover_cols=['weight'], line_width='weight', alpha=0.5, color='#1f77b3', frame_height=400, frame_width=400) * \n", " aggregator_original.get_clusters_gdf().hvplot(geo=True, color='red', size='n') +\n", " flows.hvplot(title='Generalized', geo=True, tiles='OSM', hover_cols=['weight'], line_width='weight', alpha=0.5, color='#1f77b3', frame_height=400, frame_width=400) * \n", " clusters.hvplot(geo=True, color='red', size='n') \n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Bird migration data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df = read_file('data/demodata_gulls.gpkg')\n", "df['t'] = pd.to_datetime(df['timestamp'])\n", "df = df.set_index('t')\n", "df.size" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "traj_collection = mpd.TrajectoryCollection(df, 'individual-local-identifier', min_length=MIN_LENGTH) \n", "print(\"Finished creating {} trajectories\".format(len(traj_collection)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "trips = mpd.TemporalSplitter(traj_collection).split(mode='month')\n", "print(\"Extracted {} individual trips from {} continuous tracks\".format(len(trips), len(traj_collection)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "generalized = mpd.MinTimeDeltaGeneralizer(trips).generalize(tolerance=timedelta(days=1))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "aggregator = mpd.TrajectoryCollectionAggregator(generalized, max_distance=1000000, min_distance=100000, min_stop_duration=timedelta(minutes=5))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "flows = aggregator.get_flows_gdf()\n", "clusters = aggregator.get_clusters_gdf()\n", "\n", "( flows.hvplot(geo=True, hover_cols=['weight'], line_width='weight', alpha=0.5, color='#1f77b3', tiles='OSM') * \n", " clusters.hvplot(geo=True, color='red', size='n') )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "aggregator_original = mpd.TrajectoryCollectionAggregator(trips, max_distance=1000000, min_distance=100000, min_stop_duration=timedelta(minutes=5))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "( aggregator_original.get_flows_gdf().hvplot(title='Original', geo=True, tiles='OSM', hover_cols=['weight'], line_width='weight', alpha=0.5, color='#1f77b3', frame_height=600, frame_width=400) * \n", " aggregator_original.get_clusters_gdf().hvplot(geo=True, color='red', size='n') +\n", " flows.hvplot(title='Generalized', geo=True, tiles='OSM', hover_cols=['weight'], line_width='weight', alpha=0.5, color='#1f77b3', frame_height=600, frame_width=400) * \n", " clusters.hvplot(geo=True, color='red', size='n') \n", ")" ] } ], "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.7.8" } }, "nbformat": 4, "nbformat_minor": 4 }