1
0

Removed the subdir.

This commit is contained in:
2022-07-20 15:01:07 +02:00
parent aee5e8bbd9
commit e03f1c8be8
234 changed files with 21562 additions and 456 deletions

View File

View File

@ -0,0 +1 @@
See https://gitlab.sailingteam.hg.tu-darmstadt.de/informatik/data/-/tree/master/charts/noaa_vector for the license and more information.

View File

@ -0,0 +1,71 @@
NOAA ENC<4E>
NATIONAL OCEANIC AND ATMOSPHERIC ADMINISTRATION
US1BS04M - BERING SEA NORTHERN PART (EAST)
INDEX:
NOTE A
AIDS TO NAVIGATION
CAUTION - TEMPORARY CHANGES
CAUTION - LIMITATIONS
NOTE B
WARNING - PRUDENT MARINER
AUTHORITIES
INTERNATIONAL BOUNDARIES
POLLUTION REPORTS
CAUTION - DANGER
ADDITIONAL INFORMATION
NOTES:
NOTE A
Navigation regulations are published in Chapter 2, U.S. Coast Pilot 9. Additions or revisions to Chapter 2 are published in the Notice to Mariners. Information concerning the regulations may be obtained at the Office of the Commander, 17th Coast Guard District in Juneau, Alaska or at the Office of the District Engineer, Corps of Engineers in Anchorage, Alaska.
Refer to charted regulation section numbers.
AIDS TO NAVIGATION
Consult U.S. Coast Guard Light List for supplemental information concerning aids to navigation.
See National Geospatial-Intelligence Agency List of Lights and Fog Signals for information not included in the United States Coast Guard Light List.
CAUTION - TEMPORARY CHANGES
Temporary changes or defects in aids to navigation are not indicated. See Local Notice to Mariners.
CAUTION - LIMITATIONS
Limitations on the use of radio signals as aids to marine navigation can be found in the U.S. Coast Guard Light Lists and National Geospatial-Intelligence Agency Publication 117.
Radio direction-finder bearings to commercial broadcasting stations are subject to error and should be used with caution.
NOTE B
Radio navigational aids on the Russian Arctic coast and adjacent islands north of the Arctic Circle have been omitted due to the lack of reliable information.
WARNING - PRUDENT MARINER
The prudent mariner will not rely solely on any single aid to navigation, particularly on floating aids. See U.S. Coast Guard Light List and U.S. Coast Pilot for details.
AUTHORITIES
Hydrography and topography by the National Ocean Service, Coast Survey, with additional data from the U.S. Coast Guard, National Geospatial Intelligence Agency, and the Japanese Hydrographic Department.
INTERNATIONAL BOUNDARIES
International boundaries as shown are approximate.
POLLUTION REPORTS
Report all spills of oil and hazardous substances to the National Response Center via 1-800-424-8802 (toll free), or to the nearest U.S. Coast Guard facility if telephone communication is impossible (33 CFR 153).
CAUTION - DANGER
Danger, Prohibited, and Restricted Area falling within the limits of the larger scale charts are shown thereon and not repeated.
ADDITIONAL INFORMATION
Additional information can be obtained at www.nauticalcharts.noaa.gov
END OF FILE

View File

@ -0,0 +1,6 @@
Maritime boundary provisionally applied pending formal exchange of instruments of ratification.
According to Article 3 of the Agreement Between the United States of America and Russia on the Maritime Boundary, signed June 1, 1990:
"1. In any area east of the maritime boundary that lies within 200 nautical miles of the baseline from which the breadth of the territorial sea of Russia is measured but beyond 200 nautical miles of the baselines from which the breadth of the territorial sea of the United States is measured ("eastern special area"), Russia agrees that henceforth the United States may exercise the sovereign rights and jurisdiction derived from exclusive economic zone jurisdiction that Russia would otherwise be entitled to exercise under international law in the absence of the agreement of the Parties on the maritime boundary...
3. to the extent that either Party exercises the sovereign rights or jurisdiction in the special area or areas on its side of the maritime boundary as provided for in this Article, such exercise of sovereign rights or jurisdiction derives from the agreement of the Parties and does not constitute an extension of its exclusive economic zone. To this end, each Party shall take the necessary steps to ensure that any exercise on its part of such rights or jurisdiction in the special area or areas on its side of the maritime boundary shall be so characterized in its relevant laws, regulations, and charts."

View File

@ -0,0 +1,2 @@
CAUTION - QUALITY OF BATHYMETRIC DATA
The areas represented by the object M_QUAL (Quality of data) are approximate due to generalizing for clarity. Caution is advised, particularly for nearshore navigation or voyage planning. M_QUAL represents areas of uniform quality of bathymetric data. The CATZOC (Category of zone of confidence in data) attribute of M_QUAL provides an assessment of the overall zone of confidence.

View File

