{"id":3255,"date":"2026-05-17T11:12:57","date_gmt":"2026-05-17T09:12:57","guid":{"rendered":"https:\/\/civiltracks.com\/?page_id=3255"},"modified":"2026-05-17T23:19:55","modified_gmt":"2026-05-17T21:19:55","slug":"trazado-ffcc","status":"publish","type":"page","link":"https:\/\/civiltracks.com\/index.php\/trazado-ffcc\/","title":{"rendered":"Trazado FFCC"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"3255\" class=\"elementor elementor-3255\">\n\t\t\t\t<div class=\"elementor-element elementor-element-bf2b210 e-con-full e-flex e-con e-parent\" data-id=\"bf2b210\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d62e0f4 elementor-widget elementor-widget-html\" data-id=\"d62e0f4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n.trazado-app {\r\n  max-width: 1180px;\r\n  margin: 0 auto;\r\n  padding: 32px;\r\n  font-family: system-ui, sans-serif;\r\n  color: #1f2933;\r\n  background: #DED1FF;\r\n  border-radius: 24px;\r\n}\r\n\r\n.trazado-card {\r\n  background: #ffffff;\r\n  border: 1px solid #d9e2ec;\r\n  border-radius: 16px;\r\n  padding: 24px;\r\n  margin-bottom: 24px;\r\n}\r\n\r\n.trazado-header {\r\n  background: #f3e8ff;\r\n  border: 1px solid #d8b4fe;\r\n}\r\n\r\n.trazado-header h2 {\r\n  font-size: 34px;\r\n}\r\n\r\n.trazado-card h2,\r\n.trazado-card h3 {\r\n  margin-top: 0;\r\n}\r\n\r\n.trazado-grid {\r\n  display: grid;\r\n  grid-template-columns: repeat(4, 1fr);\r\n  gap: 16px;\r\n}\r\n\r\n.trazado-tablas-grid {\r\n  display: grid;\r\n  grid-template-columns: 1fr 1fr;\r\n  gap: 24px;\r\n}\r\n\r\n.trazado-field label {\r\n  display: block;\r\n  margin-bottom: 6px;\r\n  font-size: 13px;\r\n  font-weight: 600;\r\n}\r\n\r\n.trazado-field input,\r\n.trazado-field select {\r\n  width: 100%;\r\n  padding: 10px;\r\n  border: 1px solid #dccffb;\r\n  background: #faf7ff;\r\n  border-radius: 10px;\r\n  box-sizing: border-box;\r\n  transition: all 0.15s ease;\r\n}\r\n\r\n.trazado-field input:focus,\r\n.trazado-field select:focus {\r\n  outline: none;\r\n  border: 1px solid #61CE70;\r\n  box-shadow: none;\r\n}\r\n\r\n.trazado-button {\r\n  margin-top: 20px;\r\n  padding: 13px 22px;\r\n  border: none;\r\n  border-radius: 12px;\r\n  background: #61CE70 !important;\r\n  color: white;\r\n  font-weight: 700;\r\n  cursor: pointer;\r\n}\r\n\r\n.trazado-button:hover,\r\n.trazado-button:focus,\r\n.trazado-button:active {\r\n  background: #61CE70 !important;\r\n  color: white;\r\n}\r\n\r\n.trazado-chart {\r\n  width: 100%;\r\n  height: 520px;\r\n}\r\n\r\n.trazado-table {\r\n  width: 100%;\r\n  border-collapse: collapse;\r\n  font-size: 11px;\r\n  table-layout: fixed;\r\n}\r\n\r\n.trazado-table th {\r\n  background: #f3e8ff;\r\n  padding: 2px 4px;\r\n  border: 1px solid #d8b4fe;\r\n}\r\n\r\n.trazado-table td {\r\n  padding: 1px 3px;\r\n  border: 1px solid #d9e2ec;\r\n}\r\n\r\n.trazado-table input,\r\n.trazado-table select {\r\n  width: 100%;\r\n  padding: 1px 4px;\r\n  height: 24px;\r\n  box-sizing: border-box;\r\n  text-align: right;\r\n  font-size: 11px;\r\n  border: 1px solid #e8dcff;\r\n  background: #faf7ff;\r\n  border-radius: 5px;\r\n  transition: all 0.15s ease;\r\n}\r\n\r\n.trazado-table input:focus,\r\n.trazado-table select:focus {\r\n  outline: none;\r\n  border: 1px solid #61CE70;\r\n  box-shadow: none;\r\n}\r\n\r\n.trazado-table td:first-child,\r\n.trazado-table th:first-child {\r\n  width: 26px;\r\n  text-align: right;\r\n}\r\n\r\n.trazado-table th:nth-child(2),\r\n.trazado-table td:nth-child(2) {\r\n  width: 110px;\r\n}\r\n\r\n@media (max-width: 900px) {\r\n\r\n  .trazado-grid {\r\n    grid-template-columns: repeat(2, 1fr);\r\n  }\r\n\r\n  .trazado-tablas-grid {\r\n    grid-template-columns: 1fr;\r\n  }\r\n\r\n}\r\n<\/style>\r\n\r\n<div class=\"trazado-app\">\r\n\r\n<div class=\"trazado-card trazado-header\">\r\n<h2>Dibujo de trazado ferroviario<\/h2>\r\n<p>Programa educativo en pruebas. No v\u00e1lido para uso profesional.<\/p>\r\n<\/div>\r\n\r\n<div class=\"trazado-card\">\r\n\r\n<div class=\"trazado-grid\">\r\n\r\n<div class=\"trazado-field\">\r\n<label>PPKK inicial (m)<\/label>\r\n<input id=\"PPKK0\" type=\"number\" value=\"0\">\r\n<\/div>\r\n\r\n<div class=\"trazado-field\">\r\n<label>X inicial (m)<\/label>\r\n<input id=\"X0\" type=\"number\" value=\"0\">\r\n<\/div>\r\n\r\n<div class=\"trazado-field\">\r\n<label>Y inicial (m)<\/label>\r\n<input id=\"Y0\" type=\"number\" value=\"0\">\r\n<\/div>\r\n\r\n<div class=\"trazado-field\">\r\n<label>Azimut inicial (grados cent.)<\/label>\r\n<input id=\"AzimutIni\" type=\"number\" value=\"50\">\r\n<\/div>\r\n\r\n<div class=\"trazado-field\">\r\n<label>Z inicial (m)<\/label>\r\n<input id=\"Z0\" type=\"number\" value=\"100\">\r\n<\/div>\r\n\r\n<div class=\"trazado-field\">\r\n<label>Pendiente inicial \u2030<\/label>\r\n<input id=\"PendienteI\" type=\"number\" value=\"4\">\r\n<\/div>\r\n\r\n<div class=\"trazado-field\">\r\n<label>Huso UTM<\/label>\r\n<input id=\"HusoUTM\" type=\"number\" value=\"30\">\r\n<\/div>\r\n\r\n<div class=\"trazado-field\">\r\n<label>Intervalo de puntos (m)<\/label>\r\n<input id=\"Paso\" type=\"number\" value=\"10\">\r\n<\/div>\r\n\r\n<\/div>\r\n<\/div>\r\n\r\n<div class=\"trazado-tablas-grid\">\r\n\r\n<div class=\"trazado-card\">\r\n\r\n<h3>Alineaciones en planta<\/h3>\r\n\r\n<table class=\"trazado-table\">\r\n<thead>\r\n<tr>\r\n<th>N\u00ba<\/th>\r\n<th>Tipo<\/th>\r\n<th>Longitud<\/th>\r\n<th>Radio\/Par\u00e1metro Clot.<\/th>\r\n<\/tr>\r\n<\/thead>\r\n\r\n<tbody id=\"tablaPlanta\"><\/tbody>\r\n\r\n<\/table>\r\n<\/div>\r\n\r\n<div class=\"trazado-card\">\r\n\r\n<h3>Alineaciones en alzado<\/h3>\r\n\r\n<table class=\"trazado-table\">\r\n<thead>\r\n<tr>\r\n<th>N\u00ba<\/th>\r\n<th>PPKK entrada<\/th>\r\n<th>PPKK salida<\/th>\r\n<th>Kv<\/th>\r\n<\/tr>\r\n<\/thead>\r\n\r\n<tbody id=\"tablaAlzado\"><\/tbody>\r\n\r\n<\/table>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<div class=\"trazado-card\">\r\n\r\n<button class=\"trazado-button\" onclick=\"capturarDatosTrazado()\">\r\nCalcular trazado\r\n<\/button>\r\n\r\n<div id=\"estadoTrazado\">\r\nLa conexi\u00f3n con el servidor de c\u00e1lculo puede tardar hasta 30 segundos.\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<div class=\"trazado-card\">\r\n\r\n<h3>Gr\u00e1fico del trazado<\/h3>\r\n\r\n<div id=\"grafico_trazado\" class=\"trazado-chart\"><\/div>\r\n\r\n<\/div>\r\n\r\n<div class=\"trazado-card\">\r\n\r\n<h3>Listado de coordenadas<\/h3>\r\n\r\n<table class=\"trazado-table\">\r\n\r\n<thead>\r\n<tr>\r\n<th>Alin<\/th>\r\n<th>Tipo<\/th>\r\n<th>PPKK<\/th>\r\n<th>X<\/th>\r\n<th>Y<\/th>\r\n<th>Z<\/th>\r\n<th>Azimut<\/th>\r\n<th>Radio<\/th>\r\n<\/tr>\r\n<\/thead>\r\n\r\n<tbody id=\"tablaResultados\"><\/tbody>\r\n\r\n<\/table>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<script src=\"https:\/\/cdn.plot.ly\/plotly-2.35.2.min.js\"><\/script>\r\n\r\n<script>\r\n\r\nfunction crearTablasTrazado() {\r\n\r\n  let tablaPlanta = document.getElementById(\"tablaPlanta\");\r\n  let tablaAlzado = document.getElementById(\"tablaAlzado\");\r\n\r\n  for (let i = 1; i <= 10; i++) {\r\n\r\n    let TipoAlinValor = \"\";\r\n    let LongAlinValor = \"\";\r\n    let RadioAlinValor = \"\";\r\n\r\n    if (i === 1) {\r\n      TipoAlinValor = \"1\";\r\n      LongAlinValor = \"100\";\r\n      RadioAlinValor = \"0\";\r\n    }\r\n\r\n    if (i === 2) {\r\n      TipoAlinValor = \"2\";\r\n      LongAlinValor = \"200\";\r\n      RadioAlinValor = \"-500\";\r\n    }\r\n\r\n    tablaPlanta.innerHTML += `\r\n      <tr>\r\n        <td>${i}<\/td>\r\n\r\n        <td>\r\n          <select id=\"TipoAlin_${i}\">\r\n            <option value=\"\"><\/option>\r\n            <option value=\"1\" ${TipoAlinValor === \"1\" ? \"selected\" : \"\"}>Recta<\/option>\r\n            <option value=\"2\" ${TipoAlinValor === \"2\" ? \"selected\" : \"\"}>Curva<\/option>\r\n            <option value=\"3\" ${TipoAlinValor === \"3\" ? \"selected\" : \"\"}>Clotoide<\/option>\r\n          <\/select>\r\n        <\/td>\r\n\r\n        <td>\r\n          <input id=\"LongAlin_${i}\" type=\"number\" value=\"${LongAlinValor}\">\r\n        <\/td>\r\n\r\n        <td>\r\n          <input id=\"RadioAlin_${i}\" type=\"number\" value=\"${RadioAlinValor}\">\r\n        <\/td>\r\n\r\n      <\/tr>\r\n    `;\r\n\r\n    let PPKKEntradaValor = \"\";\r\n    let PPKKSalidaValor = \"\";\r\n    let KvAlinAValor = \"\";\r\n\r\n    if (i === 1) {\r\n      PPKKEntradaValor = \"40\";\r\n      PPKKSalidaValor = \"80\";\r\n      KvAlinAValor = \"2000\";\r\n    }\r\n\r\n    tablaAlzado.innerHTML += `\r\n      <tr>\r\n\r\n        <td>${i}<\/td>\r\n\r\n        <td>\r\n          <input id=\"PPKKEntrada_${i}\" type=\"number\" value=\"${PPKKEntradaValor}\">\r\n        <\/td>\r\n\r\n        <td>\r\n          <input id=\"PPKKSalida_${i}\" type=\"number\" value=\"${PPKKSalidaValor}\">\r\n        <\/td>\r\n\r\n        <td>\r\n          <input id=\"KvAlinA_${i}\" type=\"number\" value=\"${KvAlinAValor}\">\r\n        <\/td>\r\n\r\n      <\/tr>\r\n    `;\r\n  }\r\n\r\n}\r\n\r\nfunction leerNumero(id) {\r\n\r\n  let valor = document.getElementById(id).value;\r\n\r\n  if (valor === \"\") {\r\n    return null;\r\n  }\r\n\r\n  return Number(valor);\r\n\r\n}\r\n\r\nfunction capturarDatosTrazado() {\r\n\r\n  let datos = {};\r\n\r\n  datos[\"PPKK0\"] = leerNumero(\"PPKK0\");\r\n  datos[\"X0\"] = leerNumero(\"X0\");\r\n  datos[\"Y0\"] = leerNumero(\"Y0\");\r\n  datos[\"Z0\"] = leerNumero(\"Z0\");\r\n  datos[\"AzimutIni\"] = leerNumero(\"AzimutIni\");\r\n  datos[\"Paso\"] = leerNumero(\"Paso\");\r\n  datos[\"PendienteI\"] = leerNumero(\"PendienteI\");\r\n  datos[\"HusoUTM\"] = leerNumero(\"HusoUTM\");\r\n\r\n  datos[\"Planta\"] = [];\r\n  datos[\"Alzado\"] = [];\r\n\r\n  for (let i = 1; i <= 10; i++) {\r\n\r\n    let TipoAlin = document.getElementById(\"TipoAlin_\" + i).value;\r\n    let LongAlin = leerNumero(\"LongAlin_\" + i);\r\n    let RadioAlin = leerNumero(\"RadioAlin_\" + i);\r\n\r\n    if (TipoAlin !== \"\") {\r\n\r\n      datos[\"Planta\"].push({\r\n        \"TipoAlin\": Number(TipoAlin),\r\n        \"LongAlin\": LongAlin,\r\n        \"RadioAlin\": RadioAlin\r\n      });\r\n\r\n    }\r\n\r\n    let PPKKEntrada = leerNumero(\"PPKKEntrada_\" + i);\r\n    let PPKKSalida = leerNumero(\"PPKKSalida_\" + i);\r\n    let KvAlinA = leerNumero(\"KvAlinA_\" + i);\r\n\r\n    if (\r\n      PPKKEntrada !== null ||\r\n      PPKKSalida !== null ||\r\n      KvAlinA !== null\r\n    ) {\r\n\r\n      datos[\"Alzado\"].push({\r\n        \"PPKKEntrada\": PPKKEntrada,\r\n        \"PPKKSalida\": PPKKSalida,\r\n        \"KvAlinA\": KvAlinA\r\n      });\r\n\r\n    }\r\n\r\n  }\r\n\r\n  fetch(\"https:\/\/servidorffcc.onrender.com\/calcular_dibujotrazado\", {\r\n\r\n    method: \"POST\",\r\n\r\n    headers: {\r\n      \"Content-Type\": \"application\/json\"\r\n    },\r\n\r\n    body: JSON.stringify(datos)\r\n\r\n  })\r\n\r\n  .then(async response => {\r\n\r\n    let resultado = await response.json();\r\n\r\n    if (!response.ok) {\r\n      throw new Error(resultado.error);\r\n    }\r\n\r\n    return resultado;\r\n\r\n  })\r\n\r\n  .then(resultado => {\r\n\r\n    dibujarTrazado(resultado.plotly);\r\n\r\n    rellenarTablaResultados(resultado.listado);\r\n\r\n  })\r\n\r\n  .catch(error => {\r\n\r\n    alert(error.message);\r\n\r\n  });\r\n\r\n}\r\n\r\nfunction dibujarTrazado(datosPlotly) {\r\n\r\n  let customdata = [];\r\n\r\n  for (let i = 0; i < datosPlotly.x.length; i++) {\r\n\r\n    customdata.push([\r\n      datosPlotly.ppkk[i],\r\n      datosPlotly.z[i],\r\n      datosPlotly.azimut[i]\r\n    ]);\r\n\r\n  }\r\n\r\n  let traza = {\r\n\r\n    x: datosPlotly.x,\r\n    y: datosPlotly.y,\r\n\r\n    customdata: customdata,\r\n\r\n    mode: \"lines+markers\",\r\n    type: \"scatter\",\r\n\r\n    showlegend: false,\r\n\r\n    hovertemplate:\r\n      \"PPKK: %{customdata[0]:.3f}<br>\" +\r\n      \"X: %{x:.3f}<br>\" +\r\n      \"Y: %{y:.3f}<br>\" +\r\n      \"Z: %{customdata[1]:.3f}<br>\" +\r\n      \"Azimut: %{customdata[2]:.6f}<extra><\/extra>\",\r\n\r\n    marker: {\r\n      size: 4\r\n    }\r\n\r\n  };\r\n\r\n  let trazas = [traza];\r\n\r\n  if (datosPlotly.marcas) {\r\n\r\n    datosPlotly.marcas.forEach(marca => {\r\n\r\n      trazas.push({\r\n\r\n        x: marca.x,\r\n        y: marca.y,\r\n\r\n        mode: \"lines\",\r\n        type: \"scatter\",\r\n\r\n        showlegend: false,\r\n        hoverinfo: \"skip\",\r\n\r\n        line: {\r\n          width: 2,\r\n          color: \"#7c3aed\"\r\n        }\r\n\r\n      });\r\n\r\n    });\r\n\r\n  }\r\n\r\n  Plotly.newPlot(\r\n\r\n    \"grafico_trazado\",\r\n\r\n    trazas,\r\n\r\n    {\r\n      showlegend: false,\r\n\r\n      yaxis: {\r\n        scaleanchor: \"x\",\r\n        scaleratio: 1\r\n      }\r\n    },\r\n\r\n    {\r\n      responsive: true,\r\n      displaylogo: false\r\n    }\r\n\r\n  );\r\n\r\n}\r\n\r\nfunction rellenarTablaResultados(listado) {\r\n\r\n  let tabla = document.getElementById(\"tablaResultados\");\r\n\r\n  tabla.innerHTML = \"\";\r\n\r\n  listado.forEach(p => {\r\n\r\n    tabla.innerHTML += `\r\n      <tr>\r\n\r\n        <td style=\"text-align:right;\">${p.Alin}<\/td>\r\n        <td>${p.Tipo}<\/td>\r\n        <td style=\"text-align:right;\">${Number(p.PPKK).toFixed(3)}<\/td>\r\n        <td style=\"text-align:right;\">${Number(p.X).toFixed(3)}<\/td>\r\n        <td style=\"text-align:right;\">${Number(p.Y).toFixed(3)}<\/td>\r\n        <td style=\"text-align:right;\">${Number(p.Z).toFixed(3)}<\/td>\r\n        <td style=\"text-align:right;\">${Number(p.Azimut).toFixed(6)}<\/td>\r\n        <td style=\"text-align:right;\">${Number(p.Radio).toFixed(3)}<\/td>\r\n\r\n      <\/tr>\r\n    `;\r\n\r\n  });\r\n\r\n}\r\n\r\ncrearTablasTrazado();\r\n\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Dibujo de trazado ferroviario Programa educativo en pruebas. No v\u00e1lido para uso profesional. PPKK inicial (m) X inicial (m) Y [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"om_disable_all_campaigns":false,"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-3255","page","type-page","status-publish","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/civiltracks.com\/index.php\/wp-json\/wp\/v2\/pages\/3255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/civiltracks.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/civiltracks.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/civiltracks.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/civiltracks.com\/index.php\/wp-json\/wp\/v2\/comments?post=3255"}],"version-history":[{"count":59,"href":"https:\/\/civiltracks.com\/index.php\/wp-json\/wp\/v2\/pages\/3255\/revisions"}],"predecessor-version":[{"id":3319,"href":"https:\/\/civiltracks.com\/index.php\/wp-json\/wp\/v2\/pages\/3255\/revisions\/3319"}],"wp:attachment":[{"href":"https:\/\/civiltracks.com\/index.php\/wp-json\/wp\/v2\/media?parent=3255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}