Measurement of Vessel Density within an Anchorage Area
Within bulk shipping, anchorage density may provide an indication of berth availability within a port. In this article, obtaining vessel density within an anchorage using two point-in-polygon methods will be explored.
Introduction
Within bulk ocean shipping, it is common for a vessel to drift, go to anchor, or tie up at a layby berth awaiting a load or discharge berth. The reason for a delay may be that the load or discharge berth may be occupied, the cargo is unavailable, or the berth is down for maintenance.
For vessel owners, depending on the future prospects of the vessel, a delay at berth may be an advantage. For charterers, a delay may mean additional cost to transport the cargo due to excessive demurrage exposure. The opposite could be true in both cases, for a variety of reasons.
Using government-sourced anchorage boundary data and automated information system (AIS)-sourced vessel position information we apply a point-in-polygon method of establishing the density of an anchorage. In the below example we will use Anchorage 9 in San Francisco, California and nine sample vessels. Python will be employed as an intermediary.
Method
Step 1: Import Anchorage Boundaries
Using governmental-sourced data from 33 United States Code of Federal Regulations we establish the boundary of Anchorage 9 in San Francisco. The large southern portion of Anchorage 9 was removed for simplicity.
# Anchorage polygon coordinates
anchorage_9 = [(37.7726, -122.3186),
(37.7750, -122.3655),
(37.6958, -122.3394),
(37.6958, -122.2383),
(37.7726, -122.3186)]
Step 2: Import Automated Information System (AIS) Data
Import nine vessel positions within San Francisco Bay. The number is arbitrary and held at nine positions.
# Vessel positions
vessel_positions = [(37.7386, -122.3336),
(37.7466, -122.3519),
(37.7365, -122.3616),
(37.7528, -122.3421),
(37.7489, -122.3296),
(37.7679, -122.3466),
(37.7794, -122.3534),
(37.7642, -122.3335),
(37.7342, -122.3135)]
Step 3: Apply Shapely
Using Python, apply the Shapely function point.within(). The speed of the package is an average of 0.12 seconds over a dozen iterations.
from shapely.geometry import Point, Polygon
# Create a Shapely polygon
polygon = Polygon(anchorage_9)
# Calculate density using Shapely
shapely_density = 0
for x, y in vessel_positions:
point = Point(x, y)
if point.within(polygon):
shapely_density += 1
The result produced by using Shapely is seven vessels within Anchorage 9.
Alternative to Step 3: Ray Casting Algorithm
A ray casting algorithm (Roth, 1982; Price, n.d.) is employed as a replacement to Shapely. The outcome should offer the same results as the function point.within(). The speed of the algorithm is an average of 0.00003 seconds over a dozen iterations.
# Calculate density using Ray Cast
def is_point_within_polygon(x, y, polygon):
n = len(polygon)
odd_nodes = False
j = n - 1
for i in range(n):
xi, yi = polygon[i]
xj, yj = polygon[j]
if yi < y and yj >= y or yj < y and yi >= y:
if xi + (y - yi) / (yj - yi) * (xj - xi) < x:
odd_nodes = not odd_nodes
j = i
return odd_nodes
# Calculate density
ray_cast_density = 0
for x, y in vessel_positions:
if is_point_within_polygon(x, y, anchorage_9):
ray_cast_density += 1
The result produced by using a Ray Casting algorithm is seven vessels within Anchorage 9.
Final Code Example
Both Shapely and Ray Cast are demonstrated.
# Polygon coordinates
anchorage_9 = [(37.7726, -122.3186),
(37.7750, -122.3655),
(37.6958, -122.3394),
(37.6958, -122.2383),
(37.7726, -122.3186)]
# Vessel positions
vessel_positions = [(37.7386, -122.3336),
(37.7466, -122.3519),
(37.7365, -122.3616),
(37.7528, -122.3421),
(37.7489, -122.3296),
(37.7679, -122.3466),
(37.7794, -122.3534),
(37.7642, -122.3335),
(37.7342, -122.3135)]
# Shapely: Calculate density using Shapely
from shapely.geometry import Point, Polygon
# Shapely: Create a Shapely polygon
polygon = Polygon(anchorage_9)
# Shapely: Calculate density using Shapely
shapely_density = 0
for x, y in vessel_positions:
point = Point(x, y)
if point.within(polygon):
shapely_density += 1
# Ray Cast: Calculate density using Ray Cast
def is_point_within_polygon(x, y, polygon):
n = len(polygon)
odd_nodes = False
j = n - 1
for i in range(n):
xi, yi = polygon[i]
xj, yj = polygon[j]
if yi < y and yj >= y or yj < y and yi >= y:
if xi + (y - yi) / (yj - yi) * (xj - xi) < x:
odd_nodes = not odd_nodes
j = i
return odd_nodes
# Ray Cast: Calculate density
ray_cast_density = 0
for x, y in vessel_positions:
if is_point_within_polygon(x, y, anchorage_9):
ray_cast_density += 1
Conclusion
Using a point-in-polygon method we demonstrated use of Python’s Shapely package as well as a ray casting algorithm to produce the density of vessels within an anchorage boundary. The outcome produced in both cases is seven vessels within the anchorage polygon.
The speed of the ray casting algorithm was 0.00003 seconds over a dozen iterations. The speed of Shapely was 0.12 seconds over a dozen iterations, or over 4,000 times slower than the ray casting algorithm. However, Shapely incorporates a large amount of geographic information system tools embedded within the package, therefore Shapely may prove to be a better choice depending on the use case.
Obtaining anchorage density may inform berth availability. When combined with other data, anchorage density provides a data point that can be applied to data models within voyage management.
References
Anchorage Regulation; San Francisco Bay, California. (2001, February 28). Federal Register. Retrieved September 9, 2023, from https://www.federalregister.gov/documents/2001/02/28/01-4885/anchorage-regulation-san-francisco-bay-california
Gillies, S. (n.d.). shapely · PyPI. PyPI. Retrieved September 9, 2023, from https://pypi.org/project/shapely/
A Python implementation of the Ray-Casting algorithm solution to the point-in-polygon problem. Originally a method in the APPolygonObject class written for my Curtin University, Masters of Geospatial Science, Spatial Computations 100, second assignment … (n.d.). gists · GitHub. Retrieved September 9, 2023, from https://gist.github.com/aidenprice/971e10c13c82dd73c9fc
Roth, S. (1982). Ray casting for modeling solids. https://www.sciencedirect.com/science/article/abs/pii/0146664X82901691