globalgrid2050

Geodesic Maps and More

GlobalGrid2050

How We Built a Production GIS Platform for UK Energy Infrastructure in 17 Days

By Ventus Cables & Connectivity
Published: April 2026


The Problem We Were Solving

The United Kingdom has a publicly available dataset called REPD, the Renewable Energy Planning Database. It contains every solar farm, wind turbine, battery storage facility, hydrogen plant and offshore tidal project in the country, along with their capacity in megawatts, planning status, operator, and GPS coordinates. It is updated quarterly by the Department for Energy Security and Net Zero.

The same was true of the National Grid topology — the 400kV, 275kV, 132kV and 66kV transmission lines that form the physical backbone of UK electricity. Open data. Publicly available as GeoJSON. Sitting there, underused.

The electrification of everything — heat pumps, EV charging, industrial processes, data centres is fundamentally constrained by where cables exist and what capacity they carry. That is the hidden bottleneck. Not the solar panels, not the batteries, not the planning system. The wires.

GlobalGrid2050 exists to make that constraint visible.


What the Platform Is

GlobalGrid2050 is a browser-based GIS intelligence platform. It runs entirely in the frontend, no login, no backend API, no database queries at runtime. Everything the user sees is rendered from static GeoJSON files served over HTTPS, processed by MapLibre GL JS in the browser.

The live version is at globalgrid2050.com/repd_grid_atlasv5/

The platform has three files that form its complete operating system:

This modular architecture means adding a new country is a new HTML file with a different configuration object and a different centre coordinate. The engine and stylesheet deploy unchanged.


The Technical Stack

MapLibre GL JS 3.6.2 — open source WebGL map renderer. Chosen over Mapbox because it has no API key requirement, no usage billing, and full feature parity for this use case.

CartoDB Dark Matter basemap — served from CartoDB’s CDN. The dark palette is not aesthetic preference — it maximises contrast for the neon-accented infrastructure overlays without visual noise.

GeoJSON — all data is static GeoJSON served from the web root. No vector tiles, no WMS, no tile server. This makes the architecture trivially hostable on GitHub Pages, Netlify, Cloudflare Pages or any static host.

Vanilla JavaScript — no framework. No React, no Vue, no bundler. The entire application is one IIFE (window.initVentusMap) that receives a configuration object and boots the map. This keeps the bundle size at zero and the cognitive overhead low.

GitHub Pages with Jekyll — deployment via GitHub Actions. Every file push triggers a workflow run. The deploy history is the complete audit trail of the platform’s development.


The Data Sources

REPD — Renewable Energy Planning Database

Source: Department for Energy Security and Net Zero
Format: CSV, processed to GeoJSON
File: /dist/repd_master.json
Contents: All renewable energy projects in the UK with tech type, capacity (MW), planning status, operator, mounting type, and coordinates

The REPD data is normalised to 12 technology types internally:

ID Technology
solar Solar PV (ground mount)
solar_roof Rooftop solar
wind Onshore and offshore wind
bess Battery energy storage
biomass Biomass and energy from waste
tidal Tidal and wave energy
hydrogen Hydrogen production
hydro Hydro and pumped storage
flywheel Flywheel storage
act Advanced conversion technologies
geothermal Geothermal energy
caes Compressed air energy storage

Grid Topology

Source: National Grid ESO open data
Format: GeoJSON LineString and MultiLineString
Files: /grid_400kv.geojson, /grid_275kv.geojson, /grid_220kv.geojson, /grid_132kv.geojson, /grid_66kv.geojson

Line endpoints are snapped to substation coordinates at load time using a planar distance algorithm with latitude cosine correction. Tolerance is approximately 100 metres.

Grid Substations

Source: National Grid ESO open data
Format: GeoJSON Point
File: /grid_substations.geojson
Count: ~5,800 features

Additional Asset Layers

Supermarket Network

