Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Observatorio-GC/Nodos/llms.txt

Use this file to discover all available pages before exploring further.

This page explains how the Nodos repository is laid out and how every part connects to the others at runtime. The project deliberately avoids abstractions — there is no module system, no component framework, and no generated output. Understanding the file tree is essentially equivalent to understanding the entire architecture.
The project contains no package.json, no build tool, and no module bundler. All third-party dependencies are either loaded from the unpkg CDN (Leaflet itself and togeojson) or bundled as plain .js files inside scripts/.

Directory tree

Nodos/
├── index.html              # Main entry point and Leaflet map initialisation
├── css/
│   ├── style.css           # Application styles (header, map, legend)
│   ├── Leaflet.PolylineMeasure.css
│   ├── leaflet.groupedlayercontrol.min.css
│   ├── Control.Coordinates.css
│   └── L.Control.MousePosition.css
├── js/
│   ├── funcionesMapa.js    # Map controls, layer control, print, file upload
│   ├── popups.js           # All onEachFeature popup functions and style functions
│   ├── iconos.js           # Leaflet icon definitions and factory functions
│   └── nube.png            # Upload-button icon used by leaflet.filelayer
├── scripts/
│   ├── *.js                # GeoJSON datasets as JS variable assignments (110+ files)
│   ├── bundle.js           # Third-party library bundle
│   ├── leaflet.groupedlayercontrol.min.js
│   ├── Leaflet.PolylineMeasure.js
│   ├── leaflet.browser.print.js
│   ├── leaflet.filelayer.js
│   ├── Control.Coordinates.js
│   ├── L.Control.MousePosition.js
│   ├── leaflet-tilelayer-wmts.js
│   └── leaflet.pattern.js
├── img/
│   └── *.png               # Custom map marker icons and UI images
└── fonts/
    └── *.otf / *.ttf       # Gotham and Playfair Display typefaces

Directory roles

css/ — Holds all stylesheet files. style.css is the hand-authored application stylesheet: it sets the Playfair Display font on the <h1> title and the Leaflet attribution control, defines the #map element height (responsive across breakpoints from 350 px up to 1920 px), and styles the fixed-position #referencias legend panel that appears when certain layers (ciclovías, caminabilidad) are toggled on. The remaining CSS files are distributed stylesheets for Leaflet plugins and are loaded verbatim. js/ — Contains the hand-written JavaScript helpers that supplement index.html. The three files actively loaded by index.html are popups.js, iconos.js, and funcionesMapa.js. They are loaded after all data scripts and the Leaflet library, so they can reference both the global Leaflet L object and the layer variables defined in index.html. scripts/ — The largest directory. It holds over 110 GeoJSON data files formatted as JavaScript variable declarations, plus the plugin JavaScript files for every Leaflet extension used by the map. Data files and plugin files live together in this flat directory. img/ — PNG assets used as Leaflet marker icons. Each category of point feature has a dedicated icon (e.g., Asistencia.png for health facilities, Enseñanza.png for schools, Comercio.png for commerce). Several icons exist in two sizes — _r1.png and _r2.png — to support different display densities. fonts/ — Self-hosted typeface files. Gotham (Bold, Book, Medium in .otf) is used for body text in UI components. Playfair Display (Regular, Bold, Italic, BoldItalic, Black, BlackItalic in .ttf) is used for the map title and the legend panel; it is also loaded from Google Fonts as a fallback via the @import at the top of style.css.

index.html structure

index.html is the single HTML file that ties the entire application together. Its structure is: <head> — Imports all CSS files (application styles, Leaflet core, plugin stylesheets) and all JavaScript libraries (Leaflet from CDN, togeojson from CDN, then all plugin scripts from scripts/, and finally js/popups.js and js/iconos.js). After the libraries, every GeoJSON data file is loaded with its own <script type="text/javascript" src="scripts/Filename.js"> tag. By the time the <body> executes, all data variables and all helper functions are already in scope. <header> — Contains inline styles that adjust Leaflet’s font settings, the <h1> title (“Red de Nodos Distritales”), an <img class="logoobserv"> element (hidden on small screens; style.css sets it to visibility: visible at viewports of 1024 px and above), the <div id="map"> element that Leaflet mounts into, and the <div id="referencias"> legend panel. The legend panel holds hidden <div class="icono_referencia"> elements that are shown/hidden by the onOverlayAdd / onOverlayRemove event handlers whenever the user toggles specific layers. <body> — A single <script> block that:
  1. Instantiates the base tile layers (ESRI Satellite, Argenmap WMTS, OpenTopoMap, and OpenStreetMap — though only the first three are registered in baseMaps).
  2. Creates every overlay as a L.geoJson(...) or L.marker(...) variable.
  3. Calls L.map('map', { layers: [mapabase_esri, godoycruz] }).setView([-32.9337, -68.8978], 13) to initialise the map.
  4. Calls the style-function helpers (e.g., estiloDistritosDepartamentales(), estilocaminabilidad()) that iterate over layers and apply dynamic colours.
  5. Builds the baseMaps and groupedOverlays objects.
  6. Adds L.control.mousePosition() to the map.
