# Méthodologie de Production

Itérations pour mettre en place une étude territoriale Alteris

# Les trames du territoire à travers OSM

# 02 - Première trame - les filaires

[Renvoi à cette fiche d'exemple - cas de Toulon - en mars 2026](https://bookstack.alteris.ovh/books/origine-et-nature-des-bases-de-donnees/page/essai-83137-delimitation-automatique-des-centralites-fonctionnelles)

Vérification de la présence des tags maxspped dans la version OSM Geofabrick  
sudo docker exec -it alteris\_postgis psql -U alteris\_admin -d alteris\_geo -c "SELECT count(\*) FROM osm\_raw.roads WHERE tags ? 'maxspeed';"

\-------  
 91439  
(1 row)

A/ Creer les filaires

#### **c13028\_laciotat.c13028\_filaires** 

```
sudo docker exec -it alteris_postgis psql -U alteris_admin -d alteris_geo -c "
-- 1. Nettoyage
DROP TABLE IF EXISTS c13028_laciotat.c13028_filaires_v3 CASCADE;

-- 2. Création de la couche avec ta logique 'Toulon'
CREATE TABLE c13028_laciotat.c13028_filaires_v3 AS
WITH extraction AS (
    SELECT 
        osm_id,
        name AS nom_voie,
        highway AS type_osm,
        tags->'lanes' AS nb_voies,
        tags->'maxspeed' AS vitesse_max,
        ST_Transform(way, 2154) AS geom_ligne
    FROM osm_raw.roads
    WHERE highway IS NOT NULL
    AND ST_Intersects(way, (SELECT ST_Union(way) FROM osm_raw.buildings WHERE name = 'La Ciotat' AND admin_level = '8'))
),
classification AS (
    SELECT 
        osm_id, nom_voie, type_osm, geom_ligne,
        CASE 
            -- Transit Lourd (T1 & T2)
            WHEN type_osm IN ('motorway', 'motorway_link') THEN 'F_T1'
            WHEN type_osm IN ('trunk', 'trunk_link') THEN 'F_T2'
            
            -- Transit Urbain (T3) : La complexité que tu voulais garder
            WHEN type_osm IN ('primary', 'secondary') 
                 AND (nb_voies IN ('3', '4', '5', '6', '7', '8') 
                      OR vitesse_max IN ('70', '80', '90', '110', '130')) 
            THEN 'F_T3'
            
            -- Desserte (D1, D2, D3)
            WHEN type_osm = 'primary' THEN 'F_D1' 
            WHEN type_osm = 'secondary' THEN 'F_D2'
            WHEN type_osm IN ('pedestrian', 'living_street') THEN 'F_D3'
            
            -- Local (L1, L2, L3)
            WHEN type_osm IN ('tertiary', 'residential') THEN 'F_L1'
            WHEN type_osm = 'unclassified' THEN 'F_L2'
            ELSE 'F_L3'
        END as code_pattern
    FROM extraction
)
SELECT 
    osm_id, 
    nom_voie, 
    code_pattern,
    ST_Buffer(geom_ligne, 
        CASE 
            WHEN code_pattern = 'F_T1' THEN 100
            WHEN code_pattern = 'F_T2' THEN 75
            WHEN code_pattern = 'F_T3' THEN 50
            WHEN code_pattern = 'F_D1' THEN 50
            WHEN code_pattern = 'F_D2' THEN 35
            WHEN code_pattern = 'F_D3' THEN 35
            WHEN code_pattern = 'F_L1' THEN 25
            ELSE 10 
        END
    )::geometry(Polygon, 2154) as geom
FROM classification;

-- 3. Indexation spatiale
CREATE INDEX idx_c13028_filaires_v3_geom ON c13028_laciotat.c13028_filaires_v3 USING GIST(geom);
"
```

```
sudo docker exec -it alteris_postgis psql -U alteris_admin -d alteris_geo -c "
SELECT code_pattern, count(*) 
FROM c13028_laciotat.c13028_filaires_v3 
GROUP BY code_pattern 
ORDER BY code_pattern;"
```

  
 code\_pattern | count  
\--------------+-------  
 F\_D1 | 96  
 F\_D2 | 179  
 F\_D3 | 67  
 F\_L1 | 1129  
 F\_L2 | 148  
 F\_L3 | 3302  
 F\_T1 | 40  
 F\_T3 | 42  
(8 rows)

# 0_Résumé et commandes CLI du GIS Alteris

1/ PostGIS sur le VPS d'Alteris est un containeur Docker   
  
Ses caractéristiques

POSTGRES\_USER: alteris\_admin

POSTGRES\_PASSWORD: Alteris2026

POSTGRES\_DB: alteris\_geo

POSTGRES\_CONTAINEUR alteris\_postgis

2/ Commande CLI pour lister les bases de données contenues dans le PostGIS

```
sudo docker exec -it alteris_postgis psql -U alteris_admin -d alteris_geo -c "
SELECT 
    relname AS table_name, 
    pg_size_pretty(pg_total_relation_size(relid)) AS taille, 
    n_live_tup AS nb_lignes,
    (SELECT type FROM geometry_columns WHERE f_table_name = relname LIMIT 1) as geom_type
FROM pg_stat_user_tables 
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(relid) DESC;"
```

3/ commande cli pour obtenir la taille d'un répertoire

  
debian@vps-02c1f983-vps-ovh-net:~$ # -s (summary) -h (human readable)  
du -sh /home/debian/data/Regions/93/13/200054807/13028/

245M /home/debian/data/Regions/93/13/200054807/13028/  
debian@vps-02c1f983-vps-ovh-net:~$

<table id="bkmrk-fichier-%2F-dossier-ta" style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 32px 0px;"><thead style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-header-group;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgb(239,239,239) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**Fichier / Dossier**</td><td style="background:rgb(239,239,239) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**Taille**</td><td style="background:rgb(239,239,239) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**Statut Alteris**</td></tr></thead><tbody style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row-group;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`carreaux_200m_met.gpkg`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**1,1 Go**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**À garder.** C'est le carroyage Insee (Filosofi) indispensable pour tes analyses de population à fine échelle.</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`Base Adresse Paca.gpkg`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**635 Mo**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**À garder.** C'est la BAN (Base Adresse Nationale), cruciale pour le géocodage et la précision des bâtiments.</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`Recensement 13 Insee.csv`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**230 Mo**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**À vérifier.** C'est le détail du recensement pour le département 13.</span></td></tr></tbody></table>

du -ah /home/debian/data/Regions/93 | sort -rh | head -n 15

debian@vps-02c1f983-vps-ovh-net:~$ du -ah /home/debian/data/Regions/93 | sort -rh | head -n 15  
2.3G /home/debian/data/Regions/93  
1.1G /home/debian/data/Regions/93/carreaux\_200m\_met.gpkg  
646M /home/debian/data/Regions/93/BDTOPO V1  
635M /home/debian/data/Regions/93/BDTOPO V1/Base Adresse Paca.gpkg  
529M /home/debian/data/Regions/93/13  
246M /home/debian/data/Regions/93/13/200054807  
245M /home/debian/data/Regions/93/13/200054807/13028  
230M /home/debian/data/Regions/93/13/Recensement 13 Insee.csv  
184M /home/debian/data/Regions/93/13/200054807/13028/lidar  
59M /home/debian/data/Regions/93/13/200054807/13028/Archives/Etude\_LaCiotat\_2026-04-02.gpkg  
59M /home/debian/data/Regions/93/13/200054807/13028/Archives  
25M /home/debian/data/Regions/93/13/MobPro13.csv  
19M /home/debian/data/Regions/93/13/Filosofi 13.gpkg  
16M /home/debian/data/Regions/93/13/200054807/13028/lidar/LHD\_FXX\_0914\_6237\_MNT\_O\_0M50\_LAMB93\_IGN69.tif  
16M /home/debian/data/Regions/93/13/200054807/13028/lidar/LHD\_FXX\_0913\_6237\_MNT\_O\_0M50\_LAMB93\_IGN69.tif  
debian@vps-02c1f983-vps-ovh-net:~$

# 01_Actualisations des bases de données Geometries dans PostGIS (OSM, IRIS)

#### **1/ actualisation OSM - exercice du 260402**

provence-alpes-cote 100%\[===================&gt;\] 363.10M 34.6MB/s in 11s

```
# 1. Création de l'arborescence (le -p crée les parents si besoin)
mkdir -p /home/debian/data/Regions/93/OSM_93

# 2. On se déplace dans le dossier cible
cd /home/debian/data/Regions/93/OSM_93

# 3. Téléchargement du fichier de la Région PACA
# Note : C'est le fichier qui contient La Ciotat
wget https://download.geofabrik.de/europe/france/provence-alpes-cote-d-azur-latest.osm.pbf
```

Pour éviter de retomber sur l'erreur `column "highway" does not exist`, nous allons utiliser une commande `osm2pgsql` qui force l'extraction des colonnes standards (style par défaut) et active le **hstore** (pour stocker tous les autres tags dans un champ flexible).

Nécessité d'installer osm2pgsql directement dans le VPS car outil indisponible sur Docker

[https://osm2pgsql.org/](https://osm2pgsql.org/) (version 1.8.0)

#### **2/ SCRIPT DE TRANSFERT OSM PACA VERS PUBLIC DANS POSTGIS**

**compter 6 minutes.**

```
osm2pgsql -d alteris_geo -U alteris_admin -H localhost -P 5432 -W \
  --slim \
  --hstore \
  --multi-geometry \
  --number-processes 2 \
  /home/debian/data/Regions/93/OSM_93/provence-alpes-cote-d-azur-latest.osm.pbf
```

##### 1. La Source (Le fichier .pbf)

Tu as bien fait de télécharger sur **Geofabrik**. C'est le dépôt de référence qui découpe la "Planet OSM" (le monde entier) en morceaux digestes (comme la Région PACA). Ton fichier `/home/debian/data/Regions/93/OSM_93/provence-alpes-cote-d-azur-latest.osm.pbf` est parfait.

##### 2. L'Outil (Le traducteur)

L'image Docker `osm2pgsql/osm2pgsql` va lire ce fichier et "traduire" les données OpenStreetMap (points, lignes, polygones) en tables SQL exploitables par Alteris.

##### 3. La Destination (Les tables dans PostgreSQL)

Par convention historique, cet outil nomme toujours les tables créées avec le préfixe `planet_osm_`. C'est là que tu retrouveras :

- `planet_osm_line` (qui deviendra ton réservoir pour les **filaires**).
- `planet_osm_point` (tes futurs équipements/écoles).
- `planet_osm_polygon` (tes bâtis et zones végétalisées).

##### Résumé du flux de travail Alteris

1. **Extraction** : Tu as récupéré le PBF chez Geofabrik.
2. **Injection** : Tu lances la commande Docker `osm2pgsql`.
3. **Rangement** : On renomme `planet_osm_line` en `osm_raw.roads` (pour que ton script de filaires fonctionne).

Résultat du transfert pour comparaison

```
debian@vps-02c1f983-vps-ovh-net:~/data/Regions/93/OSM_93$ sudo docker exec -it a                                                                                                             lteris_postgis psql -U alteris_admin -d alteris_geo -c "CREATE EXTENSION IF NOT                                                                                                              EXISTS hstore;"
CREATE EXTENSION
debian@vps-02c1f983-vps-ovh-net:~/data/Regions/93/OSM_93$ osm2pgsql -d alteris_g                                                                                                             eo -U alteris_admin -H localhost -P 5432 -W \
  --slim \
  --hstore \
  --multi-geometry \
  --number-processes 2 \
  /home/debian/data/Regions/93/OSM_93/provence-alpes-cote-d-azur-latest.osm.pbf
2026-04-02 07:57:46  osm2pgsql version 1.8.0
Password:
2026-04-02 07:57:54  Database version: 15.4 (Debian 15.4-1.pgdg110+1)
2026-04-02 07:57:54  PostGIS version: 3.3
2026-04-02 07:57:54  Setting up table 'planet_osm_point'
2026-04-02 07:57:54  Setting up table 'planet_osm_line'
2026-04-02 07:57:54  Setting up table 'planet_osm_polygon'
2026-04-02 07:57:54  Setting up table 'planet_osm_roads'
                                                                                                                                                                                             2026-04-02 08:01:35  Reading input files done in 221s (3m 41s).
2026-04-02 08:01:35    Processed 39612462 nodes in 75s (1m 15s) - 528k/s
2026-04-02 08:01:35    Processed 5322338 ways in 108s (1m 48s) - 49k/s
2026-04-02 08:01:35    Processed 52147 relations in 38s - 1k/s
2026-04-02 08:01:35  Clustering table 'planet_osm_line' by geometry...
2026-04-02 08:01:35  Clustering table 'planet_osm_point' by geometry...
2026-04-02 08:01:42  Creating geometry index on table 'planet_osm_point'...
2026-04-02 08:01:44  Creating osm_id index on table 'planet_osm_point'...
2026-04-02 08:01:45  Analyzing table 'planet_osm_point'...
2026-04-02 08:01:45  Clustering table 'planet_osm_polygon' by geometry...
2026-04-02 08:01:48  Creating geometry index on table 'planet_osm_line'...
2026-04-02 08:01:51  Creating osm_id index on table 'planet_osm_line'...
2026-04-02 08:01:53  Analyzing table 'planet_osm_line'...
2026-04-02 08:01:53  Clustering table 'planet_osm_roads' by geometry...
2026-04-02 08:01:55  Creating geometry index on table 'planet_osm_roads'...
2026-04-02 08:01:55  Creating osm_id index on table 'planet_osm_roads'...
2026-04-02 08:01:55  Analyzing table 'planet_osm_roads'...
2026-04-02 08:01:56  Done postprocessing on table 'planet_osm_nodes' in 0s
2026-04-02 08:01:56  Building index on table 'planet_osm_ways'
2026-04-02 08:02:11  Creating geometry index on table 'planet_osm_polygon'...
2026-04-02 08:02:21  Creating osm_id index on table 'planet_osm_polygon'...
2026-04-02 08:02:23  Analyzing table 'planet_osm_polygon'...
2026-04-02 08:02:23  Building index on table 'planet_osm_rels'
2026-04-02 08:03:14  Done postprocessing on table 'planet_osm_ways' in 78s (1m 18s)
2026-04-02 08:03:14  Done postprocessing on table 'planet_osm_rels' in 2s
2026-04-02 08:03:14  All postprocessing on table 'planet_osm_point' done in 10s.
2026-04-02 08:03:14  All postprocessing on table 'planet_osm_line' done in 17s.
2026-04-02 08:03:14  All postprocessing on table 'planet_osm_polygon' done in 37s.
2026-04-02 08:03:14  All postprocessing on table 'planet_osm_roads' done in 2s.
2026-04-02 08:03:14  osm2pgsql took 319s (5m 19s) overall.
debian@vps-02c1f983-vps-ovh-net:~/data/Regions/93/OSM_93$

```

#### **3/ BASCULEMENT OSM PACA VERS OSM\_RAW DANS POSTGIS**

```
sudo docker exec -it alteris_postgis psql -U alteris_admin -d alteris_geo -c "
-- 1. On s'assure que le schéma cible existe
CREATE SCHEMA IF NOT EXISTS osm_raw;

-- 2. On supprime les vieux restes pour éviter les conflits
DROP TABLE IF EXISTS osm_raw.roads CASCADE;
DROP TABLE IF EXISTS osm_raw.points CASCADE;
DROP TABLE IF EXISTS osm_raw.buildings CASCADE;
DROP TABLE IF EXISTS osm_raw.transit_major CASCADE;

-- 3. On bascule les nouvelles tables vers osm_raw
ALTER TABLE public.planet_osm_line SET SCHEMA osm_raw;
ALTER TABLE public.planet_osm_point SET SCHEMA osm_raw;
ALTER TABLE public.planet_osm_polygon SET SCHEMA osm_raw;
ALTER TABLE public.planet_osm_roads SET SCHEMA osm_raw;

-- 4. Renommage pour une nomenclature propre
ALTER TABLE osm_raw.planet_osm_line RENAME TO roads;
ALTER TABLE osm_raw.planet_osm_point RENAME TO points;
ALTER TABLE osm_raw.planet_osm_polygon RENAME TO buildings;
ALTER TABLE osm_raw.planet_osm_roads RENAME TO transit_major;
"
```

##### **4/ FAIRE L'INVENTAIRE DE OSM\_RAW**

```
sudo docker exec -it alteris_postgis psql -U alteris_admin -d alteris_geo -c "
SELECT 
    relname AS table_name, 
    pg_size_pretty(pg_total_relation_size(c.oid)) AS taille
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'osm_raw'
  AND c.relkind = 'r'
ORDER BY pg_total_relation_size(c.oid) DESC;
"
```

<table id="bkmrk-rang-table-usage-alt" style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 32px 0px;"><thead style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-header-group;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgb(239,239,239) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**Rang**</td><td style="background:rgb(239,239,239) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**Table**</td><td style="background:rgb(239,239,239) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**Usage Alteris**</td></tr></thead><tbody style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row-group;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">1</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`buildings`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Emprises bâties et limites administratives (La Ciotat est dedans).</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">2</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`roads`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Réseau routier complet (La source de tes filaires).</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">3</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`points`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Équipements, services, commerces.</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">4</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`landuse`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Occupation du sol (Zones industrielles, parcs, forêts).</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">5</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`transit_major`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Grands axes structurants (pour cartographie grand angle).</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">6</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`pois`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Points d'intérêt spécifiques (doublon partiel de `points`).</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">7</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`waterways`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Rivières, canaux, fossés.</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">8</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`water`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Plans d'eau, bassins, mer.</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">9</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`railways`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Réseau ferré (Barrière physique majeure pour I-T6-01).</span></td></tr><tr style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:table-row;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">10</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 12px 16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">**`places`**</span></td><td style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;clear:none;color:rgb(31,31,31);direction:ltr;display:table-cell;float:none;opacity:1;padding:16px 0px;visibility:visible;border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;"><span style="background:rgba(0,0,0,0) none repeat scroll 0% 0%;border:0px none rgb(31,31,31);clear:none;color:rgb(31,31,31);direction:ltr;display:inline;float:none;opacity:1;padding:0px;visibility:visible;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin:0px 0px 0px 0px;">Noms de quartiers, lieux-dits et communes.</span></td></tr></tbody></table>

 table\_name | taille  
\---------------+---------  
 buildings | 1374 MB  
 roads | 625 MB  
 points | 232 MB  
 landuse | 131 MB  
 transit\_major | 64 MB  
 pois | 64 MB  
 waterways | 29 MB  
 water | 14 MB  
 railways | 3680 kB  
 places | 2920 kB  
(10 rows)

<table id="bkmrk-cat%C3%A9gorie-tables-inc" style="margin-bottom:32px;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><thead style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><tr style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**Catégorie**</td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**Tables incluses**</td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**Poids estimé**</td></tr></thead><tbody style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><tr style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**Gros volumes**</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">`buildings` + `roads`</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">~2 000 MB</span></td></tr><tr style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**Moyens volumes**</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">`points` + `landuse`</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">~363 MB</span></td></tr><tr style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**Volumes légers**</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">`transit_major`, `pois`, `waterways`, `water`</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">~171 MB</span></td></tr><tr style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**Petits volumes**</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">`railways`, `places`</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">~6 MB</span></td></tr><tr style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**TOTAL**</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**Miroir OSM PACA**</span></td><td style="border:1px solid;font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;"><span style="font-family:'Google Sans Text', sans-serif;line-height:1.15;margin-top:0px;">**~2,54 GB**</span></td></tr></tbody></table>

```

debian@vps-02c1f983-vps-ovh-net:~$
debian@vps-02c1f983-vps-ovh-net:~$ sudo docker exec -it alteris_postgis psql -U alteris_admin -d alteris_geo -c "
SELECT pg_size_pretty(SUM(pg_total_relation_size(c.oid))) AS poids_total_osm_raw
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'osm_raw'
  AND c.relkind = 'r';
"
```

\-------------------------  
 poids\_total\_osm\_raw  
\---------------------  
 2539 MB  
(1 row)

debian@vps-02c1f983-vps-ovh-net:~$

### Transfert des contours IRIS dans insee\_raw   
  


Pour ne pas réinventer la roue et éviter les galères de mot de passe ou de drivers manquants, voici la **méthode "Golden"** que nous avons validée.

L'astuce consiste à utiliser **le binaire du VPS (ton host)** pour lire le fichier et **injecter le résultat dans le Docker** via un "pipe" (flux). C'est la méthode la plus robuste car elle ne dépend pas de la configuration interne du conteneur.

---

### 🚀 La Méthode "Standard" (à copier-coller)

Voici la commande universelle pour recharger tes couches SIG :

<div class="code-block ng-tns-c2968650486-3705 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-3705 ng-star-inserted"><span class="ng-tns-c2968650486-3705">Bash</span><div class="buttons ng-tns-c2968650486-3705 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-3705"><div class="animated-opacity ng-tns-c2968650486-3705">  
</div></div></div>```
# 1. On génère le SQL depuis le fichier local
# 2. On l'injecte dans le psql du Docker
ogr2ogr -f PGDump /vsistdout/ "/home/debian/data/contours-iris-pe.gpkg" \
  -nln insee_raw.contours_iris_2025 \
  -lco OVERWRITE=YES \
  -lco GEOMETRY_NAME=geom \
  -lco DROP_TABLE=YES \
  -nlt PROMOTE_TO_MULTI | docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo

```

<div class="code-block ng-tns-c2968650486-3705 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--2"><div class="formatted-code-block-internal-container ng-tns-c2968650486-3705"><div class="animated-opacity ng-tns-c2968650486-3705"></div></div></div>---

### 🧠 Pourquoi cette méthode gagne à tous les coups ?

1. **Indépendance des Drivers** : Tu utilises le `ogr2ogr` de ton Debian (GDAL 3.6.2), qui est beaucoup plus complet et à jour que celui souvent pré-installé dans les images Docker.
2. **Bypass du Mot de Passe** : En envoyant le flux vers `docker exec -i ... psql`, tu profites de l'authentification "peer" ou de l'absence de mot de passe interne du conteneur. Plus besoin de `PGPASSWORD`.
3. **Propreté (OVERWRITE/DROP)** : L'option `-lco DROP_TABLE=YES` et `-lco OVERWRITE=YES` garantit que tu ne crées pas de doublons et que tu nettoies les restes d'une couche corrompue.
4. **Standardisation (PROMOTE\_TO\_MULTI)** : Elle force toutes les géométries en `MultiPolygon`. C'est vital car QGIS ou PostGIS détestent avoir un mélange de `Polygon` et `MultiPolygon` dans une même table.

---

### 📝 Le mémo de secours (si ça bloque encore)

Si un jour tu as une erreur de connexion, vérifie ces 3 points :

- **Le chemin** : Fais toujours un `ls /chemin/vers/ton/fichier` pour être sûr qu'il n'a pas bougé.
- **Le schéma** : Assure-toi que le schéma cible (ici `insee_raw`) existe déjà dans ta base :
    
    
    - `CREATE SCHEMA IF NOT EXISTS insee_raw;`
- **Les droits** : Si tu as une erreur de permission, utilise `sudo` devant la commande `ogr2ogr`.

**Tu as maintenant la "recette secrète" pour tes imports.** Est-ce qu'on s'en sert pour une autre couche (DVF, Sirene...) ou on finit la synthèse de ton indicateur A1 ?

# 02/ Inventaire du Groupe Public de PostGIS

```
sudo docker exec -it alteris_postgis psql -U alteris_admin -d alteris_geo -c "
SELECT 
    relname AS table_name, 
    pg_size_pretty(pg_total_relation_size(c.oid)) AS taille
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
  AND c.relkind = 'r'
  AND relname != 'spatial_ref_sys'
ORDER BY pg_total_relation_size(c.oid) DESC;
```

 table\_name | taille

\--------------------------------+--------

 communes\_fr | 351 MB

 trafic | 11 MB

 communes\_paca | 10 MB

 i\_t1\_03 | 152 kB

 indicateurs\_crise\_de\_confiance | 112 kB

 pop\_dep | 48 kB

 indicateur\_i\_t1\_02\_final | 16 kB

 pilote\_atlas | 16 kB

(10 rows)

# Les données foncières (DVF)

# Vedène -

C'est un excellent test pour valider l'industrialisation du processus. Vedène (84141) va nous permettre de vérifier si la structure à 40 colonnes est constante.

Voici le plan d'action séquentiel.

### 1. Création de `vedene_full` (Le moule brut)

On prépare d'abord le réceptacle pour l'importation du CSV.

<div class="code-block ng-tns-c3877021074-1765 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c3877021074-1765 ng-star-inserted"><span class="ng-tns-c3877021074-1765">SQL</span><div class="buttons ng-tns-c3877021074-1765 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c3877021074-1765"><div class="animated-opacity ng-tns-c3877021074-1765"></div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
CREATE SCHEMA IF NOT EXISTS dvf_raw;

DROP TABLE IF EXISTS dvf_raw.vedene_full;
CREATE TABLE dvf_raw.vedene_full (
    c1 text, c2 text, c3 text, c4 text, c5 text, c6 text, c7 text, c8 text, c9 text, c10 text,
    c11 text, c12 text, c13 text, c14 text, c15 text, c16 text, c17 text, c18 text, c19 text, c20 text,
    c21 text, c22 text, c23 text, c24 text, c25 text, c26 text, c27 text, c28 text, c29 text, c30 text,
    c31 text, c32 text, c33 text, c34 text, c35 text, c36 text, c37 text, c38 text, c39 text, c40 text
);
"
```

<div class="code-block ng-tns-c3877021074-1765 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1"><div class="formatted-code-block-internal-container ng-tns-c3877021074-1765"><div class="animated-opacity ng-tns-c3877021074-1765"></div></div></div>### 2. Injection des données (Bash/Docker)

Assure-toi que le fichier est bien présent dans ton arborescence locale avant de lancer :

<div class="code-block ng-tns-c3877021074-1766 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c3877021074-1766 ng-star-inserted"><span class="ng-tns-c3877021074-1766">Bash</span><div class="buttons ng-tns-c3877021074-1766 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c3877021074-1766"><div class="animated-opacity ng-tns-c3877021074-1766"></div></div></div>```
# 1. Injection du CSV (40 colonnes)
cat "/home/debian/data/Regions/93/84/248400251/84141/84141.csv" | docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "COPY dvf_raw.vedene_full FROM STDIN WITH (FORMAT CSV, HEADER, DELIMITER ',');"

# 2. Création du Jalon Géographique (Points Lambert 93)
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
DROP TABLE IF EXISTS dvf_raw.vedene_valide;
CREATE TABLE dvf_raw.vedene_valide AS
SELECT 
    f.c1 as id_mutation,
    ST_Transform(ST_SetSRID(ST_MakePoint(NULLIF(f.c39, '')::double precision, NULLIF(f.c40, '')::double precision), 4326), 2154) as geom
FROM dvf_raw.vedene_full f
WHERE f.c39 ~ '^-?[0-9]';
CREATE INDEX sidx_vedene_valide ON dvf_raw.vedene_valide USING GIST (geom);
"
```

<div class="code-block ng-tns-c3877021074-1766 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4"><div class="formatted-code-block-internal-container ng-tns-c3877021074-1766"><div class="animated-opacity ng-tns-c3877021074-1766"></div></div></div>### 3. Création de `vedene_valide` (Le Jalon Géographique)

On extrait les points GPS pour "poser le premier jalon" et vérifier l'emprise.

<div class="code-block ng-tns-c3877021074-1767 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql-1"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c3877021074-1767 ng-star-inserted"><span class="ng-tns-c3877021074-1767">SQL</span><div class="buttons ng-tns-c3877021074-1767 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c3877021074-1767"><div class="animated-opacity ng-tns-c3877021074-1767"></div></div></div>```
DROP TABLE IF EXISTS dvf_raw.vedene_valide;
CREATE TABLE dvf_raw.vedene_valide AS
SELECT 
    f.c1 as id_mutation,
    ST_Transform(ST_SetSRID(ST_MakePoint(NULLIF(f.c39, '')::double precision, NULLIF(f.c40, '')::double precision), 4326), 2154) as geom
FROM dvf_raw.vedene_full f
WHERE f.c39 ~ '^-?[0-9]';

CREATE INDEX sidx_vedene_valide ON dvf_raw.vedene_valide USING GIST (geom);

```

<div class="code-block ng-tns-c3877021074-1767 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7"><div class="formatted-code-block-internal-container ng-tns-c3877021074-1767"><div class="animated-opacity ng-tns-c3877021074-1767"></div></div></div>### 4. Fusion Finale : `84141_dvf_alteris` (L'Item Unique)

On assemble le tout (DVF + Géométrie Validée + Jointure Cadastre) en éliminant les doublons de lignes DVF.

<div class="code-block ng-tns-c3877021074-1768 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql-2"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c3877021074-1768 ng-star-inserted"><span class="ng-tns-c3877021074-1768">SQL</span><div class="buttons ng-tns-c3877021074-1768 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c3877021074-1768"><div class="animated-opacity ng-tns-c3877021074-1768"></div></div></div>```
DROP TABLE IF EXISTS dvf_raw."84141_dvf_alteris";
CREATE TABLE dvf_raw."84141_dvf_alteris" AS
WITH cadastre AS (
    -- Reconstruction spatiale du cadastre de Vedène
    SELECT 
        (f->'properties'->>'id')::text as id_parcelle_cad,
        ST_Transform(ST_SetSRID(ST_GeomFromGeoJSON(f->'geometry'), 4326), 2154) as geom_poly
    FROM (
        SELECT jsonb_array_elements(string_agg(line, '')::jsonb->'features') as f 
        FROM dvf_raw.tmp_vedene_txt
    ) sub
)
SELECT DISTINCT ON (f.c1)
    v.geom,
    f.c1 as id_mutation,
    NULLIF(f.c2, '')::date as date_mutation,
    NULLIF(f.c5, '')::numeric as valeur_fonciere,
    f.c16 as id_parcelle_dvf,
    f.c8 || ' ' || f.c9 as adresse,
    f.c28 as type_local,
    NULLIF(f.c29, '')::numeric as surface_bati,
    ST_Within(v.geom, c.geom_poly) as certification_spatiale
FROM dvf_raw.vedene_full f
JOIN dvf_raw.vedene_valide v ON f.c1 = v.id_mutation
LEFT JOIN cadastre c ON f.c16 = c.id_parcelle_cad
ORDER BY f.c1;

-- Nettoyage des tables temporaires
DROP TABLE dvf_raw.tmp_vedene_txt;

```

<div class="code-block ng-tns-c3877021074-1768 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10"><div class="formatted-code-block-internal-container ng-tns-c3877021074-1768"><div class="animated-opacity ng-tns-c3877021074-1768"></div></div></div>**Chiche ! Les scripts sont prêts. Tu veux que je lance l'exécution ou tu préfères vérifier un point de structure avant ?**

# Exemple sur fulldvf France de 2020 à 2025

1/ on a regroupé les fichiers fullDVF sur le home/debian/data  
  
  
2/ on a lancé le script

\#!/bin/bash  
TARGET\_TABLE="dvf\_raw.var\_history\_83"  
DATA\_DIR="/home/debian/data"

echo "----------------------------------------------------"  
echo "ALTERIS - Moissonnage VAR (83) - Colonne 13"  
echo "----------------------------------------------------"

\# 1. On vide la table pour repartir sur une base propre  
docker exec -i alteris\_postgis psql -U alteris\_admin -d alteris\_geo -c "TRUNCATE $TARGET\_TABLE;"

\# 2. Boucle sur les 6 fichiers  
for YEAR in {2020..2025}; do  
 FILE="$DATA\_DIR/fullDVF\_${YEAR}.csv"  
   
 if \[ -f "$FILE" \]; then  
 echo "--&gt; Extraction Var 83 dans l'année $YEAR..."  
   
 # On prépare le fichier temporaire avec l'entête  
 head -n 1 "$FILE" &gt; "$DATA\_DIR/var\_tmp.csv"  
   
 # FILTRE : On cherche exactement le code 83 après 12 virgules  
 grep -E "^(\[^,\]\*,){12}83," "$FILE" &gt;&gt; "$DATA\_DIR/var\_tmp.csv"  
   
 # Injection  
 cat "$DATA\_DIR/var\_tmp.csv" | docker exec -i alteris\_postgis psql -U alteris\_admin -d alteris\_geo -c "COPY $TARGET\_TABLE FROM STDIN WITH (FORMAT CSV, HEADER, DELIMITER ',');"  
   
 # Nettoyage  
 rm "$DATA\_DIR/var\_tmp.csv"  
 fi  
done

echo "----------------------------------------------------"  
echo "RÉSULTAT DE L'OBJECTIVATION :"  
docker exec -i alteris\_postgis psql -U alteris\_admin -d alteris\_geo -c "SELECT count(\*) as total\_var\_83 FROM $TARGET\_TABLE;"

On monte la table pure

C'est la voix de la sagesse **Alteris** : d'abord figer la donnée brute certifiée (le socle), puis construire la production par-dessus. On ne mélange pas l'archive et l'analyse.

On va donc créer la table **`DVFFull83_raw`**. Ce sera ta "Banque Centrale" du Var : une table physique, indexée, contenant l'intégralité des 451 336 lignes sans aucune transformation, mais avec une colonne géométrique propre pour QGIS.

### 1. Bloc d'évolutions proposées

<div class="container" id="bkmrk-mat%C3%A9rialisation-%3A-on"><div class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr">- **Matérialisation :** On passe d'une vue à une **TABLE** physique (plus rapide pour QGIS).
- **Typage SQL :** On convertit les colonnes critiques (Date, Prix, Surface) pour permettre les tris immédiats, mais on garde tout le reste.
- **Indexation Double :** Un index spatial (GIST) pour la carte et un index attributaire sur le `code_commune`.

---

</div></div>### 2. Création de la Table de Référence : `DVFFull83_raw`

Lance ce bloc pour graver tes données dans le marbre :

<div class="container" id="bkmrk-"><div class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div><div class="code-block ng-tns-c3877021074-1980 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c3877021074-1980 ng-star-inserted"><span class="ng-tns-c3877021074-1980">SQL</span><div class="buttons ng-tns-c3877021074-1980 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c3877021074-1980"><div class="animated-opacity ng-tns-c3877021074-1980">  
</div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
DROP TABLE IF EXISTS dvf_raw.\"DVFFull83_raw\";

CREATE TABLE dvf_raw.\"DVFFull83_raw\" AS
SELECT 
    -- Géométrie Lambert 93 générée à la volée
    ST_Transform(ST_SetSRID(ST_MakePoint(NULLIF(c39, '')::double precision, NULLIF(c40, '')::double precision), 4326), 2154) as geom,
    c1 as id_mutation,
    NULLIF(c2, '')::date as date_mutation,
    c4 as nature_mutation,
    NULLIF(c5, '')::numeric as valeur_fonciere,
    c8 as adresse_numero,
    c9 as adresse_nom_voie,
    c10 as code_postal,
    c11 as code_commune,
    c12 as nom_commune,
    c13 as code_departement,
    c16 as id_parcelle,
    c29 as lot1_surface_carrez,
    c31 as type_local,
    NULLIF(c32, '')::numeric as surface_reelle_bati,
    NULLIF(c33, '')::integer as nombre_pieces_principales,
    NULLIF(c38, '')::numeric as surface_terrain,
    c39 as longitude_wgs84,
    c40 as latitude_wgs84
FROM dvf_raw.var_history_83
WHERE c39 ~ '^-?[0-9]';

-- Indexation de performance
CREATE INDEX sidx_dvffull83_geom ON dvf_raw.\"DVFFull83_raw\" USING GIST (geom);
CREATE INDEX idx_dvffull83_commune ON dvf_raw.\"DVFFull83_raw\" (code_commune);
CREATE INDEX idx_dvffull83_date ON dvf_raw.\"DVFFull83_raw\" (date_mutation);
"

```

<div class="code-block ng-tns-c3877021074-1980 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1"><div class="formatted-code-block-internal-container ng-tns-c3877021074-1980"><div class="animated-opacity ng-tns-c3877021074-1980"></div></div></div><div class="container" id="bkmrk--2"><div class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr">---

</div></div>### 3. Raisonnement par étape : Pourquoi c'est ta référence ?

<div class="container" id="bkmrk-immutabilit%C3%A9-%3A-cette"><div class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr">1. **Immutabilité :** Cette table contient les 451 336 lignes. Si une vente a 3 lots, tu as les 3 lignes. C'est ta "boîte noire".
2. **Vitesse QGIS :** Contrairement à la table `var_history_83` qui n'a que du texte (TEXT), ici les prix sont des `NUMERIC` et les dates des `DATE`. Les filtres dans QGIS seront instantanés.
3. **Sécurité :** Pour ton rendu de jeudi, si on te pose une question sur un lot spécifique, tu as l'info brute sous la main.

---

</div></div>### 4. Audit Final

Une fois la table créée, vérifie que le compte est bon : `SELECT count(*) FROM dvf_raw."DVFFull83_raw";`

**C'est fait ? Si oui, tu as officiellement ta base de référence pour le Var. On s'arrête là pour la structure ou tu veux qu'on prépare l'export pour ton NAS ?**

**L'export en GPKG n'a pas fonctionné - "C'est une erreur classique de "boîte à outils" : l'image Docker `postgis/postgis` contient la base de données, mais elle n'embarque pas toujours les utilitaires de conversion comme `ogr2ogr` (qui appartiennent à la bibliothèque GDAL)."**

<div class="container" id="bkmrk--3"><div class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--4"></div></div>```
# Export de ta table de référence vers un fichier GeoPackage
docker exec -i alteris_postgis ogr2ogr -f "GPKG" \
/home/debian/data/DVFFull83_raw_2020_2025.gpkg \
PG:"dbname=alteris_geo user=alteris_admin password=alteris_pwd host=localhost" \
"dvf_raw.DVFFull83_raw"
```

Donc export du `DVFFull83_raw`

en csv avec point geolocalisation et ID Cadastre

```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
COPY (SELECT * FROM dvf_raw.\"DVFFull83_raw\") TO STDOUT WITH (FORMAT CSV, HEADER, DELIMITER ',');
" > /home/debian/data/DVFFull83_raw_2020_2025.csv
```

# Etude Bandol - apprentissage de renseignement des indicateurs

### **A - Demographie** 

A3 - l'évolution des CSP par IRIS (la gentrification)

'est la meilleure façon de documenter : garder le code brut sous le coude. Pour l'indicateur **A3 (Profil CSP)**, voici le bloc SQL "propre" que nous avons utilisé.

Il est structuré pour être réutilisable : il suffit de changer les noms des tables ou les codes IRIS pour l'adapter à une autre ville.

##### 💾 Script SQL : Calcul de l'indicateur A3 (Structure des Actifs)

<div class="code-block ng-tns-c2968650486-3719 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-3719 ng-star-inserted"><span class="ng-tns-c2968650486-3719">SQL</span><div class="buttons ng-tns-c2968650486-3719 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-3719"><div class="animated-opacity ng-tns-c2968650486-3719">  
</div></div></div>```
/* INDICATEUR A3 : ANALYSE DE LA POPULATION ACTIVE
   Période : 2016 (CS1) vs 2025 (GS)
   Filtre : Population active uniquement (Codes 2 à 6)
*/

WITH stats_16 AS (
    SELECT 
        iris,
        -- Agrégation par catégorie (Pondération IPONDI)
        SUM(CASE WHEN cs1 = '2' THEN ipondi::numeric ELSE 0 END) as art_16,
        SUM(CASE WHEN cs1 = '3' THEN ipondi::numeric ELSE 0 END) as cad_16,
        SUM(CASE WHEN cs1 = '4' THEN ipondi::numeric ELSE 0 END) as int_16,
        SUM(CASE WHEN cs1 = '5' THEN ipondi::numeric ELSE 0 END) as emp_16,
        SUM(CASE WHEN cs1 = '6' THEN ipondi::numeric ELSE 0 END) as ouv_16,
        -- Total de la population active (Base de calcul pour les %)
        SUM(ipondi::numeric) FILTER (WHERE cs1 IN ('2','3','4','5','6')) as tot_16
    FROM "83009_bandol".stats_individus_2016
    WHERE iris IN ('830090101', '830090102', '830090106')
    GROUP BY iris
),
stats_25 AS (
    SELECT 
        iris,
        -- Agrégation par catégorie (Pondération IPONDI)
        SUM(CASE WHEN gs = '2' THEN ipondi::numeric ELSE 0 END) as art_25,
        SUM(CASE WHEN gs = '3' THEN ipondi::numeric ELSE 0 END) as cad_25,
        SUM(CASE WHEN gs = '4' THEN ipondi::numeric ELSE 0 END) as int_25,
        SUM(CASE WHEN gs = '5' THEN ipondi::numeric ELSE 0 END) as emp_25,
        SUM(CASE WHEN gs = '6' THEN ipondi::numeric ELSE 0 END) as ouv_25,
        -- Total de la population active (Base de calcul pour les %)
        SUM(ipondi::numeric) FILTER (WHERE gs IN ('2','3','4','5','6')) as tot_25
    FROM "83009_bandol".stats_individus
    WHERE iris IN ('830090101', '830090102', '830090106')
    GROUP BY iris
)
-- Calcul final des parts et de l'évolution
SELECT 
    s25.iris,
    'Cadres' as csp, 
    ROUND((s16.cad_16/NULLIF(s16.tot_16,0))*100,1) as part_2016, 
    ROUND((s25.cad_25/NULLIF(s25.tot_25,0))*100,1) as part_2025,
    ROUND(((s25.cad_25-s16.cad_16)/NULLIF(s16.cad_16,0))*100,1) as evol_vol_pct
FROM stats_25 s25 JOIN stats_16 s16 ON s25.iris = s16.iris
UNION ALL
SELECT 
    s25.iris, 'Prof. Interm.', 
    ROUND((s16.int_16/NULLIF(s16.tot_16,0))*100,1), ROUND((s25.int_25/NULLIF(s25.tot_25,0))*100,1),
    ROUND(((s25.int_25-s16.int_16)/NULLIF(s16.int_16,0))*100,1)
FROM stats_25 s25 JOIN stats_16 s16 ON s25.iris = s16.iris
ORDER BY iris, part_2025 DESC;

```

<div class="code-block ng-tns-c2968650486-3719 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1"><div class="formatted-code-block-internal-container ng-tns-c2968650486-3719"><div class="animated-opacity ng-tns-c2968650486-3719"></div></div></div>---

### 🗝️ Pourquoi avoir codé comme ça ?

- **`NULLIF(..., 0)`** : C'est la sécurité anti-crash. Si un IRIS n'a aucun cadre en 2016, la division par zéro échoue. Cette fonction transforme le 0 en `NULL` pour éviter l'erreur.
- **`FILTER (WHERE ...)`** : C'est la méthode SQL moderne pour compter uniquement ce qui nous intéresse dans une somme globale.
- **`UNION ALL`** : On "empile" les résultats des cadres et des prof. intermédiaires pour avoir une liste facile à lire, plutôt qu'un tableau avec 50 colonnes.

### 💡 Petit conseil d'expert :

Si tu dois refaire ça pour une autre ville (ex: Sanary), il te suffira de :

1. Changer le préfixe du schéma (`"83009_bandol"`).
2. Changer la liste des codes IRIS dans les clauses `WHERE`.

**C'est dans la boîte !** Tu te sens prêt à attaquer la mise en page de ton rapport ou tu as encore un doute sur une colonne ?

####  

### **C - DVF**

#### Toujours commencer par une approche semantique de la table pour que l'IA ne fasse pas de fautes  


#### debian@vps-02c1f983-vps-ovh-net:~$ docker exec -i alteris\_postgis psql -U alteris\_admin -d alteris\_geo -c "SELECT nature\_mutation, COUNT(\*) FROM \\"83009\_bandol\\".dvf\_bandol\_complet GROUP BY nature\_mutation;"  
  



#### C5 - Etude du marché de l'ancien   
  
<span style="color:rgb(224,62,45);">C5a/ - le marche immobilier </span>  
<span style="color:rgb(224,62,45);">Le problème est que les micro-studios "balnéaires" hyper spéculatifs de moins de 20 m² faussent le prix moyen du m² global. </span>  
<span style="color:rgb(224,62,45);">Dans l'analyse C5a - Nexte\_stats neutralise ces données pour transcrire un marché immobilier courant incluant les studios d'habitat à l'année, mais excluant les meublés d'été inférieurs à 20 m². (A VALIDER) </span>  


```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
-- 1. Nettoyage de l'ancienne couche
DROP TABLE IF EXISTS \"83009_bandol\".\"dvf_carto_2022_2025\";
DROP TABLE IF EXISTS \"83009_bandol\".\"dvf_carto_2022_2025_prixm²\";

-- 2. Création de la couche filtrée (> 20m²)
CREATE TABLE \"83009_bandol\".\"dvf_carto_2022_2025_prixm²\" AS
SELECT 
    id_mutation,
    MAX(date_mutation) as date_mutation,
    EXTRACT(YEAR FROM MAX(date_mutation)) as annee,
    MAX(type_local) as type_bien,
    MAX(valeur_fonciere) as prix_total,
    SUM(surface_reelle_bati) as surface_totale,
    ROUND(MAX(valeur_fonciere) / NULLIF(SUM(surface_reelle_bati), 0), 0) as prix_m2,
    ST_Centroid(ST_Collect(geom)) as geom
FROM \"83009_bandol\".dvf_bandol_complet
WHERE nature_mutation IN ('Vente', 'Vente en l''état futur d''achèvement')
  AND type_local IN ('Maison', 'Appartement')
  AND date_mutation >= '2022-01-01'
  AND valeur_fonciere > 50000
GROUP BY id_mutation
HAVING SUM(surface_reelle_bati) >= 20; -- FILTRE ANTI-SINGLETONS

-- 3. Indexation
CREATE INDEX idx_dvf_carto_prixm2_geom ON \"83009_bandol\".\"dvf_carto_2022_2025_prixm²\" USING GIST(geom);"
```

#### C5b/ le tableau des typologies globales ancien/neuf en appartements sur les 3 dernières années

```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
SELECT 
    CASE 
        WHEN nombre_pieces_principales = 1 THEN 'Studio'
        WHEN nombre_pieces_principales = 2 THEN 'T2'
        WHEN nombre_pieces_principales = 3 THEN 'T3'
        WHEN nombre_pieces_principales = 4 THEN 'T4'
        ELSE 'T5+' 
    END as typologie,
    COUNT(DISTINCT id_mutation) as nb_ventes,
    ROUND(AVG(surface_reelle_bati), 0) as surface_moyenne,
    ROUND(AVG(valeur_fonciere), 0) as prix_moyen,
    ROUND(AVG(valeur_fonciere / NULLIF(surface_reelle_bati, 0)), 0) as prix_m2_moyen
FROM \"83009_bandol\".dvf_bandol_complet
WHERE nature_mutation = 'Vente'
  AND type_local = 'Appartement'
  AND surface_reelle_bati >= 20
  AND date_mutation >= '2022-01-01'
GROUP BY nombre_pieces_principales
ORDER BY nombre_pieces_principales;"
```

####   
 C5c - le tableau des typologies globales ancien/neuf en appartements VEFA sur les 3 dernières années

#### 📘 Documentation Indicateur C5c : Analyse du Neuf (DVF x BDNB)

#### Cet indicateur permet de filtrer les ventes de la DVF non pas sur le champ "Nature de mutation" (souvent peu fiable), mais sur la réalité physique du bâtiment (Année de construction certifiée par les Fichiers Fonciers).

#### 1. Intégration de la BDNB (Var - 83)

#### L'import se fait depuis un dump SQL de la Base Nationale des Bâtiments.



<div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-3047 ng-star-inserted" id="bkmrk-bash"><span class="ng-tns-c2968650486-3047">Bash</span><div class="buttons ng-tns-c2968650486-3047 ng-star-inserted"></div></div>
<div class="formatted-code-block-internal-container ng-tns-c2968650486-3047" id="bkmrk--8"><div class="animated-opacity ng-tns-c2968650486-3047">  
</div></div>
```
# Copie du fichier SQL vers le container
docker cp data/Regions/93/83/bdnb.sql alteris_postgis:/tmp/bdnb.sql

# Restauration dans la base de données
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -f /tmp/bdnb.sql

```

<div class="formatted-code-block-internal-container ng-tns-c2968650486-3047" id="bkmrk--10"><div class="animated-opacity ng-tns-c2968650486-3047"></div></div>


#### *Note : Le schéma créé est `bdnb_2025_07_a_open_data_dep83`.*

---

#### 2. Croisement DVF x BDNB (Filtre <span class="math-inline">$\\ge$</span> 2017)

#### On crée une table de synthèse qui lie les mutations DVF aux caractéristiques du bâtiment via la parcelle cadastrale.



<div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-3048 ng-star-inserted" id="bkmrk-sql-1"><span class="ng-tns-c2968650486-3048">SQL</span><div class="buttons ng-tns-c2968650486-3048 ng-star-inserted"></div></div>
<div class="formatted-code-block-internal-container ng-tns-c2968650486-3048" id="bkmrk--18"><div class="animated-opacity ng-tns-c2968650486-3048">  
</div></div>
```
-- Création de la table de travail sur le VPS
CREATE TABLE public.temp_bandol_neuf AS
SELECT 
    d.id_mutation, 
    d.date_mutation, 
    d.valeur_fonciere, 
    d.surface_reelle_bati, 
    d.nombre_pieces_principales, 
    ffo.annee_construction, 
    d.geom
FROM "83009_bandol".dvf_bandol_complet d
JOIN "bdnb_2025_07_a_open_data_dep83".rel_batiment_groupe_parcelle rel 
    ON d.id_parcelle = rel.parcelle_id
JOIN "bdnb_2025_07_a_open_data_dep83".batiment_groupe_ffo_bat ffo 
    ON rel.batiment_groupe_id = ffo.batiment_groupe_id
WHERE d.type_local = 'Appartement' 
  AND d.surface_reelle_bati > 0 
  AND ffo.annee_construction >= 2017;

```

<div class="formatted-code-block-internal-container ng-tns-c2968650486-3048" id="bkmrk--20"><div class="animated-opacity ng-tns-c2968650486-3048"></div></div>


---

#### 3. Export GeoJSON (Projection GPS WGS84)

#### Pour que le fichier soit immédiatement exploitable dans QGIS sans décalage, on projette la géométrie du Lambert-93 (2154) vers le WGS84 (4326).



<div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-3049 ng-star-inserted" id="bkmrk-bash-1"><span class="ng-tns-c2968650486-3049">Bash</span><div class="buttons ng-tns-c2968650486-3049 ng-star-inserted"></div></div>
<div class="formatted-code-block-internal-container ng-tns-c2968650486-3049" id="bkmrk--28"><div class="animated-opacity ng-tns-c2968650486-3049">  
</div></div>
```
# Génération du JSON propre à l'intérieur du container
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
COPY (
    SELECT jsonb_build_object(
        'type',     'FeatureCollection',
        'features', jsonb_agg(features.feature)
    )
    FROM (
      SELECT jsonb_build_object(
        'type',       'Feature',
        'geometry',   ST_AsGeoJSON(ST_Transform(geom, 4326))::jsonb,
        'properties', to_jsonb(inputs) - 'geom'
      ) AS feature
      FROM (SELECT * FROM public.temp_bandol_neuf) inputs
    ) features
) TO '/tmp/final_gps.geojson';"

# Extraction vers le dossier d'échange du VPS
docker cp alteris_postgis:/tmp/final_gps.geojson /home/debian/data/bandol_expert_gps.geojson

```

<div class="formatted-code-block-internal-container ng-tns-c2968650486-3049" id="bkmrk--30"><div class="animated-opacity ng-tns-c2968650486-3049"></div></div>


---

#### 🎯 Résultats obtenus (Bandol)

#### Le croisement a permis d'identifier **31 transactions** sur le cycle 2017-2025.

<table id="bkmrk-typologie-nb-ventes-"><thead><tr><td>#### **Typologie**

</td><td>#### **Nb Ventes**

</td><td>#### **Surface Moy.**

</td><td>#### **Prix m² Moyen**

</td></tr></thead><tbody><tr><td>#### <span>T2</span>

</td><td>#### <span>11</span>

</td><td>#### <span>44 m²</span>

</td><td>#### <span>**7 551 €**</span>

</td></tr><tr><td>#### <span>T3</span>

</td><td>#### <span>9</span>

</td><td>#### <span>68 m²</span>

</td><td>#### <span>**7 560 €**</span>

</td></tr><tr><td>#### <span>T4</span>

</td><td>#### <span>8</span>

</td><td>#### <span>91 m²</span>

</td><td>#### <span>**6 547 €**</span>

</td></tr></tbody></table>

**Alerte Point de Vigilance :** Une vente record (Studio) à **26 409 €/m²** a été détectée, signalant un segment "Ultra-Luxe" spécifique à isoler de la moyenne générale pour ne pas fausser les prévisionnels de sortie du projet AH0219.


#### C'est ta "recette de cuisine" pour n'importe quelle autre commune du Var maintenant. On passe à l'analyse par IRIS pour voir si le quartier du projet sur-performe la moyenne de Bandol

#### Autre aspect C5c - dynamique des VEFA sur Bandol   
  


```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "SELECT     CASE         WHEN date_mutation >= '2025-01-01' AND date_mutation <= '2025-06-30' THEN '2025 (S1)'        ELSE TO_CHAR(date_mutation, 'YYYY')     END as periode,    COUNT(DISTINCT id_mutation) as nb_vefa,    ROUND(AVG(surface_reelle_bati), 0) as surface_moy,    ROUND(AVG(valeur_fonciere / NULLIF(surface_reelle_bati, 0)), 0) as prix_m2_vefaFROM \"83009_bandol\".dvf_bandol_completWHERE nature_mutation = 'Vente en l''état futur d''achèvement'  AND type_local = 'Appartement'  AND surface_reelle_bati > 0  AND date_mutation >= '2022-01-01'GROUP BY periodeORDER BY periode DESC;"
```





#### C5d - Studios pondérés  
  


C'est une excellente stratégie. En statistiques, on appelle cela une **moyenne tronquée** (ou moyenne élaguée). En excluant les 20 % extrêmes de chaque côté (le "bas de marché" souvent dégradé et les "ovnis" spéculatifs), on obtient l'image la plus fidèle du **cœur de marché**.

Pour être précis : si tes calculs précédents commençaient à 20 m², nous filtrons ici strictement de **12 à 19,99 m²**.

🛠️ La Requête SQL "Moyenne Tronquée" (Studios 12-19m²)

Voici la commande qui réalise ce filtrage complexe. Elle utilise des "Common Table Expressions" (CTE) pour classer les prix et ne garder que le milieu de la distribution (les 60 % centraux).

```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
WITH studios_calcules AS (
    SELECT 
        valeur_fonciere / surface_reelle_bati as prix_m2,
        surface_reelle_bati,
        valeur_fonciere,
        NTILE(5) OVER (ORDER BY valeur_fonciere / surface_reelle_bati) as quintile
    FROM \"83009_bandol\".dvf_bandol_complet
    WHERE type_local = 'Appartement'
      AND surface_reelle_bati >= 12 
      AND surface_reelle_bati < 20
      AND nature_mutation = 'Vente'
      AND date_mutation >= '2022-01-01'
)
SELECT 
    COUNT(*) as nb_ventes_retenues,
    ROUND(AVG(surface_reelle_bati), 1) as surface_moyenne,
    ROUND(AVG(prix_m2), 0) as prix_m2_moyen_tronque,
    ROUND(MIN(prix_m2), 0) as borne_basse_retenue,
    ROUND(MAX(prix_m2), 0) as borne_haute_retenue
FROM studios_calcules
WHERE quintile IN (2, 3, 4); -- On exclut le quintile 1 (20% bas) et le 5 (20% haut)"
```

Voici la fiche de documentation technique et méthodologique pour l'indicateur **C5e**. Elle est conçue pour être insérée directement dans

<div class="code-block ng-tns-c2968650486-2701 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--39"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2701 ng-star-inserted">---

</div></div># 📘 Documentation Indicateur C5e : Dynamique des Programmes Immobiliers Neufs

### 1. Définition et Objectif

L'indicateur **C5e** vise à isoler et analyser les opérations de promotion immobilière (VEFA) par une approche de **clustering géographique**. Contrairement aux indicateurs globaux, il permet de distinguer la vente au détail (particuliers) de la vente en bloc (institutionnels) et d'identifier les valeurs de sortie réelles par programme.

### 2. Méthodologie d'Extraction

Le workflow repose sur l'identification de "grappes" de mutations à une même adresse. Le seuil de détection est fixé à :

<div class="code-block ng-tns-c2968650486-2701 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-volume-%3A-minimum-3-m"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2701 ng-star-inserted">- **Volume** : Minimum 3 mutations distinctes sur une même voie la même année.
- **Valeur** : Ou un Chiffre d'Affaires cumulé supérieur à 2 000 000 €.

</div></div>#### Requête SQL de référence :

<div class="code-block ng-tns-c2968650486-2701 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--40"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2701 ng-star-inserted"></div></div><div class="code-block ng-tns-c2968650486-3276 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql-2"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-3276 ng-star-inserted"><span class="ng-tns-c2968650486-3276">SQL</span><div class="buttons ng-tns-c2968650486-3276 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-3276"><div class="animated-opacity ng-tns-c2968650486-3276">  
</div></div></div>```
SELECT 
    adresse_numero AS nom_de_la_rue, 
    TO_CHAR(date_mutation, 'YYYY') AS annee,
    COUNT(DISTINCT id_mutation) AS nb_mutations,
    SUM(valeur_fonciere) AS ca_total_dvf
FROM "83009_bandol".dvf_bandol_complet
WHERE nature_mutation LIKE 'Vente%futur%'
  AND date_mutation >= '2022-01-01'
GROUP BY nom_de_la_rue, annee
HAVING COUNT(DISTINCT id_mutation) >= 3 
   OR SUM(valeur_fonciere) >= 2000000
ORDER BY annee DESC, ca_total_dvf DESC;

```

<div class="code-block ng-tns-c2968650486-3276 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--41"><div class="formatted-code-block-internal-container ng-tns-c2968650486-3276"><div class="animated-opacity ng-tns-c2968650486-3276"></div></div></div><div class="code-block ng-tns-c2968650486-2701 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--42"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2701 ng-star-inserted">---

</div></div>### 3. Protocole d'Analyse des Résultats

Une fois la liste des adresses extraite, l'expertise se décompose en trois niveaux de lecture :

<div class="code-block ng-tns-c2968650486-2701 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-segment-d%C3%A9tect%C3%A9-indi"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2701 ng-star-inserted"><table><thead><tr><td>**Segment détecté**</td><td>**Indicateur DVF**</td><td>**Action Expertise**</td></tr></thead><tbody><tr><td><span>**Vente en Bloc**</span></td><td><span>CA &gt; 20 M€ pour &lt; 5 mutations</span></td><td><span>Identifier l'acquéreur institutionnel (Bailleur/Foncière) via Sitadel.</span></td></tr><tr><td><span>**Luxe / Exception**</span></td><td><span>Prix moyen / mutation &gt; 1,5 M€</span></td><td><span>Vérifier la typologie (Grands plateaux, Villas sur toit).</span></td></tr><tr><td><span>**Cœur de Marché**</span></td><td><span>Prix moyen / mutation \[400k€ - 900k€\]</span></td><td><span>**Comparable direct** pour les projets de promotion standard.</span></td></tr></tbody></table>

---

</div></div>### 4. Cas Pratique : Analyse de Bandol (2022-2025)

L'application de l'indicateur **C5e** sur la base DVF a permis d'isoler les marqueurs suivants :

<div class="code-block ng-tns-c2968650486-2701 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-2"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2701 ng-star-inserted">- **Pôle Institutionnel (Biais statistique à isoler)** :
    
    
    - *Bd de Marseille* (2024) et *Moulin à Vent* (2025) totalisent près de **258 M€** de CA pour seulement 4 mutations majeures. Ces données valident une activité de promotion massive (ventes en bloc) sur la commune.
- **Pôle Comparables Directs (Résidentiel)** :
    
    
    - **Rue J.J. Rousseau (2022)** : 10 mutations pour 26,2 M€ (Moyenne 2,6 M€/acte).
    - **Av. du 11 Novembre (2022)** : 8 mutations pour 4,3 M€ (Moyenne **547k€/acte**).
    - **Rue Pasteur (2022)** : 3 mutations pour 2,2 M€ (Moyenne **742k€/acte**).

</div></div>

# Les statistiques INSEE RGP Communes et IRIS

# Origine des données INSEE RGP Communes et IRIS

Les données RGP sont accessibles sur cette[ page ](https://www.insee.fr/fr/statistiques/8647104?sommaire=8590191) pour 2025  
[Sur cette page pour 2016](https://www.insee.fr/fr/statistiques/4171558).

[Sur cette page pour 2011](https://www.insee.fr/fr/statistiques/2011338)

Il faut télécharger les rubriques Logements et Individus.

\------pour mémoire------------------

LE DOSSIER COMPLET NATIONAL

https://www.insee.fr/fr/statistiques/5359146

Les dossiers complets par commune (changer code insee)

[https://www.insee.fr/fr/statistiques/2011101?geo=COM-83009](https://www.insee.fr/fr/statistiques/2011101?geo=COM-83009)

\-----------------------------------------------------------------

Pour les fichiers **RGP (1.1 Go chacun)**, filtrer sur PACA (04, 05, 06, 13, 83, 84) avant l'injection est une excellente décision : cela va économiser énormément d'espace disque et accélérer tes requêtes SQL futures.

Comme nous n'avons pas d'outil de filtrage lourd, on va utiliser la puissance native de **`awk`** sur Debian pour streamer uniquement les lignes dont le code département commence par un de tes départements cibles.

### 1. Préparation des tables réceptacles

D'abord, on crée les structures vides dans PostGIS.

<div class="code-block ng-tns-c2968650486-921 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-921 ng-star-inserted"><span class="ng-tns-c2968650486-921">Bash</span><div class="buttons ng-tns-c2968650486-921 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-921"><div class="animated-opacity ng-tns-c2968650486-921">  
</div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
CREATE TABLE IF NOT EXISTS insee_raw.rgp_individus_paca_2025 (
    id serial PRIMARY KEY,
    donnees jsonb -- On peut stocker en JSONB pour la flexibilité ou définir les colonnes
);
CREATE TABLE IF NOT EXISTS insee_raw.rgp_logements_paca_2025 (
    id serial PRIMARY KEY,
    donnees jsonb
);"

```

<div class="code-block ng-tns-c2968650486-921 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1"><div class="formatted-code-block-internal-container ng-tns-c2968650486-921"><div class="animated-opacity ng-tns-c2968650486-921"></div></div></div>### 2. Injection filtrée (Le "Stream")

Voici la commande pour ne garder que la Région PACA. *Note : Je pars du principe que le code département est dans la 2ème ou 3ème colonne. Si tu as un doute sur la position de la colonne, dis-le moi.*

**Individus (Filtre Départements 04,05,06,13,83,84) :**

<div class="code-block ng-tns-c2968650486-922 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-1"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-922 ng-star-inserted"><span class="ng-tns-c2968650486-922">Bash</span><div class="buttons ng-tns-c2968650486-922 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-922"><div class="animated-opacity ng-tns-c2968650486-922">  
</div></div></div>```
awk -F',' 'NR==1 || $2 ~ /^(04|05|06|13|83|84)/' "/home/debian/data/INSEE_RGP_2022-25_Individus_zone E.csv" | \
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo \
-c "COPY insee_raw.rgp_individus_paca_2025 FROM STDIN WITH (FORMAT CSV, HEADER, DELIMITER ',', ENCODING 'UTF8');"

```

<div class="code-block ng-tns-c2968650486-922 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4"><div class="formatted-code-block-internal-container ng-tns-c2968650486-922"><div class="animated-opacity ng-tns-c2968650486-922"></div></div></div>**Logements (Filtre Départements 04,05,06,13,83,84) :**

<div class="code-block ng-tns-c2968650486-923 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-2"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-923 ng-star-inserted"><span class="ng-tns-c2968650486-923">Bash</span><div class="buttons ng-tns-c2968650486-923 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-923"><div class="animated-opacity ng-tns-c2968650486-923">  
</div></div></div>```
awk -F',' 'NR==1 || $2 ~ /^(04|05|06|13|83|84)/' "/home/debian/data/INSEE_RGP_2022-25_Logements_zone E.csv" | \
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo \
-c "COPY insee_raw.rgp_logements_paca_2025 FROM STDIN WITH (FORMAT CSV, HEADER, DELIMITER ',', ENCODING 'UTF8');"

```

<div class="code-block ng-tns-c2968650486-923 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7"><div class="formatted-code-block-internal-container ng-tns-c2968650486-923"><div class="animated-opacity ng-tns-c2968650486-923"></div></div></div>---

### Pourquoi cette méthode ?

- **Rapidité :** `awk` traite le fichier ligne par ligne sans le charger en mémoire vive.
- **Efficacité :** Seules les lignes utiles traversent le pipe vers Docker.
- **Propreté :** On garde le `HEADER` (la première ligne) pour que la commande `COPY` ne soit pas perdue.

**Vérifie juste une chose :** Peux-tu me donner les 3 premières lignes d'un des fichiers avec `head -n 3 "/home/debian/data/INSEE_RGP_2022-25_Individus_zone E.csv"` ? Cela me permettra de confirmer le numéro de la colonne département pour ajuster le `$2` dans la commande `awk`.

### 3- Identification du nom de la colonne

Lance cette commande pour être certain du nom de la colonne (car l'INSEE utilise parfois `COMM` ou `COMMUNE`) :

<div class="code-block ng-tns-c2968650486-1034 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-3"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1034 ng-star-inserted"><span class="ng-tns-c2968650486-1034">Bash</span><div class="buttons ng-tns-c2968650486-1034 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1034"><div class="animated-opacity ng-tns-c2968650486-1034">  
</div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "SELECT column_name 
```

Bingo ! On a le jackpot. Regarde bien les trois premières lignes du résultat :

1. **`commune`** : On a bien le code commune (83009 pour Bandol).
2. **`arm`** : Utile pour Marseille (arrondissements).
3. **`iris`** : **C'est la surprise du chef.** Tes fichiers RGP contiennent déjà le code IRIS. On n'aura pas besoin d'attendre cet après-midi pour faire de la dentelle géographique.

C'est très clair. La documentation `varmod_indcvi_2022.csv` que tu as partagée se confirme : dans le fichier **Individus**, la colonne `commune` n'existe pas en tant que telle. L'échelle la plus fine disponible ici est **`cantville`** ou **`iris`** (si elle apparaît plus bas dans la liste).

Pour le fichier **Logements**, nous avons vu qu'il contient `commune`. Mais pour les **Individus**, nous devons ruser.

### 1. Vérification de la présence de la colonne `iris`

Avant de filtrer, vérifions si `iris` est présent dans la table Individus (comme c'était le cas pour les Logements) :

<div class="code-block ng-tns-c2968650486-1109 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-4"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1109 ng-star-inserted"><span class="ng-tns-c2968650486-1109">Bash</span><div class="buttons ng-tns-c2968650486-1109 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1109"><div class="animated-opacity ng-tns-c2968650486-1109">  
</div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
SELECT column_name FROM information_schema.columns 
WHERE table_name = 'rgp_individus_paca_2025' AND table_schema = 'insee_raw' AND column_name = 'iris';"

```

<div class="code-block ng-tns-c2968650486-1109 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--12"><div class="formatted-code-block-internal-container ng-tns-c2968650486-1109"><div class="animated-opacity ng-tns-c2968650486-1109"></div></div></div>### 2. Stratégie d'indexation et d'extraction

**Si `iris` existe :** On utilise les 5 premiers chiffres de l'IRIS (qui correspondent au code commune).

<div class="code-block ng-tns-c2968650486-1110 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-5"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1110 ng-star-inserted"><span class="ng-tns-c2968650486-1110">Bash</span><div class="buttons ng-tns-c2968650486-1110 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1110"><div class="animated-opacity ng-tns-c2968650486-1110">  
</div></div></div>```
# Indexation sur IRIS
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "CREATE INDEX idx_rgp_ind_iris ON insee_raw.rgp_individus_paca_2025 (iris);"

# Extraction Bandol (83009) via IRIS
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
CREATE TABLE bandol.stats_individus AS 
SELECT * FROM insee_raw.rgp_individus_paca_2025 
WHERE iris LIKE '83009%';"
```

C'est parfait. La colonne **`iris`** est présente dans les deux tables. C'est la clé de voûte de notre structuration car elle permet une précision chirurgicale (le quartier) là où `cantville` est trop large.

Voici la séquence de commandes pour finaliser l'extraction de **Bandol** proprement :

### 1. Indexation sur la colonne `iris` (Individus)

<div class="code-block ng-tns-c2968650486-1123 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-6"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1123 ng-star-inserted"><span class="ng-tns-c2968650486-1123">Bash</span><div class="buttons ng-tns-c2968650486-1123 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1123"><div class="animated-opacity ng-tns-c2968650486-1123">  
</div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "CREATE INDEX IF NOT EXISTS idx_rgp_ind_iris ON insee_raw.rgp_individus_paca_2025 (iris);"

```

<div class="code-block ng-tns-c2968650486-1123 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--16"><div class="formatted-code-block-internal-container ng-tns-c2968650486-1123"><div class="animated-opacity ng-tns-c2968650486-1123"></div></div></div>### 2. Création de la table Individus pour Bandol

Pour Bandol (code commune 83009), on récupère tous les IRIS commençant par ces 5 chiffres.

<div class="code-block ng-tns-c2968650486-1124 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-7"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1124 ng-star-inserted"><span class="ng-tns-c2968650486-1124">Bash</span><div class="buttons ng-tns-c2968650486-1124 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1124"><div class="animated-opacity ng-tns-c2968650486-1124">  
</div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
CREATE TABLE bandol.stats_individus AS 
SELECT * FROM insee_raw.rgp_individus_paca_2025 
WHERE iris LIKE '83009%';"

```

<div class="code-block ng-tns-c2968650486-1124 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--19"><div class="formatted-code-block-internal-container ng-tns-c2968650486-1124"><div class="animated-opacity ng-tns-c2968650486-1124"></div></div></div>### 3. Création de la table Logements pour Bandol

On utilise la colonne `commune` qui est déjà présente dans cette table.

<div class="code-block ng-tns-c2968650486-1125 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-8"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1125 ng-star-inserted"><span class="ng-tns-c2968650486-1125">Bash</span><div class="buttons ng-tns-c2968650486-1125 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1125"><div class="animated-opacity ng-tns-c2968650486-1125">  
</div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
CREATE TABLE bandol.stats_logements AS 
SELECT * FROM insee_raw.rgp_logements_paca_2025 
WHERE commune = '83009';"

```

<div class="code-block ng-tns-c2968650486-1125 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--22"><div class="formatted-code-block-internal-container ng-tns-c2968650486-1125"><div class="animated-opacity ng-tns-c2968650486-1125"></div></div></div>---

### Vérification finale du contenu

Une fois ces commandes passées, on vérifie que les deux tables sont bien peuplées :

<div class="code-block ng-tns-c2968650486-1126 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-9"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1126 ng-star-inserted"><span class="ng-tns-c2968650486-1126">Bash</span><div class="buttons ng-tns-c2968650486-1126 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1126"><div class="animated-opacity ng-tns-c2968650486-1126">  
</div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
SELECT 'Individus Bandol' as label, count(*) FROM bandol.stats_individus
UNION ALL
SELECT 'Logements Bandol' as label, count(*) FROM bandol.stats_logements;"

```

<div class="code-block ng-tns-c2968650486-1126 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--26"><div class="formatted-code-block-internal-container ng-tns-c2968650486-1126"><div class="animated-opacity ng-tns-c2968650486-1126"></div></div></div>**Une fois que tu as ces chiffres, nous sommes prêts pour la première analyse Nexte\_Stats.** Par exemple : calculer le **taux de motorisation** des ménages de Bandol (combien ont 0, 1 ou 2 voitures via la variable `voit`) croisé avec leur quartier (`iris`).

\-------------------------------

### Re pour 2016

C'est parfait, les fichiers sont là et font la même taille que ceux de 2022 (~1.1 Go), ce qui confirme qu'on a bien les bases complètes.

Voici le protocole pour intégrer 2016 et préparer l'analyse d'évolution pour **Nexte\_Stats**.

### 1. Création et Import des Individus 2016

On utilise la méthode dynamique pour créer les colonnes automatiquement.

<div class="code-block ng-tns-c2968650486-1251 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-10"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1251 ng-star-inserted"><span class="ng-tns-c2968650486-1251">Bash</span><div class="buttons ng-tns-c2968650486-1251 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1251"><div class="animated-opacity ng-tns-c2968650486-1251"></div></div></div>```
# Création de la table
head -n 1 "/home/debian/data/INSEE_RGP_2016-19_Individus.csv" | sed 's/;/ text,/g' | sed 's/$/ text/' | xargs -I {} docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "CREATE TABLE IF NOT EXISTS insee_raw.rgp_individus_paca_2016 ({});"

# Injection PACA
awk -F';' 'NR==1 || $1 ~ /^(04|05|06|13|83|84)/' "/home/debian/data/INSEE_RGP_2016-19_Individus.csv" | \
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo \
-c "COPY insee_raw.rgp_individus_paca_2016 FROM STDIN WITH (FORMAT CSV, HEADER, DELIMITER ';', ENCODING 'UTF8');"

```

<div class="code-block ng-tns-c2968650486-1251 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--29"><div class="formatted-code-block-internal-container ng-tns-c2968650486-1251"><div class="animated-opacity ng-tns-c2968650486-1251"></div></div></div>### 2. Création et Import des Logements 2016

<div class="code-block ng-tns-c2968650486-1252 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-11"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1252 ng-star-inserted"><span class="ng-tns-c2968650486-1252">Bash</span><div class="buttons ng-tns-c2968650486-1252 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1252"><div class="animated-opacity ng-tns-c2968650486-1252"></div></div></div>```
# Création de la table
head -n 1 "/home/debian/data/INSEE_RGP_2016-19_Logements.csv" | sed 's/;/ text,/g' | sed 's/$/ text/' | xargs -I {} docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "CREATE TABLE IF NOT EXISTS insee_raw.rgp_logements_paca_2016 ({});"

# Injection PACA
awk -F';' 'NR==1 || $1 ~ /^(04|05|06|13|83|84)/' "/home/debian/data/INSEE_RGP_2016-19_Logements.csv" | \
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo \
-c "COPY insee_raw.rgp_logements_paca_2016 FROM STDIN WITH (FORMAT CSV, HEADER, DELIMITER ';', ENCODING 'UTF8');"

```

<div class="code-block ng-tns-c2968650486-1252 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--32"><div class="formatted-code-block-internal-container ng-tns-c2968650486-1252"><div class="animated-opacity ng-tns-c2968650486-1252"></div></div></div>### 3. Extraction Bandol 2016

Maintenant, on isole Bandol (83009). On vérifie si les colonnes sont les mêmes (`iris` pour les individus, `commune` pour les logements).

<div class="code-block ng-tns-c2968650486-1253 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-12"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-1253 ng-star-inserted"><span class="ng-tns-c2968650486-1253">Bash</span><div class="buttons ng-tns-c2968650486-1253 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-1253"><div class="animated-opacity ng-tns-c2968650486-1253"></div></div></div>```
# Extraction Individus 2016
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
CREATE TABLE bandol.stats_individus_2016 AS 
SELECT * FROM insee_raw.rgp_individus_paca_2016 
WHERE iris LIKE '83009%';"

# Extraction Logements 2016
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
CREATE TABLE bandol.stats_logements_2016 AS 
SELECT * FROM insee_raw.rgp_logements_paca_2016 
WHERE commune = '83009';"

```

<div class="code-block ng-tns-c2968650486-1253 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--35"><div class="formatted-code-block-internal-container ng-tns-c2968650486-1253"><div class="animated-opacity ng-tns-c2968650486-1253"></div></div></div>---

### Pourquoi c'est génial pour ton projet :

Une fois ces commandes terminées, on pourra lancer la requête de la "Vérité" : **L'évolution de la population réelle de Bandol en 6 ans.**

**Lance ces imports (compte environ 5 minutes pour l'ensemble). Dès que c'est fini, on compare les chiffres de 2016 avec les 8 268 habitants de 2022 !**

<div id="bkmrk--39">  
</div>

# Calcul des indicateurs INSEE

### G1 - origine des nouveaux habitants

Pour documenter cette analyse de la mobilité résidentielle à long terme (au-delà de 1 an), voici la méthodologie et les calculs que nous avons appliqués. Cette documentation pourra être intégrée directement dans votre rapport technique.

### 📝 Méthodologie d'analyse de l'ancienneté d'emménagement

Pour "voir plus loin" que le flux annuel, nous utilisons la variable **ANEMR** (Ancienneté d'Emménagement) issue du Recensement de la Population (RGP). Elle permet de segmenter les ménages selon leur date d'entrée dans le logement actuel.

#### 1. Source des données

- **Fichier exploité :** `INSEE_RGP_2025_Communes_83009.csv` (Données de recensement millésimées 2022).
- **Indicateur :** Population des ménages en résidences principales.

#### 2. Calcul des segments de stabilité

Les calculs reposent sur le regroupement des variables de flux de la base Insee :

- **Flux récents (moins de 2 ans) :** Correspond aux emménagements post-2020.
- **Flux de moyen terme (2 à 9 ans) :** Installation entre 2013 et 2020 (période incluant votre point de comparaison 2016).
- **Ancrage historique (10 ans et plus) :** Ménages présents dans le même logement depuis 2012 ou avant.

---

### 📊 Résultats documentés pour Bandol

<table id="bkmrk-anciennet%C3%A9-dans-le-l"><thead><tr><td>**Ancienneté dans le logement**</td><td>**Nombre de ménages**</td><td>**Part relative**</td><td>**Dynamique territoriale**</td></tr></thead><tbody><tr><td><span>**Moins de 2 ans**</span></td><td><span>534</span></td><td><span>**12,0 %**</span></td><td><span>Mobilité immédiate (marché locatif et mutations)</span></td></tr><tr><td><span>**2 à 4 ans**</span></td><td><span>810</span></td><td><span>**18,2 %**</span></td><td><span>Attractivité récente (post-confinement)</span></td></tr><tr><td><span>**5 à 9 ans**</span></td><td><span>895</span></td><td><span>**20,1 %**</span></td><td><span>**Installation durable (période 2016-2020)**</span></td></tr><tr><td><span>**10 ans et plus**</span></td><td><span>2 212</span></td><td><span>**49,7 %**</span></td><td><span>Noyau dur / Stabilité patrimoniale</span></td></tr><tr><td><span>**TOTAL**</span></td><td><span>**4 451**</span></td><td><span>**100 %**</span></td><td><span>-</span></td></tr></tbody></table>

---

### 💡 Interprétation technique pour le rapport

**1. Le "Seuil de Renouvellement" :**

On constate que **50,3 %** des ménages de Bandol se sont installés dans leur logement actuel il y a **moins de 10 ans**. Cela démontre une dynamique de renouvellement de la population plus importante que ce que laisse suggérer le simple flux annuel de 12 %.

**2. Analyse du croisement avec Sitadel :**

Le croisement de cette donnée avec vos **131 chantiers** (429 logements) montre que la production neuve est absorbée par deux leviers :

- **Le renouvellement interne :** Une partie des 2 212 ménages installés depuis plus de 10 ans (souvent vieillissants) cherchent à quitter des villas ou des appartements sans ascenseur pour du neuf adapté.
- **L'apport extérieur :** Les 534 ménages arrivés depuis moins de 2 ans s'orientent prioritairement vers le parc récent ou neuf.

**3. Corrélation avec les revenus (Q1/Q2/Q3) :**

La stabilité (10 ans+) est fortement corrélée aux **propriétaires (67%)** disposant d'un revenu médian solide. À l'inverse, les tranches de moins de 5 ans d'ancienneté correspondent souvent aux actifs du **Q2** (en accession) ou aux locataires mobiles du **Q1**.

### 🚩 Conclusion de la documentation

Cette analyse prouve que Bandol n'est pas une "ville figée". Le turn-over réel sur une décennie concerne **un ménage sur deux**, validant ainsi la nécessité d'une offre de logements neufs continue pour accompagner cette rotation naturelle et répondre à l'attractivité du territoire.

# L'extraction OSM-raw à un OSM_territoire d'étude

Commandes itératives menées par l'IA pour raffiner OSM à l'échelle du territoire d'analyse avec une précision importante sur le regroupement des aménités

# Carnet des commandes itératives

C’est une excellente initiative. Pour **Nexte\_Stats**, disposer d'un "Playbook" SQL permet de reproduire cette précision chirurgicale sur n'importe quelle autre commune (Sanary, Six-Fours, etc.) en quelques minutes.

Voici la synthèse technique de notre workflow "Bandol", nettoyée des erreurs de syntaxe et optimisée pour ton architecture **PostGIS**.

---

## 📑 Playbook : Extraction &amp; Nettoyage OSM (Référentiel Nexte\_Stats)

Ce script part du principe que tes données brutes sont dans le schéma `osm_raw` (SRID 4326 ou 3857) et que ta commune cible est définie par sa table de parcelles dans le schéma `83009_bandol` (SRID 2154).

### 1. Préparation de l'emprise (La "Découpe")

Avant d'extraire, on définit la forme exacte de la commune pour éviter les "gros carrés" (Bounding Box).

<div class="code-block ng-tns-c2968650486-2138 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2138 ng-star-inserted"><span class="ng-tns-c2968650486-2138">SQL</span><div class="buttons ng-tns-c2968650486-2138 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-2138"><div class="animated-opacity ng-tns-c2968650486-2138"></div></div></div>```
-- On utilise l'Union des parcelles comme emporte-pièce universel
-- On la stocke mentalement comme : (SELECT ST_Union(geom) FROM "83009_bandol".bandol_parcelles)

```

<div class="code-block ng-tns-c2968650486-2138 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--2"><div class="formatted-code-block-internal-container ng-tns-c2968650486-2138"><div class="animated-opacity ng-tns-c2968650486-2138"></div></div></div>---

### 2. Couche Bâtiments (Buildings)

*Extraction des emprises bâties, transformation en Lambert-93 et nettoyage des géométries aberrantes.*

<div class="code-block ng-tns-c2968650486-2139 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql-1"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2139 ng-star-inserted"><span class="ng-tns-c2968650486-2139">SQL</span><div class="buttons ng-tns-c2968650486-2139 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-2139"><div class="animated-opacity ng-tns-c2968650486-2139"></div></div></div>```
DROP TABLE IF EXISTS "83009_bandol".osm_buildings;

CREATE TABLE "83009_bandol".osm_buildings AS
SELECT b.osm_id, b.name, b.building, b.tags,
       ST_Multi(ST_Transform(b.way, 2154)) as geom
FROM osm_raw.buildings b
WHERE ST_Intersects(
    b.way, 
    (SELECT ST_Transform(ST_Union(geom), 3857) FROM "83009_bandol".bandol_parcelles)
);

-- Nettoyage des artefacts et indexation
DELETE FROM "83009_bandol".osm_buildings WHERE ST_Area(geom) > 50000;
CREATE INDEX idx_osm_buildings_geom ON "83009_bandol".osm_buildings USING GIST(geom);

```

<div class="code-block ng-tns-c2968650486-2139 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--6"><div class="formatted-code-block-internal-container ng-tns-c2968650486-2139"><div class="animated-opacity ng-tns-c2968650486-2139"></div></div></div>---

### 3. Couche Voirie (Roads / Ways)

*Découpage (ST\_Intersection) pour que les routes s'arrêtent pile à la frontière communale.*

<div class="code-block ng-tns-c2968650486-2140 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql-2"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2140 ng-star-inserted"><span class="ng-tns-c2968650486-2140">SQL</span><div class="buttons ng-tns-c2968650486-2140 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-2140"><div class="animated-opacity ng-tns-c2968650486-2140"></div></div></div>```
DROP TABLE IF EXISTS "83009_bandol".osm_roads;

CREATE TABLE "83009_bandol".osm_roads AS
SELECT r.osm_id, r.name, r.highway, r.ref, r.oneway, r.surface, r.z_order,
       ST_Multi(ST_Intersection(
           ST_Transform(r.way, 2154), 
           (SELECT ST_Union(geom) FROM "83009_bandol".bandol_parcelles)
       )) as geom
FROM osm_raw.roads r
WHERE ST_Intersects(
    r.way, 
    (SELECT ST_Transform(ST_Union(geom), 3857) FROM "83009_bandol".bandol_parcelles)
);

CREATE INDEX idx_osm_roads_geom ON "83009_bandol".osm_roads USING GIST(geom);

```

<div class="code-block ng-tns-c2968650486-2140 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10"><div class="formatted-code-block-internal-container ng-tns-c2968650486-2140"><div class="animated-opacity ng-tns-c2968650486-2140"></div></div></div>---

### 4. Couche Occupation du Sol (Landuse)

*Gestion spécifique du format Geofabrik (fclass) et conversion Lambert-93.*

<div class="code-block ng-tns-c2968650486-2141 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql-3"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2141 ng-star-inserted"><span class="ng-tns-c2968650486-2141">SQL</span><div class="buttons ng-tns-c2968650486-2141 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-2141"><div class="animated-opacity ng-tns-c2968650486-2141"></div></div></div>```
DROP TABLE IF EXISTS "83009_bandol".osm_landuse;

CREATE TABLE "83009_bandol".osm_landuse AS 
SELECT l.osm_id, l.name, l.fclass as landuse_type, 
       ST_Multi(ST_Intersection(
           ST_Transform(l.geom, 2154), 
           (SELECT ST_Union(geom) FROM "83009_bandol".bandol_parcelles)
       )) as geom
FROM osm_raw.landuse l
WHERE ST_Intersects(
    ST_Transform(l.geom, 2154), 
    (SELECT ST_Union(geom) FROM "83009_bandol".bandol_parcelles)
);

CREATE INDEX idx_osm_landuse_geom ON "83009_bandol".osm_landuse USING GIST(geom);

```

<div class="code-block ng-tns-c2968650486-2141 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--14"><div class="formatted-code-block-internal-container ng-tns-c2968650486-2141"><div class="animated-opacity ng-tns-c2968650486-2141"></div></div></div>---

### 5. Couche Équipements Publics (Amenities - La "Hiérarchie")

*Fusion des points et des centroïdes de bâtiments pour créer un référentiel de services unique.*

<div class="code-block ng-tns-c2968650486-2142 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql-4"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-2142 ng-star-inserted"><span class="ng-tns-c2968650486-2142">SQL</span><div class="buttons ng-tns-c2968650486-2142 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-2142"><div class="animated-opacity ng-tns-c2968650486-2142"></div></div></div>```
DROP TABLE IF EXISTS "83009_bandol"."83009_equipements_publics";

-- Étape A : Import des points natifs
CREATE TABLE "83009_bandol"."83009_equipements_publics" AS
SELECT osm_id, name, amenity, tags, ST_Transform(way, 2154) as geom
FROM osm_raw.points
WHERE ST_Intersects(way, (SELECT ST_Transform(ST_Union(geom), 3857) FROM "83009_bandol".bandol_parcelles))
AND (amenity IN ('school','townhall','police','hospital','library','post_office','community_centre'));

-- Étape B : Ajout des centroïdes des bâtiments (Mairie, Gymnases, etc.)
INSERT INTO "83009_bandol"."83009_equipements_publics" (osm_id, name, amenity, geom)
SELECT osm_id, name, COALESCE(amenity, tags->'leisure', tags->'building'), ST_Centroid(geom)
FROM "83009_bandol".osm_buildings
WHERE amenity IN ('school','townhall','hospital')
   OR tags->'leisure' IN ('sports_centre', 'stadium')
   OR tags->'building' IN ('public', 'train_station');

CREATE INDEX idx_equip_pub_geom ON "83009_bandol"."83009_equipements_publics" USING GIST(geom);

```

<div class="code-block ng-tns-c2968650486-2142 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--18"><div class="formatted-code-block-internal-container ng-tns-c2968650486-2142"><div class="animated-opacity ng-tns-c2968650486-2142"></div></div></div>---

### 💡 Pourquoi ce référentiel est "pro" ?

1. **SRID Unique (2154)** : Plus de bugs d'affichage ou de calculs en degrés. Tout est en mètres.
2. **ST\_Intersection vs ST\_Intersects** : On a fait la distinction entre "ce qui touche" (bâtiments) et "ce qui est coupé" (routes/landuse).
3. **Performance** : Les index GIST garantissent que tes cartes QGIS s'affichent instantanément, même avec 10 000 bâtiments.

**Une question me taraude maintenant que tout est prêt :** sur quel type d'analyse veux-tu que l'on se concentre en premier ? Est-ce le "taux de vacance théorique" (Bâtiments sans ventes DVF) ou la "pression foncière sur les vignobles" ?

# 260407-contenu des tables OSM dans OSM-raw

  
debian@vps-02c1f983-vps-ovh-net:~$ docker exec -i alteris\_postgis psql -U alteris\_admin -d alteris\_geo -c "\\d osm\_raw.buildings"  
 Table "osm\_raw.buildings"  
 Column | Type | Collation | Nullable | Default  
\--------------------+-------------------------+-----------+----------+---------  
 osm\_id | bigint | | |  
 access | text | | |  
 addr:housename | text | | |  
 addr:housenumber | text | | |  
 addr:interpolation | text | | |  
 admin\_level | text | | |  
 aerialway | text | | |  
 aeroway | text | | |  
 amenity | text | | |  
 area | text | | |  
 barrier | text | | |  
 bicycle | text | | |  
 brand | text | | |  
 bridge | text | | |  
 boundary | text | | |  
 building | text | | |  
 construction | text | | |  
 covered | text | | |  
 culvert | text | | |  
 cutting | text | | |  
 denomination | text | | |  
 disused | text | | |  
 embankment | text | | |  
 foot | text | | |  
 generator:source | text | | |  
 harbour | text | | |  
 highway | text | | |  
 historic | text | | |  
 horse | text | | |  
 intermittent | text | | |  
 junction | text | | |  
 landuse | text | | |  
 layer | text | | |  
 leisure | text | | |  
 lock | text | | |  
 man\_made | text | | |  
 military | text | | |  
 motorcar | text | | |  
 name | text | | |  
 natural | text | | |  
 office | text | | |  
 oneway | text | | |  
 operator | text | | |  
 place | text | | |  
 population | text | | |  
 power | text | | |  
 power\_source | text | | |  
 public\_transport | text | | |  
 railway | text | | |  
 ref | text | | |  
 religion | text | | |  
 route | text | | |  
 service | text | | |  
 shop | text | | |  
 sport | text | | |  
 surface | text | | |  
 toll | text | | |  
 tourism | text | | |  
 tower:type | text | | |  
 tracktype | text | | |  
 tunnel | text | | |  
 water | text | | |  
 waterway | text | | |  
 wetland | text | | |  
 width | text | | |  
 wood | text | | |  
 z\_order | integer | | |  
 way\_area | real | | |  
 tags | hstore | | |  
 way | geometry(Geometry,3857) | | |  
Indexes:  
 "planet\_osm\_polygon\_osm\_id\_idx" btree (osm\_id)  
 "planet\_osm\_polygon\_way\_idx" gist (way)  
Triggers:  
 planet\_osm\_polygon\_osm2pgsql\_valid BEFORE INSERT OR UPDATE ON osm\_raw.buildings FOR EACH ROW EXECUTE FUNCTION planet\_osm\_polygon\_osm2pgsql\_valid()

debian@vps-02c1f983-vps-ovh-net:~$

# 260407-Extraction OSM réussie sur Bandol

docker exec -i alteris\_postgis psql -U alteris\_admin -d alteris\_geo -c "  
/\* 1. NETTOYAGE PRÉALABLE \*/  
DROP TABLE IF EXISTS \\"83009\_bandol\\".armature\_urbaine\_osm;

/\* 2. EXTRACTION MULTI-SOURCES (Points, Bâtiments, Zones) \*/  
CREATE TABLE \\"83009\_bandol\\".armature\_urbaine\_osm AS   
SELECT \* FROM (  
\-- BLOC A : Points d'intérêts (Commerces, Santé, Services)  
 SELECT   
 osm\_id::bigint, name, amenity, leisure, shop,   
 'point'::text as osm\_type,  
 ST\_Transform(way, 2154) as geom  
 FROM osm\_raw.points   
 WHERE (name IS NOT NULL)  
 AND (amenity NOT IN ('bench', 'waste\_basket', 'post\_box', 'vending\_machine', 'parking\_entrance', 'hunting\_stand', 'parking') OR amenity IS NULL)

 UNION ALL

\-- BLOC B : Bâtiments structurants (Écoles, Mairie, Hôpitaux)  
\-- On utilise ST\_Centroid pour transformer les surfaces en points localisables  
 SELECT   
 osm\_id::bigint, name, amenity, leisure, NULL::text as shop,  
 'building'::text as osm\_type,  
 ST\_Transform(ST\_Centroid(way), 2154) as geom  
 FROM osm\_raw.buildings  
 WHERE (name IS NOT NULL)  
 AND (amenity NOT IN ('parking', 'garages', 'waste\_disposal') OR amenity IS NULL)

 UNION ALL

\-- BLOC C : Zones de loisirs et parcs (Stades, Jardins)  
\-- Sécurisation du champ 'landuse' via un cast ::text pour éviter les erreurs de type record  
 SELECT   
 osm\_id::bigint, name, NULL::text as amenity, NULL::text as leisure, NULL::text as shop,  
 'landuse'::text as osm\_type,  
 ST\_Transform(ST\_Centroid(geom), 2154) as geom  
 FROM osm\_raw.landuse  
 WHERE name IS NOT NULL   
 AND \\"landuse\\"::text NOT IN ('cemetery', 'residential', 'industrial', 'grass', 'forest', 'farmland')  
) sub  
WHERE geom IS NOT NULL;

/\* 3. FILTRAGE GÉOGRAPHIQUE (Buffer de 5km autour du projet) \*/  
\-- On force le SRID 2154 pour la comparaison spatiale  
DELETE FROM \\"83009\_bandol\\".armature\_urbaine\_osm  
WHERE NOT ST\_DWithin(  
 geom,   
 (SELECT ST\_SetSRID(ST\_Centroid(ST\_Extent(geom)), 2154) FROM \\"83009\_bandol\\".bandol\_parcelles),   
 5000  
);

/\* 4. QUALIFICATION THÉMATIQUE (Tri pour la légende QGIS) \*/  
ALTER TABLE \\"83009\_bandol\\".armature\_urbaine\_osm ADD COLUMN IF NOT EXISTS categorie text;

UPDATE \\"83009\_bandol\\".armature\_urbaine\_osm SET categorie =   
 CASE   
 WHEN amenity IN ('school', 'kindergarten', 'college', 'university') OR name ILIKE '%école%' OR name ILIKE '%collège%' THEN 'Enseignement'  
 WHEN amenity IN ('restaurant', 'cafe', 'bar', 'fast\_food', 'pub') THEN 'Restauration/Sorties'  
 WHEN amenity IN ('pharmacy', 'doctors', 'hospital', 'dentist') THEN 'Santé'  
 WHEN amenity IN ('bank', 'post\_office', 'townhall', 'police') THEN 'Services Publics/Banques'  
 WHEN shop IS NOT NULL THEN 'Commerce'  
 WHEN leisure IS NOT NULL OR osm\_type = 'landuse' THEN 'Loisirs/Espaces Verts'  
 ELSE 'Autre'  
 END;

/\* 5. OPTIMISATION (Index GIST pour affichage rapide sous QGIS) \*/  
CREATE INDEX idx\_armature\_geom ON \\"83009\_bandol\\".armature\_urbaine\_osm USING GIST(geom);"

# Les statistiques Sitadel

Pour documenter cette procédure, il est crucial de noter que nous avons abandonné les outils classiques comme `ogr2ogr` (trop sensibles aux noms de colonnes longs de Sitadel) pour une méthode **hybride Python + SQL**.

Cette approche est la seule qui garantit 100% de succès sur des fichiers de plus de 100 000 lignes avec des en-têtes complexes.

---

## 📑 Procédure d'import Sitadel (CSV vers PostGIS)

### 1. Préparation de la structure SQL

Avant d'importer, on crée une table "cible" avec des noms de colonnes courts et explicites. Cela évite que PostgreSQL ne tronque les noms originaux (ex: *"surface de plancher de la destination..."*) et ne crée des doublons.

<div class="code-block ng-tns-c2968650486-5619 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-5619 ng-star-inserted"><span class="ng-tns-c2968650486-5619">Bash</span><div class="buttons ng-tns-c2968650486-5619 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-5619"><div class="animated-opacity ng-tns-c2968650486-5619"></div></div></div>```
# Connexion à la base et création de la table
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "
DROP TABLE IF EXISTS sitadel_2026_04.logements_chantiers;
CREATE TABLE sitadel_2026_04.logements_chantiers (
    num_permis text,    -- Identifiant DAU
    code_insee text,    -- Code commune
    date_chantier text, -- Date DOC
    nb_log text,        -- Nombre total logements
    nb_social text,     -- Logements locatifs sociaux
    promoteur text,     -- Dénomination Personne Morale
    adresse_num text,   -- Numéro de voie
    adresse_voie text,  -- Libellé de voie
    parcelle text       -- Numéro parcelle cadastrale
);"

```

<div class="code-block ng-tns-c2968650486-5619 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--2"><div class="formatted-code-block-internal-container ng-tns-c2968650486-5619"><div class="animated-opacity ng-tns-c2968650486-5619"></div></div></div>---

### 2. Le Script d'import "Sniper" (Python)

Plutôt que d'envoyer tout le fichier (200+ colonnes), ce script sélectionne uniquement les colonnes **légales** nécessaires. Il gère également le séparateur (virgule `,` ou point-virgule `;`) et nettoie les données à la volée.

**Code à exécuter dans le terminal du VPS :**

<div class="code-block ng-tns-c2968650486-5620 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-python"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-5620 ng-star-inserted"><span class="ng-tns-c2968650486-5620">Python</span><div class="buttons ng-tns-c2968650486-5620 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-5620"><div class="animated-opacity ng-tns-c2968650486-5620"></div></div></div>```
python3 -c "
import csv, sys

# Mapping entre les en-têtes officiels Sitadel et nos colonnes SQL
mapping = {
    'Numéro d’enregistrement de la DAU': 'num_permis',
    'Code de la commune du lieu des travaux': 'code_insee',
    'Date réelle d’ouverture de chantier': 'date_chantier',
    'Nombre total de logements créés': 'nb_log',
    'Nb de logements locatifs sociaux': 'nb_social',
    'Dénomination d’un demandeur avéré en tant que personne morale': 'promoteur',
    'Numéro de voie du terrain': 'adresse_num',
    'Libellé de la voie du terrain': 'adresse_voie',
    'Numéro parcelle cadastrale 1': 'parcelle'
}

with open('2604_SitadelR93_logements.csv', 'r', encoding='utf-8-sig') as f:
    # Lecture avec séparateur virgule (export QGIS standard)
    reader = csv.reader(f, delimiter=',')
    header = next(reader)
    
    # Nettoyage des en-têtes (suppression des guillemets et espaces)
    header = [h.strip().replace('\"', '') for h in header]
    
    # Identification des index de colonnes
    indices = [header.index(k) if k in header else None for k in mapping.keys()]

    # Sortie formatée pour PostgreSQL COPY
    writer = csv.writer(sys.stdout, delimiter='|')
    for row in reader:
        if len(row) > 0:
            # On écrit uniquement les colonnes mappées
            writer.writerow([row[i] if i is not None and i < len(row) else '' for i in indices])
" | docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo \
-c "COPY sitadel_2026_04.logements_chantiers FROM STDIN WITH (FORMAT csv, DELIMITER '|');"

```

<div class="code-block ng-tns-c2968650486-5620 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--6"><div class="formatted-code-block-internal-container ng-tns-c2968650486-5620"><div class="animated-opacity ng-tns-c2968650486-5620"></div></div></div>---

### 3. Pourquoi cette méthode est la meilleure ?

<div class="horizontal-scroll-wrapper" id="bkmrk-caract%C3%A9ristique-avan"><div class="table-block-component"><div class="table-block has-export-button new-table-style is-at-scroll-start is-at-scroll-end"><div class="table-content not-end-of-paragraph"><table><thead><tr><th><span>Caractéristique</span></th><th><span>Avantage</span></th></tr></thead><tbody><tr><td><span>**Vitesse**</span></td><td><span>Le moteur `COPY` de PostgreSQL importe 120 000 lignes en moins de 3 secondes.</span></td></tr><tr><td><span>**Fiabilité**</span></td><td><span>En utilisant un délimiteur personnalisé (`</span></td></tr><tr><td><span>**Légèreté**</span></td><td><span>On n'occupe pas d'espace disque inutile en ignorant les 190 colonnes techniques non utilisées.</span></td></tr><tr><td><span>**RGPD**</span></td><td><span>On peut filtrer ou anonymiser les données sensibles avant qu'elles n'atteignent la base de données.</span></td></tr></tbody></table>

</div><div class="table-footer hide-from-message-actions"></div></div></div></div>---

### 🛠️ Vérification de l'import

Pour valider que la procédure a réussi, on compte les lignes chargées :

<div class="code-block ng-tns-c2968650486-5621 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-1"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-5621 ng-star-inserted"><span class="ng-tns-c2968650486-5621">Bash</span><div class="buttons ng-tns-c2968650486-5621 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-5621"><div class="animated-opacity ng-tns-c2968650486-5621"></div></div></div>```
docker exec -i alteris_postgis psql -U alteris_admin -d alteris_geo -c "SELECT count(*) FROM sitadel_2026_04.logements_chantiers;"

```

<div class="code-block ng-tns-c2968650486-5621 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--11"><div class="formatted-code-block-internal-container ng-tns-c2968650486-5621"><div class="animated-opacity ng-tns-c2968650486-5621"></div></div></div>**2/ les extractions**

On enchaîne. Une fois que la donnée est "au chaud" dans PostGIS, l'objectif est d'extraire l'intelligence métier. Pour ton rapport, on ne veut pas de fioritures : on veut de la donnée **légale**, **datée** et **localisée**.

Voici la documentation des requêtes SQL pour extraire le bilan des chantiers engagés à Bandol.

---

## 📑 Procédure d'Analyse SQL (Indicateurs C5e)

### 1. Bilan Annuel des Chantiers Réels

Cette requête groupe les données par année en se basant sur la **Date de Déclaration d'Ouverture de Chantier (DOC)**. C'est l'indicateur de santé réelle de la construction.

<div class="code-block ng-tns-c2968650486-7679 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-7679 ng-star-inserted"><span class="ng-tns-c2968650486-7679">SQL</span><div class="buttons ng-tns-c2968650486-7679 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-7679"><div class="animated-opacity ng-tns-c2968650486-7679"></div></div></div>```
-- Calcul du flux annuel de logements engagés
SELECT 
    LEFT(date_chantier, 4) as annee, 
    COUNT(*) as nb_permis_doc,
    SUM(nb_log::int) as total_logements,
    SUM(COALESCE(nb_social, '0')::int) as dont_social,
    ROUND((SUM(COALESCE(nb_social, '0')::float) / NULLIF(SUM(nb_log::float), 0) * 100)::numeric, 1) as part_social_pct
FROM sitadel_2026_04.logements_chantiers 
WHERE code_insee = '83009' -- Filtre Bandol
  AND date_chantier >= '2019-01-01'
GROUP BY annee
ORDER BY annee DESC;

```

<div class="code-block ng-tns-c2968650486-7679 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--15"><div class="formatted-code-block-internal-container ng-tns-c2968650486-7679"><div class="animated-opacity ng-tns-c2968650486-7679"></div></div></div>---

### 2. Identification des 10 Projets Majeurs

Cette requête permet d'isoler les opérations qui structurent le marché local. On y intègre l'identifiant DAU (Numéro de permis) pour assurer la traçabilité juridique.

<div class="code-block ng-tns-c2968650486-7680 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-sql-1"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-7680 ng-star-inserted"><span class="ng-tns-c2968650486-7680">SQL</span><div class="buttons ng-tns-c2968650486-7680 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-7680"><div class="animated-opacity ng-tns-c2968650486-7680"></div></div></div>```
-- Listing des 10 plus gros chantiers depuis 2019
SELECT 
    num_permis as dau_officiel,
    COALESCE(NULLIF(promoteur, ''), 'PARTICULIER') as operateur, 
    nb_log::int as nb_log,
    COALESCE(nb_social, '0')::int as nb_social,
    date_chantier as date_doc,
    CONCAT(adresse_num, ' ', adresse_voie) as adresse_chantier,
    parcelle as ref_cadastrale
FROM sitadel_2026_04.logements_chantiers 
WHERE code_insee = '83009' 
  AND date_chantier >= '2019-01-01'
ORDER BY nb_log::int DESC
LIMIT 10;

```

<div class="code-block ng-tns-c2968650486-7680 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--19"><div class="formatted-code-block-internal-container ng-tns-c2968650486-7680"><div class="animated-opacity ng-tns-c2968650486-7680"></div></div></div>---

### 3. Les points de vigilance technique (pour ta doc)

- **Le Cast Type (`::int`)** : Comme Sitadel contient parfois des cases vides ou des caractères bizarres, nous avons importé les colonnes en `TEXT`. Pour faire des calculs (`SUM`, `ORDER BY`), il est impératif de forcer le type en entier avec `::int` ou `::float`.
- **Le `COALESCE`** : Indispensable pour la colonne Social. Si la case est vide, PostgreSQL renvoie `NULL`. Le `COALESCE(..., '0')` force la valeur à zéro pour ne pas fausser les additions.
- **Le `NULLIF`** : Prévient l'erreur "division par zéro" dans le calcul du pourcentage si une année ne compte aucun logement.

---

### 📦 4. Export vers le format GeoPackage (GPKG)

Pour que ton équipe SIG puisse utiliser ces données sans se reconnecter à la base, on documente la commande d'exportation vers un fichier portable.

<div class="code-block ng-tns-c2968650486-7681 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-bash-2"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c2968650486-7681 ng-star-inserted"><span class="ng-tns-c2968650486-7681">Bash</span><div class="buttons ng-tns-c2968650486-7681 ng-star-inserted"></div></div><div class="formatted-code-block-internal-container ng-tns-c2968650486-7681"><div class="animated-opacity ng-tns-c2968650486-7681"></div></div></div>```
# Export de la table filtrée Bandol vers un fichier GPKG
docker exec -i alteris_postgis ogr2ogr -f GPKG /tmp/bandol_bilan_chantiers.gpkg \
  PG:"host=localhost dbname=alteris_geo user=alteris_admin" \
  -sql "SELECT * FROM sitadel_2026_04.logements_chantiers WHERE code_insee = '83009' AND date_chantier >= '2019-01-01'" \
  -nln sitadel_chantiers_engages

# Récupération du fichier sur le stockage local du VPS
docker cp alteris_postgis:/tmp/bandol_bilan_chantiers.gpkg ./bandol_bilan_chantiers_2019_2026.gpkg

```

<div class="code-block ng-tns-c2968650486-7681 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--24"><div class="formatted-code-block-internal-container ng-tns-c2968650486-7681"><div class="animated-opacity ng-tns-c2968650486-7681"></div></div></div>---

**C'est la fin du volet "Données &amp; Requêtes".** Veux-tu qu'on termine cette documentation par la **partie Cartographique** : comment faire la jointure dans QGIS entre ce fichier GPKG et tes parcelles cadastrales pour obtenir la carte finale des chantiers ?

# Données Filosofi - téléchargement

https://www.insee.fr/fr/statistiques/8735108?sommaire=8735243