@ -0,0 +1,97 @@
NOAA ENC<4E>
NATIONAL OCEANIC AND ATMOSPHERIC ADMINISTRATION
US4AK5GM - PORT MOLLER AND HERENDEEN BAY
INDEX:
AIDS TO NAVIGATION
POLLUTION REPORTS
CAUTION USE OF RADIO SIGNALS (LIMITATIONS)
SUPPLEMENTAL INFORMATION
CAUTION - TEMPORARY CHANGES
WARNING - PRUDENT MARINER
ADDITIONAL INFORMATION
NOTE A
AUTHORITIES
CAUTION - LIMITATIONS
CAUTION - CHANNELS
RADAR REFLECTORS
NOAA WEATHER RADIO BROADCASTS
TIDAL INFORMATION
ADMINISTRATION AREA
COLREGS, 82.1705 (see note A)
NOTES:
AIDS TO NAVIGATION
Consult U.S. Coast Guard Light List for supplemental information concerning aids to navigation.
POLLUTION REPORTS
Report all spills of oil and hazardous substances to the National Response Center via 1-800-424-8802 (toll free), or to the nearest U.S. Coast Guard facility if telephone communication is impossible (33 CFR 153).
CAUTION USE OF RADIO SIGNALS (LIMITATIONS)
Limitations on the use of radio signals as aids to marine navigation can be found in the U.S. Coast Guard Light Lists and National Geospatial-Intelligence Agency Publication 117. Radio direction-finder bearings to commercial broadcasting stations are subject to error and should be used with caution.
SUPPLEMENTAL INFORMATION
Consult U.S. Coast Pilot 9 for important supplemental information.
CAUTION - TEMPORARY CHANGES
Temporary changes or defects in aids to navigation are not indicated. See Local Notice to Mariners
WARNING - PRUDENT MARINER
The prudent mariner will not rely solely on any single aid to navigation, particularly on floating aids. See U.S. Coast Guard Light List and U.S. Coast Pilot for details.
ADDITIONAL INFORMATION
Additional information can be obtained at www.nauticalcharts.noaa.gov
NOTE A
Navigation regulations are published in Chapter 2, U.S. Coast Pilot 9. Additions or revisions to Chapter 2 are published in the Notice to Mariners. Information concerning
the regulations may be obtained at the Office of the Commander, 17th Coast Guard District in Juneau, Alaska, or at the Office of the District Engineer, Corps of Engineers in Anchorage, Alaska. Refer to charted regulation section numbers
AUTHORITIES
Hydrography and Topography by the National Ocean Service, Coast Survey, with additional data from the U.S. Coast Guard.
CAUTION - LIMITATIONS
Limitations on the use of radio signals as aids to marine navigation can be found in the U.S. Coast Guard Light Lists and National Geospatial-Intelligence Agency Publication 117. Radio direction-finder bearings to commercial broadcasting stations are subject to error and should be used with caution.CAUTION - CHANNELS Channels are subject to frequent changes due to very strong tidal currents.
CAUTION - CHANNELS
Channels are subject to frequent changes due to very strong tidal currents.
RADAR REFLECTORS
Radar reflectors have been placed on many floating aids to navigation. Individual radar
reflector identification on these aids has been omitted from this chart.
NOAA WEATHER RADIO BROADCASTS
The NOAA Weather Radio station listed below provides continuous weather broadcasts. The reception range is typically 20 to 40 nautical miles from the antenna site, but can be as much as 100 nautical miles for stations at high elevations.
Sand Point, AK KSDP 840 AM
TIDAL INFORMATION
For tidal information see the NOS Tide Table publication or go to http://co-ops.nos.noaa.gov
ADMINISTRATION AREA
The entire extent of this ENC cell falls within the limits of an Administration Area. This area covers land, internal waters, and territorial sea. The territorial sea is a maritime zone which the United States exercises sovereignty extending to the airspace as well as to its bed and subsoil. For more information, please refer to the Coast Pilot.
COLREGS, 82.1705 (see note A)
International Regulations for Preventing Collisions at Sea, 1972. The entire area of this chart falls seaward of the COLREGS Demarcation Line.
END OF FILE

View File

@ -0,0 +1,2 @@
CAUTION - QUALITY OF BATHYMETRIC DATA
The areas represented by the object M_QUAL (Quality of data) are approximate due to generalizing for clarity. Caution is advised, particularly for nearshore navigation or voyage planning. M_QUAL represents areas of uniform quality of bathymetric data. The CATZOC (Category of zone of confidence in data) attribute of M_QUAL provides an assessment of the overall zone of confidence.

View File