Eleven major UK supermarket chains mapped as individual GeoJSON files: Tesco, Sainsbury’s, Asda, Morrisons, Aldi, Lidl, Waitrose, M&S Food, Co-op, Costco, Booths

Transit


The Architecture in Detail

The Configuration System

The engine receives a frozen configuration array at boot. Every data layer is declared as an object:

{
    id: "solar",
    label: "Solar PV",
    color: "#ffff00",
    type: "point",
    radius: 8,
    url: "/dist/repd_master.json",
    filter: ['==', ['get', 'tech'], 'solar'],
    preload: false
}

Line layers additionally carry snap: true and preload: true. The substations layer carries isSubs: true which marks it as the reference dataset for endpoint snapping.

The configuration is deep-frozen with Object.freeze recursively so it cannot be mutated at runtime.

Lazy Hydration

Layers load on demand. When a user ticks a checkbox, hydrateLayer() fetches the GeoJSON, processes it, and calls source.setData(). A FetchQueue limits concurrent requests to 4. A URL cache prevents re-fetching files already in memory.

The five topology layers and the substations layer have preload: true — they load automatically on map ready without user interaction.

All REPD technology types share a single GeoJSON source (src-repd). The first REPD layer a user enables fetches the complete repd_master.json and populates all 12 tech layers simultaneously. Subsequent REPD toggles are instant — no further network requests.

The Snapping Algorithm

Grid line endpoints in the source data do not always align precisely with substation coordinates. At hydration time, the engine runs snapLines() against the substation dataset.

The algorithm uses planar squared-distance with a latitude cosine correction rather than haversine. This is an intentional performance tradeoff — with 5,800 substations and hundreds of line endpoints per topology layer, haversine inside a nested loop would be measurably expensive at page load. The planar approximation has less than 0.1% error at UK latitudes for a 100-metre snap tolerance.

This snapping is marked as tech debt. The correct long-term solution is to pre-snap the GeoJSON in the build pipeline using Shapely/PyProj, so the browser receives already-correct topology and the runtime algorithm can be deleted entirely.

Performance Architecture

Visible Layer Cache — two arrays maintained at module scope:

Both are rebuilt once after map load and updated incrementally on each layer toggle. No getLayoutProperty calls happen inside event handlers.

Mousemove throttling — hover hit-testing is gated behind a 100ms timestamp check and a requestAnimationFrame wrapper. This means the expensive queryRenderedFeatures call fires at most 10 times per second during continuous mouse movement, not 60+.

Early exits — mode guards return immediately from click and mousemove handlers if any drawing tool is active. Empty cache arrays return before any GPU query.

A single activePopup reference is maintained at module scope. The openPopup() helper removes any existing popup before creating a new one. All popup creation goes through this single path — no raw new maplibregl.Popup().addTo(map) calls exist anywhere in the codebase except inside openPopup() itself.


The Tool Suite

Radius Search (cyan, ◎)

Draws a cyan dashed circle of configurable radius (1–160km) around a clicked point. Queries the REPD feature array to find all assets within the radius using haversine distance. Returns a popup showing total asset count, total MW capacity, breakdown by technology, and the top 5 assets by capacity.

Radius Area (magenta, ◵)

Draws a magenta dashed circle and calculates the enclosed area using the geodesic spherical cap formula:

area = 2π × R² × (1 − cos(r/R))

where R is Earth’s mean radius (6,371km) and r is the circle radius in km. This gives true geodesic area rather than a flat-earth approximation.

Results are displayed in a compact popup showing the radius and km² headline immediately, with a ▾ more toggle to expand the full breakdown: m², hectares, acres, km², square miles, and football pitches (calculated at 7,140 m² per FIFA-standard pitch).

The football pitches line is not a joke. It is the most immediately graspable unit of area for most people and consistently the number that makes the tool feel alive.

Poly Zone (orange, ⬡)

