Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion configure/src/metaconfigs/layer-vector-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
{
"field": "url",
"name": "URL",
"description": "A file path that points to a geojson. If the path is relative, it will be relative to the mission's directory. The URL must contain a proper placeholder ending such as: {z}/{x}/{y}.png.\nAlternatively vectors can be served with Geodatasets or through API calls via the following constructed URLs:\n\t<strong>• 'geodatasets:{geodataset_name}'</strong> - Simply go to 'Manage Geodatasets' at the bottom left, upload a geojson and link to it in this URL field with 'geodatasets:{geodataset_name}'\n\t<strong>• 'api:publishedall'</strong> - Grabs all features published via the DrawTool.\n\t<strong>• 'api:published:{file_intent}'</strong> - Grabs all features published via the DrawTool of a certain intent. Possible values are: roi, campaign, campsite, signpost, trail, all\n\t<strong>• 'api:drawn:{file_id}'</strong> - Grabs a user drawn file from the DrawTool. The file_id is an integer and can be found by hovering over the desired file in the DrawTool. Note that if the file chosen is still private, the file owner will be the only user who can view it.",
"description": "A file path that points to a geojson. If the path is relative, it will be relative to the mission's directory. The URL must contain a proper placeholder ending such as: {z}/{x}/{y}.png.\nInclude an optional prefix to signify the vector's source for special handling, such as being served via Geodatasets or through API calls, with the following constructed URLs:\n\t<strong>• 'geodatasets:{geodataset_name}'</strong> - Simply go to 'Manage Geodatasets' at the bottom left, upload a geojson and link to it in this URL field with 'geodatasets:{geodataset_name}'\n\t<strong>• 'api:publishedall'</strong> - Grabs all features published via the DrawTool.\n\t<strong>• 'api:published:{file_intent}'</strong> - Grabs all features published via the DrawTool of a certain intent. Possible values are: roi, campaign, campsite, signpost, trail, all\n\t<strong>• 'api:drawn:{file_id}'</strong> - Grabs a user drawn file from the DrawTool. The file_id is an integer and can be found by hovering over the desired file in the DrawTool. Note that if the file chosen is still private, the file owner will be the only user who can view it.\n\t<strong>• 'stac:{url}'</strong> - Point to a STAC catalog/collection/item of GeoJSON features.\n\t\t<strong>• 'stac-catalog'</strong> - Use this prefix if the URL is specifically to a Catalog object\n\t\t<strong>• 'stac-collection'</strong> - Use this prefix if the URL is specifically to a Collection object\n\t\t<strong>• 'stac-item'</strong> - Use this prefix if the URL is to an Item object\n\t\t• If the underlying data is a COG or similar data product, use the <strong>Tile</strong> layer type instead.",
"type": "text",
"width": 12
}
Expand Down
23 changes: 23 additions & 0 deletions src/essence/Ancillary/Description.js
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,29 @@ const Description = {
})
}
}

// check if this is actually a STAC feature
if (activeLayer.feature.stac_version) {
// extract links from feature assets
// https://github.com/radiantearth/stac-spec/blob/master/commons/assets.md#assets--
if (activeLayer.feature.assets) {
const assetKeys = Object.keys(
activeLayer.feature.assets
)
for (let i = 0; i < assetKeys.length; i++) {
const asset =
activeLayer.feature.assets[assetKeys[i]]
const link = asset?.href
const title = asset?.title
if (link !== null && link !== '')
links.push({
name: `<span style='display: flex; justify-content: space-between;'>${title}<i class='mdi mdi-open-in-new mdi-14px' style='margin-left: 4px; margin-top: 1px;'></i></span>`,
link: link,
target: F_.cleanString(title),
})
}
}
}
}

let key = activeLayer.useKeyAsName || 'name'
Expand Down
109 changes: 109 additions & 0 deletions src/essence/Basics/Layers_/Layers_.js
Original file line number Diff line number Diff line change
Expand Up @@ -3619,8 +3619,16 @@ function parseConfig(configData, urlOnLayers) {
expandLayers(layers, 0, null)

function expandLayers(d, level, prevName) {
const stacRegex = /^stac(-((item)|(catalog)|(collection)))?:/i

//Iterate over each layer
for (let i = 0; i < d.length; i++) {
// check if this is a vector STAC catalog or collection
// if so, prefetch the data and replace this entry
if (d[i].type === "vector" && stacRegex.test(d[i].url)) {
d[i] = getSTACLayers(d[i])
}

// Quick hack to use uuid instead of name as main id
d[i].uuid = d[i].uuid || d[i].name
if (L_.layers.nameToUUID[d[i].name] == null)
Expand Down Expand Up @@ -3791,6 +3799,107 @@ function parseConfig(configData, urlOnLayers) {
//Otherwise return 0
return 0
}

// recurse through a STAC layer building sublayers
function getSTACLayers(d) {
let stac_data
const urlPieces = d.url.split(':')
Comment thread
tariqksoliman marked this conversation as resolved.
Outdated
const prefix = urlPieces.length > 1 ? urlPieces[0] : ''
const url = urlPieces.length > 1 ? urlPieces[1] : urlPieces[0]
d.url = url // replace the current URL so we no longer need to worry about the special prefix
if (prefix !== 'stac-item') {
$.ajax({
url: L_.getUrl('stac', d.url, d),
success: (resp) => {
stac_data = resp
},
async: false,
})
const path = d.url.split('/').slice(0, -1).join('/')
const basename = F_.fileNameFromPath(d.url)
const stac_type = stac_data.type.toLowerCase()
if (stac_type === 'catalog') {
const sublayers = []
const children = stac_data.links.filter(
(l) => l.rel.toLowerCase() === 'child'
)
for (let i = 0; i < children.length; i++) {
const uuid = `${d.uuid}-${i}`
sublayers.push(
getSTACLayers(
Object.assign({}, d, {
url: children[i].href.replace('./', `${path}/`),
display_name: F_.fileNameFromPath(children[i].href),
uuid: uuid,
name: uuid,
})
)
)
}

return Object.assign(
{
type: 'header',
sublayers,
description: '',
display_name: '',
name: '',
uuid: '',
},
{
description: d.description,
display_name: d.display_name || basename,
name: d.name,
uuid: d.uuid,
}
)
} else if (stac_type === 'collection') {
const sublayers = []
const items = stac_data.links.filter(
(l) => l.rel.toLowerCase() === 'item'
)
for (let i = 0; i < items.length; i++) {
const uuid = `${d.uuid}-${i}`
sublayers.push(
// we shouldn't need to pre-fetch item data
Object.assign({}, d, {
url: items[i].href.replace('./', `${path}/`),
display_name: F_.fileNameFromPath(items[i].href),
uuid: uuid,
name: uuid,
})
)
}
return Object.assign(
{
type: 'header',
sublayers,
description: '',
display_name: '',
name: '',
uuid: '',
},
{
description: d.description,
display_name: d.display_name || basename,
name: d.name,
uuid: d.uuid,
}
)
} else if (
stac_type === 'feature' ||
stac_type === 'featurecollection'
) {
return Object.assign({}, d, {
display_name: d.display_name || basename,
})
} else {
console.warn('Could not process STAC layer')
return d
}
}
return d
}
}

window.L_ = L_
Expand Down
Loading