@ -0,0 +1,144 @@
NOAA ENC<4E>
NATIONAL OCEANIC AND ATMOSPHERIC ADMINISTRATION
US4FL87M - CAPE CANAVERAL TO BETHEL SHOAL
INDEX:
NOTE A
AIDS TO NAVIGATION
NOAA WEATHER BROADCASTS
CAUTION - TEMPORARY CHANGES
CAUTION - DREDGED AREAS
SUPPLEMENTAL INFORMATION
AUTHORITIES
POLLUTION REPORTS
RADAR REFLECTORS
WARNING - PRUDENT MARINER
CAUTION - SUBMARINE PIPELINES AND CABLES
HURRICANES AND TROPICAL STORMS
CAUTION - LIMITATIONS
ADDITIONAL INFORMATION
TIDAL INFORMATION
CAUTION - USACE HYDROGRAPHIC SURVEYS
NOTES:
NOTE A
Navigation regulations are published in Chapter 2, U.S.
Coast Pilot 4. Additions or revisions to Chapter 2 are pub-
lished in the Notice to Mariners. Information concerning the
regulations may be obtained at the Office of the Commander,
7th Coast Guard District in Miami, Florida, or at the Office
of the District Engineer, Corps of Engineers in Jacksonville,
Florida.
Refer to charted regulation section numbers.
AIDS TO NAVIGATION
Consult U.S. Coast Guard Light List for
supplemental information concerning aids to
navigation.
NOAA WEATHER BROADCASTS
The NOAA Weather Radio stations listed
below provide continuous weather broadcasts.
The reception range is typically 20 to 40
nautical miles from the antenna site, but can be
as much as 100 nautical miles for stations at
high elevations.
Melbourne, FL WXJ-70 162.550 MHz
Fort Pierce, FL WWF-69 162.425 MHz
CAUTION - TEMPORARY CHANGES
Temporary changes or defects in aids to
navigation are not indicated.
See Local Notice to Mariners.
CAUTION - DREDGED AREAS
Improved channels are
subject to shoaling, particularly at the edges.
SUPPLEMENTAL INFORMATION
Consult U.S. Coast Pilot 4 for important
supplemental information.
AUTHORITIES
Hydrography and topography by the National Ocean Service, Coast
Survey, with additional data from the Corps of Engineers, and U.S.
Coast Guard.
POLLUTION REPORTS
Report all spills of oil and hazardous sub-
stances to the National Response Center via
1-800-424-8802 (toll free), or to the nearest U.S.
Coast Guard facility if telephone communication
is impossible (33 CFR 153).
RADAR REFLECTORS
Radar reflectors have been placed on many
floating aids to navigation. Individual radar
reflector identification on these aids has been
omitted from this chart.
WARNING - PRUDENT MARINER
The prudent mariner will not rely solely on
any single aid to navigation, particularly on
floating aids. See U.S. Coast Guard Light List
and U.S. Coast Pilot for details.
CAUTION - SUBMARINE PIPELINES AND CABLES
Additional uncharted submarine pipelines and
submarine cables may exist within the area of
this chart. Not all submarine pipelines and sub-
marine cables are required to be buried, and
those that were originally buried may have
become exposed. Mariners should use extreme
caution when operating vessels in depths of
water comparable to their draft in areas where
pipelines and cables may exist, and when
anchoring, dragging, or trawling.
Covered wells may be marked by lighted or
unlighted buoys.
HURRICANES AND TROPICAL STORMS
Hurricanes, tropical storms and other major storms may
cause considerable damage to marine structures, aids to
navigation and moored vessels, resulting in submerged debris
in unknown locations.
Charted soundings, channel depths and shoreline may not
reflect actual conditions following these storms. Fixed aids to
navigation may have been damaged or destroyed. Buoys may
have been moved from their charted positions, damaged, sunk,
extinguished or otherwise made inoperative. Mariners should
not rely upon the position or operation of an aid to navigation.
Wrecks and submerged obstructions may have been displaced
from charted locations. Pipelines may have become uncovered
or moved.
Mariners are urged to exercise extreme caution and are
requested to report aids to navigation discrepancies and
hazards to navigation to the nearest United States Coast Guard
unit.
CAUTION - LIMITATIONS
Limitations on the use of radio signals as
aids to marine navigation can be found in the
U.S. Coast Guard Light Lists and National
Geospatial-Intelligence Agency Publication 117.
Radio direction-finder bearings to commercial
broadcasting stations are subject to error and
should be used with caution.
ADDITIONAL INFORMATION
Additional information can be obtained at www.nauticalcharts.noaa.gov
TIDAL INFORMATION
For tidal information see the NOS Tide Table publication or go to http://co-ops.nos.noaa.gov.
CAUTION - USACE HYDROGRAPHIC SURVEYS
USACE conducts hydrographic surveys to monitor navigation conditions.
These surveys are not intended to detect underwater features. Uncharted features hazardous to surface navigation are not expected but may exist in federal channels.
END OF FILE

View File

@ -0,0 +1,16 @@
Exclusive Economic Zone (EEZ)
The EEZ is a zone beyond and adjacent to the territorial sea within which the U.S. has certain
sovereign rights and jurisdiction. Under some U.S. laws, the inner limit of the EEZ extends landward
to the seaward limit of the states submerged lands. For more information, please refer to the Coast
Pilot.
Contiguous Zone
The Contiguous Zone is a zone contiguous to the territorial sea, in which the United States may
exercise the control necessary to prevent and punish infringement within its territory or territorial sea
of its customs, fiscal, immigration, cultural heritage or sanitary laws and regulations. For more
information, please refer to the Coast Pilot.
Administration Area
This area covers land, internal waters, and territorial sea. The territorial sea is a maritime zone over
which the United States exercises sovereignty extending to the airspace as well as to its bed and
subsoil. For more information, please refer to the Coast Pilot.

View File

@ -0,0 +1,14 @@
The Inland Navigational Rules Act of 1980 is in effect for vessels transiting this
area. The seaward boundaries of this area are the COLREGS demarcation lines.
In the area seaward of the COLREGS demarcation lines, vessels are governed by
COLREGS: International Regulations for Preventing Collisions at Sea, 1972.
The COLREGS demarcation lines are defined in 33 CFR 80.727b.
Navigation regulations are published in Chapter 2, U.S.
Coast Pilot 4. Additions or revisions to Chapter 2 are pub-
lished in the Notice to Mariners. Information concerning the
regulations may be obtained at the Office of the Commander,
7th Coast Guard District in Miami, Florida, or at the Office
of the District Engineer, Corps of Engineers in Jacksonville,
Florida.
Refer to charted regulation section numbers.

View File

@ -0,0 +1 @@
Depths from surveys of 2000-2007 - Regulations for Ocean Dumping Sites are contained in 40 CFR, Parts 220-229. Additional information concerning the regulations and requirements for use of the sites may be obtained from the Environmental Protection Agency (EPA). See U.S. Coast Pilots appendix for addresses of EPA offices. Dumping subsequent to the survey dates may have reduced the depths shown.

View File

@ -0,0 +1,2 @@
This area represents the limits of the Low-Mid Inclination launch hazard areas associated with the majority of launches from Cape Canaveral. Launch debris may fall within these areas. See Notice to Mariners or contact the Coast Guard for launch hazard areas specific to each launch and the times they will be in effect.

View File

@ -0,0 +1 @@
This area represents the limits of the High Inclination launch hazard areas associated with the majority of launches from Cape Canaveral. Launch debris may fall within these areas. See Notice to Mariners or contact the Coast Guard for launch hazard areas specific to each launch and the times they will be in effect.

View File

