Globalization & Conflict
  • Home
  • The Map
  • Mechanism
  • Explore
  • Evidence
  • Policy
  • About

On this page

  • Strategic Choke Points & Conflict

The Map

Where are the world’s strategic choke points, and where does conflict cluster?

Strategic Choke Points & Conflict

Maritime choke points — straits, capes, and canals where shipping lanes narrow — are among the most strategically important locations on Earth. The Strait of Hormuz alone sees roughly 20% of the world’s oil supply pass through its waters daily.

The map below shows these choke points alongside geolocalized conflict events from the UCDP (Uppsala Conflict Data Program) dataset. Toggle between periods of high and low world trade to see how conflict patterns shift.

Code
topojson = require("topojson-client@3")

world = FileAttachment("data/world-110m.json").json()
chokepoints = FileAttachment("data/chokepoints.json").json()
conflicts = FileAttachment("data/conflict_events.json").json()
Code
// --- Trade period toggle ---
viewof tradePeriod = Inputs.radio(
  ["High Trade Openness", "Low Trade Openness"],
  {value: "High Trade Openness", label: "Toggle trade period"}
)
Code
// --- Filter conflicts based on toggle ---
filteredConflicts = {
  const isHigh = tradePeriod === "High Trade Openness";
  return conflicts.filter(d => d.high_trade === isHigh);
}
Code
// --- Summary stats ---
htl.html`<div class="data-callout" style="max-width: 700px; margin: 0.5rem auto 1rem;">
  <strong>${filteredConflicts.length}</strong> grid cells with conflict events shown
  &nbsp;·&nbsp;
  <strong>${chokepoints.length}</strong> maritime choke points marked
  &nbsp;·&nbsp;
  Period: <strong>${tradePeriod === "High Trade Openness" ? "above" : "below"}</strong> median world trade openness
</div>`
Code
// --- The Map ---
{
  const width = 960;
  const height = 500;

  const projection = d3.geoNaturalEarth1()
    .fitSize([width, height], {type: "Sphere"});
  const path = d3.geoPath(projection);

  const svg = d3.create("svg")
    .attr("viewBox", [0, 0, width, height])
    .style("max-width", "100%")
    .style("background", "#f7fbff");

  // Ocean
  svg.append("path")
    .datum({type: "Sphere"})
    .attr("d", path)
    .attr("fill", "#e8f0fe")
    .attr("stroke", "#b0c4de")
    .attr("stroke-width", 0.5);

  // Countries
  const countries = topojson.feature(world, world.objects.countries);
  svg.append("g")
    .selectAll("path")
    .data(countries.features)
    .join("path")
    .attr("d", path)
    .attr("fill", "#e8e8e0")
    .attr("stroke", "#ccc")
    .attr("stroke-width", 0.3);

  // Country borders
  svg.append("path")
    .datum(topojson.mesh(world, world.objects.countries, (a, b) => a !== b))
    .attr("d", path)
    .attr("fill", "none")
    .attr("stroke", "#bbb")
    .attr("stroke-width", 0.3);

  // Conflict dots
  const maxEvents = d3.max(filteredConflicts, d => d.events) || 1;
  const conflictDots = svg.append("g")
    .selectAll("circle")
    .data(filteredConflicts.sort((a, b) => b.events - a.events))
    .join("circle")
    .attr("cx", d => {
      const p = projection([d.lng, d.lat]);
      return p ? p[0] : -100;
    })
    .attr("cy", d => {
      const p = projection([d.lng, d.lat]);
      return p ? p[1] : -100;
    })
    .attr("r", d => Math.max(1.5, Math.sqrt(d.events) * 1.2))
    .attr("fill", "#e53935")
    .attr("fill-opacity", 0.45)
    .attr("stroke", "#c62828")
    .attr("stroke-width", 0.3)
    .attr("stroke-opacity", 0.4);

  conflictDots.append("title")
    .text(d => `${d.events} conflict event${d.events > 1 ? 's' : ''} (${d.lat.toFixed(1)}°, ${d.lng.toFixed(1)}°)`);

  // Choke point markers
  const chokeG = svg.append("g")
    .selectAll("g")
    .data(chokepoints)
    .join("g")
    .attr("transform", d => {
      const p = projection([d.lng, d.lat]);
      return p ? `translate(${p[0]},${p[1]})` : `translate(-100,-100)`;
    });

  // Outer ring
  chokeG.append("circle")
    .attr("r", 10)
    .attr("fill", "none")
    .attr("stroke", "#ff9800")
    .attr("stroke-width", 2)
    .attr("opacity", 0.7);

  // Inner dot
  chokeG.append("circle")
    .attr("r", 3)
    .attr("fill", "#ff9800")
    .attr("opacity", 0.9);

  // Tooltip
  chokeG.append("title")
    .text(d => `${d.name} — ${d.context}`);

  // Labels
  chokeG.append("text")
    .attr("x", 14)
    .attr("y", 4)
    .attr("font-size", "8px")
    .attr("font-family", "'Source Sans 3', sans-serif")
    .attr("font-weight", "600")
    .attr("fill", "#e65100")
    .text(d => d.name);

  // Legend
  const legend = svg.append("g")
    .attr("transform", `translate(20, ${height - 80})`);

  legend.append("rect")
    .attr("width", 180).attr("height", 70)
    .attr("fill", "white").attr("opacity", 0.85)
    .attr("rx", 4);

  // Conflict dot legend
  legend.append("circle").attr("cx", 15).attr("cy", 15).attr("r", 5)
    .attr("fill", "#e53935").attr("opacity", 0.5);
  legend.append("text").attr("x", 28).attr("y", 19)
    .attr("font-size", "10px").attr("fill", "#333")
    .text("Conflict events");

  // Choke point legend
  legend.append("circle").attr("cx", 15).attr("cy", 35).attr("r", 6)
    .attr("fill", "none").attr("stroke", "#ff9800").attr("stroke-width", 2);
  legend.append("circle").attr("cx", 15).attr("cy", 35).attr("r", 2)
    .attr("fill", "#ff9800");
  legend.append("text").attr("x", 28).attr("y", 39)
    .attr("font-size", "10px").attr("fill", "#333")
    .text("Maritime choke point");

  // Size legend
  legend.append("circle").attr("cx", 10).attr("cy", 55).attr("r", 2)
    .attr("fill", "#e53935").attr("opacity", 0.5);
  legend.append("circle").attr("cx", 25).attr("cy", 55).attr("r", 4)
    .attr("fill", "#e53935").attr("opacity", 0.5);
  legend.append("circle").attr("cx", 45).attr("cy", 55).attr("r", 7)
    .attr("fill", "#e53935").attr("opacity", 0.5);
  legend.append("text").attr("x", 60).attr("y", 59)
    .attr("font-size", "9px").attr("fill", "#666")
    .text("Size = event count");

  return svg.node();
}
TipWhat to look for

In periods of low trade openness, conflict events cluster more densely near choke points. When trade is booming, this clustering weakens — consistent with the idea that major powers have stronger incentives to keep routes secure.

The paper proposes a game-theoretic mechanism that may explain this clustering. Next: The Mechanism

 

Gallea & Rohner, PNAS 2021 · Paper · Replication Data