A free-draw polygon tool constrained within a user-defined radius (0.1–5km). Two-phase interaction:

Phase 1 (SET_CENTRE): First click places the centre and renders the orange boundary guide circle.

Phase 2 (DRAW): Subsequent clicks add polygon vertices. Any vertex placed outside the boundary is automatically clamped back to the circle edge using geodesic bearing projection — the point is not just truncated, it is correctly projected onto the boundary at the exact bearing from centre to click.

Double-click closes the polygon. Area is calculated using the spherical excess formula. Results show perimeter, km², ha, acres, m², and football pitches.

A 220ms deferred click timeout prevents ghost vertices on double-click — the same guard protects the Measure tool.

Measure (yellow, 📏)

Free polygon drawing with no radius constraint. Click to add vertices, double-click to close. Displays running line distance while drawing, then switches to perimeter and area on close. Undo button removes the last vertex. Area uses the same spherical excess formula as Poly Zone.

Status Colours (◑)

Toggles REPD dot colours from technology-based to planning-status-based:

Status Colour
Operational #00ff88 green
Under Construction #ffcc00 amber
Awaiting Construction #ffaa00 orange
Consented #ff8800 deep orange
Application Submitted #8888ff blue
Pre-Construction #aaaaff light blue

Export CSV

Exports all currently visible REPD layers as a CSV file with columns: name, tech, raw_tech, capacity_mw, status, operator, mounting, longitude, latitude. Named with today’s date.


The Visual Design System

The palette is a deliberate control room aesthetic — the kind of interface you would expect to see in a grid operations centre, not a consumer app.

Role Colour
System accent / UI chrome #00ffff cyan
Radius Search circle #00ffff cyan
Radius Area circle #ff00ff magenta
Poly Zone boundary #ff6600 orange
Measure tool #ffff00 yellow
Background / map chrome #000000 and #050505
Operational assets #00ff88 green
Amber alerts #ffae00 amber
Error / fatal #ff0000 red

The colour system ensures each tool is unambiguous on the dark basemap and that no two tools share an accent colour.

Solar farms use an interpolated yellow-to-red scale by capacity. Wind turbines are cyan. Battery storage is amber. The colour choices are not arbitrary — they map loosely to the energy type (solar = sun, wind = sky, battery = heat).


The Fullscreen Mode

The platform has a fullscreen mode that:


How to Rebuild This From Scratch

If this repository is ever lost, here is the complete rebuild specification.

Dependencies

<link href="https://cdn.jsdelivr.net/npm/maplibre-gl@3.6.2/dist/maplibre-gl.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/maplibre-gl@3.6.2/dist/maplibre-gl.js"></script>

No other dependencies. No npm. No bundler.

File Structure

/
├── ventus-core.js
├── ventus.css
├── grid_400kv.geojson
├── grid_275kv.geojson
├── grid_220kv.geojson
├── grid_132kv.geojson
├── grid_66kv.geojson
├── grid_66kv.geojson
├── grid_substations.geojson
├── grid_11kv_ukpn.geojson
├── power_plants.geojson
├── industrial_offtakers.geojson
├── datacentres.geojson
├── airports.geojson
├── railways.geojson
├── ev_chargers.geojson
├── stadiums.geojson
├── elizabeth_line.geojson
├── london_underground.geojson
├── uk_metros_trams.geojson
├── hs2.geojson
├── supermarkets_tesco.geojson
├── supermarkets_sainsburys.geojson
├── supermarkets_asda.geojson
├── supermarkets_morrisons.geojson
├── supermarkets_aldi.geojson
├── supermarkets_lidl.geojson
├── supermarkets_waitrose.geojson
├── supermarkets_ms.geojson
├── supermarkets_coop.geojson
├── supermarkets_costco.geojson
├── supermarkets_booths.geojson
├── dist/
│   └── repd_master.json
└── repd_grid_atlasv5/
    └── index.html

The HTML Cartridge