@ -0,0 +1,6 @@
CAUTION <20> QUALITY OF BATHYMETRIC DATA
The areas represented by the object M_QUAL (Quality of data) are approximate due
to generalizing for clarity. Caution is advised, particularly for nearshore navigation
or voyage planning. M_QUAL represents areas of uniform quality of bathymetric data.
The CATZOC (Category of zone of confidence in data) attribute of M_QUAL provides
an assessment of the overall zone of confidence.

View File

@ -0,0 +1,132 @@
NOAA ENC<4E>
NATIONAL OCEANIC AND ATMOSPHERIC ADMINISTRATION
US4VA70M - CHINCOTEAGUE INLET TO GREAT MACHIPONGO INLET
INDEX
AUTHORITIES
AIDS TO NAVIGATION
NOTE A
WARNING - PRUDENT MARINER
POLLUTION REPORTS
SUPPLEMENTAL INFORMATION
CAUTION - TEMPORARY CHANGES
CAUTION - LIMITATIONS
CAUTION - SUBMARINE PIPELINES AND CABLES
RADAR REFLECTORS
NOAA WEATHER BROADCASTS
CAUTION - DREDGED AREAS
TIDAL INFORMATION
ADDITIONAL INFORMATION
NOTES:
AUTHORITIES
Hydrography and Topography by the National Ocean Service, Coast
Survey, with additional data from the Corps of Engineers, Geological
Survey, and U.S. Coast Guard.
AIDS TO NAVIGATION
Consult U.S. Coast Guard Light List for
supplemental information concerning aids to
navigation.
NOTE A
Navigation regulations are published in Chapter 2, U.S.
Coast Pilot 3. Additions or revisions to Chapter 2 are pub-
lished in the Notice to Mariners. Information concerning the
regulations may be obtained at the Office of the Commander,
5th Coast Guard District in Portsmouth, Virginia or at the
Office of the District Engineer, Corps of Engineers in
Norfolk, Virginia.
Refer to charted regulation section numbers.
WARNING - PRUDENT MARINER
The prudent mariner will not rely solely on
any single aid to navigation, particularly on
floating aids. See U.S. Coast Guard Light List
and U.S. Coast Pilot for details.
POLLUTION REPORTS
Report all spills of oil and hazardous substances to the
National Response Center via 1-800-424-8802 (toll free), or
to the nearest U.S. Coast Guard facility if telephone com-
munication is impossible (33 CFR 153).
SUPPLEMENTAL INFORMATION
Consult U.S. Coast Pilot 3 for important
supplemental information.
CAUTION - TEMPORARY CHANGES
Temporary changes or defects in aids to
navigation are not indicated. See
Local Notice to Mariners.
CAUTION - LIMITATIONS
Limitations on the use of radio signals as
aids to marine navigation can be found in the
U.S. Coast Guard Light Lists and National
Geospatial-Intelligence Agency Publication 117.
Radio direction-finder bearings to commercial
broadcasting stations are subject to error and
should be used with caution.
CAUTION - SUBMARINE PIPELINES AND CABLES
Additional uncharted submarine pipelines and
submarine cables may exist within the area of
this chart. Not all submarine pipelines and sub-
marine cables are required to be buried, and
those that were originally buried may have
become exposed. Mariners should use extreme
caution when operating vessels in depths of
water comparable to their draft in areas where
pipelines and cables may exist, and when
anchoring, dragging, or trawling.
Covered wells may be marked by lighted or
unlighted buoys.
RADAR REFLECTORS
Radar reflectors have been placed on many
floating aids to navigation. Individual radar
reflector identification on these aids has been
omitted from this chart.
NOAA WEATHER RADIO BROADCASTS
The NOAA Weather Radio stations listed
below provide continuous weather broadcasts.
The reception range is typically 37 to 74 kilometers / 20
to 40 nautical miles from the antenna site, but can be
as much as 100 nautical miles / 185 kilometers for stations at
high elevations.
Norfolk, VA KHB-37 162.550 MHz
Salisbury, MD KEC-92 162.475 MHz
Heathsville, VA WXM-57 162.400 MHz
CAUTION - DREDGED AREAS
Improved channels are
subject to shoaling, particularly at the edges.
TIDAL INFORMATION
For tidal information see the NOS tide table publication or go to http://co-ops.nos.noaa.gov.
ADDITIONAL INFORMATION
Additional information can be obtained at www.nauticalcharts.noaa.gov
END OF FILE

View File

@ -0,0 +1,8 @@
Exclusive Economic Zone (EEZ)
The EEZ is a zone beyond and adjacent to the territorial sea within which the U.S. has certain sovereign rights and jurisdiction. Under some U.S. laws, the inner limit of the EEZ extends landward to the seaward limit of the states submerged lands. For more information, please refer to the Coast Pilot.
Contiguous Zone
The Contiguous Zone is a zone contiguous to the territorial sea, in which the United States may exercise the control necessary to prevent and punish infringement within its territory or territorial sea of its customs, fiscal, immigration, cultural heritage or sanitary laws and regulations. For more information, please refer to the Coast Pilot.
Administration Area
This area covers land, internal waters, and territorial sea. The territorial sea is a maritime zone over which the United States exercises sovereignty extending to the airspace as well as to its bed and subsoil. For more information, please refer to the Coast Pilot.

View File

@ -0,0 +1 @@
Mariners are warned that numerous uncharted duck blinds, stakes, and fishing structures, some submerged, may exist in the fish trap areas. Such structures are not charted unless known to be permanent.

View File

