|
|
@@ -1,17 +1,13 @@
|
|
|
-import random
|
|
|
-
|
|
|
from geoplotlib.layers import BaseLayer
|
|
|
from geoplotlib.core import BatchPainter
|
|
|
import geoplotlib
|
|
|
-from geoplotlib.utils import BoundingBox, epoch_to_str, haversine
|
|
|
+from geoplotlib.utils import BoundingBox, epoch_to_str
|
|
|
import pyglet
|
|
|
|
|
|
import pandas as pd
|
|
|
import numpy as np
|
|
|
-import math
|
|
|
-import json
|
|
|
|
|
|
-from de2.routing import get_graph, euler_distance, get_closest_vertex, ig
|
|
|
+from de2.routing import get_graph, euler_distance, pathfinder, find_percentage_point_in_path as fpp
|
|
|
|
|
|
|
|
|
class PoABLayer(BaseLayer):
|
|
|
@@ -46,23 +42,8 @@ class PoABLayer(BaseLayer):
|
|
|
self.vcache = {} # vessel -> source
|
|
|
self.pcache = {} # vessel -> path, dists
|
|
|
|
|
|
- # with open("paths/endpointsWGS84.json", 'r') as f:
|
|
|
- # self.endpoints = json.load(f)["features"]
|
|
|
- # for feature in self.endpoints:
|
|
|
- # loc_BD72 = feature["geometry"]["x"], feature["geometry"]["y"]
|
|
|
- # loc_WGS84 = BD72_to_WGS84(loc_BD72[0], loc_BD72[1])
|
|
|
- # feature["geometry"]["lat"] = loc_WGS84[0]
|
|
|
- # feature["geometry"]["lon"] = loc_WGS84[1]
|
|
|
-
|
|
|
self.graph = get_graph()
|
|
|
|
|
|
- # with open("paths/assenWGS84.json", 'r') as f:
|
|
|
- # axes = json.load(f)["features"]
|
|
|
- # for feature in axes:
|
|
|
- # self.graph.append(feature["geometry"]["paths"][0])
|
|
|
- # print(self.paths)
|
|
|
- # self.idx = 0
|
|
|
-
|
|
|
def draw_shape(self, x, y):
|
|
|
"""
|
|
|
Draws the shape on the layer, at a specific location.
|
|
|
@@ -73,52 +54,27 @@ class PoABLayer(BaseLayer):
|
|
|
"""
|
|
|
self.painter.points(x, y, 5)
|
|
|
|
|
|
+ def draw_path(self, path, proj):
|
|
|
+ """
|
|
|
+ Draws a path on the layer.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ path: The path to draw as (x, y) tuples.
|
|
|
+ proj: The projector.
|
|
|
+ """
|
|
|
+ for ix in range(len(path) - 1):
|
|
|
+ point1 = path[ix]
|
|
|
+ point2 = path[ix + 1]
|
|
|
+ vx1, vy1 = proj.lonlat_to_screen(np.asarray([point1[0]]), np.asarray([point1[1]]))
|
|
|
+ vx2, vy2 = proj.lonlat_to_screen(np.asarray([point2[0]]), np.asarray([point2[1]]))
|
|
|
+ self.painter.lines(vx1, vy1, vx2, vy2, width=1.5)
|
|
|
+
|
|
|
def draw(self, proj, mouse_x, mouse_y, ui_manager):
|
|
|
self.painter = BatchPainter()
|
|
|
tooltips = []
|
|
|
|
|
|
self.painter.set_color(self.__colors__["nodes"])
|
|
|
|
|
|
- # DRAW THE ENDPOINTS
|
|
|
- # for feature in self.endpoints:
|
|
|
- # loc_WGS84 = feature["geometry"]["x"], feature["geometry"]["y"]
|
|
|
- # x, y = proj.lonlat_to_screen(np.asarray([loc_WGS84[0]]), np.asarray([loc_WGS84[1]]))
|
|
|
- #
|
|
|
- # if euler_distance(x, y, mouse_x, mouse_y) < 10:
|
|
|
- # self.painter.set_color(self.__colors__["highlight"])
|
|
|
- # tooltips.append(feature["attributes"]["NUMMER"])
|
|
|
- # else:
|
|
|
- # self.painter.set_color(self.__colors__["nodes"])
|
|
|
- # self.draw_shape(x, y)
|
|
|
-
|
|
|
- # # DATA ISSUE -- IGNORED
|
|
|
- # for coord in [(4.24245, 51.27711), (4.24242, 51.27713), (4.24243, 51.2771)]:
|
|
|
- # x, y = proj.lonlat_to_screen(np.asarray([coord[0]]), np.asarray([coord[1]]))
|
|
|
- # self.draw_shape(x, y)
|
|
|
- #
|
|
|
- # poly = [[4.239617449849437, 51.275336155669656], [4.239346838137977, 51.27554571293344],
|
|
|
- # [4.242655275582035, 51.277226300904815], [4.242881992657049, 51.27701194846825],
|
|
|
- # [4.239617449849437, 51.275336155669656]]
|
|
|
- # for px, p1 in enumerate(poly[:-1]):
|
|
|
- # p2 = poly[px+1]
|
|
|
- # x1, y1 = proj.lonlat_to_screen(np.asarray([p1[0]]), np.asarray([p1[1]]))
|
|
|
- # x2, y2 = proj.lonlat_to_screen(np.asarray([p2[0]]), np.asarray([p2[1]]))
|
|
|
- # self.painter.lines(x1, y1, x2, y2, width=2)
|
|
|
-
|
|
|
- # DRAW THE PoAB GRAPH
|
|
|
- # for gx, g in enumerate(self.clusters):
|
|
|
- # self.painter.set_color(self.colors[gx])
|
|
|
- # for v in g.vs:
|
|
|
- # x, y = proj.lonlat_to_screen(np.asarray([v["x"]]), np.asarray([v["y"]]))
|
|
|
- # self.draw_shape(x, y)
|
|
|
- # # self.painter.set_color(self.__colors__["nodes"])
|
|
|
- # for e in g.es:
|
|
|
- # src = e.source_vertex
|
|
|
- # tgt = e.target_vertex
|
|
|
- # cx1, cy1 = proj.lonlat_to_screen(np.asarray([src["x"]]), np.asarray([src["y"]]))
|
|
|
- # cx2, cy2 = proj.lonlat_to_screen(np.asarray([tgt["x"]]), np.asarray([tgt["y"]]))
|
|
|
- # self.painter.lines(cx1, cy1, cx2, cy2, width=2)
|
|
|
-
|
|
|
if not self.sim_active:
|
|
|
ui_manager.status("Press Space to Start Simulation")
|
|
|
else:
|
|
|
@@ -136,32 +92,11 @@ class PoABLayer(BaseLayer):
|
|
|
|
|
|
if vessel.mmsi not in self.vcache or self.vcache[vessel.mmsi] != vessel.source:
|
|
|
self.vcache[vessel.mmsi] = vessel.source
|
|
|
-
|
|
|
- src, _ = get_closest_vertex(self.graph, vessel.source[0], vessel.source[1])
|
|
|
- tgt, _ = get_closest_vertex(self.graph, vessel.target[0], vessel.target[1])
|
|
|
- path = [vessel.source]
|
|
|
- dists = []
|
|
|
- if src.index != tgt.index:
|
|
|
- p = self.graph.get_k_shortest_paths(src.index, tgt.index, 1, weights="distance", mode="all")
|
|
|
- if len(p) > 0:
|
|
|
- for vix in p[0]:
|
|
|
- vertex = self.graph.vs[vix]
|
|
|
- path.append((vertex["x"], vertex["y"]))
|
|
|
- dists.append(haversine(path[-2][0], path[-2][1], path[-1][0], path[-1][1]))
|
|
|
- path.append(vessel.target)
|
|
|
- dists.append(haversine(path[-2][0], path[-2][1], path[-1][0], path[-1][1]))
|
|
|
-
|
|
|
- self.pcache[vessel.mmsi] = path, dists
|
|
|
+ self.pcache[vessel.mmsi] = pathfinder(self.graph, vessel.source, vessel.target)
|
|
|
|
|
|
path, dists = self.pcache[vessel.mmsi]
|
|
|
- tot_dist = sum(dists)
|
|
|
|
|
|
- for ix in range(len(path) - 1):
|
|
|
- point1 = path[ix]
|
|
|
- point2 = path[ix+1]
|
|
|
- vx1, vy1 = proj.lonlat_to_screen(np.asarray([point1[0]]), np.asarray([point1[1]]))
|
|
|
- vx2, vy2 = proj.lonlat_to_screen(np.asarray([point2[0]]), np.asarray([point2[1]]))
|
|
|
- self.painter.lines(vx1, vy1, vx2, vy2, width=1.5)
|
|
|
+ self.draw_path(path, proj)
|
|
|
|
|
|
tot_distance = vessel.total_distance
|
|
|
traveled_approx = tot_distance - vessel.distance_left
|
|
|
@@ -169,23 +104,11 @@ class PoABLayer(BaseLayer):
|
|
|
traveled_approx += delta * vessel.velocity
|
|
|
percentage = traveled_approx / tot_distance
|
|
|
|
|
|
- acpos = tot_dist * percentage
|
|
|
- perc = 0.
|
|
|
- s = 0.
|
|
|
- p1 = path[0]
|
|
|
- p2 = path[-1]
|
|
|
- for dx, d in enumerate(dists):
|
|
|
- s += d
|
|
|
- if s > acpos:
|
|
|
- p1 = path[dx]
|
|
|
- p2 = path[dx+1]
|
|
|
- p = sum(dists[dx+1:]) / tot_dist
|
|
|
- if 1 - perc - p == 0:
|
|
|
- percentage = 1
|
|
|
- else:
|
|
|
- percentage = (percentage - perc) / (1 - perc - p)
|
|
|
- break
|
|
|
- perc = s / tot_dist
|
|
|
+ if sum(dists) == 0:
|
|
|
+ p1 = p2 = path[0]
|
|
|
+ percentage = 1.
|
|
|
+ else:
|
|
|
+ p1, p2, percentage = fpp(path, dists, percentage)
|
|
|
sx, sy = proj.lonlat_to_screen(np.asarray([p1[0]]), np.asarray([p1[1]]))
|
|
|
tx, ty = proj.lonlat_to_screen(np.asarray([p2[0]]), np.asarray([p2[1]]))
|
|
|
|
|
|
@@ -220,16 +143,11 @@ if __name__ == '__main__':
|
|
|
sim = Simulator(port)
|
|
|
sim.setClassicDEVS()
|
|
|
sim.setRealTime(scale=0.0002)
|
|
|
- sim.setTerminationTime(1_209_600) # 14 days
|
|
|
+ sim.setTerminationTime(14 * 24 * 60 * 60) # 14 days
|
|
|
|
|
|
layer = PoABLayer(sim)
|
|
|
|
|
|
geoplotlib.set_window_size(640, 760)
|
|
|
- # geoplotlib.tiles_provider({
|
|
|
- # 'url': lambda zoom, xtile, ytile: 'http://b.tile.stamen.com/terrain/%d/%d/%d.png' % (zoom, xtile, ytile),
|
|
|
- # 'tiles_dir': 'mytiles',
|
|
|
- # 'attribution': 'Map tiles by Stamen Design, under CC BY 3.0. Data @ OpenStreetMap contributors.'
|
|
|
- # })
|
|
|
geoplotlib.tiles_provider({
|
|
|
'url': lambda zoom, xtile, ytile: 'https://tile.openstreetmap.org/%d/%d/%d.png' % (zoom, xtile, ytile),
|
|
|
'tiles_dir': 'mytiles',
|
|
|
@@ -239,15 +157,4 @@ if __name__ == '__main__':
|
|
|
geoplotlib.add_layer(layer)
|
|
|
geoplotlib.show()
|
|
|
|
|
|
- print("TOTAL USAGES:")
|
|
|
- S = 0
|
|
|
- for vessel in sim.model.pool.state["waiting"].values():
|
|
|
- if vessel.usage_time > 0:
|
|
|
- print("\t%s: %f" % (vessel.mmsi, vessel.usage_time))
|
|
|
- S += vessel.usage_time
|
|
|
- for vessel in sim.model.sailer.state["vessels"]:
|
|
|
- if vessel.usage_time > 0:
|
|
|
- print("\t%s: %f" % (vessel.mmsi, vessel.usage_time))
|
|
|
- S += vessel.usage_time
|
|
|
- print("-------------")
|
|
|
- print("OVERALL: %f" % (S / 36))
|
|
|
+ sim.model.print_statistics()
|