尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Tableau de bord du canton de Vaud, commune par commune. Sa première couche, Permis (l'ancien site Chantiers Vaud), est décrite ci-dessous.
Branche
prototype/live-api. Ce site ne stocke ni ne rediffuse les données CAMAC. C'est le navigateur de chaque visiteur qui interroge directement le service public du canton (ogc.vd.ch, couche ArcGISwmsVD/MapServer/537). Aucun fichier de données cantonales n'est produit, versionné ou publié. La version qui héberge les données reste surmain, pour comparer les deux.
Carte citoyenne des demandes de permis de construire du canton de Vaud : enquêtes publiques en cours avec leur date de fin, décisions attendues, et historique depuis 1999 (environ 112 000 dossiers). Le site informe ; il ne prend pas position sur les projets.
/?d=<n°> ouvre un dossier, /?commune=<slug> cadre une commune.
Le marqueur « autour de moi » n'est jamais écrit dans l'URL ; le centre de la carte, lui, l'est (après
« Autour de moi », un lien partagé montre donc le quartier). La mesure d'audience GoatCounter, active seulement
si VITE_GOATCOUNTER est défini à la construction, compte chaque page par son chemin seul, sans ces paramètres
(web/src/lib/audience.ts)./infos-legales) : consultation, observations, oppositions et recours, avec renvois
aux textes officiels (LATC, RLATC, LPA-VD, LAT, LTF).Les noms de propriétaire, de requérant ou d'architecte des avis officiels ne sont pas repris. Dans les descriptions
libres, les noms de particuliers sont masqués dans le navigateur, avant affichage
(web/src/lib/masquage.ts, portage exact de mask_names du script de la version hébergée, conservé sous
l'étiquette chantiers-hebergee, vérifié sur les 112 534 descriptions : 229 masquées, aucune différence) ; les
entreprises et collectivités restent nommées.
| Besoin | Requête au canton (depuis le navigateur) |
|---|---|
| Dossiers en cours (au chargement) | ETAT = enquête, ou procédure de moins de 3 ans : ~2400 dossiers, 2 pages en parallèle, ~0,4 s |
| Fiche d'un dossier | NO_CAMAC = <n°> (~0,2 à 0,5 s), ou par lots NO_CAMAC IN (…) pour la liste |
| Historique sur la carte | Points légers (n°, statut, nature, date), une année à la fois : ~4 000 points / ~60 Ko par année |
| Page commune | Points légers de l'emprise de la commune, rattachés à la commune dans le navigateur |
web/src/lib/communes.ts (point dans polygone, sinon commune la plus proche),
avec les limites simplifiées de web/static/communes-limites.json. Ces limites et l'index
web/static/communes.json viennent de swisstopo (swissBOUNDARIES3D, données ouvertes). Ils sont produits par
pipeline/communes.py et versionnés.web/src/lib/api.ts. Pagination parallèle, 6 requêtes au plus en même temps, cache mémoire
pour la visite, délai d'attente de 20 s, messages d'erreur si ogc.vd.ch ne répond pas. Le module refuse de
s'exécuter hors du navigateur : ni le build ni le serveur de développement n'interrogent le canton.Limites du serveur cantonal, constatées le 13 octobre 2026 :
export (image) n'affiche rien au-delà du 1:10 000, et dynamicLayers ne lève pas cette limite. Les images ne
servent donc pas pour l'historique à l'échelle du canton : la carte charge des points légers.mainogc.vd.ch.jj/mm/aaaa de
DATE_DECISION), et les données sont toujours celles du jour.| Dossier | Rôle |
|---|---|
web/ | Site statique SvelteKit + MapLibre (fond swisstopo) ; données CAMAC lues en direct par src/lib/api.ts et src/lib/couches/permis/donnees.svelte.ts |
pipeline/ | communes.py produit l'index et les limites des communes (swisstopo). schema.py : modèles du schéma commun. cron.py : un passage du cron. hotels_de_ville.py : outil d'initialisation de hotels-de-ville.csv |
schema/ | JSON Schema générés depuis pipeline/schema.py (ne pas modifier) |
sources.json | Déclaration de chaque source (attribution, voie d'accès, fraîcheur, Couverture, sonde), lue par le site et le cron |
.github/workflows/ | Construction et publication sur GitHub Pages, sans aucune donnée CAMAC |
Prérequis : Node 24+, pnpm. uv seulement pour régénérer les communes ou le schéma commun, et pour les tests du pipeline.
cd web && pnpm install && pnpm dev
Tests du site (Vitest, sans navigateur ni appel au canton) :
cd web && pnpm test
Préparation des communes, relancée à chaque fusion : limites, hôtels de ville (lus dans
pipeline/hotels-de-ville.csv), cadre de la partie terrestre et anciens noms (répertoire historisé de l'OFS). Elle
échoue si un hôtel de ville du CSV tombe hors de la partie terrestre de sa commune, et place une commune absente du
CSV en repli avec un avertissement. Elle télécharge environ 450 Mo dans data/cache/ la première fois.
cd pipeline && uv run python communes.py
Hôtels de ville, seulement pour une nouvelle commune : l'outil d'initialisation réécrit pipeline/hotels-de-ville.csv
(qui fait foi ; les lignes manuel n'y bougent jamais) et la liste des cas à revoir,
pipeline/hotels-de-ville-a-revoir.csv. Il télécharge environ 500 Mo dans data/cache/hotels-de-ville/.
cd pipeline && uv run python hotels_de_ville.py
Chaque source est déclarée une seule fois, dans sources.json à la racine ; toutes les attributions affichées en
viennent. La construction du site échoue si le fichier ne suit pas le schéma ou cite un n° OFS qui n'est pas une
commune actuelle.
Le schéma commun (ADR 0013) s'écrit seulement dans les modèles Pydantic de pipeline/schema.py. On en tire le JSON
Schema (schema/) puis les types du site (web/src/lib/schema.ts), tous deux versionnés. Après une modification
des modèles :
pnpm --dir web schema # régénère schema/ et web/src/lib/schema.ts (uv et pnpm requis)
cd pipeline && uv run pytest # tests du pipeline
Le cron (ADR 0005 et 0014) envoie une sonde à chaque source de sources.json qui a un bloc sonde, puis écrit
etat-sources.json et schema/ dans le dépôt de données vigie-vaud-donnees, committe et pousse. Pendant J0, on le
lance en local contre un clone de ce dépôt ; --sans-push écrit l'état et committe sans pousser, et affiche les
issues panne-source qu'il ouvrirait ou fermerait au lieu de toucher à GitHub :
cd pipeline && uv run python cron.py --depot ../../vigie-vaud-donnees --sans-push
Le site lit etat-sources.json sur les Pages du dépôt de données (donnees dans config.json). Pour qu'il lise
plutôt ce clone local, par exemple sur la page /couverture, on le désigne au serveur de développement :
cd web && DONNEES_LOCALES=../../vigie-vaud-donnees pnpm dev
Au passage public, le déclencheur pipeline/depot-donnees/.github/workflows/cron.yml se pose tel quel dans le dépôt
de données : il appelle toutes les 30 minutes le workflow réutilisable .github/workflows/cron.yml, qui fait le
passage puis publie le dépôt de données sur Pages, avec son seul GITHUB_TOKEN. Ce jeton sert aussi aux issues
panne-source : une issue « Panne : » s'ouvre quand la source passe en panne (sauf si elle est
déjà ouverte), puis est commentée et fermée à son retour. Une erreur de l'API des issues ne fait pas échouer le
passage : l'état est publié quand même, et le passage suivant ouvre ou ferme ce qui a manqué.
Le même passage importe les conseils (ADR 0015) : chacun une fois par jour, au premier passage après 7 h à Lausanne,
depuis le jour de son dernier import réussi (conseils/import.json), et de nouveau au passage suivant si l'import a
échoué. Quand aucun import d'un conseil n'a réussi depuis plus de 24 h (ou dès le premier échec d'un conseil qui n'a
jamais été importé), une issue import-conseils « Import en échec : » s'ouvre, puis est commentée et fermée au premier import réussi ; la source n'est pas
mise en panne pour autant, seules les sondes en décident. Le rattrapage de tout l'historique d'OpenParlData suit le
même chemin avec --rattrapage, sans toucher aux sites des communes ; le rattrapage ciblé des sites communaux, avec
--rattrapage-cible suivi d'une plateforme (i-web) ou du n° OFS d'une commune scrapée, rouvre toutes leurs pages,
sans plafond de requêtes, au même débit, sans relire OpenParlData ni les autres communes, et note son heure dans
conseils/import.json (rattrapages). En local sans rien pousser :
cd pipeline && uv run python cron.py --depot ../../vigie-vaud-donnees --sans-push --rattrapage
cd pipeline && uv run python cron.py --depot ../../vigie-vaud-donnees --sans-push --rattrapage-cible i-web
ou dans le dépôt de données, par un lancement manuel du workflow « Cron » avec la case rattrapage cochée ou le
champ rattrapage_cible rempli. Rattrapages et passages ordinaires partagent le même groupe concurrency : ils ne
tournent jamais en même temps. Mais ce groupe ne garde qu'une seule exécution en attente : un rattrapage lancé
pendant un passage attend sa fin, et si le passage planifié suivant (à :17 ou :47) arrive avant, il prend sa place
dans la file et le rattrapage est annulé, sans autre trace que dans l'onglet Actions. On lance donc un rattrapage
quand aucun passage ne tourne : quelques minutes après :17 ou :47, une fois le passage fini (hors du premier passage
après 7 h à Lausanne, qui importe les sites et dure jusqu'à 45 minutes), puis on vérifie dans Actions qu'il a démarré
et on le relance s'il a été annulé. Une fois lancé, c'est lui qui retient les passages planifiés jusqu'à sa fin.
Les fichiers de lecture (conseils/index.json, fil.json, les listes par conseil et par commune) se reconstruisent
seuls depuis l'archive, sans aucune requête à OpenParlData, après un changement de leur forme ou une réécriture à la
main de l'archive (ADR 0017) :
cd pipeline && uv run python conseils.py --depot ../../vigie-vaud-donnees --reconstruire
Les adresses du dépôt, du courriel de contact, du site public et des Pages du dépôt de données sont écrites une
seule fois, dans config.json à la racine. Le site les lit par web/src/lib/config.ts.
Le workflow ci.yml se lance sur chaque PR : svelte-check, la construction (qui valide sources.json), la
vérification qu'aucune donnée CAMAC n'est dans le site construit, la régénération du schéma commun (qui doit ne rien
changer) et les tests du pipeline (pytest).
Le workflow publier.yml se lance à la main. Il construit le site, sans aucun fichier de données cantonales, et le
publie sur GitHub Pages si la variable PUBLIER vaut true. Variables : BASE_PATH (ex. /vigie-vaud sans
domaine propre), GOATCOUNTER (facultatif).
Le code est sous licence AGPL-3.0 (fichier LICENSE). Les données restent sous les conditions de leur source.
Source : Géodonnées Etat de Vaud, couche « Demandes de permis de construire (enquête publique) » de la CAMAC (fiche viageo). Ces données sont dépourvues de foi publique : seule la Feuille des avis officiels (FAO) fait foi.
Leur utilisation est régie par la norme DCG 8401, qui interdit la rediffusion à des tiers sans autorisation de la Direction du cadastre et de la géoinformation. Ce prototype ne rediffuse rien : il ne fait qu'orienter le navigateur du visiteur vers le service public du canton, dont il met en forme les réponses.
Limites communales, fond de carte et recherche d'adresses © swisstopo.