Fullstack Portal Created by the HCMR for the Marine Strategy Framework Directive Program in order to cover demands and aspects considering extendability and maintainability
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

508 lines
13 KiB

var requestsGridlayer
2 years ago
var wfd;
var legends = {};
var selectedEntityGroup = null;
var selectedEntityId = null;
var selectedMru = null;
async function get_layer_list() {
let response = await fetch(BASE_URL + '/src/geoserver/get_layers.php');
if (response.ok) { // if HTTP-status is 200-299
// get the response body (the method explained below)
let json = await response.json();
return json
} else {
alert("HTTP-Error: " + response.status);
}
}
async function fetchGeoJson(layerCode) {
console.debug('fetching geojson...');
const url = BASE_URL + "/interface/geojson/" + layerCode;
try {
const response = await fetch(url);
const data = await response.json();
console.debug('geojson data: ', data);
2 years ago
return data;
} catch (error) {
console.error(error);
}
}
function highlightFeature(e) {
let overLayer = e.target;
e.target.tempStyle = {
weight: overLayer.options.weight,
color: overLayer.options.color,
dashArray: overLayer.options.dashArray,
fillOpacity: overLayer.options.fillOpacity
};
console.debug("highlighted: ", e.target);
try {
overLayer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7
});
} catch (err) {
console.log('could not change style');
}
}
function resetHighlight(e) {
try {
e.target.setStyle(e.target.tempStyle);
delete e.target.tempStyle;
} catch {
console.debug('eee');
}
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
}
function styleLine(feature, layer) {
return {
fillColor: getColor(), //feature.properties.name
weight: 2,
radius: 8,
opacity: 1,
color: '#000',
dashArray: '3',
fillOpacity: 0.8
};
}
function stylePoint(feature, latlng) {
console.debug(feature);
return L.circleMarker(latlng, styleRules);
};
function getColor(d=null) {
if (d != null)
return intToRGB(hashCode(d));
else
return "#ff7800";
}
function intToRGB(i){
var c = (i & 0x00FFFFFF)
.toString(16)
.toUpperCase();
return "00000".substring(0, 6 - c.length) + c;
}
function hashCode(str) { // java String#hashCode
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
}
return hash;
}
// zoom to feature (for data sources)
function zoomToFeature(e) {
let featureId = e.target.feature.properties.id;
console.debug('feature zoomed: ', e.target);
2 years ago
try {
selectedEntityGroup = e.target.feature.id.split('.')[0];
selectedEntityId = e.target.feature.properties.id;
} catch (error) {
selectedEntityId = e.target.feature.properties.id;
}
lonlat = {lon: e.latlng.lng, lat: e.latlng.lat};
moreInfoPopup(e.target.feature.properties);
try {
mapL.fitBounds(e.target.getBounds());
} catch (err) {
console.log('cannot zoom ', err);
}
}
function boundsToExtent(northEast, southWest, my_crs) {
let my_proj = my_crs.projection;
let rt = my_proj.project(northEast);
let lb = my_proj.project(southWest);
return {
left: lb.x,
bottom: lb.y,
right: rt.x,
top: rt.y
}
}
function getBathymetry() {
// load contours in JSON
const url = "https://ows.emodnet-bathymetry.eu/wfs?service=WFS&version=1.1.0&request=GetFeature&typeName=emodnet:contours&outputFormat=application/json";
const rainbow_url = "https://ows.emodnet-bathymetry.eu/wms";
let remoteLayer;
// add rainbow colored bathymetry map
const rnb = L.tileLayer.wms(rainbow_url, { transparent: true, layers: 'emodnet:mean_rainbowcolour', format: 'image/png'});
const cnt = L.tileLayer.wms(rainbow_url, { transparent: true, layers: 'emodnet:contours', format: 'image/png'});
// legends['DPTH'] = L.control.Legend({
// position: "bottomright",
// title: 'Bathymetry',
// symbolWidth: 150,
// symbolHeight: 208,
// collapsed: false,
// legends: [{
// type: "image",
// label: ' ',
// url: "https://tiles.emodnet-bathymetry.eu/legends/legend_rainbow.png"
// }]
// }).addTo(mapL);
2 years ago
remoteLayer = L.layerGroup([rnb, cnt]);
return remoteLayer;
}
async function getDepthOnPoint(latlng) {
await fetch(`https://rest.emodnet-bathymetry.eu/depth_sample?geom=POINT(${latlng.lng}%20${latlng.lat})`, {
"credentials": "omit",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-site",
"Sec-GPC": "1"
},
"method": "GET",
"mode": "cors"
}).then(res => {
return res.json();
}).then(depthInfo => {
const depth = depthInfo.avg.toString();
L.popup()
.setLatLng(latlng)
.setContent(`<table class="table"><tr><th>Topography (m)</th></tr><tr><td>${depth}</td></tr></table>`)
.openOn(mapL);
});
}
function getHabitat(layerCode) {
// load contours in JSON
const url = "https://ows.emodnet-seabedhabitats.eu/geoserver/emodnet_view/wms";
const lgndUrl = "https://ows.emodnet-seabedhabitats.eu/geoserver/emodnet_view/ows?service=WMS&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=eusm2021_bio_200&style=eusm2019_msfd_200"
// add rainbow colored bathymetry map
let habitats = new L.layerGroup();
const lrs = ['eusm2021_msfd_800', 'eusm2021_msfd_400', 'eusm2021_msfd_200'];
let l;
lrs.forEach(layer => {
l = L.tileLayer.betterWms(url, { transparent: true, layers: layer, format: 'image/png'});
habitats.addLayer(l)
});
// legends[layerCode] = L.control.Legend({
// position: "bottomright",
// symbolWidth: 400,
// symbolHeight: 600,
// collapsed: false,
// title: 'Habitat Type',
// legends: [{
// type: "image",
// label: ' ',
// url: lgndUrl
// }]
// }).addTo(mapL);
//
2 years ago
return habitats;
}
function moreInfoPopup(props) {
let title;
if (props.hasOwnProperty('code')) {
title = `${props.code} &mdash; ${props.name}`;
} else {
title = `Grid &mdash; ${props.cellcode}`;
}
console.debug(props);
// if (typeof props.code == 'undefined' && typeof props.name == 'undefined')
if (typeof props.tspr !== 'undefined') {
2 years ago
title = `POSEIDON &mdash; ${props.pid}`;
props.entityGroup = 'POSEIDON';
}
2 years ago
if (typeof props.ctStationCode !== 'undefined')
title = `WFD &mdash; ${props.ctStationCode}`;
Alpine.store('entity', props);
2 years ago
getPagePartial('more-info').then(content => {
new L.control.window(mapL, {
title: title,
content: `${content}`,
visible: true,
position: 'left'
});
});
}
function mruPopup(props) {
if (props.hasOwnProperty('nssg')) {
L.popup()
.setLatLng([props.y_coord, props.x_coord])
.setContent(`<table class="table"><tr><th>NSSG Label</th></tr><tr><td>${props.nssg_label}</td></tr></table>`)
.openOn(mapL);
return;
}
let title;
Alpine.store('mru', props);
title = `MRU: ${props.mr_ms_aa}`;
getPagePartial('mru-info').then(content => {
content.props = props;
new L.control.window(mapL, {
title: title,
content: `${content}`,
visible: true,
position: 'left'
});
});
}
// Fetches html from elements folder
async function getPagePartial(partialName, target=null) {
// const url = BASE_URL + `/src/Views/${partialName}.php`;
const url = BASE_URL + `/interface/partial/${partialName}`;
2 years ago
const res = await fetch(url)
.then((response) => {return response.text();})
.then((content) => {
return content
})
.catch((err) => {return err;});
try {
// fill target element with html
document.querySelector(target).innerHTML = res;
} catch(err) {
return res;
}
}
function getProduct(layer) {
let url = layer.endpoint;
let legendUrl = layer.legend;
let l;
l = L.tileLayer.betterWms(url, { transparent: true, layers: layer.code, format: 'image/png'});
// legends[layer.code] = L.control.Legend({
// position: "bottomright",
// symbolWidth: 100,
// symbolHeight: 200,
// collapsed: false,
// title: 'Probability of habitat presence',
// legends: [{
// type: "image",
// label: ' ',
// url: legendUrl
// }]
// }).addTo(mapL);
2 years ago
mapL.on('click', e => {
let location = e.latlng;
});
return l;
}
function initializeLayerTree() {
pTree = new PickleTree({
c_target: 'layertree', //'maptab_treeview',
c_config: {
// options here
switchMode: true,
hasLink: true,
drag: false,
contextPos: 'before',
foldedStatus: true
},
switchCallback: layerTreeSwitch,
c_data: myData
});
}
function getWFD(layer) {
var wmsGroup = L.layerGroup();
2 years ago
const layerCode = layer.code;
const layerTitle = layer.name;
const legendName = layerCode.split('_').slice(1,3).join('_');
const lgndUrl = BASE_URL + "/img/legends/" + legendName + ".png";
2 years ago
let l;
2 years ago
l = L.tileLayer.wms(BASE_URL + '/geoserver/wms', { transparent: true, layers: layerCode + layer.minSuffix, format: 'image/png'});
wmsGroup.addLayer(l);
2 years ago
layerControls[layerCode] = L.control.slider(value => {
wmsGroup.removeLayer(l);
2 years ago
l = L.tileLayer.wms(BASE_URL + '/geoserver/wms', { transparent: true, layers: layerCode + value, format: 'image/png'});
wmsGroup.addLayer(l);
},{
min: layer.minSuffix,
max: layer.maxSuffix,
step: 1,
value: layer.minSuffix,
2 years ago
logo: 'Year Selector ' + layerTitle,
}).addTo(mapL);
2 years ago
// legends[layerCode] = L.control.Legend({
// position: "bottomright",
// title: layerTitle,
// symbolWidth: 90,
// symbolHeight: 130,
// collapsed: false,
// legends: [{
// type: "image",
// label: '',
// url: lgndUrl
// }]
// }).addTo(mapL);
//
return wmsGroup;
2 years ago
}
async function searchForRequests() {
let response = await fetch(BASE_URL + '/actions/requests');
if (response.ok) { // if HTTP-status is 200-299
// get the response body (the method explained below)
let json = await response.json();
return json;
} else {
alert("HTTP-Error: " + response.status);
}
}
function flattenJson(data, depth = 1) {
var result = {};
function recurse(cur, prop) {
if (Object(cur) !== cur || depth === 0) {
result[prop] = cur;
} else if (Array.isArray(cur)) {
for(var i=0, l=cur.length; i<l; i++)
recurse(cur[i], prop + "[" + i + "]");
if (l == 0)
result[prop] = [];
} else {
var isEmpty = true;
for (var p in cur) {
isEmpty = false;
recurse(cur[p], prop ? prop + "." + p : p, depth - 1);
}
if (isEmpty && prop)
result[prop] = {};
}
}
recurse(data, "", depth);
return result;
}
async function downloadShapefile(layerName, srs) {
let response = await fetch(BASE_URL + '/geoserver/shapefile/' + layerName + '/' + srs, {
"credentials": "include",
"headers": {
"Accept": "application/zip",
"Accept-Language": "en-US,en;q=0.5",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
},
"method": "GET",
"mode": "cors"
});
if (response.ok) { // if HTTP-status is 200-299
// get the response body (the method explained below)
let zip = await response.blob();
var a = document.createElement("a");
let data = await zip;
a.href = window.URL.createObjectURL(data);
a.download = layerName + "_shapefiles";
a.click();
} else {
alert("HTTP-Error: " + response.status);
}
}
async function getFisheriesProduct() {
// Create timeline slider control
const group = L.layerGroup();
// load contours in JSON
const bgLayer = L.tileLayer.betterWms(BASE_URL + '/geoserver/wms', { layers: 'nssg_areas', transparent: true, format: "image/png"});
const url = BASE_URL + "/interface/charts/afppy";
2 years ago
try {
const response = await fetch(url);
const data = await response.json();
let pies;
// Add the custom control to the map
pies = createPie(data, 1990).addTo(group);
layerControls['AFPPY'] = L.control.slider(value => {
pies.remove();
pies = createPie(data, value);
group.addLayer(pies);
},{
min: 1990,
max: 2019,
step: 1,
value: 1990,
logo: 'Year Selector',
}).addTo(mapL);
} catch (error) {
console.error(error);
}
bgLayer.addTo(group);
return group;
}
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}