@ -0,0 +1,17 @@
The Inland Navigational Rules Act of 1980 is in effect for vessels
transiting this area. The seaward boundaries of this area are the COLREGS
demarcation lines. In the area seaward of the COLREGS demarcation lines, vessels
are governed by COLREGS: International Regulations for Prevention of Collisions
at Sea, 1972. The COLREGS demarcation lines are defined in 33 CFR 80.505c,
33 CFR 80.505d, 33 CFR 80.505e and 33 CFR 505h.
NOTE A
Navigation regulations are published in Chapter 2, U.S.
Coast Pilot 3. Additions or revisions to Chapter 2 are pub-
lished in the Notice to Mariners. Information concerning the
regulations may be obtained at the Office of the Commander,
5th Coast Guard District in Portsmouth, Virginia or at the
Office of the District Engineer, Corps of Engineers in
Norfolk, Virginia.
Refer to charted regulation section numbers.

View File

@ -0,0 +1,6 @@
CAUTION - QUALITY OF BATHYMETRIC DATA
The areas represented by the object M_QUAL (Quality of data) are approximate
due to generalizing for clarity. Caution is advised, particularly for nearshore
navigation or voyage planning. M_QUAL represents areas of uniform quality of
bathymetric data. The CATZOC (Category of zone of confidence in data) attribute
of M_QUAL provides an assessment of the overall zone of confidence.

View File

@ -0,0 +1 @@
This should not be found by the discovery chart tests.

View File

