Skip to content

Commit

Permalink
Merge pull request #170 from etalab/communes-associees-deleguees
Browse files Browse the repository at this point in the history
Communes associees deleguees
  • Loading branch information
ThomasG77 authored Jan 31, 2023
2 parents 4c5ffad + f1c5685 commit a38f249
Show file tree
Hide file tree
Showing 10 changed files with 391 additions and 6 deletions.
62 changes: 62 additions & 0 deletions build/communes-associees-deleguees.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const {join} = require('path')
const {keyBy} = require('lodash')
const communes = require('@etalab/decoupage-administratif/data/communes.json')
const epci = require('@etalab/decoupage-administratif/data/epci.json')
const area = require('@turf/area').default
const pointOnFeature = require('@turf/point-on-feature').default
const truncate = require('@turf/truncate').default
const bbox = require('@turf/bbox').default
const bboxPolygon = require('@turf/bbox-polygon').default
const {readGeoJSONFeatures, writeData, fixPrecision} = require('./util')

const resolution = process.env.BUILD_LOW_RESOLUTION === '1' ? '50m' : '5m'

const COMMUNES_ASSOCIEES_DELEGUEES_FEATURES_PATH = join(__dirname, '..', 'data', `communes-associees-deleguees-${resolution}.geojson.gz`)

const COMMUNES_EPCI_MATCHING = epci.reduce((acc, curr) => {
curr.membres.forEach(membre => {
acc[membre.code] = curr.code
})

return acc
}, {})

async function buildCommunesAssocieesDeleguees() {
const communesAssocieesDelegueesFeatures = await readGeoJSONFeatures(COMMUNES_ASSOCIEES_DELEGUEES_FEATURES_PATH)
const communesAssocieesDelegueesFeaturesIndex = keyBy(communesAssocieesDelegueesFeatures, f => f.properties.code)

const communesAssocieesDelegueesData = communes
.filter(commune => {
return ['commune-associee', 'commune-deleguee'].includes(commune.type)
})
.map(commune => {
const communeData = {
code: commune.code,
type: commune.type,
nom: commune.nom,
chefLieu: commune.chefLieu,
codeDepartement: commune.departement,
codeRegion: commune.region
}

if (commune.code in communesAssocieesDelegueesFeaturesIndex) {
const contour = communesAssocieesDelegueesFeaturesIndex[commune.code].geometry
communeData.contour = contour
communeData.surface = fixPrecision(area(contour) / 10000, 2)
communeData.centre = truncate(pointOnFeature(contour), {precision: 4}).geometry
const bboxCommune = bbox(communesAssocieesDelegueesFeaturesIndex[commune.code])
const bboxPolygonCommune = bboxPolygon(bboxCommune)
communeData.bbox = bboxPolygonCommune.geometry
}

if (commune.chefLieu in COMMUNES_EPCI_MATCHING) {
communeData.codeEpci = COMMUNES_EPCI_MATCHING[commune.chefLieu]
}

return communeData
})

await writeData('communes-associees-deleguees', communesAssocieesDelegueesData)
}

module.exports = {buildCommunesAssocieesDeleguees}
36 changes: 36 additions & 0 deletions build/communes.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,30 @@ const COMMUNES_EPCI_MATCHING = epci.reduce((acc, curr) => {
return acc
}, {})

const COMMUNES_DELEGUEES_INDEX = communes
.filter(commune => {
return ['commune-deleguee'].includes(commune.type)
}).reduce((acc, curr) => {
if (!(curr.chefLieu in acc)) {
acc[curr.chefLieu] = []
}

acc[curr.chefLieu].push({code: curr.code, nom: curr.nom})
return acc
}, {})

const COMMUNES_ASSOCIEES_INDEX = communes
.filter(commune => {
return ['commune-associee'].includes(commune.type)
}).reduce((acc, curr) => {
if (!(curr.chefLieu in acc)) {
acc[curr.chefLieu] = []
}

acc[curr.chefLieu].push({code: curr.code, nom: curr.nom})
return acc
}, {})

