/**
* @desc A mixin object containing methods related to map layers
* @module MapLayersMixin
*/
import { OSM, BingMaps } from 'ol/source';
import { transform } from "ol/proj";
import { GeoTIFF as GeoTIFFSource } from 'ol/source';
import { get as getProjection, useGeographic } from 'ol/proj';
export const MapLayersMixin = {
methods: {
/**
* Sets the base layer of the map based on the selectedBaseLayer value.
* If selectedBaseLayer is 1, sets the base layer source to OpenStreetMap (OSM).
* If selectedBaseLayer is not 1, sets the base layer source to Bing Maps with the specified key and imagerySet.
* Updates the map size and forces a component update.
* @async
* @returns {Promise<void>}
*/
async setBaseLayer() {
if (this.selectedBaseLayer.value == 1) {
this.baseLayer.setSource(new OSM());
} else {
this.baseLayer.setSource(new BingMaps({
key: 'AnNHHAjCQ3arTU0FoTUB1zoCdKC2png2M2pstqoV5uFhCHorOx_aUz1Yt8RA6Xly',
imagerySet: 'AerialWithLabels',
}));
}
this.baseLayer.getSource().changed();
this.map.updateSize();
this.$forceUpdate();
},
/**
* Clears the shape source and adds features to it based on the selected shape.
* @async
* @function setShapeLayer
* @memberof module:mixins/ol-map-layers
* @returns {Promise<void>} A promise that resolves when the shape layer is set.
*/
async setShapeLayer() {
this.shapeSource.clear();
if (this.selectedShape) {
let ret = await this.get("Common/GetShape", {
Id: this.selectedShape.value,
Srid: this.srid
});
if (ret && ret.features) {
let features = this.format.readFeatures(ret);
this.shapeSource.addFeatures(features);
this.animateToExtent(this.shapeSource);
}
}
},
/**
* Creates a point collection feature from the given data.
*
* @param {Object} data - The data used to create the point collection.
* @param {string} projection - The projection used for transforming coordinates.
* @returns {Object} - The created point collection feature.
*/
createPointCollection(data, projection) {
var featureCollection = {
type: 'FeatureCollection',
features: data.data.map(function(row) {
return {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: transform([row[0], row[1]], 'EPSG:4326', projection)
},
properties: {
value: row[2],
date: row[3],
color_code: row[4] ?? '#ff0000',
name: row[8] || row[5],
nuts_0: row[6],
description: row[7],
point_id: row[9],
sample: row[10],
has_spectrum: row[11]
},
};
})
};
return featureCollection;
},
/**
* Sets the point layer on the map.
* @async
* @returns {Promise<void>} A promise that resolves when the point layer is set.
*/
async setPointLayer() {
this.pointSource.clear();
this.pointFeatures = [];
if (!this.showPoints) return;
if (!this.selectedIndicator) {
return;
} else {
this.$store.working = true;
let data = await this.get("Home/GetIndicatorValues", { indicatorId: this.selectedIndicator.value, dataSourceId: this.selectedDataSource ? this.selectedDataSource.value : null });
let pointCollection = this.createPointCollection(data, this.projection);
this.pointFeatures = this.format.readFeatures(pointCollection);
this.pointSource.addFeatures(this.pointFeatures);
this.pointLayer.setSource(this.clustered ? this.clusteredSource : this.pointSource);
//this.pointLayer.setVisible(true);
this.animateToExtent(this.pointSource);
this.$store.working = false;
}
},
/**
* Sets the tile layer containig GeoTiff sources for the map.
* @async
* @returns {Promise<void>} A promise that resolves when the tile layer is set.
*/
async setTileLayer() {
this.$store.working = true;
//useGeographic();
// create appropriate source
if (this.selectedCatalog) {
let source;
source = new GeoTIFFSource({
normalize: false,
sources: [{ url: this.selectedCatalog.source },
],
//nodata: this.selectedTitle.no_data,
projection: getProjection("EPSG:" + this.selectedTitle.srid),
});
source.on("change", () => {
if (source.getState() === "error") {
this.showError(this.$t("Error loading GeoTIFF") + ": " + source.getError());
return;
}
});
this.tiffLayer.setSource(source);
this.tiffLayer.setStyle({
color: JSON.parse(this.selectedTitle.color_map)
});
//['interpolate', ['linear'], ['band', 1],
// 0, [255, 255, 255, 0], 60, [0, 0, 255], 120, [0, 255, 0]]
//color: ['case', ['==', ['band', 1], 0], [0, 0, 255, 0], ['<=', ['band', 1], 50], [255, 0, 0], [0, 0, 255]]
//});
this.tiffLayer.changed();
this.tiffLayer.setVisible(true);
} else {
this.tiffLayer.setSource(null);
this.tiffLayer.setVisible(false);
// this.map.getLayers().getArray().find(x => x.get("type") == 'GeoTIFF').setVisible(false);
}
this.$store.working = false;
},
/**
* Sets the boundaries layer on the map based on the selected NUTS level.
* If the NUTS level is greater than or equal to 0, it makes an asynchronous request to retrieve the boundaries data.
* The retrieved data is then added to the boundaries source of the map.
* If the NUTS level is less than 0, the boundaries source is cleared.
* @returns {Promise<void>} A promise that resolves when the boundaries layer is set.
*/
async setBoundariesLayer() {
if (this.nutsLevel && this.nutsLevel.value >= 0) {
this.$store.working = true;
let featureCollection = await this.get("Home/GetBoundaries", {
level: this.nutsLevel.value, srid: this.srid, zoom: Math.round(this.zoom), extent: this.extent.join(","), indicatorId: this.selectedIndicator ? this.selectedIndicator.value : null, dataSourceId: this.selectedDataSource ? this.selectedDataSource.value : null
});
this.boundariesSource.clear();
if (featureCollection.features) {
this.boundariesSource.addFeatures(this.format.readFeatures(featureCollection));
}
this.$store.working = false;
} else {
this.boundariesSource.clear();
}
},
},
}