Skip to content

Commit

Permalink
chore: move share to modules
Browse files Browse the repository at this point in the history
  • Loading branch information
yohanboniface committed Jul 5, 2024
1 parent 9f6c322 commit 056f524
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 100 deletions.
36 changes: 35 additions & 1 deletion umap/static/umap/js/modules/formatter.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
/* Uses globals for: csv2geojson, osmtogeojson, GeoRSSToGeoJSON (not available as ESM) */
import { translate } from './i18n.js'

export default class Formatter {
export const EXPORT_FORMATS = {
geojson: {
formatter: async (map) => JSON.stringify(map.toGeoJSON(), null, 2),
ext: '.geojson',
filetype: 'application/json',
},
gpx: {
formatter: async (map) => await map.formatter.toGPX(map.toGeoJSON()),
ext: '.gpx',
filetype: 'application/gpx+xml',
},
kml: {
formatter: async (map) => await map.formatter.toKML(map.toGeoJSON()),
ext: '.kml',
filetype: 'application/vnd.google-earth.kml+xml',
},
csv: {
formatter: async (map) => {
const table = []
map.eachFeature((feature) => {
const row = feature.toGeoJSON().properties
const center = feature.getCenter()
delete row._umap_options
row.Latitude = center.lat
row.Longitude = center.lng
table.push(row)
})
return csv2geojson.dsv.csvFormat(table)
},
ext: '.csv',
filetype: 'text/csv',
},
}

export class Formatter {
async fromGPX(str) {
const togeojson = await import('../../vendors/togeojson/togeojson.es.js')
return togeojson.gpx(this.toDom(str))
Expand Down
4 changes: 3 additions & 1 deletion umap/static/umap/js/modules/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import { AjaxAutocomplete, AjaxAutocompleteMultiple } from './autocomplete.js'
import Browser from './browser.js'
import Caption from './caption.js'
import Facets from './facets.js'
import Formatter from './formatter.js'
import { Formatter } from './formatter.js'
import Help from './help.js'
import Importer from './importer.js'
import Orderable from './orderable.js'
import { HTTPError, NOKError, Request, RequestError, ServerRequest } from './request.js'
import Rules from './rules.js'
import { SCHEMA } from './schema.js'
import Share from './share.js'
import { SyncEngine } from './sync/engine.js'
import Dialog from './ui/dialog.js'
import { EditPanel, FullPanel, Panel } from './ui/panel.js'
Expand Down Expand Up @@ -49,6 +50,7 @@ window.U = {
Rules,
SCHEMA,
ServerRequest,
Share,
SyncEngine,
Tooltip,
URLs,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,11 @@
U.Share = L.Class.extend({
EXPORT_TYPES: {
geojson: {
formatter: async (map) => JSON.stringify(map.toGeoJSON(), null, 2),
ext: '.geojson',
filetype: 'application/json',
},
gpx: {
formatter: async (map) => await map.formatter.toGPX(map.toGeoJSON()),
ext: '.gpx',
filetype: 'application/gpx+xml',
},
kml: {
formatter: async (map) => await map.formatter.toKML(map.toGeoJSON()),
ext: '.kml',
filetype: 'application/vnd.google-earth.kml+xml',
},
csv: {
formatter: async (map) => {
const table = []
map.eachFeature((feature) => {
const row = feature.toGeoJSON().properties
const center = feature.getCenter()
delete row._umap_options
row.Latitude = center.lat
row.Longitude = center.lng
table.push(row)
})
return csv2geojson.dsv.csvFormat(table)
},
ext: '.csv',
filetype: 'text/csv',
},
},

initialize: function (map) {
import { EXPORT_FORMATS } from './formatter.js'

export default class Share {
constructor(map) {
this.map = map
},
}

build: function () {
build() {
this.container = L.DomUtil.create('div', '')
this.title = L.DomUtil.createTitle(
this.container,
Expand All @@ -63,16 +31,10 @@ U.Share = L.Class.extend({

L.DomUtil.add('h4', '', this.container, L._('Download'))
L.DomUtil.add('small', 'label', this.container, L._("Only visible layers' data"))
for (const key in this.EXPORT_TYPES) {
if (this.EXPORT_TYPES.hasOwnProperty(key)) {
L.DomUtil.createButton(
'download-file',
this.container,
this.EXPORT_TYPES[key].name || key,
() => this.download(key),
this
)
}
for (const format of Object.keys(EXPORT_FORMATS)) {
L.DomUtil.createButton('download-file', this.container, format, () =>
this.download(key)
)
}
L.DomUtil.create('div', 'vspace', this.container)
L.DomUtil.add(
Expand Down Expand Up @@ -135,7 +97,7 @@ U.Share = L.Class.extend({
for (let i = 0; i < this.map.HIDDABLE_CONTROLS.length; i++) {
UIFields.push(`queryString.${this.map.HIDDABLE_CONTROLS[i]}Control`)
}
const iframeExporter = new U.IframeExporter(this.map)
const iframeExporter = new IframeExporter(this.map)
const buildIframeCode = () => {
iframe.textContent = iframeExporter.build()
exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
Expand All @@ -149,23 +111,23 @@ U.Share = L.Class.extend({
L._('Embed and link options')
)
iframeOptions.appendChild(builder.build())
},
}

open: function () {
open() {
if (!this.container) this.build()
this.map.panel.open({ content: this.container })
},
}

format: async function (mode) {
const type = this.EXPORT_TYPES[mode]
async format(mode) {
const type = EXPORT_FORMATS[mode]
const content = await type.formatter(this.map)
let name = this.map.options.name || 'data'
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
const filename = name + type.ext
return { content, filetype: type.filetype, filename }
},
}

download: async function (mode) {
async download(mode) {
const { content, filetype, filename } = await this.format(mode)
const blob = new Blob([content], { type: filetype })
window.URL = window.URL || window.webkitURL
Expand All @@ -176,50 +138,49 @@ U.Share = L.Class.extend({
document.body.appendChild(el)
el.click()
document.body.removeChild(el)
},
})

U.IframeExporter = L.Evented.extend({
options: {
includeFullScreenLink: true,
currentView: false,
keepCurrentDatalayers: false,
viewCurrentFeature: false,
},

queryString: {
scaleControl: false,
miniMap: false,
scrollWheelZoom: false,
zoomControl: true,
editMode: 'disabled',
moreControl: true,
searchControl: null,
tilelayersControl: null,
embedControl: null,
datalayersControl: true,
onLoadPanel: 'none',
captionBar: false,
captionMenus: true,
},

dimensions: {
width: '100%',
height: '300px',
},

initialize: function (map) {
}
}

class IframeExporter {
constructor(map) {
this.map = map
this.baseUrl = U.Utils.getBaseUrl()
this.options = {
includeFullScreenLink: true,
currentView: false,
keepCurrentDatalayers: false,
viewCurrentFeature: false,
}

this.queryString = {
scaleControl: false,
miniMap: false,
scrollWheelZoom: false,
zoomControl: true,
editMode: 'disabled',
moreControl: true,
searchControl: null,
tilelayersControl: null,
embedControl: null,
datalayersControl: true,
onLoadPanel: 'none',
captionBar: false,
captionMenus: true,
}

this.dimensions = {
width: '100%',
height: '300px',
}
// Use map default, not generic default
this.queryString.onLoadPanel = this.map.getOption('onLoadPanel')
},
}

getMap: function () {
getMap() {
return this.map
},
}

buildUrl: function (options) {
buildUrl(options) {
const datalayers = []
if (this.options.viewCurrentFeature && this.map.currentFeature) {
this.queryString.feature = this.map.currentFeature.getSlug()
Expand All @@ -239,15 +200,15 @@ U.IframeExporter = L.Evented.extend({
const currentView = this.options.currentView ? window.location.hash : ''
const queryString = L.extend({}, this.queryString, options)
return `${this.baseUrl}?${U.Utils.buildQueryString(queryString)}${currentView}`
},
}

build: function () {
build() {
const iframeUrl = this.buildUrl()
let code = `<iframe width="${this.dimensions.width}" height="${this.dimensions.height}" frameborder="0" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
if (this.options.includeFullScreenLink) {
const fullUrl = this.buildUrl({ scrollWheelZoom: true })
code += `<p><a href="${fullUrl}">${L._('See full screen')}</a></p>`
}
return code
},
})
}
}
1 change: 0 additions & 1 deletion umap/templates/umap/js.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,5 @@
<script src="{% static 'umap/js/umap.controls.js' %}" defer></script>
<script src="{% static 'umap/js/umap.slideshow.js' %}" defer></script>
<script src="{% static 'umap/js/umap.tableeditor.js' %}" defer></script>
<script src="{% static 'umap/js/umap.share.js' %}" defer></script>
<script src="{% static 'umap/js/umap.js' %}" defer></script>
<script src="{% static 'umap/js/components/fragment.js' %}" defer></script>

0 comments on commit 056f524

Please sign in to comment.