async function buildCommunes() {
const communesFeatures = await readGeoJSONFeatures(COMMUNES_FEATURES_PATH)
const communesFeaturesIndex = keyBy(communesFeatures, f => f.properties.code)
Expand Down Expand Up @@ -51,6 +75,18 @@ async function buildCommunes() {
communeData.codeEpci = COMMUNES_EPCI_MATCHING[commune.code]
}

if (commune.code in COMMUNES_ASSOCIEES_INDEX) {
communeData.associees = COMMUNES_ASSOCIEES_INDEX[commune.code]
} else {
communeData.associees = null
}

if (commune.code in COMMUNES_DELEGUEES_INDEX) {
communeData.deleguees = COMMUNES_DELEGUEES_INDEX[commune.code]
} else {
communeData.deleguees = null
}

if (commune.code in communesFeaturesIndex) {
const contour = communesFeaturesIndex[commune.code].geometry
communeData.contour = contour
Expand Down
2 changes: 2 additions & 0 deletions build/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#!/usr/bin/env node --max_old_space_size=4096
const {buildCommunes} = require('./communes')
const {buildCommunesAssocieesDeleguees} = require('./communes-associees-deleguees')
const {buildEpcis} = require('./epcis')
const {buildDepartements} = require('./departements')
const {buildRegions} = require('./regions')

async function main() {
await buildCommunes()
await buildCommunesAssocieesDeleguees()
await buildEpcis()
await buildDepartements()
await buildRegions()
Expand Down
188 changes: 188 additions & 0 deletions definition.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ parameters:
- codeRegion
- region
- population
- deleguees
- associees
- zone
collectionFormat: csv
default:
Expand All @@ -43,6 +45,37 @@ parameters:
- codeDepartement
- codeRegion
- population
communeAssocieeDelegueeFieldsParam:
name: fields
in: query
description: Liste des champs souhaités dans la réponse
type: array
items:
type: string
enum:
- nom
- code
- type
- chefLieu
- centre
- surface
- contour
- bbox
- codeEpci
- epci
- codeDepartement
- departement
- codeRegion
- region
collectionFormat: csv
default:
- nom
- code
- type
- chefLieu
- codeEpci
- codeDepartement
- codeRegion
epciFieldsParam:
name: fields
in: query
Expand Down Expand Up @@ -116,6 +149,13 @@ parameters:
type: string
enum: ['centre', 'contour', 'mairie', 'bbox']
default: centre
communeAssocieeDelegueeGeometryParam:
name: geometry
in: query
description: Géométrie à utiliser pour la sortie géographique
type: string
enum: ['centre', 'contour', 'bbox']
default: centre
typeCommune:
name: type
in: query
Expand All @@ -126,6 +166,16 @@ parameters:
items:
type: string
enum: ['commune-actuelle', 'arrondissement-municipal']
typeCommuneAssocieeDeleguee:
name: type
in: query
description: Type permettant de filtrer si on retourne les communes, les arrondissements ou les 2. Par défaut à commune-actuelle.
required: false
type: array
collectionFormat: csv
items:
type: string
enum: ['commune-associee', 'commune-deleguee']
zoneParam:
name: zone
in: query
Expand Down Expand Up @@ -244,6 +294,87 @@ paths:
description: Commune introuvable
schema:
$ref: '#/definitions/Error'

/communes_associees_deleguees:
get:
summary: Recherche des communes associées et/ou déléguées
tags:
- Communes associées et déléguées
parameters:
- name: lat
in: query
description: Latitude (en degrés)
type: number
format: float
- name: lon
in: query
description: Longitude (en degrés)
type: number
format: float
- name: nom
in: query
description: Nom de la commune
type: string
- name: code
in: query
description: Code de la commune
type: string
- name: codeEpci
in: query
description: Code de l'EPCI associé
type: string
- name: codeDepartement
in: query
description: Code du département associé
type: string
- name: codeRegion
in: query
description: Code de la région associée
type: string
- $ref: '#/parameters/typeCommuneAssocieeDeleguee'
- $ref: '#/parameters/communeAssocieeDelegueeFieldsParam'
- $ref: '#/parameters/formatParam'
- $ref: '#/parameters/communeAssocieeDelegueeGeometryParam'
responses:
200:
description: Liste de communes associées et/ou déléguées
schema:
type: array
items:
$ref: '#/definitions/Commune'
400:
description: Erreur. Requête mal formée
schema:
$ref: '#/definitions/Error'

/communes_associees_deleguees/{code}:
get:
summary: Récupérer les informations concernant une commune associée ou déléguée
tags:
- Communes associées et déléguées
parameters:
- name: code
in: path
description: Code INSEE de la commune associée ou déléguée
required: true
type: string
- $ref: '#/parameters/communeAssocieeDelegueeFieldsParam'
- $ref: '#/parameters/formatParam'
- $ref: '#/parameters/communeAssocieeDelegueeGeometryParam'
responses:
200:
description: Informations concernant une commune associée ou déléguée
schema:
$ref: '#/definitions/Commune'
400:
description: Erreur. Requête mal formée
schema:
$ref: '#/definitions/Error'
404:
description: Commune associée ou déléguée introuvable
schema:
$ref: '#/definitions/Error'

/epcis:
get:
summary: Recherche des EPCI
Expand Down Expand Up @@ -560,6 +691,26 @@ definitions:
$ref: '#/definitions/Departement'
region:
$ref: '#/definitions/Region'
associees:
type: array
description: Liste des codes postaux associés à la commune
items:
type: object
properties:
code:
type: string
nom:
type: string
deleguees:
type: array
description: Liste des codes postaux associés à la commune
items:
type: object
properties:
code:
type: string
nom:
type: string
population:
type: integer
description: Population municipale
Expand All @@ -579,6 +730,43 @@ definitions:
bbox:
type: object
description: Rectangle englobant la commune (Polygon GeoJSON)
CommuneAssocieeDeleguee:
type: object
properties:
code:
type: string
description: Code INSEE de la commune associée ou déléguée
nom:
type: string
description: Nom de la commune associée ou déléguée
codeEpci:
type: string
description: Code de l'EPCI associé à la commune associée ou déléguée
codeDepartement:
type: string
description: Code du département associé à la commune associée ou déléguée
codeRegion:
type: string
description: Code de la région associée à la commune associée ou déléguée
epci:
$ref: '#/definitions/Epci'
departement:
$ref: '#/definitions/Departement'
region:
$ref: '#/definitions/Region'
surface:
type: number
format: float
description: Surface de la commune associée ou déléguée, en hectares
centre:
type: object
description: Centre de la commune associée ou déléguée (Point GeoJSON)
contour:
type: object
description: Contour de la commune associée ou déléguée (Polygon GeoJSON)
bbox:
type: object
description: Rectangle englobant la commune associée ou déléguée (Polygon GeoJSON)
Epci:
type: object
properties:
Expand Down
2 changes: 2 additions & 0 deletions download-sources.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ mkdir -p data
echo "Retrieve datasets"
wget -N -P data/ http://etalab-datasets.geo.data.gouv.fr/contours-administratifs/2022/geojson/communes-5m.geojson.gz
wget -N -P data/ http://etalab-datasets.geo.data.gouv.fr/contours-administratifs/2022/geojson/communes-50m.geojson.gz
wget -N -P data/ http://etalab-datasets.geo.data.gouv.fr/contours-administratifs/2022/geojson/communes-associees-deleguees-5m.geojson.gz
wget -N -P data/ http://etalab-datasets.geo.data.gouv.fr/contours-administratifs/2022/geojson/communes-associees-deleguees-50m.geojson.gz
wget -N -P data/ http://etalab-datasets.geo.data.gouv.fr/contours-administratifs/2022/geojson/chflieux-communes-arrondissements-municipaux.geojson.gz
wget -N -P data/ http://etalab-datasets.geo.data.gouv.fr/contours-administratifs/2022/geojson/epci-5m.geojson.gz
wget -N -P data/ http://etalab-datasets.geo.data.gouv.fr/contours-administratifs/2022/geojson/epci-50m.geojson.gz
Expand Down
15 changes: 15 additions & 0 deletions lib/communeAssocieesDelegueesHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const {initFields, initFormat} = require('./helpers')

const initCommunesAssocieeDelegueeFields = initFields({
default: ['nom', 'code', 'type', 'chefLieu', 'codeDepartement', 'codeEpci', 'codeRegion', 'codesPostaux'],
base: ['nom', 'code']
})

const initCommuneAssocieeDelegueeFormat = initFormat({
geometries: ['centre', 'contour', 'bbox'],
defaultGeometry: 'centre'
})

const communesAssocieesDelegueesDefaultQuery = {type: ['commune-associee', 'commune-deleguee']}

module.exports = {initCommunesAssocieeDelegueeFields, initCommuneAssocieeDelegueeFormat, communesAssocieesDelegueesDefaultQuery}
Loading

0 comments on commit a38f249

Please sign in to comment.