Files

206 lines
9.1 KiB
Python

"""Genera CAPAS_REFERENCIA.pdf en el directorio del converter."""
from fpdf import FPDF
from pathlib import Path
OUT = Path(__file__).parent / "CAPAS_REFERENCIA.pdf"
# ── datos ──────────────────────────────────────────────────────────────────────
SECCIONES = [
("OBJETOS PUNTUALES", [
("BOYLAT", "Boya lateral (babor/estribor)", "boyas, buoys"),
("BOYCAR", "Boya cardinal (N/S/E/W)", "boycar"),
("BOYISD", "Boya de peligro aislado", "boyisd"),
("BOYSAW", "Boya de aguas seguras", "boysaw"),
("BCNLAT", "Baliza lateral", "balizas, beacons"),
("BCNSPP", "Baliza especial", "bcnspp"),
("LIGHTS", "Luz / faro", "luces, lights, faroles"),
("LNDMRK", "Hito en tierra (torre, tanque...)", "Puntos del Terreno"),
("SOUNDG", "Sonda batimetrica", "sondas, soundings, profundidades"),
("UWTROC", "Roca sumergida / a flor de agua", "rocas, rocks"),
("WRECKS", "Naufragio", "naufragio, wreck"),
("OBSTRN", "Obstruccion", "obstruccion, obstruction"),
]),
("OBJETOS LINEALES", [
("COALNE", "Linea de costa", "Linderos, coastline, costa, linea_de_costa"),
("DEPCNT", "Curva batimetrica (isobata)", "isobata, curvas_nivel, depth_contour"),
("CBLSUB", "Cable submarino", "cable"),
("PIPSOL", "Tuberia submarina / en tierra", "tuberia"),
("RIVERS", "Rio / canal", "rio, river"),
]),
("OBJETOS DE AREA", [
("LNDARE", "Area terrestre", "Area Terreno, tierra, land"),
("DEPARE", "Area de profundidad", "fondos, batimetria, depth_area"),
("FAIRWY", "Canal de navegacion", "canal_navegacion, fairway"),
("RESARE", "Area restringida", "zona_restringida, restricted"),
("ACHARE", "Area de fondeo", "fondeadero, anchorage"),
("HRBARE", "Area portuaria", "puerto, harbor"),
("BERTHS", "Atraque / muelle", "atraque, berth"),
("SBDARE", "Area de fondo marino", "fondo_marino, seabed"),
]),
]
ATTR_ROWS = [
("nombre / name", "OBJNAM", "Nombre del objeto (aparece en tooltip)"),
("catlam / lateral", "CATLAM", "Categoria lateral: 1=babor, 2=estribor"),
("colour / color", "COLOUR", "Color: 1=blanco, 3=rojo, 4=verde, 6=amarillo"),
("colpat / patron", "COLPAT", "Patron de color: 1=horizontal, 2=vertical"),
("boyshp / forma", "BOYSHP", "Forma boya: 1=conica, 2=cilindrica, 4=esferica"),
("litchr / destello", "LITCHR", "Destello: 1=F, 2=Fl, 3=LFl, 4=Q, 8=Iso, 5=IQ"),
("sigper / periodo", "SIGPER", "Periodo en segundos (ej: 4.0)"),
("siggrp / grupo", "SIGGRP", "Grupo de destellos: (2), (2+1), etc."),
("alcance / range", "VALNMR", "Alcance nominal en millas nauticas"),
("altura / height", "HEIGHT", "Altura de la luz sobre el mar (metros)"),
("status / estado", "STATUS", "Estado: 1=permanente, 2=ocasional"),
("profundidad / depth", "DRVAL1", "Profundidad minima (metros)"),
("depth_max", "DRVAL2", "Profundidad maxima (metros)"),
("sonda / sounding", "VALSOU", "Valor de sonda (metros)"),
("contour / valor", "VALDCO", "Valor de curva batimetrica (metros)"),
]
LITCHR_ROWS = [
("1", "F", "Fija"),
("2", "Fl", "Destellante"),
("3", "LFl", "Gran destello"),
("4", "Q", "Centelleante"),
("5", "IQ", "Centelleante interrumpido"),
("6", "Oc", "Ocultante"),
("8", "Iso", "Isofasica"),
("25", "VQ", "Rapida continua"),
("28", "Mo", "Morse"),
]
# ── PDF ────────────────────────────────────────────────────────────────────────
class PDF(FPDF):
def header(self):
self.set_font("Helvetica", "B", 11)
self.set_fill_color(30, 80, 140)
self.set_text_color(255, 255, 255)
self.cell(0, 10, "QGISS57Converter - Referencia de nombres de capas", fill=True, new_x="LMARGIN", new_y="NEXT")
self.set_text_color(0, 0, 0)
self.ln(2)
def footer(self):
self.set_y(-12)
self.set_font("Helvetica", "I", 8)
self.set_text_color(120, 120, 120)
self.cell(0, 10, f"Pagina {self.page_no()}", align="C")
pdf = PDF(orientation="P", unit="mm", format="A4")
pdf.set_auto_page_break(auto=True, margin=15)
pdf.add_page()
pdf.set_font("Helvetica", size=9)
# intro
pdf.set_font("Helvetica", size=9)
pdf.multi_cell(0, 5,
"Nombra tus capas QGIS con cualquiera de los textos de la columna 'Nombres reconocidos' "
"(sin importar mayusculas). Tambien puedes usar el acronimo S-57 directamente como nombre de capa. "
"Para agregar nombres nuevos, edita 'layer_mappings' en cell_config.json.")
pdf.ln(3)
COL = [22, 58, 110] # x positions
W = [22, 55, 78] # widths
def th(texts, fill_rgb=(200, 215, 235)):
pdf.set_fill_color(*fill_rgb)
pdf.set_font("Helvetica", "B", 8)
for i, t in enumerate(texts):
pdf.set_x(10 + sum(W[:i]))
pdf.cell(W[i], 6, t, border=1, fill=True)
pdf.ln()
def tr(texts, alt=False):
fill_rgb = (245, 248, 252) if alt else (255, 255, 255)
pdf.set_fill_color(*fill_rgb)
pdf.set_font("Helvetica", size=8)
# measure max height needed
heights = []
for i, t in enumerate(texts):
lines = pdf.get_string_width(t) / W[i] + 1
heights.append(max(1, int(lines) + 1) * 5)
h = max(heights)
h = min(h, 10)
for i, t in enumerate(texts):
pdf.set_x(10 + sum(W[:i]))
pdf.multi_cell(W[i], h / max(1, pdf.get_string_width(t) / W[i] + 1),
t, border=1, fill=True, max_line_height=5)
# ensure we're on next line
pdf.ln(0)
for section_title, rows in SECCIONES:
pdf.set_font("Helvetica", "B", 9)
pdf.set_fill_color(30, 80, 140)
pdf.set_text_color(255, 255, 255)
pdf.cell(0, 7, f" {section_title}", fill=True, new_x="LMARGIN", new_y="NEXT")
pdf.set_text_color(0, 0, 0)
th(["Acronimo S-57", "Descripcion", "Nombres reconocidos en QGIS"])
for idx, (acro, desc, aliases) in enumerate(rows):
pdf.set_fill_color(245, 248, 252) if idx % 2 else pdf.set_fill_color(255, 255, 255)
pdf.set_font("Helvetica", "B", 8)
pdf.set_x(10)
pdf.cell(W[0], 6, acro, border=1, fill=True)
pdf.set_font("Helvetica", size=8)
pdf.cell(W[1], 6, desc, border=1, fill=True)
pdf.multi_cell(W[2], 6, aliases, border=1, fill=True)
pdf.ln(4)
# atributos
pdf.set_font("Helvetica", "B", 9)
pdf.set_fill_color(30, 80, 140)
pdf.set_text_color(255, 255, 255)
pdf.cell(0, 7, " CAMPOS DE ATRIBUTOS (columnas de tu SHP)", fill=True, new_x="LMARGIN", new_y="NEXT")
pdf.set_text_color(0, 0, 0)
AW = [55, 22, 78]
pdf.set_fill_color(200, 215, 235)
pdf.set_font("Helvetica", "B", 8)
pdf.set_x(10); pdf.cell(AW[0], 6, "Nombre campo en SHP", border=1, fill=True)
pdf.cell(AW[1], 6, "Atrib. S-57", border=1, fill=True)
pdf.cell(AW[2], 6, "Descripcion", border=1, fill=True)
pdf.ln()
for idx, (shp_col, s57, desc) in enumerate(ATTR_ROWS):
pdf.set_fill_color(245, 248, 252) if idx % 2 else pdf.set_fill_color(255, 255, 255)
pdf.set_font("Helvetica", size=8)
pdf.set_x(10); pdf.cell(AW[0], 6, shp_col, border=1, fill=True)
pdf.set_font("Helvetica", "B", 8)
pdf.cell(AW[1], 6, s57, border=1, fill=True)
pdf.set_font("Helvetica", size=8)
pdf.cell(AW[2], 6, desc, border=1, fill=True)
pdf.ln()
# tabla LITCHR
pdf.ln(4)
pdf.set_font("Helvetica", "B", 9)
pdf.set_fill_color(30, 80, 140)
pdf.set_text_color(255, 255, 255)
pdf.cell(0, 7, " CODIGOS LITCHR - Caracteristica de luz", fill=True,
new_x="LMARGIN", new_y="NEXT")
pdf.set_text_color(0, 0, 0)
LW = [20, 30, 100]
pdf.set_fill_color(200, 215, 235)
pdf.set_font("Helvetica", "B", 8)
pdf.set_x(10); pdf.cell(LW[0], 6, "Codigo", border=1, fill=True)
pdf.cell(LW[1], 6, "Abrev.", border=1, fill=True)
pdf.cell(LW[2], 6, "Descripcion", border=1, fill=True)
pdf.ln()
for idx, (code, abbr, desc) in enumerate(LITCHR_ROWS):
pdf.set_fill_color(245, 248, 252) if idx % 2 else pdf.set_fill_color(255, 255, 255)
pdf.set_font("Helvetica", size=8)
pdf.set_x(10); pdf.cell(LW[0], 6, code, border=1, fill=True)
pdf.cell(LW[1], 6, abbr, border=1, fill=True)
pdf.cell(LW[2], 6, desc, border=1, fill=True)
pdf.ln()
pdf.ln(5)
pdf.set_font("Helvetica", "I", 8)
pdf.set_text_color(80, 80, 80)
pdf.multi_cell(0, 5,
"Nota: para anadir un nombre de capa no listado aqui, edita 'layer_mappings' en cell_config.json. "
"Para anadir campos de atributos nuevos, edita 'attribute_mappings'.")
pdf.output(str(OUT))
print(f"PDF generado: {OUT} ({OUT.stat().st_size} bytes)")