var requestsGridlayer
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 ) ;
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 ) ;
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 } ;
console . debug ( 'zoomed feature: ' , e . target . feature ) ;
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);
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);
//
return habitats ;
}
function moreInfoPopup ( props ) {
let title ;
if ( props . hasOwnProperty ( 'code' ) ) {
title = ` ${ props . code } — ${ props . name } ` ;
} else {
title = ` Grid — ${ props . cellcode } ` ;
}
if ( typeof props . tspr !== 'undefined' ) {
title = ` POSEIDON — ${ props . pid } ` ;
props . entity _group = 'POSEIDON' ;
}
if ( typeof props . ctStationCode !== 'undefined' ) {
title = ` WFD — ${ props . ctStationCode } ` ;
props . category = 'coastal_wfd' ;
}
Alpine . store ( 'entity' , props ) ;
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 } ` ;
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);
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 ( ) ;
const layerCode = layer . code ;
const layerTitle = layer . name ;
const legendName = layerCode . split ( '_' ) . slice ( 1 , 3 ) . join ( '_' ) ;
const lgndUrl = BASE _URL + "/img/legends/" + legendName + ".png" ;
let l ;
l = L . tileLayer . wms ( BASE _URL + '/geoserver/wms' , { transparent : true , layers : layerCode + layer . minSuffix , format : 'image/png' } ) ;
wmsGroup . addLayer ( l ) ;
layerControls [ layerCode ] = L . control . slider ( value => {
wmsGroup . removeLayer ( l ) ;
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 ,
logo : 'Year Selector ' + layerTitle ,
} ) . addTo ( mapL ) ;
// 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 ;
}
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 ( layerCode ) {
// 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" } ) ;
try {
const data = await fetchGeoJson ( layerCode ) ;
console . debug ( "fisheries json: " , data ) ;
let pies ;
// Add the custom control to the map
pies = createPie ( data , 1990 ) . addTo ( group ) ;
layerControls [ layerCode ] = 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 ;
}