@ -0,0 +1,469 @@
"""This module tests if the database abstraction is working correctly."""
# Standard library
from io import StringIO
from os.path import join
import sqlite3
from tempfile import TemporaryDirectory
import warnings
# Typing
from typing import cast
from typing import List
from typing import Optional
# Unit testing
from unittest.mock import patch
from unittest import skip
from unittest import skipIf
from unittest import TestCase
# Verification
from hypothesis import given
from hypothesis import HealthCheck
from hypothesis import settings
import hypothesis.strategies as st
import numpy
# Geometry
from shapely.geometry import Point
# Package under test
from pyrate.common.charts.db import to_wkb
from pyrate.common.charts import SpatialiteDatabase
from pyrate.plan.geometry import CartesianLocation
from pyrate.plan.geometry import CartesianPolygon
from pyrate.plan.geometry import Geospatial
from pyrate.plan.geometry import LocationType
from pyrate.plan.geometry import PolarGeometry
from pyrate.plan.geometry import PolarLocation
from pyrate.plan.geometry import PolarPolygon
from pyrate.plan.geometry import PolarRoute
# Flags and helpers
from pyrate.common.testing import IS_CI
from pyrate.common.testing import IS_EXTENDED_TESTING
from pyrate.common.testing import SPATIALITE_AVAILABLE
from pyrate.common.testing.strategies.geometry import location_types
from pyrate.common.testing.strategies.geometry import polar_locations
from pyrate.common.testing.strategies.geometry import polar_objects
from pyrate.common.testing.strategies.geometry import polar_polygons
from pyrate.common.testing.strategies.geometry import polar_routes_stable
# force testing this in CI to make sure it is tested regularly at least there
SKIP_IF_SPATIALITE_IS_MISSING = skipIf(
not SPATIALITE_AVAILABLE and not IS_CI, "allow spatialite to be missing and skip the tests in that case"
)
# reduce the example count since else this will take way too long, especially on the extended tests
TEST_REDUCED_COUNT = settings(
max_examples=500 if IS_EXTENDED_TESTING else 50,
deadline=1000,
suppress_health_check=(HealthCheck.too_slow,),
)
@SKIP_IF_SPATIALITE_IS_MISSING
class TestDatabase(TestCase):
"""Test for basic use of the database."""
@staticmethod
def _apply_id_if_missing(geometry: Geospatial, identifier: Optional[int]) -> None:
if geometry.identifier is None:
geometry.identifier = identifier
def test_empty_creation(self) -> None:
"""Tests whether the creation of a new database if not crashing anything."""
with SpatialiteDatabase(":memory:") as database:
self.assertEqual(len(database), database.count_geometries())
self.assertEqual(
database.count_geometries(), 0, "a freshly initialized database should contain no polygons"
)
self.assertEqual(
database.count_vertices(), 0, "a freshly initialized database should contain no vertices"
)
def test_disable_issue_create_statement(self) -> None:
"""Tests whether initializing with ``issue_create_statement=False`` fails."""
with SpatialiteDatabase(":memory:", issue_create_statement=False) as database:
with self.assertRaises(sqlite3.OperationalError):
database.count_geometries()
def test_write_invalid_geometry_no_update_exception(self) -> None:
"""Tests that an exception is raised if an invalid geometry is attempted to be written.
This tests the case where ``update=False``.
"""
with self.assertRaises(ValueError):
with SpatialiteDatabase(":memory:") as database:
point = PolarLocation(latitude=-70.2, longitude=+120.444, name="Pointy Point")
invalid_geometry = PolarPolygon([point, point, point])
database.write_geometry(invalid_geometry, update=False)
def test_write_invalid_geometry_no_update_suppressed(self) -> None:
"""Tests that NO exception is raised if an invalid geometry is attempted to be written.
This tests the case where ``update=False`` and ``raise_on_failure=False``.
"""
with self.assertRaises(UserWarning):
with warnings.catch_warnings():
warnings.simplefilter("error")
with SpatialiteDatabase(":memory:") as database:
point = PolarLocation(latitude=-70.2, longitude=+120.444, name="Pointy Point")
invalid_geometry = PolarPolygon([point, point, point])
database.write_geometry(invalid_geometry, update=False, raise_on_failure=False)
@skip("SpatialiteDatabase.write_geometry() currently does not detect it when update=True")
def test_write_invalid_geometry_with_update_exception(self) -> None:
"""Tests that an exception is raised if an invalid geometry is attempted to be written.
This tests the case where ``update=True``.
"""
with self.assertRaises(ValueError):
with SpatialiteDatabase(":memory:") as database:
point = PolarLocation(latitude=-70.2, longitude=+120.444, name="Pointy Point")
invalid_geometry = PolarPolygon([point, point, point])
database.write_geometry(invalid_geometry, update=True)
@skip("SpatialiteDatabase.write_geometry() currently does not detect it when update=True")
def test_write_invalid_geometry_with_update_suppressed(self) -> None:
"""Tests that NO exception is raised if an invalid geometry is attempted to be written.
This tests the case where ``update=True`` and ``raise_on_failure=False``.
"""
with self.assertRaises(UserWarning):
with warnings.catch_warnings():
warnings.simplefilter("error")
with SpatialiteDatabase(":memory:") as database:
point = PolarLocation(latitude=-70.2, longitude=+120.444, name="Pointy Point")
invalid_geometry = PolarPolygon([point, point, point])
database.write_geometry(invalid_geometry, update=True, raise_on_failure=False)
def test_convert_invalid_geometry_type(self) -> None:
"""Tests whether converting an unsupported geometry type raises a :class:`NotImplementedError`."""
with self.assertRaises(NotImplementedError):
# This obviously is a faulty cast, but we need it to trigger the exception
polar = cast(PolarLocation, CartesianLocation(55, 55))
to_wkb(polar)
def test_create_twice(self) -> None:
"""Tests that opening/creating/initializing a database twice does not cause any problems.
This method checks for output on stdout and stderr since sqlite will sometimes just print some
warnings instead of raising exceptions. This is a regression test.
"""
# this creates as shared database (within this process); need to pass uri=True later on
uri = "file::memory:?cache=shared"
# capture stdout & stderr
with patch("sys.stdout", new=StringIO()) as fake_stdout:
with patch("sys.stderr", new=StringIO()) as fake_stderr:
# open two databases
with SpatialiteDatabase(uri, uri=True):
with SpatialiteDatabase(uri, uri=True):
pass
# assert that nothing got printed
self.assertEqual(len(fake_stdout.getvalue()), 0)
self.assertEqual(len(fake_stderr.getvalue()), 0)
def test_clear_and_count(self) -> None:
"""Tests :meth:`~.SpatialiteDatabase.clear` and the two counting methods."""
with SpatialiteDatabase(":memory:") as database:
self.assertEqual(len(database), 0)
self.assertEqual(database.count_vertices(), 0)
poly = PolarPolygon([PolarLocation(0, 0), PolarLocation(0, 1), PolarLocation(1, 1)])
poly.identifier = 1
database.write_geometry(poly)
self.assertEqual(len(database), 1)
self.assertEqual(database.count_vertices(), len(poly.locations))
poly.identifier = 1
database.write_geometry(poly, update=True)
self.assertEqual(len(database), 1)
self.assertEqual(database.count_vertices(), len(poly.locations))
poly.identifier = 2
database.write_geometry(poly)
self.assertEqual(len(database), 2)
self.assertEqual(database.count_vertices(), len(poly.locations) * 2)
database.clear()
self.assertEqual(len(database), 0)
self.assertEqual(database.count_vertices(), 0)
def test_result_multi_geometry(self) -> None:
"""Tests whether the DB can correctly handle query results that are multi-polygons/-routes."""
# Test with both routes and polygons
for geometry_type in (PolarRoute, PolarPolygon):
with self.subTest(f"With type {geometry_type.__name__}"):
with SpatialiteDatabase(":memory:") as database:
horseshoe = numpy.array(
[
[-3.06913376, 47.50722936],
[-3.0893898, 47.52566325],
[-3.07788849, 47.54640812],
[-3.03050995, 47.55278059],
[-2.9875946, 47.54675573],
[-2.97849655, 47.53006788],
[-2.97712326, 47.51801223],
[-2.97849655, 47.50908464],
[-3.04887772, 47.50653362],
[-3.04922104, 47.51047605],
[-2.9898262, 47.51349065],
[-2.99480438, 47.54084606],
[-3.03136826, 47.54698747],
[-3.06947708, 47.54327953],
[-3.07806015, 47.52763379],
[-3.06741714, 47.51198337],
[-3.06913376, 47.50722936],
]
)
touch_point = PolarLocation(longitude=-3.0588340759277344, latitude=47.50943249496333)
database.write_geometry(geometry_type.from_numpy(horseshoe)) # type: ignore
result = list(database.read_geometries_around(touch_point, radius=3_000))
self.assertTrue(len(result) in {2, 3})
def _random_insert_and_extract_all_generic(
self, geometry: PolarGeometry, location_type: LocationType, update: bool
) -> None:
"""Tests whether inserting and then reading works in a very basic setting."""
with SpatialiteDatabase(":memory:") as database:
# it should be empty in the beginning
self.assertEqual(0, len(database))
self.assertEqual(0, database.count_geometries())
self.assertEqual(0, database.count_vertices())
# insert the polygon
try:
database.write_geometry(geometry, update=update)
except ValueError:
return # this example is corrupt, try the next one
else:
if update and len(database) == 0: # Errors cannot be checked if update==True
return # this example is corrupt, try the next one
# now the database should not be empty anymore
self.assertEqual(1, len(database))
self.assertEqual(1, database.count_geometries())
if isinstance(geometry, (PolarRoute, PolarPolygon)):
# Some repeated points might be removed, so we cannot check the exact number of vertices
self.assertGreaterEqual(len(geometry.locations), database.count_vertices())
else: # is a PolarLocation
self.assertEqual(1, database.count_vertices())
# the element should be included in "all"
read_obstacles = list(database.read_all())
self.assertEqual(1, len(read_obstacles))
# it should only be included if the type matches
all_filtered = list(database.read_all(only_location_type=location_type))
if geometry.location_type == location_type:
self.assertEqual(all_filtered, read_obstacles)
else:
self.assertEqual(len(all_filtered), 0)
# and it should be the one that we have written into the database in the first place
read_obstacles_single = read_obstacles[0]
# the id may be newly generated if polygon has the id None, so
# set it to the generated one for the sake of equality testing
TestDatabase._apply_id_if_missing(geometry, read_obstacles_single.identifier)
assert isinstance(read_obstacles_single, type(geometry)) # Make mypy understand this check
if isinstance(geometry, PolarPolygon):
self.assertTrue(geometry.almost_congruent(read_obstacles_single)) # type: ignore
else:
self.assertTrue(geometry.equals_exact(read_obstacles_single, tolerance=1e-3))
@given(polar_locations(), location_types(), st.booleans())
@TEST_REDUCED_COUNT
def test_random_insert_and_extract_all_locations(
self, geometry: PolarGeometry, location_type: LocationType, update: bool
) -> None:
"""Basic test with locations."""
self._random_insert_and_extract_all_generic(geometry, location_type, update)
@given(polar_routes_stable(), location_types(), st.booleans())
@TEST_REDUCED_COUNT
def test_random_insert_and_extract_all_routes(
self, geometry: PolarGeometry, location_type: LocationType, update: bool
) -> None:
"""Basic test with routes."""
self._random_insert_and_extract_all_generic(geometry, location_type, update)
@given(polar_polygons(), location_types(), st.booleans())
@TEST_REDUCED_COUNT
def test_random_insert_and_extract_all_polygons(
self, geometry: PolarGeometry, location_type: LocationType, update: bool
) -> None:
"""Basic test with polygons."""
self._random_insert_and_extract_all_generic(geometry, location_type, update)
def test_copy_to_other_database(self) -> None:
"""Tests whether database can be copied.
This test is not performed using hypothesis as it takes too long.
"""
location_1 = PolarLocation(latitude=-76.400, longitude=-171.924)
location_2 = PolarLocation(latitude=-70.400, longitude=-171.924)
location_3 = PolarLocation(latitude=-76.400, longitude=-170.924)
polygons = [
PolarPolygon(
locations=[location_1, location_2, location_3],
name="K",
identifier=1234145,
location_type=LocationType.SHALLOW_WATER,
),
PolarPolygon(locations=[location_1, location_2, location_3], identifier=2342),
]
with TemporaryDirectory() as directory_name:
database_file_name = join(directory_name, "other_db.sqlite")
with SpatialiteDatabase(":memory:") as first_database:
with first_database.disable_synchronization():
first_database.write_geometries(polygons)
first_database.copy_contents_to_database(database_file_name)
with SpatialiteDatabase(database_file_name) as second_database:
read = list(second_database.read_all())
def sorter(geometry: Geospatial) -> int:
return geometry.identifier or -1
read = list(sorted(read, key=sorter))
polygons = list(sorted(polygons, key=sorter))
self.assertEqual(len(read), len(polygons))
for polygon_a, polygon_b in zip(read, polygons):
assert isinstance(polygon_a, PolarPolygon) # Make mypy understand this check
self.assertTrue(polygon_a.equals_almost_congruent(polygon_b, rel_tolerance=1e-15))
@settings(max_examples=50 if IS_EXTENDED_TESTING else 10, suppress_health_check=(HealthCheck.too_slow,))
@given(st.lists(polar_objects(), min_size=0, max_size=3))
def test_database_simplification_zero_tolerance(self, geometries: List[PolarGeometry]) -> None:
"""Tests whether database objects can be simplified."""
for index, geometry in enumerate(geometries):
geometry.identifier = index
with SpatialiteDatabase(":memory:") as database:
try:
database.write_geometries(geometries)
except ValueError:
return # this example is corrupt, try the next one
database.simplify_contents(0.0)
read = list(database.read_all())
# only one polygon should be returned
self.assertEqual(len(read), len(geometries))
for original, read_back in zip(geometries, read):
self.assertTrue(original.equals_exact(read_back, tolerance=1e-3))
def test_database_simplification(self) -> None:
"""Tests whether database objects can be simplified."""
# set unique identifiers
points = numpy.array(Point(0, 0).buffer(10_000, resolution=16).exterior.coords)
cartesian_polygon = CartesianPolygon.from_numpy(points, identifier=10042)
polygon = cartesian_polygon.to_polar(origin=PolarLocation(-50.111, -30))
self.assertEqual(len(polygon.locations), 65)
with SpatialiteDatabase(":memory:") as database:
database.write_geometry(polygon)
database.simplify_contents(100)
read = list(database.read_all())
# only one polygon should be returned
self.assertEqual(len(read), 1)
read_polygon = read[0]
assert isinstance(read_polygon, PolarPolygon) # Make mypy understand this check
# That polygon should be similar
self.assertEqual(33, len(read_polygon.locations))
self.assertAlmostEqual(read_polygon.area, polygon.area, places=-3)
self.assertTrue(read_polygon.equals_almost_congruent(polygon, rel_tolerance=0.01))
# else, it should be the same
polygon.locations = read_polygon.locations
self.assertEqual(polygon, read_polygon)
@SKIP_IF_SPATIALITE_IS_MISSING
class TestDatabaseReadAroundHandcrafted(TestCase):
"""Tests :meth:`pyrate.common.charts.SpatialiteDatabase.read_obstacles_around` with known examples."""
included_polygon = PolarPolygon(
[PolarLocation(1, 1), PolarLocation(1, -1), PolarLocation(-1, -1), PolarLocation(-1, 1)], identifier=1
)
excluded_polygon = PolarPolygon(
[PolarLocation(56, 170), PolarLocation(56.5, 170), PolarLocation(56, 170.2)], identifier=2
)
both_polygons = [included_polygon, excluded_polygon]
def setUp(self) -> None:
self.database = SpatialiteDatabase(":memory:")
self.database.write_geometries(self.both_polygons)
super().setUp()
def tearDown(self) -> None:
self.database.close()
super().tearDown()
def test_read_around_includes_full(self) -> None:
"""Reads a complete polygon."""
around = list(self.database.read_geometries_around(PolarLocation(0, 2), radius=500_000))
self.assertEqual(1, len(around))
self.assertEqual(1, len(around))
read = around[0]
assert isinstance(read, PolarPolygon) # Make mypy understand this check
self.assertTrue(self.included_polygon.almost_congruent(read))
def test_read_around_includes_nothing(self) -> None:
"""Tests that :meth:`pyrate.common.charts.SpatialiteDatabase.read_obstacles_around` works correctly.
Reads nothing.
"""
around = list(self.database.read_geometries_around(PolarLocation(0, 2), radius=0))
self.assertEqual(0, len(around))
def test_read_around_includes_partial(self) -> None:
"""Tests that :meth:`pyrate.common.charts.SpatialiteDatabase.read_obstacles_around` works correctly.
Reads about half of the polygon.
"""
query_point = PolarLocation(latitude=0.0, longitude=5.0)
# this is the distance to center of self.included_polygon
radius = query_point.distance(PolarLocation(0.0, 0.0))
read = list(self.database.read_geometries_around(query_point, radius=radius))
self.assertEqual(1, len(read))
read_polygon = read[0]
assert isinstance(read_polygon, PolarPolygon) # Make mypy understand this check
# these shall only be very roughly similar, as half of the polygon is missing
# thus, we allow for a very large relative tolerance
self.assertTrue(read_polygon.equals_almost_congruent(self.included_polygon, rel_tolerance=0.6))
# this is roughly the part that should be included in the result
eastern_half = PolarPolygon(
[PolarLocation(1, 0), PolarLocation(-1, 0), PolarLocation(-1, 1), PolarLocation(1, 1)]
)
# thus, we allow for less relative tolerance
self.assertTrue(read_polygon.almost_congruent(eastern_half, rel_tolerance=0.15))