The HTML file is a pure structural document. It loads ../ventus.css and ../ventus-core.js then calls window.initVentusMap() with a configuration object. The configuration object is the only thing that changes between regions. The engine and stylesheet are shared.

The boot call:

window.initVentusMap({
    config: ukConfig,   // array of layer group objects
    center: [-3.5, 54.0],
    zoom: 4.2
});

Each layer group object:

{
    group: "Group Display Name",
    layers: [
        {
            id: "unique_id",
            label: "Display Label",
            color: "#hexcolor",
            type: "line" | "point",
            width: 2.5,        // line layers only
            radius: 8,         // point layers only
            url: "/data.geojson",
            filter: [...],     // MapLibre expression, optional
            snap: true,        // line layers that need endpoint snapping
            isSubs: true,      // marks the substations reference layer
            preload: true,     // loads automatically on map ready
            minzoom: 13.5      // optional minimum zoom for layer visibility
        }
    ]
}

The Engine Structure

ventus-core.js is a single IIFE exported as window.initVentusMap. Internal structure:

  1. UtilitiesdeepFreeze, escapeHTML, normalizeStatus, fmt, haversine
  2. Config loading — freeze config, initialise runtime state map
  3. ConstantsREPD_IDS, TRANSIT_IDS, TECH_COLOURS, STATUS_COLOURS, SEARCH_THRESHOLD
  4. Tool state — mode booleans and state objects for all five tools
  5. Popup management — single activePopup reference, openPopup(), closeActivePopup()
  6. FullscreenenterFullscreen(), exitFullscreen(), curtain toggle
  7. Tool implementations — radius, radius area, poly zone, measure
  8. Clock — 1-second interval updating system time and 2050 countdown
  9. Map initialisation — MapLibre map instance, ResizeObserver
  10. Performance cache_visibleInteractiveIds, _visibleHoverIds, rebuild and toggle functions
  11. Search and export — search index build, fuzzy name search, CSV export
  12. DOM builderbuildDOM() creates the layer panel from config, wires all event listeners
  13. Layer hydrationhydrateLayer(), handleLayerToggle(), fetch queue
  14. Map load handler — registers all sources and layers, seeds performance cache, wires map events

Critical Implementation Details

Ghost vertex prevention: Both the Measure and Poly Zone tools use a 220ms deferred click timeout (_pendingToolClick). The dblclick handler clears this timeout before processing polygon close. Without this, double-click fires two click events before the dblclick event, adding a ghost vertex at the closing point.

Popup accumulation prevention: Always use openPopup(). Never call new maplibregl.Popup().addTo(map) directly. The openPopup() helper removes the previous popup before creating a new one and listens for the close event to null the reference.

Snapping immutability: snapLines() uses features.map() not features.forEach() with mutation. The source array from the URL cache must not be mutated — if a layer is re-enabled after disable, the cached promise returns the original features and snapping runs again cleanly.

REPD shared source: All 12 REPD tech types read from a single MapLibre source (src-repd). MapLibre expressions filter by the tech property per layer. This means only one GeoJSON fetch regardless of how many REPD layers are enabled.


The Preflight Script

ventus-preflight.js is a Node.js regression checker that runs before every deployment. It verifies 88 invariants across all three files including popup lifecycle, ghost vertex fix integrity, performance cache wiring, CSS syntax, HTML ID completeness, script load order, REPD config consistency, and snap flags.

Run with:

node ventus-preflight.js

It exits 0 on full pass and 1 with a failure list on any regression.


What Comes Next

Python ETL pre-snapping pipeline — the highest value pending improvement. Pre-snap all topology GeoJSON using Shapely with PyProj for true geodesic accuracy, then delete snapLines() from the frontend entirely. This removes the only significant runtime computation from the load path.

GeoJSON simplification — reduce coordinate precision and strip unused properties from all data files before serving. Will improve hydration speed and pan/zoom smoothness, particularly for the 132kV and 66kV layers which have the highest feature counts.

