Skip to content

dakk/libweatherrouting

Repository files navigation

libweatherrouting

CI Status License: GPL v3 PyPI - Version

A 100% python weather routing library for sailing.

Reference

An introductory explanation (english, french, spanish and italian translations) of weather routing tools and methods can be find in: https://globalsolochallenge.com/weather-routing/

Install

pip install weatherrouting

Usage

For a comprehensive usage reference example pleace refer to wind_forecast_routing QGIS plugin or GWeatherRouting standalone application

Almost one external function has to be implemented as a preliminary requirement for library usage:

Wind direction and speed for a given location at specified time

A function that accept a datetime item, a float latitude and float longitude as parameters, performs a wind forecast analysis for the specified time and location (usually sampling a grib file) and returns a tuple with true wind direction (twd) expressed in degrees and true wind speed (tws) expressed in meters per second or None if running out of temporal/geographic grib scope.

def getWindAt(t, lat, lon)
    # wind forecast analysys implementation
    ...
    return (twd, tws)

Point validity (Optional)

A function that accept a float latitude and float longitude as parameters, performs a test to check if the specified location is eligible as waypoint (i.e. lay or not on sea) and returns a boolean (True if valid, False if invalid)

def point_validity(lat, lon)
    # 
    ...
    return True/False

Line validity (Optional)

A function that accept a vector defined as four float parameters (latitude1, longitude1, latitude2, longitude2) performs a test to check whether the specified line between two waypoints is valid (i.e. lays completely or not on sea, or in other words is in line of sight) and returns a boolean (True if valid, False if invalid)

def line_validity(lat1, lon1, lat1, lon1)
    # 
    ...
    return True/False

Import weatherrouting module

from weatherrouting import Routing, Polar
from weatherrouting.routers.linearbestisorouter import LinearBestIsoRouter
from datetime import datetime

Define a track points list

Define a list of trackpoints as lat,long tuples (almost 2) that have to be reached by the route

track = ((38.1, 5.1), (38.4, 5.2), (38.2, 5.7))

Define a polar wrapper

Define the polar object from a polar file describing the performance of the boat at different wind speeds (tws) and different angles (twd)

polar_obj = Polar("polar_files/bavaria38.pol")

Define the start datetime

Define the polar object from a polar file describing the performance of the boat at different wind speeds (tws) and different angles (`twd~)

start = datetime.fromisoformat('2021-04-02T12:00:00')

Define routing object

routing_obj = Routing(
    LinearBestIsoRouter,            # specify a router type
    polar_obj,                      # the polar object for a specific sail boat
    track,                          # the list of track points (lat,lon)
    getWindAt,                      # the function that returns (twd,tws) for a specified (datetime, lat, lon)
    start,                          # the start datetime
    start_position = (37.8, 4.8)    # the start location (lat lon, optional, the first track point if undefined)
    pointValidity = point_validity  # the point validity function (optional)
    lineValidity = line_validity    # the line validity function (optional)
)

Perform route calculation

Calculate subsequent steps until the end track point is reached

while not self.routing_obj.end:
    res = self.routing_obj.step() # default step duration is set to 1 hour

# you can call a step with custom timedelta (in hour) at anytime
while not self.routing_obj.end:
    res = self.routing_obj.step(timedelta=0.25) # 15min time delta

the step method returns a RoutingResult object with the following informations during routing calculation:

res.time         # the datetime of step  
res.isochrones   # all points reached at a specified datetime
res.progress     # the calculation progress 

and after the end of the routing calculation contains a list of tuple containing the waypoints informations (lat,lon,datetime, twd, tws, speed, heading)

res.path         # the list of route waypoints

Export path as geojson

The path could be exported as a geojson object for cartographic representation

from weatherrouting.utils import pathAsGeojson
import json

json.dumps(pathAsGeojson(res.path))

License

Read the LICENSE file.

Credits

This work is partially based and inspired by Riccardo Apolloni Virtual Sailing Simulator.