les tronçons de centralité fonctionnelle
Second essai de la requête en étant plus sélectif
| Fonctionnel | Paramètres géométriques | ||
| Niveau 1 | Centre Urbain | Présence continue ou presque d'activités commerciales / tertiaires / équipements publics / espaces publics |
présence d'au moins 18 items pour chaque linéaire de voie de 200 mètres
|
| Niveau 2 | Centre Local | Agrégations de fonctionnalités commerciales ou tertiaires couplées à un intensité démographique INSEE Carroyé |
présence d'au moins 10 items pour chaque linéaire de voie de 200 mètres
|
| Niveau 3 | Noyau de vie quotidienne | Ponctualité de services formant une centralité | présence de 8 items dans un rayon de 200 mètres |
| Niveau 4 | Espaces Résidentiels | Restent des zones agglomérées OSM ne figurant dans aucun des 3 premiers niveaux | autres |
-------------------------------------------------------------------------------------
Encore une subtilité de PostGIS ! L'erreur Only lon/lat coordinate systems are supported in geography est très parlante quand on connaît le moteur interne de la base de données.
Explication de l'erreur : Dans la base OSM de votre VPS, les géométries (l.way) sont stockées nativement en "Web Mercator" (EPSG:3857, le système de Google Maps), dont les coordonnées sont déjà exprimées en mètres (et non en degrés de longitude/latitude). Or, quand on utilise la fonction ::geography pour obtenir une distance ultra-précise (qui prend en compte la courbure de la Terre), PostgreSQL exige que la donnée source soit en Longitude/Latitude (EPSG:4326).
Il suffit donc de transformer la géométrie en 4326 juste avant de la passer en geography.
Voici la requête avec la petite correction magique ST_Transform(l.way, 4326) intégrée au calcul de longueur.
La Requête SQL (La Bonne !)
DROP TABLE IF EXISTS toulon_hierarchie_fonctionnelle;
CREATE TABLE toulon_hierarchie_fonctionnelle AS
WITH stats_troncons AS (
SELECT
f.osm_id,
f.nom_voie,
f.code_pattern,
COUNT(i.osm_id) as total_items,
-- On transforme d'abord en 4326 (lon/lat) pour que la conversion geography fonctionne parfaitement
ST_Length(ST_Transform(l.way, 4326)::geography) as longueur_rue_m,
-- Calcul de la densité pour 200m
CASE
WHEN ST_Length(ST_Transform(l.way, 4326)::geography) > 0
THEN (COUNT(i.osm_id)::numeric / ST_Length(ST_Transform(l.way, 4326)::geography)::numeric) * 200
ELSE 0
END as items_pour_200m,
f.geom
FROM zones_motifs_filaires f
JOIN planet_osm_line l ON f.osm_id = l.osm_id
LEFT JOIN toulon_items_nomenclature_full i ON ST_Intersects(ST_Transform(i.geom, 3857), f.geom)
GROUP BY f.osm_id, f.nom_voie, f.code_pattern, f.geom, l.way
),
classification AS (
SELECT
osm_id, nom_voie, code_pattern, total_items,
ROUND(longueur_rue_m::numeric) as longueur_rue_m,
ROUND(items_pour_200m::numeric, 1) as items_pour_200m,
geom,
CASE
-- NIVEAU 1 : Centre Urbain (>= 10 items pour un linéaire de 200m)
WHEN items_pour_200m >= 10 THEN 1
-- NIVEAU 2 : Centre Local (>= 5 items pour un linéaire de 200m)
WHEN items_pour_200m >= 5 THEN 2
-- NIVEAU 3 : Noyau de vie quotidienne (5 items ou plus sur le tronçon)
WHEN total_items >= 5 THEN 3
-- NIVEAU 4 : Espaces Résidentiels (le reste)
ELSE 4
END as niveau_fonctionnel
FROM stats_troncons
)
SELECT * FROM classification
WHERE niveau_fonctionnel < 4;
CREATE INDEX idx_hierarchie_geom ON toulon_hierarchie_fonctionnelle USING GIST(geom);
Exportation
Puis vous pouvez relancer l'export avec la commande que l'on connaît bien maintenant (après avoir fait \q) :
sudo -u postgres ogr2ogr -f "GPKG" \
"/tmp/Toulon_Hierarchie_Fonctionnelle.gpkg" \
PG:"dbname=alteris_db" \
"toulon_hierarchie_fonctionnelle" && \
sudo mv /tmp/Toulon_Hierarchie_Fonctionnelle.gpkg /home/debian/osm_data/ && \
sudo chown debian:debian /home/debian/osm_data/Toulon_Hierarchie_Fonctionnelle.gpkg
Cette fois-ci, le calcul mathématique de la longueur devrait passer sans aucune erreur et générer votre cartographie des Niveaux 1, 2 et 3 !
Est-ce que la requête s'est bien exécutée cette fois ? J'ai hâte de savoir comment Toulon "réagit" à vos seuils stricts !