Additional country cartridges — Spain, Germany, United States. Each is a new HTML file with a new configuration object pointing at new GeoJSON data. The engine and CSS do not change.

Automated performance budgets — set a measurable INP target and enforce it in the preflight script using Puppeteer or Playwright headless browser traces.


Why It Matters

The electrification of the UK economy is the defining infrastructure challenge of the next 25 years. Every heat pump, every EV charger, every data centre, every green hydrogen electrolyser needs a connection. The connection needs a cable. The cable needs capacity on the grid. The grid has constraints that are invisible to almost everyone making decisions about where to put things.

This platform makes those constraints visible in a browser, for free, with no login, to anyone who wants to understand them.

That is why it exists.


GlobalGrid2050 is built and maintained by Ventus Cables & Connectivity.
Data sources: DESNZ REPD, National Grid ESO, OpenStreetMap contributors, CARTO, Open Charge Map.
Platform: globalgrid2050.com

Global Grid 2050 Vision

March 2026

GlobalGrid2050 is an open engineering, procurement, construction, and operations platform designed to document, analyse, and improve the world’s electrical energy systems as they undergo rapid electrification.

Its ambition is structural rather than informational. It is intended to become the open infrastructure layer of the grid, starting in the UK and scaling globally as a shared system of engineering truth.


The Macro Reality: Why This Platform Must Exist

The transition to net zero is widely misunderstood as a simple replacement of fossil fuels with renewable generation. The underlying physics tells a very different story.

The UK currently consumes approximately 1,644 TWh of primary energy each year across transport, heating, and industry. However, a large proportion of this energy is lost during conversion:

Electrification fundamentally changes this equation. Electric vehicles convert roughly 70% of energy into motion, and heat pumps deliver between 3.5 and 5 units of heat for every unit of electricity consumed.

The implication is direct: A fully electrified UK would likely require only 500 to 700 TWh per year rather than 1,644 TWh. This is not a reduction driven by behavioural change. It is a direct consequence of improved system efficiency.

This efficiency creates a new constraint. The electricity grid becomes the limiting system. Connection queues are now extending to 10 to 15 years, and the existing network remains largely centralised and analogue in structure.

The challenge is no longer generation capacity. It is system design, integration, and execution at scale.


The Shift to Infrastructure Scale

The UK is now transitioning from megawatt-scale solar developments to gigawatt-scale infrastructure. These projects are no longer simple generation assets. They behave as distributed power stations with integrated storage and direct transmission network interfaces.

At this scale, new engineering realities emerge. Large populations of distributed inverters create complex electrical environments. Parallel conductor systems extend across hundreds of metres and begin to exhibit coupling effects that are not adequately captured in simplified models.

Civil works, drainage, and high voltage interface design become dominant constraints rather than secondary considerations.

This is no longer a renewables sector in the conventional sense. It is national infrastructure engineering with the same level of consequence and complexity as conventional power stations.


The Grid Problem Is Not Energy, It Is Design

Electrification reduces total energy demand but increases power density, network stress, and system complexity. Without structural redesign, the system fails at scale.

Across multiple projects, consistent patterns are emerging:

High voltage interface design becomes a critical dependency that can determine the success or failure of an entire project.

These are not theoretical concerns. They are execution risks that are already embedded within current deployment models. The gap is not in technology availability but in the way systems are designed and specified.


Open Hardware and the Safety Gap

One of the most critical unresolved issues in solar infrastructure is direct current safety. Unlike alternating current systems, direct current has no natural zero crossing. Once an arc forms, it can persist indefinitely under generation conditions.

This creates a persistent fire risk that is not adequately addressed by conventional protection approaches.

GlobalGrid2050 introduces open hardware as a direct response to this gap. The module-level DC arc suppression and insulation fault disconnection approach represents a shift from reactive protection to preventative distributed safety architecture.

