276 lines
19 KiB
Python
276 lines
19 KiB
Python
"""
|
|
parse_lista_luces.py
|
|
Genera CSV de ayudas a la navegacion de Barranquilla a partir de
|
|
Lista de Luces DIMAR 2015 (ya parseada manualmente).
|
|
"""
|
|
import csv, re, sys, os
|
|
from collections import Counter
|
|
|
|
def dms_to_dd(deg, minutes):
|
|
return float(deg) + float(minutes) / 60.0
|
|
|
|
# ---- DATA ----
|
|
# (no, name, lat_deg, lat_min, lon_deg, lon_min, char, height_m, range_nm, colour, description, feat_type, orient)
|
|
records = [
|
|
# FAROS MAYORES
|
|
(13, 'Faro F1 Recalada', 11, 6.37, 74, 50.97, 'Iso G 2s', 20, 9, 'G', 'Torre naranja bandas blancas. Faro de Recalada', 'LIGHTS', ''),
|
|
(14, 'Faro F2 Recalada', 11, 6.36, 74, 51.28, 'Iso R 2s', 23, 13.4, 'R', 'Torre naranja bandas blancas. Racon B', 'LIGHTS', ''),
|
|
(32, 'Faro Morro Hermoso', 10, 57.80, 75, 1.05, 'Fl W 4s', 134, 28, 'W', 'Torre blanca bandas rojas. Giratorio', 'LIGHTS', ''),
|
|
(33, 'Faro Galerazamba', 10, 47.12, 75, 15.96, 'Fl W 4s', 14, 11, 'W', 'Torre fibra vidrio blanca bandas rojas. Giratorio', 'LIGHTS', ''),
|
|
|
|
# FAROLES X (Tajamares Bocas de Ceniza)
|
|
# Estas son balizas laterales fijas en tierra → BCNLAT (no LIGHTS).
|
|
# IALA-B: Verde = babor (CATLAM=1), Rojo = estribor (CATLAM=2).
|
|
# La luz se extrae automáticamente de LITCHR/SIGGRP/SIGPER/COLOUR.
|
|
(15, 'Faro X1', 11, 6.13, 74, 50.97, 'Q(4)G 11s', 6, 6, 'G', 'Torre verde bandas blancas', 'BCNLAT', ''),
|
|
(16, 'Faro X2', 11, 6.00, 74, 51.20, 'Q(4)R 11s', 6, 6, 'R', 'Torre roja bandas blancas', 'BCNLAT', ''),
|
|
(18, 'Faro X3', 11, 5.48, 74, 50.83, 'Q(4)G 11s', 6, 6, 'G', 'Torre verde bandas blancas', 'BCNLAT', ''),
|
|
(17, 'Faro X4', 11, 5.58, 74, 51.10, 'Q(4)R 11s', 6, 6, 'R', 'Torre roja bandas blancas', 'BCNLAT', ''),
|
|
(19, 'Faro X5', 11, 5.35, 74, 50.80, 'Q(4)G 11s', 6, 6, 'G', 'Torre verde bandas blancas', 'BCNLAT', ''),
|
|
(20, 'Faro X6', 11, 5.26, 74, 51.03, 'Q(4)R 11s', 6, 6, 'R', 'Torre roja bandas blancas', 'BCNLAT', ''),
|
|
(21, 'Faro X7', 11, 2.49, 74, 48.86, 'Q(4)G 11s', 8, 6, 'G', 'Baliza enrejado verde bandas blancas', 'BCNLAT', ''),
|
|
(22, 'Faro X8', 11, 4.90, 74, 50.95, 'Q(4)R 11s', 6, 6, 'R', 'Torre roja bandas blancas', 'BCNLAT', ''),
|
|
(23, 'Faro X9', 11, 2.15, 74, 48.29, 'Q(4)G 11s', 8, 6, 'G', 'Baliza enrejado verde bandas blancas', 'BCNLAT', ''),
|
|
(24, 'Faro X10', 11, 4.56, 74, 50.88, 'Q(4)R 11s', 6, 6, 'R', 'Torre roja bandas blancas', 'BCNLAT', ''),
|
|
(25, 'Faro X11', 11, 1.79, 74, 47.73, 'Q(4)G 11s', 8, 6, 'G', 'Baliza enrejado verde bandas blancas', 'BCNLAT', ''),
|
|
(26, 'Faro X12', 11, 3.90, 74, 50.65, 'Q(4)R 11s', 6, 6, 'R', 'Baliza enrejado roja bandas blancas', 'BCNLAT', ''),
|
|
(27, 'Faro X13', 11, 1.55, 74, 47.38, 'Q(4)G 11s', 8, 6, 'G', 'Baliza enrejado verde bandas blancas', 'BCNLAT', ''),
|
|
(28, 'Faro X14', 11, 3.47, 74, 50.37, 'Q(4)R 11s', 6, 6, 'R', 'Torre roja bandas blancas', 'BCNLAT', ''),
|
|
(30, 'Faro X15', 11, 1.37, 74, 47.13, 'Q(4)G 11s', 6, 6, 'G', 'Baliza enrejado verde bandas blancas', 'BCNLAT', ''),
|
|
(29, 'Faro X16', 11, 3.00, 74, 49.98, 'Q(4)R 11s', 6, 6, 'R', 'Torre roja bandas blancas', 'BCNLAT', ''),
|
|
(31, 'Faro X17', 11, 1.12, 74, 46.70, 'Q(4)G 11s', 6, 6, 'G', 'Baliza enrejado verde bandas blancas', 'BCNLAT', ''),
|
|
|
|
# ENFILACIONES / RANGE LIGHTS
|
|
(196, 'Enfilacion E1', 11, 6.22, 74, 50.90, 'Iso Bu 5s', 10, 13, 'W', 'Baliza enrejado naranja y blanco. Rumbo 135.7', 'LIGHTS', '135.7'),
|
|
(197, 'Enfilacion E3', 11, 6.10, 74, 50.78, 'Iso Bu 5s', 22, 9, 'W', 'Torre enrejada naranja y blanco. Rumbo 139.3', 'LIGHTS', '139.3'),
|
|
(198, 'Enfilacion E3A', 11, 6.02, 74, 50.70, 'Iso W 5s', 20, 12.3, 'W', 'Torre naranja y blanco. Rumbo 135.7', 'LIGHTS', '135.7'),
|
|
(201, 'Enfilacion E4', 11, 4.21, 74, 50.81, 'Iso R 4s', 11, 4.5, 'R', 'Baliza enrejado naranja bandas blancas. Rumbo 142.3', 'LIGHTS', '142.3'),
|
|
(203, 'Enfilacion E6', 11, 3.78, 74, 50.62, 'Iso Bu 4s', 12, 8, 'R', 'Baliza enrejado roja bandas blancas. Rumbo 167.7', 'LIGHTS', '167.7'),
|
|
(204, 'Enfilacion E8', 11, 3.51, 74, 50.51, 'Iso Bu 4s', 25, 14.5, 'W', 'Baliza enrejado naranja bandas blancas. Rumbo 167.7', 'LIGHTS', '167.7'),
|
|
(205, 'Enfilacion E10', 11, 3.59, 74, 50.50, 'Iso G 5s', 11, 10, 'G', 'Torre naranja bandas blancas. Rumbo 167.3', 'LIGHTS', '167.3'),
|
|
(206, 'Enfilacion E12', 11, 3.37, 74, 50.44, 'Iso G 5s', 22, 8, 'G', 'Baliza tablero blanco franja roja. Rumbo 167.3', 'LIGHTS', '167.3'),
|
|
(207, 'Enfilacion E14', 11, 3.37, 74, 50.44, 'Iso Bu 6s', 22, 8, 'W', 'Tablero blanco con franja roja. Rumbo 122', 'LIGHTS', '122'),
|
|
(237, 'Enfilacion E16', 11, 3.22, 74, 50.20, 'Iso Bu 6s', 12, 9, 'W', 'Baliza enrejado naranja bandas blancas. Rumbo 122', 'LIGHTS', '122'),
|
|
(238, 'Enfilacion E18', 11, 2.58, 74, 49.53, 'Fl WRG 4s', 18, 6, 'WRG', 'Torre roja bandas blancas. Sector 9 grados. Rumbo 142', 'LIGHTS', '142'),
|
|
|
|
# BOYAS LATERALES CANAL RIO MAGDALENA
|
|
(199, 'Boya No. 1', 11, 5.07, 74, 50.01, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(200, 'Boya No. 3', 11, 4.55, 74, 50.69, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(202, 'Boya No. 5', 11, 3.94, 74, 50.46, 'Q G 1s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(208, 'Boya No. 7', 11, 3.60, 74, 50.25, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(209, 'Boya No. 9', 11, 2.81, 74, 49.44, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(210, 'Boya No. 11', 11, 2.38, 74, 48.73, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(211, 'Boya No. 12', 11, 2.23, 74, 48.81, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(212, 'Boya No. 13', 11, 2.06, 74, 48.12, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(213, 'Boya No. 14', 11, 1.31, 74, 47.30, 'Fl R 3s', 3, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(214, 'Boya No. 15', 11, 1.69, 74, 47.63, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(215, 'Boya No. 16', 11, 1.64, 74, 47.85, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(218, 'Boya No. 18', 11, 1.31, 74, 47.30, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(219, 'Boya No. 19', 11, 1.05, 74, 46.59, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(220, 'Boya No. 20', 11, 0.93, 74, 46.64, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(221, 'Boya No. 21', 11, 0.84, 74, 46.32, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(222, 'Boya No. 22', 11, 0.74, 74, 46.40, 'Q R 1s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(223, 'Boya No. 23', 10, 58.50, 74, 45.30, 'Fl G 1.3s', 3, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(224, 'Boya No. 24', 11, 0.55, 74, 46.23, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(225, 'Boya No. 25', 11, 0.40, 74, 45.98, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(226, 'Boya No. 26', 11, 0.35, 74, 46.10, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(227, 'Boya No. 27', 10, 59.91, 74, 45.72, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(228, 'Boya No. 28', 10, 59.99, 74, 45.92, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(229, 'Boya No. 29', 10, 59.24, 74, 45.48, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(230, 'Boya No. 30', 10, 59.24, 74, 45.64, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(231, 'Boya No. 31', 10, 58.50, 74, 45.29, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(232, 'Boya No. 33', 10, 57.56, 74, 45.34, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(233, 'Boya No. 35', 10, 56.56, 74, 45.25, 'Fl G 3s', 4, 6, 'G', 'Castillete verde', 'BOYLAT', ''),
|
|
(234, 'Boya No. 36', 10, 56.49, 74, 45.40, 'Fl R 3s', 4, 6, 'R', 'Castillete roja', 'BOYLAT', ''),
|
|
(235, 'Boya Cardinal Norte', 10, 57.55, 74, 45.21, 'Fl W 1s', 4, 6, 'W', 'Castillete cardinal N negros', 'BOYCAR', ''),
|
|
(236, 'Boya Cardinal Sur', 10, 57.55, 74, 45.21, 'Fl W 15s', 4, 6, 'W', 'Castillete cardinal S negros', 'BOYCAR', ''),
|
|
(239, 'Boya de Oleaje', 11, 8.04, 74, 45.48, 'Fl Y 20s', 0.5, 4.5, 'Y', 'Esferica amarilla. Recolectora datos oceanograficos', 'BOYSPEC', ''),
|
|
(240, 'Boya Peligro Aislado', 10, 57.27, 74, 45.44, 'Fl(2) W 4s', 3.3, 3, 'W', 'Castillete roja bandas negras. Bajo rocoso', 'BOYISD', ''),
|
|
]
|
|
|
|
# ════════════════════════════════════════════════════════════════════════════
|
|
# IHO S-57 Ed.3.1 — códigos OFICIALES (no inventados)
|
|
# Ref: s57attributes.csv distribuido con GDAL/OGR
|
|
# ════════════════════════════════════════════════════════════════════════════
|
|
|
|
# COLOUR codes (ATTL 75)
|
|
colour_s57 = {
|
|
'W': '1', # White
|
|
'K': '2', # Black
|
|
'R': '3', # Red
|
|
'G': '4', # Green
|
|
'B': '5', # Blue
|
|
'Y': '6', # Yellow
|
|
'Gy': '7', # Grey
|
|
'Br': '8', # Brown
|
|
'Amb': '9', # Amber
|
|
'Vi': '10', # Violet
|
|
'Or': '11', # Orange
|
|
'Mg': '12', # Magenta
|
|
'WRG': '1,3,4', # White/Red/Green (multi-colour sectors)
|
|
'': '1', # default white
|
|
}
|
|
colour_name = {
|
|
'W': 'white', 'K': 'black', 'R': 'red', 'G': 'green',
|
|
'B': 'blue', 'Y': 'yellow', 'Gy': 'grey', 'Br': 'brown',
|
|
'Amb': 'amber','Vi': 'violet','Or': 'orange', 'Mg': 'magenta',
|
|
'WRG': 'white/red/green', '': 'white',
|
|
}
|
|
|
|
# LITCHR codes (ATTL 107) — S-57 Ed.3.1 official values
|
|
char_map = {
|
|
'F': '1', # Fixed
|
|
'Fl': '2', # Flashing
|
|
'LFl': '3', # Long flashing
|
|
'Q': '4', # Quick (50-60/min)
|
|
'VQ': '5', # Very quick (100-120/min)
|
|
'UQ': '6', # Ultra quick (≥160/min)
|
|
'Iso': '7', # Isophase
|
|
'Oc': '8', # Occulting
|
|
'IQ': '9', # Interrupted quick
|
|
'IVQ': '10', # Interrupted very quick
|
|
'IUQ': '11', # Interrupted ultra quick
|
|
'Mo': '12', # Morse code
|
|
'FFl': '13', # Fixed and flashing
|
|
'Fl+LFl': '14',
|
|
'Oc+Fl': '15',
|
|
'Al.Oc': '25',
|
|
'Al.LFl': '26',
|
|
'Al.Fl': '27',
|
|
'Al.Grp': '28',
|
|
}
|
|
|
|
# BOYSHP codes (ATTL 4)
|
|
# 1=Conical 2=Can 3=Sphere 4=Pillar 5=Spar 6=Barrel 7=Super-buoy 8=Ice buoy
|
|
# Barranquilla buoys are "castillete" → pillar (4)
|
|
BOYSHP_CASTILLETE = '4'
|
|
|
|
# BCNSHP codes (ATTL 2)
|
|
# 1=Stake 2=Withy 3=Tower 4=Lattice 5=Pile 6=Cairn 7=Buoyant beacon
|
|
# "Torre" → 3, "Baliza enrejado" / "celosía" → 4
|
|
def bcnshp_from_desc(desc):
|
|
d = desc.lower()
|
|
if 'enrejad' in d or 'celosí' in d or 'lattice' in d:
|
|
return '4' # Lattice tower
|
|
return '3' # Solid tower (default)
|
|
|
|
# CATLAM codes (ATTL 36) for IALA-B (Américas):
|
|
# Green marks = port side (left hand entering) → CATLAM=1
|
|
# Red marks = starboard side (right hand entering) → CATLAM=2
|
|
def catlam_from_colour(col_letter):
|
|
return {'G': '1', 'R': '2'}.get(col_letter, '')
|
|
|
|
# CATCAM codes (ATTL 13) for cardinal marks:
|
|
# 1=N 2=E 3=S 4=W
|
|
def catcam_from_name(name):
|
|
nl = name.lower()
|
|
if 'norte' in nl or 'north' in nl: return '1'
|
|
if 'este' in nl or 'east' in nl: return '2'
|
|
if 'sur' in nl or 'south' in nl: return '3'
|
|
if 'oeste' in nl or 'west' in nl: return '4'
|
|
return ''
|
|
|
|
def parse_char(char_str):
|
|
"""Parse human-readable light character string → (litchr_code, siggrp, sigper).
|
|
Examples: 'Q(4)G 11s' → ('4','4','11')
|
|
'Fl W 4s' → ('2','','4')
|
|
'Iso Bu 5s' → ('7','','5')
|
|
"""
|
|
# Extract base character (longest prefix match, try longest first)
|
|
base = re.split(r'[\s\(\.]', char_str)[0]
|
|
# Try compound chars first (Al.Fl, Fl+LFl …)
|
|
litchr = None
|
|
for key in sorted(char_map, key=len, reverse=True):
|
|
if char_str.startswith(key):
|
|
litchr = char_map[key]
|
|
break
|
|
if litchr is None:
|
|
litchr = char_map.get(base, '2') # default Fl if unknown
|
|
mg = re.search(r'\((\d+)\)', char_str)
|
|
siggrp = mg.group(1) if mg else ''
|
|
mp = re.search(r'([\d.]+)s', char_str)
|
|
sigper = mp.group(1) if mp else ''
|
|
return litchr, siggrp, sigper
|
|
|
|
# ────────────────────────────────────────────────────────────────────────────
|
|
# Campos del CSV de salida — usan nombres de atributos S-57 directamente
|
|
# para que el converter los recoja sin ningún mapeo adicional.
|
|
# ────────────────────────────────────────────────────────────────────────────
|
|
fields = ['no_dimar', 'OBJNAM', 'lon', 'lat', 'feat_type',
|
|
'LITCHR', 'LITCHR_TXT', 'SIGGRP', 'SIGPER',
|
|
'COLOUR', 'COLOUR_TXT', 'COLPAT',
|
|
'VALNMR', 'HEIGHT', 'ORIENT',
|
|
'CATLAM', 'CATCAM', 'BOYSHP', 'BCNSHP', 'TOPSHP',
|
|
'INFORM', '_dimar_char_raw', '_source']
|
|
|
|
out_path = r'D:\Proyectos Software\QGISS57Converter\dimar_ayudas_barranquilla.csv'
|
|
|
|
with open(out_path, 'w', newline='', encoding='utf-8') as f:
|
|
w = csv.DictWriter(f, fieldnames=fields)
|
|
w.writeheader()
|
|
for rec in records:
|
|
no, name, lat_d, lat_m, lon_d, lon_m, char, ht, rng, col, desc, ftype, orient = rec
|
|
lat = dms_to_dd(lat_d, lat_m)
|
|
lon = -dms_to_dd(lon_d, lon_m) # West = negative
|
|
litchr, siggrp, sigper = parse_char(char)
|
|
|
|
catlam = ''
|
|
catcam = ''
|
|
boyshp = ''
|
|
bcnshp = ''
|
|
topshp = ''
|
|
colpat = ''
|
|
|
|
if ftype == 'BOYLAT':
|
|
# Castillete lateral: pillar (4), with CATLAM
|
|
boyshp = BOYSHP_CASTILLETE
|
|
catlam = catlam_from_colour(col)
|
|
elif ftype == 'BCNLAT':
|
|
# Faros de orilla (X marks): shore fixed beacon with CATLAM
|
|
bcnshp = bcnshp_from_desc(desc)
|
|
catlam = catlam_from_colour(col)
|
|
elif ftype in ('BOYCAR', 'BCNCAR'):
|
|
boyshp = '4' # pillar for cardinal buoys
|
|
catcam = catcam_from_name(name)
|
|
colpat = '1' # horizontal bands (standard cardinal pattern)
|
|
elif ftype == 'BOYISD':
|
|
boyshp = '4'
|
|
colpat = '1' # horizontal bands (black over red)
|
|
elif ftype == 'BOYSAW':
|
|
boyshp = '1' # conical or spherical for safe water
|
|
colpat = '4' # vertical stripes (white/red)
|
|
elif ftype in ('BOYSPEC', 'BOYSPP'):
|
|
boyshp = '3' # sphere for special/data buoys
|
|
ftype = 'BOYSPP' # normalise to S-57 acronym
|
|
|
|
w.writerow({
|
|
'no_dimar': no,
|
|
'OBJNAM': name,
|
|
'lon': f'{lon:.6f}',
|
|
'lat': f'{lat:.6f}',
|
|
'feat_type': ftype,
|
|
'LITCHR': litchr,
|
|
'LITCHR_TXT': char.split()[0],
|
|
'SIGGRP': siggrp,
|
|
'SIGPER': sigper,
|
|
'COLOUR': colour_s57.get(col, '1'),
|
|
'COLOUR_TXT': colour_name.get(col, 'white'),
|
|
'COLPAT': colpat,
|
|
'VALNMR': rng,
|
|
'HEIGHT': ht,
|
|
'ORIENT': orient,
|
|
'CATLAM': catlam,
|
|
'CATCAM': catcam,
|
|
'BOYSHP': boyshp,
|
|
'BCNSHP': bcnshp,
|
|
'TOPSHP': topshp,
|
|
'INFORM': desc,
|
|
'_dimar_char_raw': char,
|
|
'_source': 'DIMAR Lista de Luces 2015',
|
|
})
|
|
|
|
print(f'Saved {len(records)} records -> {out_path}')
|
|
types = Counter(r[11] for r in records)
|
|
for t, c in sorted(types.items()):
|
|
print(f' {t}: {c}')
|