From 632084ae6fd4dc6e104845c01f954fb183743de6 Mon Sep 17 00:00:00 2001 From: SAFINE LAGET Anis <anis.safine@beta.gouv.fr> Date: Mon, 10 Mar 2025 11:07:26 +0000 Subject: [PATCH] =?UTF-8?q?feat(QGIS):=20mieux=20int=C3=A9grer=20Camino=20?= =?UTF-8?q?dans=20QGIS=20(pub/pnm-public/camino!1662)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{01-utilisation/02-flux.md => qgis.md} | 2 +- docs-sources/mkdocs.yml | 2 +- packages/api/src/api/rest/format/titres.ts | 8 +- .../src/api/rest/index.test.integration.ts | 127 ++++++++++++++++-- .../footer.stories_snapshots_Default.html | 1 + packages/ui/src/components/page/footer.tsx | 11 ++ 6 files changed, 139 insertions(+), 12 deletions(-) rename docs-sources/docs/{01-utilisation/02-flux.md => qgis.md} (99%) diff --git a/docs-sources/docs/01-utilisation/02-flux.md b/docs-sources/docs/qgis.md similarity index 99% rename from docs-sources/docs/01-utilisation/02-flux.md rename to docs-sources/docs/qgis.md index 7c95c8364..7af893a4f 100644 --- a/docs-sources/docs/01-utilisation/02-flux.md +++ b/docs-sources/docs/qgis.md @@ -1,4 +1,4 @@ -# Flux GeoJSON +# Intégrer le Flux GeoJSON dans QGIS Les flux géographiques de Camino exposent les informations sur les titres miniers et autorisations au format GeoJSON. diff --git a/docs-sources/mkdocs.yml b/docs-sources/mkdocs.yml index 758ad4be6..c23ef5e28 100644 --- a/docs-sources/mkdocs.yml +++ b/docs-sources/mkdocs.yml @@ -1,9 +1,9 @@ site_name: Camino nav: - 'index.md' + - QGIS: 'qgis.md' - Utilisation: - 'API GraphQL': '01-utilisation/01-graphql.md' - - 'Flux GeoJson': '01-utilisation/02-flux.md' - Développement: - Introduction: '02-developpement/01-introduction.md' - 'Base de données': '02-developpement/02-base-de-donnees.md' diff --git a/packages/api/src/api/rest/format/titres.ts b/packages/api/src/api/rest/format/titres.ts index 60bfe147f..14064861d 100644 --- a/packages/api/src/api/rest/format/titres.ts +++ b/packages/api/src/api/rest/format/titres.ts @@ -23,6 +23,7 @@ import { getSections, getSectionsWithValue } from 'camino-common/src/static/titr import { DemarchesTypes } from 'camino-common/src/static/demarchesTypes' import { GetEntreprises, getEntreprises } from '../entreprises.queries' import { EntrepriseId } from 'camino-common/src/entreprise' +import { slugify } from 'camino-common/src/strings' const getFacadesMaritimeCell = (secteursMaritime: SecteursMaritimes[], separator: string): string => getFacadesComputed(secteursMaritime) @@ -126,7 +127,12 @@ export const titreGeojsonPropertiesFormat = ( const { departements, regions } = territoiresFind(communesIndex, titre.communes, titre.secteursMaritime) const { dateDebut, dateFin, dateDemande } = getTitreDates(titre) + const additionalInformation = titreContenuTableFormat(titre) + const cleanedAdditionalInformation = Object.keys(additionalInformation).reduce<Record<string, string>>((acc, value) => { + acc[slugify(value).replace(/-/g, '_')] = additionalInformation[value] + return acc + }, {}) return { id: titre.slug, nom: titre.nom, @@ -150,7 +156,7 @@ export const titreGeojsonPropertiesFormat = ( amodiataires_noms: titre.amodiataireIds?.map(id => entreprisesIndex[id]?.nom ?? '') ?? [], amodiataires_legal: titre.amodiataireIds?.map(id => entreprisesIndex[id]?.legal_etranger ?? entreprisesIndex[id]?.legal_siren ?? '') ?? [], references: titre.references && titre.references.map(reference => `${ReferencesTypes[reference.referenceTypeId].nom}: ${reference.nom}`), - ...titreContenuTableFormat(titre), + ...cleanedAdditionalInformation, } } diff --git a/packages/api/src/api/rest/index.test.integration.ts b/packages/api/src/api/rest/index.test.integration.ts index 659be2afa..932304974 100644 --- a/packages/api/src/api/rest/index.test.integration.ts +++ b/packages/api/src/api/rest/index.test.integration.ts @@ -1,31 +1,79 @@ import { dbManager } from '../../../tests/db-manager' import { afterAll, beforeAll, test, expect, vi, describe } from 'vitest' import type { Pool } from 'pg' -import { newTitreId } from '../../database/models/_format/id-create' +import { newDemarcheId, newEtapeId, newTitreId } from '../../database/models/_format/id-create' import { insertTitreGraph } from '../../../tests/integration-test-helper' import { titreSlugValidator } from 'camino-common/src/validators/titres' import { restDownloadCall } from '../../../tests/_utils' import { ADMINISTRATION_IDS } from 'camino-common/src/static/administrations' import { HTTP_STATUS } from 'camino-common/src/http' +import { ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/etape' +import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts' +import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes' +import { toCaminoDate } from 'camino-common/src/date' +import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes' +import { GEO_SYSTEME_IDS } from 'camino-common/src/static/geoSystemes' +import { FeatureMultiPolygon } from 'camino-common/src/perimetre' console.info = vi.fn() console.error = vi.fn() let dbPool: Pool +const multiPolygonWith4Points: FeatureMultiPolygon = { + type: 'Feature', + properties: {}, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [-53.16822754488772, 5.02935254143807], + [-53.15913163720232, 5.029382753429523], + [-53.15910186841349, 5.020342601941031], + [-53.168197650929095, 5.02031244452273], + [-53.16822754488772, 5.02935254143807], + ], + ], + ], + }, +} + beforeAll(async () => { const { pool } = await dbManager.populateDb() dbPool = pool const titreId = newTitreId('titre-id-1-for-import') const titreSlug = titreSlugValidator.parse('titre-slug-1-for-import') + const demarcheId = newDemarcheId('demarche-id-1-for-import') + const etapeId = newEtapeId('etape-id-1-for-import') await insertTitreGraph({ id: titreId, slug: titreSlug, nom: 'nomTitre', typeId: 'arm', titreStatutId: 'val', - propsTitreEtapesIds: {}, + propsTitreEtapesIds: { points: etapeId }, + demarches: [ + { + id: demarcheId, + titreId: titreId, + typeId: DEMARCHES_TYPES_IDS.Octroi, + etapes: [ + { + id: etapeId, + titreDemarcheId: demarcheId, + date: toCaminoDate('2025-01-01'), + typeId: ETAPES_TYPES.demande, + statutId: ETAPES_STATUTS.FAIT, + isBrouillon: ETAPE_IS_NOT_BROUILLON, + geojsonOrigineGeoSystemeId: GEO_SYSTEME_IDS.WGS84, + geojson4326Perimetre: multiPolygonWith4Points, + geojsonOriginePerimetre: multiPolygonWith4Points, + }, + ], + }, + ], }) }) @@ -47,8 +95,8 @@ describe('titres', async () => { ) expect(tested.text).toMatchInlineSnapshot(` - "id,nom,type,domaine,date_debut,date_fin,date_demande,statut,substances,surface renseignee km2,communes (surface calculee km2),forets,facades_maritimes,departements,regions,administrations_noms,titulaires_noms,titulaires_adresses,titulaires_legal,titulaires_categorie,amodiataires_noms,amodiataires_adresses,amodiataires_legal,amodiataires_categorie,geojson - titre-slug-1-for-import,nomTitre,autorisation de recherches,minéraux et métaux,,,,valide,,,,,,,,Direction Générale des Territoires et de la Mer de Guyane,,,,,,,,,null" + "id,nom,type,domaine,date_debut,date_fin,date_demande,statut,substances,surface renseignee km2,communes (surface calculee km2),forets,facades_maritimes,departements,regions,administrations_noms,titulaires_noms,titulaires_adresses,titulaires_legal,titulaires_categorie,amodiataires_noms,amodiataires_adresses,amodiataires_legal,amodiataires_categorie,geojson,Franchissements de cours d'eau,Prospection mécanisée + titre-slug-1-for-import,nomTitre,autorisation de recherches,minéraux et métaux,,,,valide,,,,,,,,Direction Générale des Territoires et de la Mer de Guyane,,,,,,,,,"{""type"":""MultiPolygon"",""coordinates"":[[[[-53.16822754488772,5.02935254143807],[-53.15913163720232,5.029382753429523],[-53.15910186841349,5.020342601941031],[-53.168197650929095,5.02031244452273],[-53.16822754488772,5.02935254143807]]]]}",0,Non" `) }) test('peut télécharger les titres en xlsx', async () => { @@ -94,10 +142,71 @@ describe('titres', async () => { ) expect(tested.body).toMatchInlineSnapshot(` - { - "features": [], - "type": "FeatureCollection", - } - `) + { + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [ + -53.16822754488772, + 5.02935254143807, + ], + [ + -53.15913163720232, + 5.029382753429523, + ], + [ + -53.15910186841349, + 5.020342601941031, + ], + [ + -53.168197650929095, + 5.02031244452273, + ], + [ + -53.16822754488772, + 5.02935254143807, + ], + ], + ], + ], + "type": "MultiPolygon", + }, + "properties": { + "administrations_noms": [ + "Direction Générale des Territoires et de la Mer de Guyane", + ], + "amodiataires_legal": [], + "amodiataires_noms": [], + "communes": [], + "date_debut": null, + "date_demande": null, + "date_fin": null, + "departements": [], + "domaine": "minéraux et métaux", + "facades_maritimes": [], + "forets": [], + "franchissements_de_cours_d_eau": "0", + "id": "titre-slug-1-for-import", + "nom": "nomTitre", + "prospection_mecanisee": "Non", + "references": [], + "regions": [], + "statut": "valide", + "substances": [], + "surface_par_communes": [], + "surface_totale": null, + "titulaires_legal": [], + "titulaires_noms": [], + "type": "autorisation de recherches", + }, + "type": "Feature", + }, + ], + "type": "FeatureCollection", + } + `) }) }) diff --git a/packages/ui/src/components/page/footer.stories_snapshots_Default.html b/packages/ui/src/components/page/footer.stories_snapshots_Default.html index 1be2e8fc8..33a47e1d0 100644 --- a/packages/ui/src/components/page/footer.stories_snapshots_Default.html +++ b/packages/ui/src/components/page/footer.stories_snapshots_Default.html @@ -16,6 +16,7 @@ <li><a href="/mocked-href" title="Plan du site" class="fr-footer__top-link" aria-label="Plan du site">Plan du site</a></li> <li><a class="fr-footer__top-link" href="https://camino.gitbook.io/guide-dutilisation/camino/glossaire" target="_blank" rel="noopener noreferrer" title="Page glossaire - lien externe">Glossaire</a></li> <li><a class="fr-footer__top-link" href="https://camino.gitbook.io/guide-dutilisation/camino/guide-dutilisation" target="_blank" rel="noopener noreferrer" title="Page guide d’utilisation - lien externe">Tutoriel</a></li> + <li><a class="fr-footer__top-link" href="https://docs.camino.beta.gouv.fr/qgis/" target="_blank" rel="noopener noreferrer" title="Page guide d'intégration de Camino dans QGIS - lien externe">Intégrer Camino dans QGIS</a></li> <li><a class="fr-footer__top-link" href="https://docs.camino.beta.gouv.fr/" target="_blank" rel="noopener noreferrer" title="Page de la documentation - lien externe">API</a></li> </ul> </div> diff --git a/packages/ui/src/components/page/footer.tsx b/packages/ui/src/components/page/footer.tsx index a8a68ff45..687720b5a 100644 --- a/packages/ui/src/components/page/footer.tsx +++ b/packages/ui/src/components/page/footer.tsx @@ -64,6 +64,17 @@ export const Footer: FunctionalComponent<Props> = (props: Props) => ( Tutoriel </a> </li> + <li> + <a + class={fr.cx('fr-footer__top-link')} + href="https://docs.camino.beta.gouv.fr/qgis/" + target="_blank" + rel="noopener noreferrer" + title="Page guide d'intégration de Camino dans QGIS - lien externe" + > + Intégrer Camino dans QGIS + </a> + </li> <li> <a class={fr.cx('fr-footer__top-link')} href="https://docs.camino.beta.gouv.fr/" target="_blank" rel="noopener noreferrer" title="Page de la documentation - lien externe"> API -- GitLab