44##
55
66import argparse
7- import os
8- from datetime import datetime
7+ import json
8+ import logging
9+ from datetime import timedelta
10+ from pathlib import Path
911
1012import numpy as np
11- import matplotlib .pyplot as plt
1213from astropy import units as u
1314
1415from WeatherRoutingTool .config import Config , set_up_logging
15- from WeatherRoutingTool .routeparams import RouteParams
16- from WeatherRoutingTool .ship .shipparams import ShipParams
1716from WeatherRoutingTool .utils .graphics import get_figure_path
1817from WeatherRoutingTool .utils .maps import Map
19- from WeatherRoutingTool .ship . maripower_tanker import MariPowerTanker
18+ from WeatherRoutingTool .routeparams import RouteParams
2019from WeatherRoutingTool .ship .direct_power_boat import DirectPowerBoat
20+ from WeatherRoutingTool .ship .maripower_tanker import MariPowerTanker
21+ from WeatherRoutingTool .ship .shipparams import ShipParams
2122
22-
23- def run_maripower_test_scenario (calmfactor , windfactor , wavefactor , waypoint_dict , geojsondir , maripower_scenario ,
24- draught_fp , draught_ap , sog ):
25- boat = MariPowerTanker (file_name = config .CONFIG_PATH )
26- boat .set_ship_property ('Draught_FP' , draught_fp .mean ())
27- boat .set_ship_property ('Draught_AP' , draught_ap .mean ())
28- boat .set_ship_property ('WindForcesFactor' , windfactor )
29- boat .set_ship_property ('WaveForcesFactor' , wavefactor )
30- boat .set_ship_property ('CalmWaterFactor' , calmfactor )
31- boat .speed = sog
32- boat .load_data ()
33-
34- print ('Running maripower setting ' + maripower_scenario )
35-
36- ship_params = boat .get_ship_parameters (waypoint_dict ['courses' ], waypoint_dict ['start_lats' ],
37- waypoint_dict ['start_lons' ], time [:- 1 ], sog )
38-
39- start = (lat [0 ], lon [0 ])
40- finish = (lat [- 1 ], lon [- 1 ])
41-
42- rp = RouteParams (
43- count = lat .shape [0 ] - 2 ,
44- start = start ,
45- finish = finish ,
46- gcr = None ,
47- route_type = 'read_from_csv' ,
48- time = waypoint_dict ['travel_times' ],
49- lats_per_step = lat ,
50- lons_per_step = lon ,
51- course_per_step = waypoint_dict ['courses' ],
52- dists_per_step = waypoint_dict ['dist' ],
53- starttime_per_step = time ,
54- ship_params_per_step = ship_params )
55-
56- if geojsondir :
57- filename = os .path .join (geojsondir , 'route_' + maripower_scenario + '.json' )
58- print ('Writing file: ' , filename )
59- rp .return_route_to_API (filename )
60-
61-
62- def run_dpm_test_scenario (waypoint_dict , geojsondir , maripower_scenario , sog ):
23+ def run_dpm_test_scenario (waypoint_dict , geojsondir , sog , output_route ):
6324 boat = DirectPowerBoat (file_name = config .CONFIG_PATH )
6425 boat .speed = sog
6526 boat .load_data ()
6627
67- print ('Running direct power boat setting ' + maripower_scenario )
68-
6928 ship_params = boat .get_ship_parameters (waypoint_dict ['courses' ], waypoint_dict ['start_lats' ],
70- waypoint_dict ['start_lons' ], time [: - 1 ], sog )
29+ waypoint_dict ['start_lons' ], waypoint_dict [ 'start_times' ], sog )
7130
7231 start = (lat [0 ], lon [0 ])
7332 finish = (lat [- 1 ], lon [- 1 ])
7433
34+ # add arrival at destination to 'start_times'
35+ travel_time = timedelta (seconds = waypoint_dict ['travel_times' ][- 1 ].to ("second" ).value )
36+ waypoint_dict ['start_times' ] = np .append (
37+ waypoint_dict ['start_times' ],
38+ waypoint_dict ['start_times' ][- 1 ] + travel_time
39+ )
40+
7541 rp = RouteParams (
7642 count = lat .shape [0 ] - 2 ,
7743 start = start ,
@@ -83,152 +49,66 @@ def run_dpm_test_scenario(waypoint_dict, geojsondir, maripower_scenario, sog):
8349 lons_per_step = lon ,
8450 course_per_step = waypoint_dict ['courses' ],
8551 dists_per_step = waypoint_dict ['dist' ],
86- starttime_per_step = time ,
52+ starttime_per_step = waypoint_dict [ 'start_times' ] ,
8753 ship_params_per_step = ship_params )
8854
8955 if geojsondir :
90- filename = os . path . join ( geojsondir , 'route_' + maripower_scenario + '.json' )
56+ filename = output_route
9157 print ('Writing file: ' , filename )
9258 rp .return_route_to_API (filename )
9359
60+ def lat_lon_from_file (filename ):
61+ with open (filename ) as file :
62+ rp_dict = json .load (file )
9463
95- def cut_indices (lat , lon , time , sog , fore_draught , aft_draught , cut_route ):
96- start_indices_lat = int (np .where (abs (lat - cut_route [0 ]) < 0.001 )[0 ][0 ])
97- end_indices_lat = int (np .where (abs (lat - cut_route [2 ]) < 0.001 )[0 ][0 ])
98- start_indices_lon = int (np .where (abs (lon - cut_route [1 ]) < 0.001 )[0 ][0 ])
99- end_indices_lon = int (np .where (abs (lon - cut_route [3 ]) < 0.001 )[0 ][0 ])
100-
101- print ('start_lat: ' , lat [start_indices_lat ])
102- print ('end_lat: ' , lat [end_indices_lat ])
103- print ('start_lon: ' , lon [start_indices_lon ])
104- print ('end_lon: ' , lon [end_indices_lon ])
64+ point_list = rp_dict ['features' ]
65+ count = len (point_list )
10566
106- if ( start_indices_lat != start_indices_lon ) or ( end_indices_lat != end_indices_lon ):
107- raise ValueError ( 'Latitude and longitude are not matching for cut' )
67+ lats_per_step = np . full ( count , - 99. )
68+ lons_per_step = np . full ( count , - 99. )
10869
109- lat = lat [start_indices_lat :end_indices_lat + 1 ]
110- lon = lon [start_indices_lat :end_indices_lat + 1 ]
111- time = time [start_indices_lat :end_indices_lat + 1 ]
112- fore_draught = fore_draught [start_indices_lat :end_indices_lat + 1 ]
113- aft_draught = aft_draught [start_indices_lat :end_indices_lat + 1 ]
114- sog = sog [start_indices_lat :end_indices_lat ]
115-
116- print ('mean speed cut: ' , sog .mean ())
117- print ('start time cut: ' , time [0 ])
118- print ('mean aft draugh cut: ' , aft_draught .mean ())
119- print ('mean fore draugh cut: ' , fore_draught .mean ())
120-
121- return lat , lon , time , sog , fore_draught , aft_draught
70+ for ipoint in range (0 , count ):
71+ coord_pair = point_list [ipoint ]['geometry' ]['coordinates' ]
72+ lats_per_step [ipoint ] = coord_pair [1 ]
73+ lons_per_step [ipoint ] = coord_pair [0 ]
12274
75+ return lats_per_step , lons_per_step
12376
12477if __name__ == "__main__" :
12578 parser = argparse .ArgumentParser (description = 'Weather Routing Tool' )
12679 required_args = parser .add_argument_group ('required arguments' )
12780 optional_args = parser .add_argument_group ('optional arguments' )
12881 required_args .add_argument ('-f' , '--file' , help = "Config file name (absolute path)" , required = True , type = str )
129- required_args .add_argument ('-r' , '--route' , help = "Route file name (absolute path)" , required = True , type = str )
130- required_args .add_argument ('-n' , '--name' , help = "Name string for output json file" , required = True , type = str )
131-
132- optional_args .add_argument ('--write-geojson' , help = "<True|False>. Defaults to 'False'" , required = False ,
133- type = str , default = 'False' )
134- optional_args .add_argument ('-wave' , '--wave_scenario' , help = "Weight for wave resistance (maripower only)" ,
135- required = False , type = float , default = 1. )
136- optional_args .add_argument ('-wind' , '--wind_scenario' , help = "Weight for wind resistance (maripower only)" ,
137- required = False , type = float , default = 1. )
138- optional_args .add_argument ('-calm' , '--calm_water_scenario' , help = "Weight for calm water resistance "
139- "(maripower only)" ,
140- required = False , type = float , default = 1. )
141- optional_args .add_argument ('-bt' , '--boat_type' ,
142- help = "<maripower|direct_power_method>. Defaults to 'direct_power_method' " ,
143- required = False ,
144- type = str , default = 'direct_power_method' )
82+ required_args .add_argument ('-r-in' , '--input_route' , help = "Route file name (absolute path)" , required = True , type = str )
83+ required_args .add_argument ('-r-out' , '--output_route' , help = "Route file name (absolute path)" , required = True , type = str )
14584
14685 set_up_logging ()
14786
14887 # read arguments
14988 args = parser .parse_args ()
150-
151- config = Config (file_name = args .file )
152- config .print ()
153-
154- scenario_name = args .name
89+ config = Config .assign_config (Path (args .file ))
15590
15691 windfile = config .WEATHER_DATA
15792 depthfile = config .DEPTH_DATA
158- if str (args .write_geojson ).lower () == 'true' :
159- routepath = config .ROUTE_PATH
160- else :
161- routepath = None
93+ input_route = args .input_route
94+ output_route = args .output_route
16295 coursesfile = config .COURSES_FILE
16396 figurefile = get_figure_path ()
16497 time_resolution = config .DELTA_TIME_FORECAST
16598 time_forecast = config .TIME_FORECAST
166- departure_time = datetime . strptime ( config .DEPARTURE_TIME , '%Y-%m-%dT%H:%MZ' )
99+ departure_time = config .DEPARTURE_TIME
167100 lat1 , lon1 , lat2 , lon2 = config .DEFAULT_MAP
168101 default_map = Map (lat1 , lon1 , lat2 , lon2 )
169-
170- maripower_test_scenarios_calm = args .calm_water_scenario
171- maripower_test_scenarios_wind = args .wind_scenario
172- maripower_test_scenarios_wave = args .wave_scenario
173-
174- lat , lon , time , sog , fore_draught , aft_draught , power , fuel_rate = RouteParams .from_gzip_file (args .route )
175-
176- # possibility to analyse only single parts of the route
177- # lat, lon, time, sog, fore_draught, aft_draught = cut_indices(lat, lon, time, sog, fore_draught,
178- # aft_draught, cut_route)
102+ sog = 7.717 * u .meter / u .second
179103
180104 # obtain position, time and courses for every waypoint
181- waypoint_dict = RouteParams .get_per_waypoint_coords (lon , lat , time [0 ], sog )
105+ lat , lon = lat_lon_from_file (input_route )
106+ waypoint_dict = RouteParams .get_per_waypoint_coords (lon , lat , departure_time , sog )
182107
183108 # obtain RouteParams object for different models or for gzip data
184- if str (args .boat_type ) == 'direct_power_method' :
185- run_dpm_test_scenario (
186- waypoint_dict ,
187- routepath ,
188- scenario_name ,
189- sog
190- )
191-
192- if str (args .boat_type ) == 'maripower' :
193- run_maripower_test_scenario (
194- maripower_test_scenarios_calm ,
195- maripower_test_scenarios_wind ,
196- maripower_test_scenarios_wave ,
109+ run_dpm_test_scenario (
197110 waypoint_dict ,
198- routepath ,
199- scenario_name ,
200- fore_draught ,
201- aft_draught ,
202- sog
203- )
204-
205- if str (args .boat_type ) == 'data' :
206- boat = DirectPowerBoat (file_name = config .CONFIG_PATH )
207- power = power * boat .power_at_sp * 0.01 * 4 / 3 # power_at_sp is 75% of SMCR power
208-
209- ship_params = ShipParams .set_default_array_1D (len (lon ))
210- ship_params .fuel_rate = fuel_rate
211- ship_params .power = power
212-
213- start = (lat [0 ], lon [0 ])
214- finish = (lat [- 1 ], lon [- 1 ])
215-
216- rp = RouteParams (
217- count = lat .shape [0 ] - 2 ,
218- start = start ,
219- finish = finish ,
220- gcr = None ,
221- route_type = 'read_from_gzip' ,
222- time = waypoint_dict ['travel_times' ],
223- lats_per_step = lat ,
224- lons_per_step = lon ,
225- course_per_step = waypoint_dict ['courses' ],
226- dists_per_step = waypoint_dict ['dist' ],
227- starttime_per_step = time ,
228- ship_params_per_step = ship_params ,
229- )
230-
231- if routepath :
232- filename = os .path .join (routepath , 'route_' + scenario_name + '.json' )
233- print ('Writing file: ' , filename )
234- rp .return_route_to_API (filename )
111+ input_route ,
112+ sog ,
113+ output_route
114+ )
0 commit comments