View File

@ -0,0 +1,96 @@
"""Tests whether ``pyrate.common.charts.raw_files`` correctly handles IHO S-57 chart files."""
# Python standard
from pathlib import Path
# Testing
from unittest import skipIf
from unittest import TestCase
# Extra test tooling
import pytest
# Pyrate library
from pyrate.common.testing import IS_CI
from pyrate.plan.geometry import LocationType
# Module under test
from pyrate.common.charts import ChartFileHandler
from pyrate.common.charts.s57_files import _OSGEO_PRESENT
from pyrate.common.charts import S57ChartHandler
PATH_TO_EXAMPLES = Path(__file__).parent / "example_charts"
CHARTS = [
PATH_TO_EXAMPLES / "nested_folder/US4VA70M/US4VA70M.000",
PATH_TO_EXAMPLES / "US1BS04M/US1BS04M.000",
PATH_TO_EXAMPLES / "US4AK5GM/US4AK5GM.000",
PATH_TO_EXAMPLES / "US4FL87M/US4FL87M.000",
]
CHARTS.sort()
class TestChartDiscovery(TestCase):
"""Tests that charts are correctly discovered"""
def test_discovery(self):
"""Also checks for nested folders and npn-chart files being present"""
discovered = list(S57ChartHandler.find_chart_files(PATH_TO_EXAMPLES))
discovered.sort()
# check that exactly the expected charts have been found
self.assertListEqual(discovered, CHARTS)
# check that they have the characteristic file extension
for chart_path in discovered:
self.assertTrue(chart_path.name.endswith(".000"))
# force testing this in CI to make sure it is tested regularly at least there
@skipIf(not _OSGEO_PRESENT and not IS_CI, "allow osgeo to be missing and skip the tests in that case")
class TestReadCharts(TestCase):
"""Tests whether actually reading the charts works"""
def setUp(self) -> None:
self.handler: ChartFileHandler = S57ChartHandler()
def test_reading_non_existent_file(self):
"""Tests reading a chart file that does not exist."""
with self.assertRaises(FileNotFoundError):
# Wrapping this in a list causes the generator/iterator to be actually evaluated
list(self.handler.read_chart_file("/does/surely/not/exist/and/if/it/does/we/have/a/troll"))
with self.assertRaises(FileNotFoundError):
# Wrapping this in a list causes the generator/iterator to be actually evaluated
list(self.handler.read_chart_file("/does/surely/not/exist/and/if/it/does/we/have/a/troll.000"))
def test_reading_wrong_file_type(self):
"""Tests reading a chart file that is not an S57 file (this Python program file)."""
with self.assertRaises(IOError):
# This test python file is not a chart
not_a_chart_file = __file__
# Wrapping this in a list causes the generator/iterator to be actually evaluated
list(self.handler.read_chart_file(not_a_chart_file))
@pytest.mark.filterwarnings("ignore:Ignoring LineString geometry in chart")
def test_reading_contains_all_types(self):
"""Checks for specific types of entries in the charts.
Note:
Only tests for Landmasses as of now
"""
all_obstacles = [obstacle for chart in CHARTS for obstacle in self.handler.read_chart_file(chart)]
self.assertGreater(len(all_obstacles), 0, "no obstacles were read")
relevant_types = (
(LocationType.LAND, "Landmass"),
(LocationType.SHALLOW_WATER, "Depth"),
(LocationType.OBSTRUCTION, "Buoy"),
)
for location_type, name_component in relevant_types:
filtered = [
o
for o in all_obstacles
if (o.name is not None and name_component in o.name and location_type == o.location_type)
]
self.assertTrue(filtered, f"no obstacle of type {name_component} was found")