-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
63 changed files
with
5,959 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
|
||
# misc | ||
.env* | ||
.DS_Store | ||
|
||
# production | ||
yarn.lock | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* eslint-disable max-len */ | ||
/* eslint-disable no-console */ | ||
|
||
/* | ||
1. Récupérer toutes les catégories de level "pays" dans la collection geographicalcategories | ||
2. Récupérer tous les pays dans le fichier countries.geo.json | ||
3. Pour chaque pays du fichier countries.geo.json, s'il existe dans la collection geographicalcategories, mettre à jour sinon ajouter | ||
*/ | ||
|
||
// Lancement : NODE_ENV=development MONGO_URI="mongodb://localhost:27017" MONGO_DBNAME="paysage" node --experimental-specifier-resolution=node scripts/import-geographical-categories-countries.js | ||
import 'dotenv/config'; | ||
import worldGeoJSON from './countries.geo.json' assert { type: "json" }; | ||
|
||
import { client, db } from '../src/services/mongo.service'; | ||
import BaseMongoCatalog from '../src/api/commons/libs/base.mongo.catalog'; | ||
|
||
const MONGO_TARGET_COLLECTION_NAME = 'geographicalcategories'; | ||
|
||
async function getPaysageIds(existingIdsCount) { | ||
const catalog = new BaseMongoCatalog({ db, collection: '_catalog' }); | ||
return Promise.all( | ||
worldGeoJSON.features.slice(0, worldGeoJSON.features.length - existingIdsCount).map(() => catalog.getUniqueId(MONGO_TARGET_COLLECTION_NAME, 5)), | ||
); | ||
} | ||
|
||
async function getCountriesToUpgrade() { | ||
return db.collection(MONGO_TARGET_COLLECTION_NAME).find({ level: 'country' }).toArray(); | ||
} | ||
|
||
async function treatment() { | ||
const countriesToUpgrade = await getCountriesToUpgrade(); | ||
|
||
// Get paysage ids | ||
const ids = await getPaysageIds(countriesToUpgrade.length); | ||
|
||
const promises = worldGeoJSON.features.map((country, index) => ({ | ||
geometry: country.geometry, | ||
id: countriesToUpgrade.find((item) => item.originalId === country.properties.iso_a3)?.id || ids[index], | ||
level: 'country', | ||
nameFr: country.properties.name_fr, | ||
originalId: country.properties.iso_a3, | ||
})).map((geo) => ( | ||
db.collection(MONGO_TARGET_COLLECTION_NAME).updateOne({ originalId: geo.originalId }, { $set: geo }, { upsert: true }) | ||
)); | ||
|
||
await Promise.all(promises); | ||
} | ||
|
||
console.log('--- START ---'); | ||
await treatment(); | ||
await client.close(); | ||
console.log('--- END ---'); |
100 changes: 100 additions & 0 deletions
100
scripts/import-geographical-categories-regions-departments-academies.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Example : NODE_ENV=development MONGO_URI="mongodb://localhost:27017" MONGO_DBNAME="paysage" node --experimental-specifier-resolution=node scripts/import-geographical-categories-regions-departments-academies.js | ||
// source regions: https://data.opendatasoft.com/explore/dataset/georef-france-region%40public/export/?disjunctive.reg_name | ||
// Source departments: https://data.opendatasoft.com/explore/dataset/georef-france-departement%40public/table/?disjunctive.reg_name&disjunctive.dep_name&sort=year | ||
import 'dotenv/config'; | ||
|
||
import { client, db } from '../src/services/mongo.service'; | ||
import BaseMongoCatalog from '../src/api/commons/libs/base.mongo.catalog'; | ||
|
||
const MONGO_SOURCE_COLLECTION_NAME = 'geocodes'; | ||
const MONGO_TARGET_COLLECTION_NAME = 'geographicalcategories'; | ||
|
||
import regions from './data/regions.geo.json' assert { type: "json" }; | ||
import departments from './data/departments.geo.json' assert { type: "json" }; | ||
import academies from './data/fr-en-contour-academies-2020.geo.json' assert { type: "json" }; | ||
|
||
const configs = [ | ||
{ | ||
data: regions, | ||
geoCodeField: 'reg_code', | ||
level: 'region', | ||
prefix: 'R', | ||
sourceIdField: 'reg_id', | ||
sourceIdLength: 2, | ||
sourceNameField: 'reg_nom', | ||
}, | ||
{ | ||
data: departments, | ||
geoCodeField: 'dep_code', | ||
level: 'department', | ||
parentIdField: 'reg_id', | ||
prefix: 'D', | ||
sourceIdField: 'dep_id', | ||
sourceIdLength: 3, | ||
sourceNameField: 'dep_nom', | ||
}, | ||
{ | ||
data: academies, | ||
geoCodeField: 'code_academie', | ||
level: 'academy', | ||
parentIdField: 'reg_id', | ||
prefix: 'A', | ||
sourceIdField: 'aca_id', | ||
sourceIdLength: 3, | ||
sourceNameField: 'aca_nom', | ||
}, | ||
]; | ||
|
||
async function treatment() { | ||
const promises = configs.map(async (config) => { | ||
const data = config.data; | ||
// Load uniq from Mongo geocodes | ||
const uniqueGeoIds = await db.collection(MONGO_SOURCE_COLLECTION_NAME).distinct(config.sourceIdField); | ||
const uniqueGeos = await Promise.all( | ||
uniqueGeoIds.map((uniqueId) => db.collection(MONGO_SOURCE_COLLECTION_NAME).findOne({ [config.sourceIdField]: uniqueId })), | ||
); | ||
// Generate as many ids as needed | ||
const catalog = new BaseMongoCatalog({ db, collection: '_catalog' }); | ||
const allIds = await Promise.all( | ||
uniqueGeos.map(() => catalog.getUniqueId(MONGO_TARGET_COLLECTION_NAME, 5)), | ||
); | ||
const p = uniqueGeos.map((geo, index) => { | ||
if (config.level === 'academy') { | ||
return { | ||
geometry: data.features.find((geojson) => `A${geojson.properties.code_academie}` === geo[config.sourceIdField])?.geometry || null, | ||
id: allIds[index], | ||
level: config.level, | ||
nameFr: geo[config.sourceNameField], | ||
originalId: geo[config.sourceIdField], | ||
parentOriginalId: geo[config.parentIdField], | ||
}; | ||
} | ||
return { | ||
geometry: data.features.find((geojson) => `${config.prefix}${geojson.properties[config.geoCodeField][0].length < config.sourceIdLength ? '0' : ''}${geojson.properties[config.geoCodeField][0]}` === geo[config.sourceIdField])?.geometry || null, | ||
id: allIds[index], | ||
level: config.level, | ||
nameFr: geo[config.sourceNameField], | ||
originalId: geo[config.sourceIdField], | ||
parentOriginalId: config.level === 'region' ? 'FRA' : geo[config.parentIdField], | ||
}; | ||
} | ||
).map((geo) => db.collection(MONGO_TARGET_COLLECTION_NAME).updateOne({ originalId: geo.originalId }, { $set: geo }, { upsert: true })); | ||
await Promise.all(p); | ||
}); | ||
await Promise.all(promises); | ||
} | ||
|
||
console.log('--- START ---'); | ||
await treatment(); | ||
await client.close(); | ||
console.log('--- END ---'); | ||
|
||
// TODO | ||
// Ajouter les geojson | ||
// Ajouter le parent direct | ||
// Modifier l'API pour autoriser l'urban unitf | ||
// Pays : https://data.enseignementsup-recherche.gouv.fr/explore/dataset/curiexplore-pays/table/?disjunctive.iso3&sort=iso3 | ||
// + ajouter lien vers la fichecurie | ||
// pour une fiche pays ajouter les groupes d'appartenance (Bologne, UE27, EURO blabla) | ||
|
||
// description |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import fs from 'fs'; | ||
|
||
import 'dotenv/config'; | ||
import refUU from './data/referentiel-geographique-francais-communes-unites-urbaines-aires-urbaines-depart.json' assert { type: "json" }; | ||
|
||
import { client, db } from '../src/services/mongo.service'; | ||
import BaseMongoCatalog from '../src/api/commons/libs/base.mongo.catalog'; | ||
|
||
const MONGO_TARGET_COLLECTION_NAME = 'geographicalcategories'; | ||
|
||
async function getUUToUpgrade() { | ||
return db.collection(MONGO_TARGET_COLLECTION_NAME).find({ level: 'urbanUnity' }).toArray(); | ||
} | ||
|
||
async function getPaysageIds(existingIdsCount, listUU) { | ||
const catalog = new BaseMongoCatalog({ db, collection: '_catalog' }); | ||
return Promise.all( | ||
Object.keys(listUU).slice(0, Object.keys(listUU).length - existingIdsCount).map(() => catalog.getUniqueId(MONGO_TARGET_COLLECTION_NAME, 5)), | ||
); | ||
} | ||
|
||
async function treatment() { | ||
const allUu = {}; | ||
refUU.forEach((el) => { | ||
if (el.uu_code) { | ||
if (!allUu[el.uu_code]) { | ||
allUu[el.uu_code] = { | ||
list: [{ | ||
code_com: el.com_code, | ||
geometry: el.geom.geometry || null, | ||
}], | ||
uucr_nom: el.uucr_nom | ||
} | ||
} else { | ||
allUu[el.uu_code].list.push({ | ||
code_com: el.com_code, | ||
geometry: el.geom.geometry || null, | ||
}); | ||
} | ||
} | ||
}); | ||
|
||
const uUToUpgrade = await getUUToUpgrade(); | ||
|
||
// Get paysage ids | ||
const ids = await getPaysageIds(uUToUpgrade.length, allUu); | ||
console.log(ids); | ||
const promises = Object.keys(allUu).map((urbanUnity, index) => ({ | ||
geometry: { coordinates: allUu[urbanUnity].list.map((commune) => commune.geometry.coordinates[0]), type: "MultiPolygon" }, | ||
id: uUToUpgrade.find((item) => item.originalId === urbanUnity)?.id || ids[index], | ||
level: 'urbanUnity', | ||
nameFr: allUu[urbanUnity].uucr_nom, | ||
originalId: urbanUnity, | ||
})).map((geo) => ( | ||
db.collection(MONGO_TARGET_COLLECTION_NAME).updateOne({ originalId: geo.originalId }, { $set: geo }, { upsert: true }) | ||
)); | ||
|
||
await Promise.all(promises); | ||
} | ||
|
||
console.log('--- START ---'); | ||
await treatment(); | ||
await client.close(); | ||
console.log('--- END ---'); | ||
|
||
|
||
// { | ||
// uu_code: { | ||
// list: [ | ||
// { | ||
// code_com: "ghjhg" | ||
// geometry: {} | ||
// } | ||
// ], | ||
// uucr_nom: | ||
// } | ||
// } | ||
|
||
|
||
// urbanUnity |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import express from 'express'; | ||
import { db } from '../../services/mongo.service'; | ||
|
||
const annuaire = db.collection('annuaire'); | ||
const rt = db.collection('relationtypes'); | ||
|
||
const router = new express.Router(); | ||
|
||
const lightProjection = { | ||
_id: 0, | ||
id: 1, | ||
person: "$relatedObject.displayName", | ||
personGender: "$relatedObject.gender", | ||
structureName: "$resource.displayName", | ||
startDate: 1, | ||
endDate: 1, | ||
status: 1, | ||
active: 1, | ||
endDatePrevisional: 1, | ||
mandateEmail: 1, | ||
mandateTemporary: 1, | ||
personalEmail: 1, | ||
mandatePhonenumber: 1, | ||
mandatePrecision: 1, | ||
personId: "$relatedObject.id", | ||
structureId: "$resource.id", | ||
relationType: { | ||
$cond: { | ||
if: { $eq: ["$relatedObject.gender", 'Homme'] }, | ||
then: "$relationType.maleName", | ||
else: { | ||
$cond: { | ||
if: { $eq: ["$relatedObject.gender", 'Femme'] }, | ||
then: "$relationType.feminineName", | ||
else: "$relationType.name" | ||
} | ||
} | ||
} | ||
}, | ||
} | ||
|
||
router.get('/annuaire/aggregations', async (req, res) => { | ||
const relationTypesDocs = await rt | ||
.find({ for: "persons" }) | ||
.project({ _id: 0, name: 1, priority: { $ifNull: ['$priority', 99] } }) | ||
.toArray(); | ||
const relationTypes = relationTypesDocs.sort((a, b) => a.priority - b.priority).map(rt => rt.name); | ||
const structures = await annuaire.distinct('resource.displayName'); | ||
const categories = await annuaire.distinct('resource.categories.usualNameFr'); | ||
const mandateTypeGroups = await annuaire.distinct('relationType.mandateTypeGroup'); | ||
return res.json({ relationTypes, structures, categories, mandateTypeGroups }); | ||
}); | ||
|
||
router.get('/annuaire', async (req, res) => { | ||
const { relationType, structure, category, mandateTypeGroup, skip = "0", limit = "0" } = req.query; | ||
const filters = { | ||
...(relationType && { "relationType.name": { $in: relationType.split(',') } }), | ||
...(structure && { "resource.displayName": { $in: structure.split(',') } }), | ||
...(category && { "resource.categories.usualNameFr": { $in: category.split(',') } }), | ||
...(mandateTypeGroup && { "relationType.mandateTypeGroup": { $in: mandateTypeGroup.split(',') } }), | ||
}; | ||
const data = (parseInt(limit, 10) > 0) | ||
? await annuaire.find(filters).project(lightProjection).skip(parseInt(skip, 10)).limit(parseInt(limit, 10)).sort({ startDate: -1 }).toArray() | ||
: []; | ||
const totalCount = await annuaire.countDocuments(filters); | ||
return res.json({ data, totalCount }); | ||
}); | ||
|
||
router.get('/annuaire/export', async (req, res) => { | ||
const { relationType, structure, category, mandateTypeGroup } = req.query; | ||
const filters = { | ||
...(relationType && { "relationType.name": { $in: relationType.split(',') } }), | ||
...(structure && { "resource.displayName": { $in: structure.split(',') } }), | ||
...(category && { "resource.categories.usualNameFr": { $in: category.split(',') } }), | ||
...(mandateTypeGroup && { "relationType.mandateTypeGroup": { $in: mandateTypeGroup.split(',') } }), | ||
}; | ||
const data = await annuaire.find(filters).toArray() | ||
console.log(data); | ||
return res.json(data); | ||
}); | ||
|
||
export default router; |
Oops, something went wrong.