wip: simpler importer API

This commit is contained in:
Yohan Boniface 2024-05-23 20:14:46 +02:00
parent 1e4de02694
commit b657a5e9b3
6 changed files with 56 additions and 106 deletions

View file

@ -18,8 +18,6 @@ import {
uMapAlertCreation as AlertCreation, uMapAlertCreation as AlertCreation,
uMapAlertConflict as AlertConflict, uMapAlertConflict as AlertConflict,
} from '../components/alerts/alert.js' } from '../components/alerts/alert.js'
import { Plugin as GeoDataMine } from './plugins/geodatamine.js'
import { Plugin as Communes } from './plugins/communes.js'
// Import modules and export them to the global scope. // Import modules and export them to the global scope.
// For the not yet module-compatible JS out there. // For the not yet module-compatible JS out there.
@ -51,6 +49,4 @@ window.U = {
Tooltip, Tooltip,
URLs, URLs,
Utils, Utils,
GeoDataMine,
Communes,
} }

View file

@ -1,12 +1,17 @@
import { DomUtil, DomEvent } from '../../vendors/leaflet/leaflet-src.esm.js' import { DomUtil, DomEvent } from '../../vendors/leaflet/leaflet-src.esm.js'
import { translate } from './i18n.js' import { translate } from './i18n.js'
import { uMapAlert as Alert } from '../components/alerts/alert.js' import { uMapAlert as Alert } from '../components/alerts/alert.js'
import Dialog from './ui/dialog.js'
import { Importer as GeoDataMine } from './importers/geodatamine.js'
import { Importer as Communes } from './importers/communes.js'
export default class Importer { export default class Importer {
constructor(map) { constructor(map) {
this.map = map this.map = map
this.presets = map.options.importPresets this.presets = map.options.importPresets
this.TYPES = ['geojson', 'csv', 'gpx', 'kml', 'osm', 'georss', 'umap'] this.TYPES = ['geojson', 'csv', 'gpx', 'kml', 'osm', 'georss', 'umap']
this.PLUGINS = [new GeoDataMine(map), new Communes(map)]
this.dialog = new Dialog(this.map._controlContainer)
} }
build() { build() {
@ -47,9 +52,10 @@ export default class Importer {
className: 'umap-multiplechoice by2', className: 'umap-multiplechoice by2',
parent: this.container, parent: this.container,
}) })
for (const plugin of this.map.plugins) { for (const plugin of this.PLUGINS) {
const { name, callback } = plugin.addImporter() L.DomUtil.createButton('flat', plugins, plugin.name, () =>
L.DomUtil.createButton('flat', plugins, name, () => callback.bind(plugin)(this)) plugin.open.bind(plugin)(this)
)
} }
this.typeLabel = L.DomUtil.add( this.typeLabel = L.DomUtil.add(
'label', 'label',

View file

@ -0,0 +1,38 @@
import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
import { BaseAjax, SingleMixin } from '../autocomplete.js'
class Autocomplete extends SingleMixin(BaseAjax) {
URL = 'https://geo.api.gouv.fr/communes?nom={q}&limit=5'
createResult(item) {
return super.createResult({
value: item.code,
label: `${item.nom} (${item.code})`,
})
}
}
export class Importer {
constructor() {
this.name = 'Communes'
}
async open(importer) {
const container = DomUtil.create('div')
DomUtil.createTitle(container, this.name)
DomUtil.element({tagName: 'p', parent: container, textContent: 'Importer les contours d\'une commune française.'})
const options = {
on_select: (choice) => {
importer.urlInput.value = `https://geo.api.gouv.fr/communes?code=${choice.item.value}&format=geojson&geometry=contour`
importer.typeInput.value = 'geojson'
importer.dialog.close()
},
}
this.autocomplete = new Autocomplete(container, options)
importer.dialog.open({
content: container,
className: 'communes dark',
})
}
}

View file

@ -1,9 +1,5 @@
import { DomUtil, DomEvent, stamp } from '../../../vendors/leaflet/leaflet-src.esm.js' import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
import { translate } from '../i18n.js'
import { BaseAjax, SingleMixin } from '../autocomplete.js' import { BaseAjax, SingleMixin } from '../autocomplete.js'
import { Request } from '../request.js'
import Alert from '../ui/alert.js'
import Dialog from '../ui/dialog.js'
class Autocomplete extends SingleMixin(BaseAjax) { class Autocomplete extends SingleMixin(BaseAjax) {
URL = 'https://geodatamine.fr/boundaries/search?text={q}' URL = 'https://geodatamine.fr/boundaries/search?text={q}'
@ -16,34 +12,21 @@ class Autocomplete extends SingleMixin(BaseAjax) {
} }
} }
export class Plugin { export class Importer {
constructor(map) { constructor() {
this.map = map
this.name = 'GeoDataMine' this.name = 'GeoDataMine'
this.baseUrl = 'https://geodatamine.fr' this.baseUrl = 'https://geodatamine.fr'
this.type = 'importer'
this.dialog = new Dialog(this.map._controlContainer)
this.map.registerPlugin(this)
this.options = { this.options = {
theme: null, theme: null,
boundary: null, boundary: null,
aspoint: false, aspoint: false,
} }
const alert = new Alert(document.querySelector('header'))
this.request = new Request(alert)
}
addImporter() {
return {
name: this.name,
callback: this.open,
}
} }
async open(importer) { async open(importer) {
const container = DomUtil.create('div') const container = DomUtil.create('div')
DomUtil.createTitle(container, this.name) DomUtil.createTitle(container, this.name)
const response = await this.request.get(`${this.baseUrl}/themes`) const response = await importer.map.request.get(`${this.baseUrl}/themes`)
const select = DomUtil.element({ tagName: 'select', parent: container }) const select = DomUtil.element({ tagName: 'select', parent: container })
if (response && response.ok) { if (response && response.ok) {
const { themes } = await response.json() const { themes } = await response.json()
@ -58,25 +41,19 @@ export class Plugin {
} else { } else {
console.error(response) console.error(response)
} }
const options = { this.autocomplete = new Autocomplete(container, {
className: 'edit-owner', on_select: (choice) => (this.options.boundary = choice.item.value),
on_select: (choice) => this.onSelect(choice), })
}
this.autocomplete = new Autocomplete(container, options)
const confirm = () => { const confirm = () => {
importer.urlInput.value = `${this.baseUrl}/data/${select.value}/${this.options.boundary}?format=geojson` importer.urlInput.value = `${this.baseUrl}/data/${select.value}/${this.options.boundary}?format=geojson`
importer.typeInput.value = 'geojson' importer.typeInput.value = 'geojson'
this.dialog.close() importer.dialog.close()
} }
L.DomUtil.createButton('', container, 'OK', confirm) L.DomUtil.createButton('', container, 'OK', confirm)
this.dialog.open({ importer.dialog.open({
content: container, content: container,
className: 'geodatamine dark', className: 'geodatamine dark',
}) })
} }
onSelect(choice) {
this.options.boundary = choice.item.value
}
} }

View file

@ -1,60 +0,0 @@
import { DomUtil, DomEvent, stamp } from '../../../vendors/leaflet/leaflet-src.esm.js'
import { translate } from '../i18n.js'
import { BaseAjax, SingleMixin } from '../autocomplete.js'
import { Request } from '../request.js'
import Alert from '../ui/alert.js'
import Dialog from '../ui/dialog.js'
class Autocomplete extends SingleMixin(BaseAjax) {
URL = 'https://geo.api.gouv.fr/communes?nom={q}&limit=5'
createResult(item) {
return super.createResult({
value: item.code,
label: `${item.nom} (${item.code})`,
})
}
}
export class Plugin {
constructor(map) {
this.map = map
this.name = 'Communes'
this.type = 'importer'
this.dialog = new Dialog(this.map._controlContainer)
this.map.registerPlugin(this)
this.options = {
theme: null,
boundary: null,
aspoint: false,
}
const alert = new Alert(document.querySelector('header'))
this.request = new Request(alert)
}
addImporter() {
return {
name: this.name,
callback: this.open,
}
}
async open(importer) {
const container = DomUtil.create('div')
DomUtil.createTitle(container, this.name)
const options = {
on_select: (choice) => {
this.options.boundary = choice.item.value
importer.urlInput.value = `https://geo.api.gouv.fr/communes?code=${this.options.boundary}&format=geojson&geometry=contour`
importer.typeInput.value = 'geojson'
this.dialog.close()
},
}
this.autocomplete = new Autocomplete(container, options)
this.dialog.open({
content: container,
className: 'communes dark',
})
}
}

View file

@ -69,9 +69,6 @@ U.Map = L.Map.extend({
L.DomEvent.on(document.body, 'dataload', (e) => this.fire('dataload', e)) L.DomEvent.on(document.body, 'dataload', (e) => this.fire('dataload', e))
this.server = new U.ServerRequest() this.server = new U.ServerRequest()
this.request = new U.Request() this.request = new U.Request()
this.plugins = []
new U.GeoDataMine(this)
new U.Communes(this)
this.initLoader() this.initLoader()
this.name = this.options.name this.name = this.options.name
@ -355,10 +352,6 @@ U.Map = L.Map.extend({
} }
}, },
registerPlugin: function (plugin) {
this.plugins.push(plugin)
},
initControls: function () { initControls: function () {
this.helpMenuActions = {} this.helpMenuActions = {}
this._controls = {} this._controls = {}