From d3ed46356d826bbc6a64c0a588935dc3567caa79 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 11 Mar 2025 17:52:51 +0100 Subject: [PATCH] feat: add experimental BAN importer This importer takes a CSV as input, sends it to the BAN API, and then paste it into the import textarea, so it can be imported as usual. Co-authored-by: David Larlet --- umap/static/umap/base.css | 12 +++ umap/static/umap/css/dialog.css | 2 +- umap/static/umap/css/importers.css | 7 ++ umap/static/umap/img/importers/banfr.svg | 1 + umap/static/umap/js/modules/importer.js | 3 + .../static/umap/js/modules/importers/banfr.js | 93 +++++++++++++++++++ umap/static/umap/vars.css | 1 + 7 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 umap/static/umap/img/importers/banfr.svg create mode 100644 umap/static/umap/js/modules/importers/banfr.js diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 6651df52..4bf1ce0a 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -202,3 +202,15 @@ dt { height: 100vh; opacity: 0.5; } +.table-scrollable { + background-image: linear-gradient(to right, var(--background-color), var(--background-color)), + linear-gradient(to right, var(--background-color), var(--background-color)), + linear-gradient(to right, rgba(0, 0, 20, .50), rgba(255, 255, 255, 0)), + linear-gradient(to left, rgba(0, 0, 20, .50), rgba(255, 255, 255, 0)); + background-position: left center, right center, left center, right center; + background-repeat: no-repeat; + background-size: 20px 100%, 20px 100%, 10px 100%, 10px 100%; + background-attachment: local, local, scroll, scroll; + display: block; + overflow-x: auto; +} diff --git a/umap/static/umap/css/dialog.css b/umap/static/umap/css/dialog.css index a3ffca7e..f608b97e 100644 --- a/umap/static/umap/css/dialog.css +++ b/umap/static/umap/css/dialog.css @@ -2,7 +2,7 @@ z-index: var(--zindex-dialog); margin: auto; margin-top: 100px; - width: 40vw; + width: var(--dialog-width); max-width: 100vw; max-height: 50vh; padding: 20px; diff --git a/umap/static/umap/css/importers.css b/umap/static/umap/css/importers.css index 5f6ac39d..7beebf3a 100644 --- a/umap/static/umap/css/importers.css +++ b/umap/static/umap/css/importers.css @@ -55,3 +55,10 @@ .importers ul .datasets:before { background-image: url(../img/importers/datasets.svg); } +.importer.banfr h3:before, +.importers ul .banfr:before { + background-image: url(../img/importers/banfr.svg); +} +.importer table { + width: calc(var(--dialog-width) - 2 * var(--box-margin)); +} diff --git a/umap/static/umap/img/importers/banfr.svg b/umap/static/umap/img/importers/banfr.svg new file mode 100644 index 00000000..47badd7d --- /dev/null +++ b/umap/static/umap/img/importers/banfr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/umap/static/umap/js/modules/importer.js b/umap/static/umap/js/modules/importer.js index d375d164..b6d1a59a 100644 --- a/umap/static/umap/js/modules/importer.js +++ b/umap/static/umap/js/modules/importer.js @@ -94,6 +94,9 @@ export default class Importer extends Utils.WithTemplate { case 'datasets': import('./importers/datasets.js').then(register) break + case 'banfr': + import('./importers/banfr.js').then(register) + break } } } diff --git a/umap/static/umap/js/modules/importers/banfr.js b/umap/static/umap/js/modules/importers/banfr.js new file mode 100644 index 00000000..64428287 --- /dev/null +++ b/umap/static/umap/js/modules/importers/banfr.js @@ -0,0 +1,93 @@ +import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js' +import { BaseAjax, SingleMixin } from '../autocomplete.js' +import * as Utils from '../utils.js' +import { AutocompleteCommunes } from './communesfr.js' +import { translate } from '../i18n.js' +import { uMapAlert as Alert } from '../../components/alerts/alert.js' + +const TEMPLATE = ` +
+

Géocodage d’adresses en France

+

Géocoder un fichier CSV avec la base adresse nationale.

+
+ Choisir un fichier CSV (encodé en UTF-8) + +
+
+ Aperçu des données +
+
+
+ Sélectionner les colonnes à utiliser + +
+
+` + +export class Importer { + constructor(umap, options) { + this._umap = umap + this.name = options.name || 'Géocodage FR' + this.id = 'banfr' + } + + async open(importer) { + let data + const [container, { table, columns, csvFile }] = + Utils.loadTemplateWithRefs(TEMPLATE) + csvFile.addEventListener('change', () => { + const reader = new FileReader() + reader.onload = (evt) => { + data = evt.target.result + const rows = csv2geojson.auto(data).slice(0, 5) + const cols = Object.keys(rows[0]) + table.innerHTML = '' + columns.innerHTML = '' + const tr = document.createElement('tr') + for (const column of cols) { + tr.appendChild(Utils.loadTemplate(`${column}`)) + columns.appendChild( + Utils.loadTemplate( + `` + ) + ) + } + table.appendChild(tr) + for (const row of rows) { + const tr = document.createElement('tr') + for (const column of cols) { + tr.appendChild(Utils.loadTemplate(`${row[column]}`)) + } + table.appendChild(tr) + } + } + reader.readAsText(csvFile.files[0]) + }) + + const confirm = async (form) => { + const formData = new FormData() + formData.append('data', csvFile.files[0]) + for (const option of columns.querySelectorAll('input:checked')) { + formData.append('columns', option.value) + } + const response = await this._umap.request.post( + 'https://api-adresse.data.gouv.fr/search/csv/', + {}, + formData + ) + if (response?.ok) { + importer.raw = await response.text() + importer.format = 'csv' + } + } + + importer.dialog + .open({ + template: container, + className: `${this.id} importer dark`, + cancel: false, + accept: translate('Geocode'), + }) + .then(confirm) + } +} diff --git a/umap/static/umap/vars.css b/umap/static/umap/vars.css index 3c6095a7..af30d376 100644 --- a/umap/static/umap/vars.css +++ b/umap/static/umap/vars.css @@ -44,6 +44,7 @@ --small-box-padding: 4px; --box-margin: 14px; --text-margin: 7px; + --dialog-width: 40vw; /* z-indexes (leaflet CSS sets the map at 400 by default) */ --zindex-alert: 500;