feat(lang): routage préfixé /fr/ et /en/ avec redirect JS langue sur les chemins non préfixés
- page-redirect sur / et tous les chemins sans préfixe : localStorage zektyc-lang puis navigator.language, défaut fr ; fallback FR si la page n'a pas de version EN - /en/ sert enfin la home EN (public/en/), fix de LANG_ROUTES.en - home EN générée à partir d'i18n.json (ld+json Organization/FAQPage valides) - i18n.js/components.js : switch de langue par préfixe + liens préfixés - anciennes URLs /zmap/en/* : 301 vers /en/zmap/* ; pages EN zmap déplacées vers le layout <page>/en/ standard - canonicals/hreflang fr-en-x-default sur toutes les pages statiques + sitemaps (équipe, zmap, archives, vitesses-par-route ajoutées) ; suppression du domaine obsolète zektyc.duckdns.org (robots, sitemap index, security.txt)
This commit is contained in:
parent
e0811492fa
commit
d1c994bc7f
30 changed files with 566 additions and 124 deletions
207
public/zmap/road-speeds/en/index.html
Normal file
207
public/zmap/road-speeds/en/index.html
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="ZMap's per-road speed database: 90.5 million sampled points, 3.6 million km of roads mapped with their speed limit (OpenStreetMap), across all of Europe." />
|
||||
<meta name="robots" content="index, follow" />
|
||||
<title>Per-road speeds · ZMap · Zektyc</title>
|
||||
<link rel="canonical" href="https://riricdev.tail5ea5cd.ts.net/en/zmap/road-speeds/" />
|
||||
<link rel="alternate" hreflang="fr" href="https://riricdev.tail5ea5cd.ts.net/fr/zmap/vitesses-par-route/" />
|
||||
<link rel="alternate" hreflang="en" href="https://riricdev.tail5ea5cd.ts.net/en/zmap/road-speeds/" />
|
||||
<link rel="alternate" hreflang="x-default" href="https://riricdev.tail5ea5cd.ts.net/fr/zmap/vitesses-par-route/" />
|
||||
<meta name="theme-color" content="#070a0f" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:site_name" content="Zektyc" />
|
||||
<meta property="og:title" content="Per-road speeds · ZMap" />
|
||||
<meta property="og:description" content="ZMap knows the speed limit of every road in Europe: 90.5 million points, 3.6 million km, built from OpenStreetMap data." />
|
||||
<meta property="og:url" content="https://riricdev.tail5ea5cd.ts.net/en/zmap/road-speeds/" />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:locale:alternate" content="fr_FR" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/css/style.css?v=8" />
|
||||
<style>
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 12px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
.stat {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 10px;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
.stat b {
|
||||
display: block;
|
||||
font-size: 1.7em;
|
||||
line-height: 1.2;
|
||||
color: var(--accent, #4dd6a8);
|
||||
}
|
||||
.stat span {
|
||||
font-size: 0.85em;
|
||||
opacity: 0.7;
|
||||
}
|
||||
table.speeds {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
}
|
||||
table.speeds th,
|
||||
table.speeds td {
|
||||
text-align: right;
|
||||
padding: 6px 10px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
table.speeds th:first-child,
|
||||
table.speeds td:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
.bar {
|
||||
display: inline-block;
|
||||
height: 10px;
|
||||
border-radius: 3px;
|
||||
background: var(--accent, #4dd6a8);
|
||||
vertical-align: middle;
|
||||
}
|
||||
code {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
padding: 1px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header id="h"></header>
|
||||
|
||||
<main class="legal" id="main">
|
||||
<p class="legal-note"><a href="/zmap/en/">← Back to ZMap</a></p>
|
||||
<h1>Per-road speeds</h1>
|
||||
<p class="legal-meta">
|
||||
ZMap's internal database · how it is built and what it contains
|
||||
</p>
|
||||
|
||||
<div class="dev-banner">
|
||||
🧭 <strong>Navigation feature.</strong> ZMap snaps every point of your
|
||||
route to its actual road and reads its speed limit from a local database
|
||||
covering all of Europe — then keeps it cached on your phone for offline
|
||||
driving.
|
||||
</div>
|
||||
|
||||
<section class="projects-page">
|
||||
<article class="card">
|
||||
<h3>The idea</h3>
|
||||
<p>
|
||||
Most navigation apps need a connection to know the speed limit. ZMap
|
||||
does it differently: a per-road speed-limit database is built from
|
||||
OpenStreetMap data and lives on the server. When a route is computed,
|
||||
each trip point is snapped to the nearest road and given its speed.
|
||||
The full route — speeds included — is then cached on the phone: while
|
||||
driving, no network request is needed.
|
||||
</p>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat"><b>90.5M</b><span>sampled points</span></div>
|
||||
<div class="stat"><b>3.6M km</b><span>of roads with a known speed</span></div>
|
||||
<div class="stat"><b>5,104</b><span>cells of 0.5° × 0.5°</span></div>
|
||||
<div class="stat"><b>370 MB</b><span>compressed grid (gzip)</span></div>
|
||||
<div class="stat"><b>40 m</b><span>sampling step along roads</span></div>
|
||||
<div class="stat"><b>5 B</b><span>per point (lon, lat, speed)</span></div>
|
||||
</div>
|
||||
|
||||
<section class="projects-page">
|
||||
<article class="card">
|
||||
<h3>How it is built</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Source:</strong> the OpenStreetMap Europe extract
|
||||
(Geofabrik, 34.8 GB) contains 98.2 million roads
|
||||
(<code>highway</code>).
|
||||
</li>
|
||||
<li>
|
||||
<strong>Filtering:</strong> <code>osmium tags-filter</code> keeps
|
||||
only the roads (8.5 GB), then only those carrying a speed
|
||||
(<code>maxspeed</code>) are kept — about 13 million.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Sampling:</strong> a point is placed every 40 metres along
|
||||
each road, with its speed in km/h.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Indexing:</strong> Europe is split into 0.5° cells
|
||||
(≈ 55 km), each subdivided into 32 × 32. Every point is quantized
|
||||
to ≈ 0.76 m and stored in 5 bytes, then the cell is gzip-compressed:
|
||||
90.5 million points in 370 MB total.
|
||||
</li>
|
||||
</ol>
|
||||
<p>
|
||||
It is fully reproducible: the build script
|
||||
(<code>build_maxspeed.py</code>) runs end to end on a small server.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h3>What is inside</h3>
|
||||
<p>
|
||||
Share of points by speed limit (most common values) :
|
||||
</p>
|
||||
<table class="speeds">
|
||||
<tr><th>Limit</th><th>Share</th><th></th></tr>
|
||||
<tr><td>50 km/h</td><td>26.2%</td><td><span class="bar" style="width:100%"></span></td></tr>
|
||||
<tr><td>30 km/h (30 zones)</td><td>18.5%</td><td><span class="bar" style="width:71%"></span></td></tr>
|
||||
<tr><td>90 km/h</td><td>9.5%</td><td><span class="bar" style="width:36%"></span></td></tr>
|
||||
<tr><td>80 km/h</td><td>9.2%</td><td><span class="bar" style="width:35%"></span></td></tr>
|
||||
<tr><td>70 km/h</td><td>6.0%</td><td><span class="bar" style="width:23%"></span></td></tr>
|
||||
<tr><td>60 km/h</td><td>5.7%</td><td><span class="bar" style="width:22%"></span></td></tr>
|
||||
<tr><td>100 km/h</td><td>4.6%</td><td><span class="bar" style="width:18%"></span></td></tr>
|
||||
<tr><td>40 km/h</td><td>3.3%</td><td><span class="bar" style="width:13%"></span></td></tr>
|
||||
<tr><td>48 km/h (30 mph, UK)</td><td>2.8%</td><td><span class="bar" style="width:11%"></span></td></tr>
|
||||
<tr><td>97 km/h (60 mph, UK)</td><td>2.4%</td><td><span class="bar" style="width:9%"></span></td></tr>
|
||||
<tr><td>32 km/h (20 mph, UK)</td><td>2.1%</td><td><span class="bar" style="width:8%"></span></td></tr>
|
||||
<tr><td>20 km/h (pedestrian zones)</td><td>2.1%</td><td><span class="bar" style="width:8%"></span></td></tr>
|
||||
<tr><td>120 km/h</td><td>1.8%</td><td><span class="bar" style="width:7%"></span></td></tr>
|
||||
<tr><td>130 km/h (motorways)</td><td>1.7%</td><td><span class="bar" style="width:6%"></span></td></tr>
|
||||
<tr><td>110 km/h</td><td>1.4%</td><td><span class="bar" style="width:5%"></span></td></tr>
|
||||
</table>
|
||||
<p class="legal-note">
|
||||
<em>Numeric</em> values found in OpenStreetMap. Actual limits may
|
||||
differ (roadworks, temporary signs, weather). Roads with no limit
|
||||
(e.g. some German sections) have no <code>maxspeed</code>: ZMap then
|
||||
shows no speed.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h3>In the app</h3>
|
||||
<p>
|
||||
The server returns, with every route, an array of speeds aligned with
|
||||
the geometry points (one value per point). The phone stores
|
||||
everything in its local cache: while driving, the current section's
|
||||
limit is read without network, and offline mode keeps the whole trip.
|
||||
Snapping a 4,500-point route takes about 170 ms on the server.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h3>Accuracy and coverage</h3>
|
||||
<ul>
|
||||
<li>Coverage: all of Europe, longitude −12° to 46°, latitude 27° to 72°.</li>
|
||||
<li>Snapping: the nearest road within 40 m of the point.</li>
|
||||
<li>Point location accuracy: ≈ 0.76 m.</li>
|
||||
<li>Data: OpenStreetMap, free (ODbL licence).</li>
|
||||
</ul>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer id="f"></footer>
|
||||
<script src="/js/theme.js" defer></script>
|
||||
<script src="/js/components.js?v=6" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue