Skip to content

Commit

Permalink
Merge branch 'develop' into feat-pb-901-kml-change-name-file
Browse files Browse the repository at this point in the history
  • Loading branch information
sommerfe committed Sep 25, 2024
2 parents cdd8a6c + d0f0931 commit d2006f0
Show file tree
Hide file tree
Showing 33 changed files with 428 additions and 136 deletions.
32 changes: 32 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"@turf/helpers": "^7.1.0",
"@turf/nearest-point": "^7.1.0",
"@turf/point-to-line-distance": "^7.1.0",
"@turf/simplify": "^7.1.0",
"animate.css": "^4.1.1",
"axios": "^1.7.5",
"bootstrap": "^5.3.3",
Expand All @@ -71,6 +72,7 @@
"file-saver": "^2.0.5",
"form-data": "^4.0.0",
"geographiclib-geodesic": "^2.1.1",
"geotiff": "^2.1.3",
"hammerjs": "^2.0.8",
"jquery": "^3.7.1",
"jszip": "^3.10.1",
Expand Down
12 changes: 12 additions & 0 deletions src/api/file-proxy.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,15 @@ export function proxifyUrl(url) {
}
return `${getServiceProxyBaseUrl()}${fileAsPath}`
}

export function unProxifyUrl(proxified_url) {
if (
(typeof proxified_url === 'string' || proxified_url instanceof String) &&
proxified_url.startsWith(getServiceProxyBaseUrl())
) {
let url = proxified_url.replace(getServiceProxyBaseUrl(), '')
return `${url.split('/')[0]}://${decodeURIComponent(url.split('/')[1])}`
}

return proxified_url
}
3 changes: 0 additions & 3 deletions src/api/files.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ export const getKmlUrl = (id) => {
* @returns {Promise<KmlMetadata>}
*/
export const createKml = (kml) => {
console.log('createKml', kml)
return new Promise((resolve, reject) => {
const form = buildKmlForm(kml)
form.append('author', 'web-mapviewer')
Expand Down Expand Up @@ -157,7 +156,6 @@ export const createKml = (kml) => {
* @returns {Promise<KmlMetadata>}
*/
export const updateKml = (id, adminId, kml) => {
console.log('updateKml name', kml)
return new Promise((resolve, reject) => {
validateId(id, reject)
validateAdminId(adminId, reject)
Expand Down Expand Up @@ -232,7 +230,6 @@ export const getKmlFromUrl = (url) => {
* @returns {Promise<KmlMetadata>} KML metadata
*/
export const getKmlMetadataByAdminId = (adminId) => {
console.log('getKmlMetadataByAdminId', adminId)
return new Promise((resolve, reject) => {
validateAdminId(adminId, reject)
axios
Expand Down
58 changes: 58 additions & 0 deletions src/api/layers/GeoTIFFLayer.class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import AbstractLayer, { LayerAttribution } from '@/api/layers/AbstractLayer.class'
import { InvalidLayerDataError } from '@/api/layers/InvalidLayerData.error'
import LayerTypes from '@/api/layers/LayerTypes.enum'

/**
* Metadata for an external Cloud-Optimized GeoTIFF layer
*
* @WARNING DON'T USE GETTER AND SETTER ! Instances of this class will be used a Vue 3 reactive
* object which SHOULD BE plain javascript object ! For convenience we use class instances but this
* has some limitations and javascript class getter and setter are not correctly supported which
* introduced subtle bugs. As rule of thumb we should avoid any public methods with side effects on
* properties, properties should change be changed either by the constructor or directly by setting
* them, not through a functions that updates other properties as it can lead to subtle bugs due
* to Vue reactivity engine.
*/
export default class GeoTIFFLayer extends AbstractLayer {
/**
* @param {String} geoTIFFConfig.fileSource The URL to access the GeoTIFF data.
* @param {Boolean} [geoTIFFConfig.visible=true] If the layer is visible on the map (or hidden).
* When `null` is given, then it uses the default value. Default is `true`
* @param {Number} [geoTIFFConfig.opacity=1.0] The opacity of this layer, between 0.0
* (transparent) and 1.0 (opaque). When `null` is given, then it uses the default value.
* Default is `1.0`
* @param {String | null} [geoTIFFConfig.data=null] Data/content of the GeoTIFF file, as a
* string. Default is `null`
* @throws InvalidLayerDataError if no `geoTIFFConfig` is given or if it is invalid
*/
constructor(geoTIFFConfig) {
if (!geoTIFFConfig) {
throw new InvalidLayerDataError('Missing GeoTIFF layer data', geoTIFFConfig)
}
const { fileSource = null, visible = true, opacity = 1.0, data = null } = geoTIFFConfig
if (fileSource === null) {
throw new InvalidLayerDataError('Missing GeoTIFF file source', geoTIFFConfig)
}
const isLocalFile = !fileSource.startsWith('http')
const attributionName = isLocalFile ? fileSource : new URL(fileSource).hostname
const fileName = isLocalFile
? fileSource
: fileSource.substring(fileSource.lastIndexOf('/') + 1)
super({
name: fileName,
id: fileSource,
type: LayerTypes.GEOTIFF,
baseUrl: fileSource,
opacity: opacity ?? 1.0,
visible: visible ?? true,
attributions: [new LayerAttribution(attributionName)],
isExternal: true,
hasDescription: false,
hasLegend: false,
})
this.isLocalFile = isLocalFile
this.fileSource = fileSource
this.isLoading = false
this.data = data
}
}
1 change: 1 addition & 0 deletions src/api/layers/LayerTypes.enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ const LayerTypes = {
GPX: 'GPX',
VECTOR: 'VECTOR',
GROUP: 'GROUP',
GEOTIFF: 'GEOTIFF',
}
export default LayerTypes
4 changes: 4 additions & 0 deletions src/api/print.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import axios from 'axios'
import { Circle } from 'ol/style'

import { unProxifyUrl } from '@/api/file-proxy.api'
import {
getApi3BaseUrl,
getViewerDedicatedServicesBaseUrl,
Expand Down Expand Up @@ -116,6 +117,9 @@ class GeoAdminCustomizer extends BaseCustomizer {
if (symbolizer.externalGraphic) {
size = image.getSize()
anchor = image.getAnchor()
// service print can't handle a proxied url, so we ensure we're
// giving the original url for the print job.
symbolizer.externalGraphic = unProxifyUrl(symbolizer.externalGraphic)
} else if (image instanceof Circle) {
const radius = image.getRadius()
const width = adjustWidth(2 * radius, this.printResolution)
Expand Down
3 changes: 2 additions & 1 deletion src/modules/drawing/components/DrawingExporter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const store = useStore()
const projection = computed(() => store.state.position.projection)
const isDrawingEmpty = computed(() => store.getters.isDrawingEmpty)
const activeKmlLayer = computed(() => store.getters.activeKmlLayer)
function onExportOptionSelected(dropdownItem) {
exportSelection.value = dropdownItem.value
Expand All @@ -37,7 +38,7 @@ function exportDrawing() {
type = 'application/gpx+xml;charset=UTF-8'
} else {
fileName = generateFilename('.kml')
content = generateKmlString(projection.value, features)
content = generateKmlString(projection.value, features, activeKmlLayer.value?.name)
type = 'application/vnd.google-earth.kml+xml;charset=UTF-8'
}
saveAs(new Blob([content], { type }), fileName)
Expand Down
16 changes: 3 additions & 13 deletions src/modules/drawing/components/DrawingToolbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const activeKmlLayerIndex = computed(() =>
store.getters.getIndexOfActiveLayerById(activeKmlLayer.value.id)
)
const activeKmlLayerName = ref(activeKmlLayer.value?.name)
const isActiveLayerNameEditMode = ref(false)
// This is necessary to update the layer name in case the sanitized name is different
watch(activeKmlLayer, () => {
Expand Down Expand Up @@ -78,7 +77,6 @@ function onCloseClearConfirmation(confirmed) {
}
async function onSaveName() {
isActiveLayerNameEditMode.value = !isActiveLayerNameEditMode.value
if (activeKmlLayerName.value === activeKmlLayer.value.name) return
store.dispatch('updateLayer', {
index: activeKmlLayerIndex.value,
Expand Down Expand Up @@ -109,8 +107,8 @@ function onDeleteLastPoint() {
:class="{ 'rounded-bottom-0': isPhoneMode }"
>
<div
class="d-flex justify-content-center align-items-center gap-2 p-4"
v-if="activeKmlLayer"
class="d-flex justify-content-center align-items-center gap-2 p-3"
>
<label for="activeKmlLayerName" class="mr-3">
{{ i18n.t('file_name') }}
Expand All @@ -121,21 +119,13 @@ function onDeleteLastPoint() {
v-model="activeKmlLayerName"
type="string"
class="form-control"
:disabled="!isActiveLayerNameEditMode"
data-cy="drawing-toolbox-file-name-input"
:placeholder="`${i18n.t('draw_layer_label')}`"
/>
<button
v-if="!isActiveLayerNameEditMode"
class="btn btn-outline-secondary"
type="button"
@click="isActiveLayerNameEditMode = !isActiveLayerNameEditMode"
>
{{ i18n.t('edit_button') }}
</button>
<button
v-else
class="btn btn-outline-secondary"
type="button"
data-cy="drawing-toolbox-file-name-save-button"
@click="onSaveName"
>
{{ i18n.t('save_button') }}
Expand Down
5 changes: 2 additions & 3 deletions src/modules/drawing/lib/export-utils.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import DOMPurify from 'dompurify'
import Feature from 'ol/Feature'
import { GPX } from 'ol/format'
import { LineString, Polygon } from 'ol/geom'
import { Circle, Icon } from 'ol/style'
import Style from 'ol/style/Style'

import DOMPurify from 'dompurify'
import i18n from '@/modules/i18n/index'
import { WGS84 } from '@/utils/coordinates/coordinateSystems'
import { featureStyleFunction } from '@/utils/featureStyleUtils'
Expand Down Expand Up @@ -83,7 +83,6 @@ export function generateKmlString(projection, features = [], fileName) {
}
let kmlString = EMPTY_KML_DATA
let exportFeatures = []
console.log('features', features)
features.forEach((f) => {
const clone = f.clone()
clone.setId(f.getId())
Expand Down Expand Up @@ -133,7 +132,7 @@ export function generateKmlString(projection, features = [], fileName) {

// Remove empty placemark added to have <Document> tag
kmlString = kmlString.replace(/<Placemark\/>/g, '')
const clean = DOMPurify.sanitize(fileName, {USE_PROFILES: { xml: true }})
const clean = DOMPurify.sanitize(fileName, { USE_PROFILES: { xml: true } })
kmlString = kmlString.replace(
/<Document>/,
`<Document><name>${clean ? clean : i18n.global.t('draw_layer_label')}</name>`
Expand Down
6 changes: 0 additions & 6 deletions src/modules/drawing/useKmlDataManagement.composable.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ export default function useSaveKmlOnChange(drawingLayerDirectReference) {
if (!activeKmlLayer.value?.adminId) {
// creation of the new KML (copy or new)
const kmlMetadata = await createKml(kmlData)
console.log('kmlMetadata', kmlMetadata)
const kmlLayer = new KMLLayer({
kmlFileUrl: getKmlUrl(kmlMetadata.id),
visible: true,
Expand All @@ -116,11 +115,9 @@ export default function useSaveKmlOnChange(drawingLayerDirectReference) {
kmlData: kmlData,
kmlMetadata: kmlMetadata,
})
console.log('kmlLayer', kmlLayer)
// If there's already an activeKmlLayer, but without adminId, it means we are copying it and editing it.
// Meaning we must remove the old one from the layers; it will otherwise be there twice
// (once the pristine "old" KML, and once the new copy)
console.log('create activeKmlLayer', activeKmlLayer.value)
if (activeKmlLayer.value) {
await store.dispatch('removeLayer', {
layerId: activeKmlLayer.value.id,
Expand All @@ -132,8 +129,6 @@ export default function useSaveKmlOnChange(drawingLayerDirectReference) {
...dispatcher,
})
} else {
console.log('update activeKmlLayer', activeKmlLayer.value)

// if a KMLLayer is already defined, we update it
const kmlMetadata = await updateKml(
activeKmlLayer.value.fileId,
Expand All @@ -156,7 +151,6 @@ export default function useSaveKmlOnChange(drawingLayerDirectReference) {
opacity: 1,
kmlData: kmlData,
})
console.log('kmlLayer', kmlLayer)
if (!temporaryKml.value) {
await store.dispatch('addSystemLayer', { layer: kmlLayer, ...dispatcher })
} else {
Expand Down
10 changes: 5 additions & 5 deletions src/modules/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@
"drawing_attached": "Zeichnung als Anhang hinzugefügt",
"drawing_too_large": "Ihre Zeichnung ist zu gross, entfernen Sie einige Details.",
"drop_invalid_url": "URL ist ungültig.",
"drop_me_here": "KML Datei hierhin ziehen",
"drop_me_here": "Datei hier ablegen (KML, KMZ, GPX, GeoTIFF)",
"duplicate_layer": "Karte duplizieren",
"east": "Ost",
"ech": "Geokatalog",
Expand Down Expand Up @@ -293,22 +293,23 @@
"import": "Importieren",
"import_file": "Datei importieren",
"import_file_succeeded": "Erfolg",
"import_file_tooltip": "Importieren eine externe KML- oder GPX-Datei",
"import_file_url_placeholder": "GPX KML URL",
"import_file_tooltip": "Importieren eine externe KML, KMZ, GPX oder GeoTIFF-Datei",
"import_file_url_placeholder": "GPX KML KMZ GeoTIFF URL",
"import_kml": "KML Import",
"import_maps": "Karten importieren",
"import_maps_tooltip": "Importieren Sie externe WMTS- oder WMS-Datenquellen",
"import_maps_url_placeholder": "WMTS WMS URL",
"import_online_placeholder": "WMTS WMS GPX KML URL",
"import_tooltip": "Importieren Sie externe WMTS-, WMS-, GPX- oder KML-Datenquellen",
"import_wms": "WMS Import",
"imported_file_out_of_bounds": "Der Dateiinhalt liegt ausserhalb der Projektionsgrenzen",
"inform_draw_rectangl_ctrl": "Mittels CTRL + Rechteck (cmd für Mac) über die Karte ziehen, lassen sich mehrere Objekte auf einmal räumlich abfragen.",
"inspire": "INSPIRE",
"inspire_service_link_href": "https://www.geo.admin.ch/de/home.html",
"inspire_service_link_label": "geo.admin.ch",
"invalid_email": "ungültige E-Mail",
"invalid_file": "Datei ungültig",
"invalid_kml_gpx_file_error": "Ungültige Datei, nur KML- oder GPX-Dateien werden unterstützt",
"invalid_import_file_error": "Ungültige Datei, nur KML, KMZ, GPX oder GeoTIFF-Dateien werden unterstützt",
"invalid_url": "URL ist ungültig.",
"invalid_wms_capabilities": "Ungültige WMS-Capabilities-Daten",
"invalid_wmts_capabilities": "Ungültige WMTS-Capabilities-Daten",
Expand All @@ -325,7 +326,6 @@
"kgs_service_link_label": "Kulturgüterschutz",
"kml": "KML",
"kml_gpx_file_empty": "Die KML/GPX-Datei ist leer",
"kml_gpx_file_out_of_bounds": "Der Dateiinhalt liegt ausserhalb der Projektionsgrenzen",
"kml_icon_url_cors_issue": "Die KML-Datei „{layerName}“ enthält Symbol(e) mit der URL {url}, die keine CORS-Unterstützung bietet! Bitte wenden Sie sich an den Administrator dieser URL, um die Unterstützung für CORS hinzuzufügen.",
"kml_no_text_elements": "Information: Die Labels werden nicht gespeichert",
"kml_style_default": "Standard",
Expand Down
Loading

0 comments on commit d2006f0

Please sign in to comment.