After the inline script, <script src="js/funcionesMapa.js"></script> is loaded, which registers the grouped layer control, scale bar, polyline measure tool, browser print control, file upload control, and the onOverlayAdd / onOverlayRemove legend-toggle handlers.

Data loading pattern

Each GeoJSON file in scripts/ declares one global variable whose value is a GeoJSON FeatureCollection. Example from scripts/Centrosdesalud.js:
var centrosdesalud = {
  "type": "FeatureCollection",
  "name": "Centros de Salud",
  "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
  "features": [ /* ... */ ]
};
index.html includes this file via a <script> tag:
<script type="text/javascript" src="scripts/Centrosdesalud.js"></script>
The global variable is then referenced directly when creating the Leaflet layer:
centrosdesalud = L.geoJson(centrosdesalud, {
    pointToLayer: crearIconoAsistencia,
    onEachFeature: agregarPopupSalud
}),
Polygon and polyline layers follow the same pattern but omit pointToLayer and instead call .setStyle({ color: "...", fillOpacity: ... }) — or delegate to a dedicated style function for layers whose colours are data-driven (e.g., estiloDistritosDepartamentales() assigns one of nine colours based on each district’s qc_id property).

js/popups.js

This file contains every onEachFeature callback used in the map. Each function accepts (feature, layer), checks whether the relevant properties exist, and calls layer.bindPopup(htmlString). Examples:
// Salud — health facilities
function agregarPopupSalud(feature, layer) {
    if (feature.properties && feature.properties.Nombre_1) {
        layer.bindPopup(
            "<strong>" + feature.properties.Nombre_1 + "</strong><br/>" +
            feature.properties.Direccion
        );
    }
}

// Nodos — district-level urban nodes
function agregarPopupNodos(feature, layer) {
    if (feature.properties && feature.properties.NOMBRE) {
        layer.bindPopup(
            "<strong>" + feature.properties.NOMBRE + "</strong><br/>" +
            "Servicios faltantes: <strong>" + feature.properties.DESCRIPTIO
        );
    }
}

// Gastronomía — bars, cafés, restaurants
function agregarPopupGastronomia(feature, layer) {
    if (feature.properties && feature.properties.Nombre) {
        layer.bindPopup(
            "<strong>" + feature.properties.Nombre + "</strong><br/>" +
            "Dirección <strong>" + feature.properties.Direccion + "</strong><br/>" +
            "Horario <strong>"   + feature.properties.Horario   + "</strong><br/>" +
            "Contacto <strong>"  + feature.properties.Contacto
        );
    }
}
The file also contains all the dynamic-style functions (estiloDistritosDepartamentales, estilozoni, estilocaminabilidad, etc.) that are called from index.html after the map is created.

js/iconos.js

This file defines the icon infrastructure for all point layers. It works in two stages: Stage 1 — Extend L.Icon to create reusable base classes with shared anchor and shadow settings:
var iconoComun = L.Icon.extend({
    options: {
        shadowUrl: 'img/marker-shadow.png',
        iconSize:     [25, 41],
        shadowSize:   [41, 41],
        iconAnchor:   [12, 41],
        popupAnchor:  [ 1, -34]
    }
});
A second class iconoParaTren uses a smaller iconSize: [20, 20] for transit-stop markers. Stage 2 — Instantiate icon objects by passing iconUrl to the extended class:
var iconoAsistencia  = new iconoComun({ iconUrl: 'img/Asistencia.png'  });
var iconoEnseñanza   = new iconoComun({ iconUrl: 'img/Enseñanza.png'   });
var iconoComercio    = new iconoComun({ iconUrl: 'img/Comercio.png'    });
var iconoCultura     = new iconoComun({ iconUrl: 'img/Cultura.png'     });
// ... and many more
Stage 3 — Expose factory functions that Leaflet’s pointToLayer option calls for each GeoJSON point feature:
function crearIconoAsistencia(feature, latlng) {
    return L.marker(latlng, { icon: iconoAsistencia });
}
Each factory function is paired with an asignarIcono* object ({ pointToLayer: crearIcono* }) for contexts where the full options object is passed directly to L.geoJson.

Build docs developers (and LLMs) love