It enables rapid disconnection at the module level, detects arc signatures using analog methods, and responds to insulation faults without reliance on software or communication systems.

This aligns solar infrastructure with the protection philosophy used in battery systems where fault isolation occurs at the smallest practical unit. Publishing this design openly allows peer review, laboratory validation, and industry-wide adoption. It moves safety from proprietary abstraction into shared engineering reality.


Economic Reality and Transparency as Infrastructure

Infrastructure decisions are ultimately constrained by cost—yet cost itself is often opaque. GlobalGrid2050 addresses this by introducing transparent pricing models based on physical inputs.

In medium voltage cable systems, raw metal content represents approximately 30 percent of the total delivered cost. The remaining 70 percent consists of manufacturing, logistics, and margin.

This allows a first-principle approximation where net cable price can be derived from live metal values. Conductor weight relationships further enable accurate estimation, with copper and aluminium weights directly proportional to cross-sectional area.

This level of transparency allows developers to make early-stage feasibility decisions with clarity, benchmark procurement strategies, and reduce asymmetry in pricing information. It transforms engineering from a process dependent on quotations into a system that can be analysed and understood.


The Structural Problem in Delivery

Field experience consistently highlights a misalignment between delivery incentives and asset lifetimes. Engineering, procurement, and construction (EPC) contractors are typically liable for approximately two years, while the assets themselves are expected to operate for 25 to 40 years.

This creates a structural gap where short-term optimisation can override long-term integrity.

Operational teams are now dealing with the consequences. Degradation mechanisms such as potential induced degradation are widespread. Cable routing decisions made during construction constrain maintenance access for decades.

Repowering is becoming a standard requirement rather than an exception, driven by inverter lifespans, voltage standard transitions, and manufacturer discontinuity.

These issues are not isolated. They are systemic and repeatable across projects. The industry is effectively relearning the same lessons in parallel without a shared repository of experience.


The Skills Deficit

The rate of deployment has outpaced the development of engineering capability. There is a shortage of experienced professionals, fragmented training pathways, and limited standardisation of knowledge.

This leads to repeated design errors, inconsistent execution quality, and increased system risk.

The solution is not incremental training programmes. It is the creation of a system where knowledge is structured, shared, and continuously refined. This is the role GlobalGrid2050 is intended to fulfil.


GlobalGrid2050 as Infrastructure

GlobalGrid2050 is not a standard blog or a static repository. It is a knowledge system designed to support utility-scale infrastructure deployment.

It integrates engineering documentation, component-level knowledge, pricing models, power system studies, and field intelligence into a unified platform.

To achieve its full objective, it must evolve into a collaborative environment where engineering frameworks, data sets, and hardware designs are openly shared and iterated. This includes standardised employer requirements, open data atlases for solar generation and battery storage, shared calculation libraries, and an ecosystem of open hardware aligned under shared licensing principles.


Strategic Position

The global energy transition requires approximately 75 terawatts of solar capacity by 2050 alongside massive grid reinforcement and coordination at industrial scale.

This cannot be delivered through fragmented engineering practices or proprietary silos. It requires a shared, open, and evolving engineering system where design logic, field experience, and economic reality are continuously integrated.


Conclusion

GlobalGrid2050 represents a shift from projects to systems, from documents to infrastructure, and from private knowledge to open engineering reality.

It is not simply an information platform. It is an intervention in how the grid is designed, built, and maintained.

The solution is empirical. Electrification of UK energy reduces 1,144 TWh of demand, while some end users pay £300 million per TWh per year at 30 pence per kWh.

This requires a coordinated effort across Power Systems Studies, LV and HV procurement, and engineering knowledge alongside cross-sector collaboration between civil, mechanical, and electrical disciplines—and active engagement with financial markets and government.

The direction is clear. The task is execution at scale with discipline, clarity, and modernity.