diff --git a/API/Backend/Config/routes/configs.js b/API/Backend/Config/routes/configs.js index acae3fe2..c2b4b70a 100644 --- a/API/Backend/Config/routes/configs.js +++ b/API/Backend/Config/routes/configs.js @@ -694,7 +694,7 @@ function addLayer(req, res, next, cb, forceConfig, caller = "addLayer") { mission: "{mission_name}", layer: { name: "{new_layer_name}", - type: "header || vector || vectortile || query || model || tile || data", + type: "header || vector || vectortile || query || model || tile || data || image", "more...": "...", }, "placement?": { diff --git a/API/Backend/Config/validate.js b/API/Backend/Config/validate.js index d1dbebec..0e5b6470 100644 --- a/API/Backend/Config/validate.js +++ b/API/Backend/Config/validate.js @@ -89,6 +89,12 @@ const validateLayers = (config) => { // Check model params (pos, rot, scale) errs = errs.concat(isValidModelParams(layer)); break; + case "image": + // Check url + errs = errs.concat(isValidUrl(layer)); + // Check zooms + errs = errs.concat(isValidZooms(layer)); + break; default: errs = errs.concat( err(`Unknown layer type: '${layer.type}'`, ["layers[layer].type"]) @@ -316,6 +322,10 @@ const fillInMissingFieldsWithDefaults = (layer) => { layer.style = layer.style || {}; layer.style.className = layer.name.replace(/ /g, "").toLowerCase(); break; + case "image": + layer.style = layer.style || {}; + layer.style.className = layer.name.replace(/ /g, "").toLowerCase(); + break; case "model": break; default: diff --git a/API/Backend/Draw/routes/draw.js b/API/Backend/Draw/routes/draw.js index 7d1e6dd6..9e3fb255 100644 --- a/API/Backend/Draw/routes/draw.js +++ b/API/Backend/Draw/routes/draw.js @@ -204,7 +204,7 @@ const clipOver = function ( historyIndex: lastHistory[0].history_id + 1, history: lastHistory[0].history, }; - } else return { historyIndex: 0, history: [] }; + } else return { historyIndex: 0, history: null }; }) .then((historyObj) => { let history = historyObj.history; @@ -335,7 +335,7 @@ const clipUnder = function ( historyIndex: lastHistory[0].history_id + 1, history: lastHistory[0].history, }; - } else return { historyIndex: 0, history: [] }; + } else return { historyIndex: 0, history: null }; }) .then((historyObj) => { let history = historyObj.history; diff --git a/API/Backend/Utils/routes/utils.js b/API/Backend/Utils/routes/utils.js index abb1288f..a691a061 100644 --- a/API/Backend/Utils/routes/utils.js +++ b/API/Backend/Utils/routes/utils.js @@ -296,6 +296,25 @@ router.post("/getbands", function (req, res) { ); }); +//utils getminmax +router.post("/getminmax", function (req, res) { + const path = encodeURIComponent(req.body.path); + const bands = encodeURIComponent(req.body.bands); + + execFile( + "python", + ["private/api/gdalinfoMinMax.py", path, bands], + function (error, stdout, stderr) { + if (error) { + logger("warn", error); + res.status(400).send(); + } else { + res.send(stdout); + } + } + ); +}); + //utils ll2aerll router.post("/ll2aerll", function (req, res) { const lng = encodeURIComponent(req.body.lng); diff --git a/configuration/env.js b/configuration/env.js index b9eaee47..dbf1b4a0 100644 --- a/configuration/env.js +++ b/configuration/env.js @@ -109,6 +109,7 @@ function getClientEnvironment(publicUrl) { THIRD_PARTY_COOKIES: process.env.THIRD_PARTY_COOKIES || "", SKIP_CLIENT_INITIAL_LOGIN: process.env.SKIP_CLIENT_INITIAL_LOGIN || "", IS_DOCKER: process.env.IS_DOCKER, + WITH_TITILER: process.env.WITH_TITILER, } ); // Stringify all values so we can feed into webpack DefinePlugin diff --git a/configuration/webpack.config.js b/configuration/webpack.config.js index a08eed67..f2c707f9 100644 --- a/configuration/webpack.config.js +++ b/configuration/webpack.config.js @@ -381,7 +381,7 @@ module.exports = function (webpackEnv) { // Process any JS outside of the app with Babel. // Unlike the application JS, we only compile the standard ES features. { - test: /\.(js|mjs)$/, + test: /\.(js|mjs|cjs)$/, exclude: /@babel(?:\/|\\{1,2})runtime/, loader: require.resolve("babel-loader"), options: { diff --git a/configure/public/toolConfigs.json b/configure/public/toolConfigs.json index a65eff0e..c549a0ff 100644 --- a/configure/public/toolConfigs.json +++ b/configure/public/toolConfigs.json @@ -1 +1 @@ -{"Identifier":{"defaultIcon":"map-marker","description":"Mouse over the map for a by-pixel legend of a raster.","descriptionFull":{"title":"Mouse over to query underlying datasets. This will read the raw values from a geo-referenced dataset, which can be any bit-depth (8,16,32). You can set up multiple file to return values from.","example":{"[Layer_Name]":{"url":"(str) path_to_data/data.tif","bands":"(int) how many bands to query from","sigfigs":"(int) how many digits after the decimal","unit":"(str) whatever string unit","timeFormat":"(str) for formatting injected '{starttime}' and '{endtime}' in url. See syntax in https://d3js.org/d3-time-format#locale_format"},"...":{}}},"hasVars":true,"name":"Identifier","toolbarPriority":1,"separatedTool":true,"paths":{"IdentifierTool":"essence/Tools/Identifier/IdentifierTool"},"config":{"rows":[{"components":[{"field":"separatedTool","name":"Separated Tool","description":"If true, this tool will live outside the left-hand toolbar and be independently accessible.","type":"checkbox","width":3,"defaultChecked":true},{"field":"variables.justification","name":"Justification","description":"The legend will display on the right side of the screen if set to right, otherwise default to the left side","type":"dropdown","width":2,"options":["left","right"]}]},{"components":[{"field":"variables.layers","name":"Layers","description":"Only show DEM if associated layer is on.","type":"objectarray","width":12,"object":[{"field":"name","name":"Layer Name or UUID","description":"This is the layer name exactly as it appears in the Layers section in the configuration.","type":"text","width":4},{"field":"url","name":"URL to .tif","description":"This can be a relative path to a file under the Mission name or a full url path. The former is preferred is the file is large. Can use '{starttime}' and '{endtime}' if the layer is time enabled. If this field is left empty, the Identifier Tool will try to best-match the hovered-over pixel color with this layer's legend (if any).","type":"text","width":8},{"field":"bands","name":"Bands","description":"Number of bands from which to query.","type":"number","min":0,"step":1,"width":2},{"field":"sigfigs","name":"SigFigs","description":"Number of significant figures to use after the decimal of returned values.","type":"number","min":0,"step":1,"width":2},{"field":"unit","name":"Unit","description":"A string that is appended to your returned value. e.g. ' m' would be appended on a raw value ('41') and show '41 m'. If it was 'm', it would return '41m', without a space.","type":"text","width":2},{"field":"scalefactor","name":"Scale Factor","description":"A number for which to multiply the raw value by for display purposes only. Useful, for instance, if the underlying dataset is in units that are off by factor's of 10 from what's desired to be shown to users.","type":"number","width":2},{"field":"timeFormat","name":"Time Format","description":"A string for formatting the injected '{starttime}' and '{endtime}' in the url. See syntax in https://d3js.org/d3-time-format#locale_format","type":"text","width":4}]}]}]}},"Layers":{"defaultIcon":"layers","description":"Hierarchically toggle layers on and off and alter their opacities.","descriptionFull":{"title":"Allows users to toggle on and off layers, download them, filter their features and change some parameters such as opacity.","example":{"expanded":"(bool) is initial state expanded [default false]"}},"hasVars":true,"name":"Layers","toolbarPriority":1,"paths":{"LayersTool":"essence/Tools/Layers/LayersTool"},"expandable":true,"config":{"rows":[{"components":[{"field":"variables.expanded","name":"Expanded","description":"Whether all layer groupings default to being expanded (as opposed to being collapsed).","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Legend":{"defaultIcon":"map-legend","description":"Show a chart legend that maps colors and symbols to meaning.","descriptionFull":{"title":"A layer can be configured with a legend by pointing its Legend field to a .csv file or by including a JSON legend array into the layer's Raw Variables. The Legend Tool renders symbologies and gradient scales for any properly configured on layer.","example":{"displayOnStart":true,"justification":"right"}},"hasVars":true,"name":"Legend","toolbarPriority":2,"separatedTool":true,"paths":{"LegendTool":"essence/Tools/Legend/LegendTool"},"config":{"rows":[{"components":[{"field":"separatedTool","name":"Separated Tool","description":"If true, this tool will live outside the left-hand toolbar and be independently accessible.","type":"checkbox","width":3,"defaultChecked":true},{"field":"variables.displayOnStart","name":"Display on Start","description":"Whether the expanded legend should automatically be displayed on start.","type":"checkbox","width":3,"defaultChecked":false},{"field":"variables.justification","name":"Justification","description":"The legend will display on the right side of the screen if set to right, otherwise default to the left side","type":"dropdown","width":2,"options":["left","right"]}]}]}},"Info":{"defaultIcon":"information-variant","description":"Display the geojson properties field of a clicked feature.","descriptionFull":{"title":"Lists out the geojson properties of any clicked feature. Any clicked feature will open the Info tool and display the data in JSON formatting. Some layer 'kinds' disable opening the Info tool and displaying data automatically, like the 'Waypoints' kind layer.","example":{"sortAlphabetically":true}},"hasVars":true,"name":"Info","toolbarPriority":3,"paths":{"InfoTool":"essence/Tools/Info/InfoTool"},"expandable":true,"config":{"rows":[{"components":[{"field":"variables.sortAlphabetically","name":"Sort Alphabetically","description":"Whether to sort the feature's fields alphabetically instead of listing them in their native order.","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Sites":{"defaultIcon":"pin","description":"A button bar to navigate between various map locations.","descriptionFull":{"title":"A button bar to quickly navigate between preset map locations.","example":{"sites":[{"name":"(str) Name of site","code":"(str) Unique identifier. Can match header layer to toggle it's sublayers","view":["(num) Latitude","(num) Longitude","(num) Zoom level"]},{"...":"..."}]}},"hasVars":true,"name":"Sites","toolbarPriority":4,"paths":{"SitesTool":"essence/Tools/Sites/SitesTool"},"config":{"rows":[{"components":[{"field":"variables.sites","name":"Sites","description":"","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"Name of site","type":"text","width":4},{"field":"code","name":"Code","description":"Unique identifier. Can match header layer to toggle its sublayers.","type":"text","width":2},{"field":"view.0","name":"Latitude","description":"","type":"number","width":2},{"field":"view.1","name":"Longitude","description":"","type":"number","width":2},{"field":"view.2","name":"Zoom Level","description":"","type":"number","min":0,"step":1,"width":2}]}]}]}},"Isochrone":{"defaultIcon":"circle-double","description":"Find the range of locations accessible to an explorer within a given time.","descriptionFull":{"title":"Given a user-defined starting point, render a shaded region where colors indicate minimum travel time or resource expenditure to reach a given location. Hover over the region to view the least costly path from the start to the cursor. Costs are calculated based on selectable and configurable models, which may each require multiple different tilesets as input.","example":{"data":{"DEM":[{"name":"Unique Name 1","tileurl":"Layers/Example/{z}/{x}/{y}.png","minZoom":8,"maxNativeZoom":18,"resolution":256,"interpolateSeams":true},{"...":"..."}],"slope":[{"...":"..."}],"cost":[{"...":"..."}]},"interpolateSeams":false,"models":["Traverse Time","Isodistance","..."]}},"hasVars":true,"name":"Isochrone","toolbarPriority":10,"paths":{"IsochroneTool":"essence/Tools/Isochrone/IsochroneTool"},"config":{"rows":[{"name":"Data Sources","components":[{"field":"variables.data.DEM","name":"Elevation (DEM)","description":"Configure DEM data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"components":[{"field":"variables.data.slope","name":"Slope","description":"Configure Slope data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"components":[{"field":"variables.data.obstacle","name":"Obstacle","description":"Configure Obstacle map data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"components":[{"field":"variables.data.cost","name":"Cost","description":"Configure Cost data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"components":[{"field":"variables.data.shade","name":"Shade","description":"Configure Shade data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"name":"Models","components":[{"field":"variables.models","name":"Enabled Models","description":"Comma-separated list of isochrone models to enable. Possible values are: 'Traverse Time', 'Isodistance', 'Example' ","type":"textarray","width":12}]},{"name":"Settings","components":[{"field":"variables.interpolateSeams","name":"Interpolate Seams (Global)","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams. Set this property to false to disable this behavior for all sources that do not explicitly set their own 'interpolateSeams' property to true.","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Viewshed":{"defaultIcon":"wifi-strength-2","description":"Realtime user generated viewsheds.","descriptionFull":{"title":"Renders dynamic tilesets based on line-of-sight visibilities from user defined source points. DEM tiles are used to generate these. At least one DEM tileset must be configured. curvature is optional and can be set to false to disable using the Major Radius to account for curvature during generations. cameraPresets are optional and the objects within only require the name field.","example":{"data":[{"name":"Unique Name 1","demtileurl":"Layers/Example/demtileset/{z}/{x}/{y}.png","minZoom":8,"maxNativeZoom":18},{"...":"..."}],"curvature":false,"cameraPresets":[{"name":"CAM A","height":2,"azCenter":0,"azFOV":70,"elCenter":-10,"elFOV":30},{"...":"..."}],"defaultObserverHeight":2,"defaultTargetHeight":0}},"hasVars":true,"name":"Viewshed","toolbarPriority":101,"paths":{"ViewshedTool":"essence/Tools/Viewshed/ViewshedTool","ViewshedTool_Manager":"essence/Tools/Viewshed/ViewshedTool_Manager","ViewshedTool_Algorithm":"essence/Tools/Viewshed/ViewshedTool_Algorithm"},"config":{"rows":[{"components":[{"field":"variables.data","name":"Layer specific DEMs","description":"Only show DEM if associated layer is on.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"User-friendly name for DEM","type":"text","width":2},{"field":"demtileurl","name":"DEM Path","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"","type":"number","min":0,"step":1,"width":1},{"field":"maxNativeZoom","name":"Maximum Native Zoom","description":"","type":"number","min":0,"step":1,"width":1}]}]},{"components":[{"field":"variables.cameraPresets","name":"Camera Presets","description":"Only show DEM if associated layer is on.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"Camera Name","type":"text","width":10},{"field":"height","name":"Height","description":"Height in meters","type":"number","min":0,"width":2},{"field":"azCenter","name":"Azimuth Center","description":"","type":"number","width":3},{"field":"azFOV","name":"Azimuth FOV","description":"","type":"number","width":3},{"field":"elCenter","name":"Elevation Center","description":"","type":"number","width":3},{"field":"elFOV","name":"Elevation FOV","description":"","type":"number","width":3}]}]},{"components":[{"field":"variables.curvature","name":"Curvature","description":"Whether to account for planetary curvature while computing viewsheds.","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Shade":{"defaultIcon":"sun-angle-outline","description":"Realtime user generated sun and orbiter masks.","descriptionFull":{"title":"Shades the ground when line-of-sights to an orbiting target are occluded.","example":{"dem":"Data/missionDEM.tif","data":[{"name":"User-friendly name for DEM","demtileurl":"pathToDEMTiles/{z}/{x}/{y}.png","minZoom":8,"maxNativeZoom":18}],"sources":[{"name":"User-friendly name for orbiter or body that 'casts shadows'","value":"NAIF SPICE Spacecraft name or ID"},{"name":"...","value":"..."}],"observers":[{"name":"User-friendly name for observer for spacecraft time computations. Set to null to turn off time converting.","value":"SPICE Spacecraft name or ID","frame":"SPICE reference frame. i.e. IAU_MARS","body":"SPICE planet body. i.e. MARS"}],"defaultHeight":0,"observerTimePlaceholder":null,"utcTimeFormat":null}},"hasVars":true,"name":"Shade","toolbarPriority":102,"paths":{"ShadeTool":"essence/Tools/Shade/ShadeTool","ShadeTool_Manager":"essence/Tools/Shade/ShadeTool_Algorithm","ShadeTool_Algorithm":"essence/Tools/Shade/ShadeTool_Algorithm"},"config":{"rows":[{"components":[{"field":"variables.dem","name":"DEM path","description":"A path to a DEM.tif. This is used to get the current center elevation. This can/should be the same file used for the Measure Tool and the Coordinate's elevation.","type":"text","width":12}]},{"components":[{"field":"variables.data","name":"Layer specific DEMs","description":"At minimum, the Shade tool requires at least one 'data' source. A data source describes a DEM tileset (see /auxiliary/gdal2customtiles or /auxiliary/1bto4b) and allows users to select it by name to generate shade maps over.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"User-friendly name for DEM","type":"text","width":2},{"field":"demtileurl","name":"DEM Path","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"","type":"number","min":0,"step":1,"width":1},{"field":"maxNativeZoom","name":"Maximum Native Zoom","description":"","type":"number","min":0,"step":1,"width":1}]}]},{"components":[{"field":"variables.sources","name":"Sources","description":"An array of objects with the properties 'name' and 'value'. 'name' is the display name for the Source Entity dropdown. 'value' is the SPICE spacecraft ID that gets passed to the backend ll2aerll.py script. Ensure the right kernels for the configured source entities/targets exist in /private/api/spice/kernels.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"User-friendly name for orbiter or body that 'casts light'","type":"text","width":4},{"field":"value","name":"Value","description":"NAIF SPICE Spacecraft name or ID","type":"text","width":4}]}]},{"components":[{"field":"variables.observers","name":"Observers","description":"An array of objects with the properties 'name' and 'value'. 'name' is the display name for the Source Entity dropdown. 'value' is the SPICE spacecraft ID that gets passed to the backend chronos.py scripts. Ensure the right kernels for the configured observers exist in /private/api/spice/kernels and that there is a proper chronos setup file for each observer's value private/api/spice/chronosSetups/chronos-{lowercased_observer_value}.setup.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"User-friendly name for observer for spacecraft time computations","type":"text","width":3},{"field":"value","name":"Value","description":"NAIF SPICE Spacecraft name or ID","type":"text","width":3},{"field":"frame","name":"Frame","description":"SPICE reference frame. i.e. 'IAU_MARS'","type":"text","width":3},{"field":"body","name":"Body","description":"SPICE planet body. i.e. 'MARS'","type":"text","width":3}]}]},{"components":[{"field":"variables.defaultHeight","name":"Default Height","description":"Sets a default for the 'Height' parameter. Height in meters above the surface to use when calculating line-of-sight shading. For instance, a point on the surface (0m) may not be visible to a 'Source Entity', say the Mars Reconnaissance Orbiter (MRO), but 2m above that point may be. This value does not only apply to the center longitude and latitude but to all points on the visible terrain. Gradually increasing this value shows the shade map n-meters above the surface. The regular default is 0 meters.","type":"number","min":0,"width":4},{"field":"variables.observerTimePlaceholder","name":"Observer Time Placeholder","description":"Sets the placeholder information for when the observer time's input box is cleared. Useful for denoting the expected time format to be inputted. For example “SOL DDDD HH:MM:SS”. Default null.","type":"text","width":4},{"field":"variables.utcTimeFormat","name":"UTC Time Format","description":"Sets the placeholder information for when the observer time's input box is cleared. Useful for denoting the expected time format to be inputted. Uses d3 time syntax (https://d3js.org/d3-time-format#locale_format). Example for day-of-year: '%Y-%j %H:%M:%S'. Defaults to times like so: 2023 SEP 06 19:27:05.","type":"text","width":4}]}]}},"Chemistry":{"defaultIcon":"flask","description":"Display chemistry percentages via graphs of a clicked point.","descriptionFull":{},"hasVars":false,"name":"Chemistry","paths":{"ChemistryTool":"essence/Tools/Chemistry/ChemistryTool"}},"Curtain":{"defaultIcon":"waves","description":"Curtain views of Ground Penetrating Radar data.","descriptionFull":{"title":"Vertical imagery aligned under terrain for visualizing data from ground penetrating radar.","example":{"withCredentials":false}},"hasVars":true,"name":"Curtain","paths":{"CurtainTool":"essence/Tools/Curtain/CurtainTool"},"config":{"rows":[{"components":[{"field":"variables.withCredentials","name":"With Credentials","description":"","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Kinds":{"defaultIcon":"palette-swatch","description":"Not a real tool but plugin to configure different layer interactions.","descriptionFull":{},"hasVars":false,"name":"Kinds","kinds":["info","waypoint","chemistry_tool","draw_tool","edl_wedge"],"paths":{"Kinds":"essence/MMGIS-Private-Tools/Kinds/Kinds"}},"Measure":{"defaultIcon":"tape-measure","description":"Measure distances and generates elevation profiles.","descriptionFull":{"title":"Specify a path to a Digital Elevation Model (dem) .tif. Measure distances and generates elevation profiles. Can also query specific bands at specific points of images and generate profiles of them. If multiple dems are specified, a dropdown will be present for users to toggle between them.","example":{"dem":"(str) path to Data/defaultDEM.tif","layerDems":{"[layer_name]":"(str) path/to/layers/dem.tif"},"onlyShowDemIfLayerOn":true,"defaultMode":"segment || continuous || continuous_color"}},"hasVars":true,"name":"Measure","paths":{"MeasureTool":"essence/Tools/Measure/MeasureTool"},"config":{"rows":[{"components":[{"field":"variables.dem","name":"DEM path","description":"Path to a primary DEM (such as Data/defaultDEM.tif). Required if Layer Specific DEMs is unset.","type":"text","width":12}]},{"components":[{"field":"variables.layerDems","name":"Layer Specific DEMs","description":"Object of layer names and the paths to their DEMs. Users may switch between DEMs to profile via a dropdown. The dropdown only renders if there is more than one DEM configured overall.","type":"objectarray","width":12,"object":[{"field":"layer","name":"Layer Name","description":"","type":"text","width":4},{"field":"dem","name":"DEM Path","description":"","type":"text","width":8}]}]},{"components":[{"field":"variables.onlyShowDemIfLayerOn","name":"Only Show DEM If On","description":"If true, hides the configured Layer Specific DEMs of off layers from the tool's DEM selection dropdown. If false, all Layer Specific DEMs, even with invalid layer names, always show in the dropdown.","type":"checkbox","width":2,"defaultChecked":false}]},{"components":[{"field":"variables.defaultMode","name":"Default Mode","description":"Which measurement mode to default to. Options are 'segment', 'continuous' and 'continuous_color'","type":"dropdown","width":2,"options":["segment","continuous","continuous_color"]}]}]}},"Draw":{"defaultIcon":"pencil","description":"Advanced and collaborative map drawing.","descriptionFull":{"title":"The Draw tool is an advanced vector data creation and editing tool supporting a multi-user environment. Users can create and manage their own files which can have points, lines, and polygons as well as arrows and text to support annotation. Files can be viewed between users and features copied from one file to another.","example":{"intents":["Polygon_1_Alias","Polygon_2_Alias","Polygon_3_Alias","Line_Alias","Point_Alias","All_Alias"],"defaultDrawClipping":"over || under || off","defaultPublicFilter":false,"defaultYoursOnlyFilter":true,"defaultOnFilter":false,"leadsCanEditFileInfo":false,"hoverLengthOnLines":false,"mtttt":"MTTTT endpoint path that overrides MTTTT_HOST env and provides backwards compatibility","mttttInfoLink":"Powered by link destination","mttttHostPath":"Path to append to MTTTT_HOST env /mttt/sites/JEZ","mttttWithCreds":false,"scienceIntent":true,"templates":{"myTemplate":[{"type":"slider","field":"a","min":0,"max":100,"step":1,"default":0},{"type":"number","field":"b","min":0,"max":100,"step":1,"required":true,"default":3},{"type":"text","field":"c","minLength":2,"maxLength":4,"required":true,"regex":null,"default":null},{"type":"textarea","field":"d","maxLength":10,"required":true,"default":"hi"},{"type":"checkbox","field":"e","default":true},{"type":"dropdown","field":"f","items":["Yes","No","Maybe"],"default":"No"},{"type":"incrementer","field":"g","default":"ID-#"},{"type":"date","field":"h","format":"HH:mm:ss","default":"now"}]}}},"hasVars":true,"name":"Draw","toolbarPriority":1001,"paths":{"DrawTool":"essence/MMGIS-Private-Tools/Draw/DrawTool"},"tests":{"DrawToolTest":"essence/MMGIS-Private-Tools/Draw/DrawTool.test"},"expandable":true,"config":{"rows":[{"name":"Intent Aliases","description":"There are five files that are group editable with the correct permission. The group authentication is set an environment variable in the .env file during startup. These files are meant as collaborative layers that a only a few people will manage and contribute to do to the potential of race conditions on who did the last edit.","components":[{"field":"variables.intents.0","name":"Polygon 1 Alias","description":"","type":"text","width":2},{"field":"variables.intents.1","name":"Polygon 2 Alias","description":"","type":"text","width":2},{"field":"variables.intents.2","name":"Polygon 3 Alias","description":"","type":"text","width":2},{"field":"variables.intents.3","name":"Line Alias","description":"","type":"text","width":2},{"field":"variables.intents.4","name":"Point Alias","description":"","type":"text","width":2},{"field":"variables.intents.5","name":"All Alias","description":"","type":"text","width":2}]},{"components":[{"field":"variables.defaultDrawClipping","name":"Default Draw Clipping","description":"Default clipping mode for drawing. Drawing a polygon Over another would clip away that other polygon. Drawing a polygon Under another would have that polygon clip away the newly drawn one. When the clipping mode is Off, no clipping occurs. Users may freely change the clipping mode.","type":"dropdown","width":3,"options":["over","under","off"]},{"field":"variables.leadsCanEditFileInfo","name":"Leads Can Edit File Info","description":"If true, lead roles can edit the file info, (name, description, tags, folder, make private) of any user's public file.","type":"checkbox","width":3,"defaultChecked":false},{"field":"variables.hoverLengthOnLines","name":"Hover Length On Lines","description":"If true, the hover text for line features will include the total length of the line in meters.","type":"checkbox","width":3,"defaultChecked":false}]},{"components":[{"field":"variables.defaultPublicFilter","name":"Default Public Filter","description":"When the DrawTool first opens, filter the file list down to only public files or not.","type":"checkbox","width":4,"defaultChecked":false},{"field":"variables.defaultYoursOnlyFilter","name":"Default Yours Only Filter","description":"When the DrawTool first opens, filter the file list down to only files you own or not.","type":"checkbox","width":4,"defaultChecked":true},{"field":"variables.defaultOnFilter","name":"Default On Filter","description":"When the DrawTool first opens, filter the file list down to only files that are on or not. ","type":"checkbox","width":4,"defaultChecked":false}]},{"components":[{"field":"variables.templates","name":"Default File Property Templates","description":"Templates create forms for feature properties. For instance, all features in a given draw file could, in the feature's edit panel, have the field “Reviewed” be togglable via a checkbox. Users may make their own templates too but the ones configured here are promoted and cannot be delete.","type":"objectarray","width":12,"object":[{"field":"name","name":"Template Name","description":"","type":"text","width":4},{"field":"name","name":"Property Field Name","description":"","type":"text","width":4},{"field":"type","name":"Component","description":"","type":"dropdown","width":2,"options":["slider","number","text","textarea","checkbox","dropdown","incrementer","date"]},{"field":"required","name":"Required","description":"Field requires entry.","type":"checkbox","width":2,"defaultChecked":false},{"field":"min","name":"Min Value","description":"For Slider and Number","type":"number","width":4},{"field":"max","name":"Max Value","description":"For Slider and Number","type":"number","width":4},{"field":"step","name":"Step Size","description":"For Slider and Number","type":"number","width":4},{"field":"minLength","name":"Min Length","description":"For Text and Textarea","type":"number","width":4},{"field":"maxLength","name":"Max Length","description":"For Text and Textarea","type":"number","width":4},{"field":"regex","name":"Regex","description":"For Text and Textarea","type":"text","width":3},{"field":"items","name":"Dropdown Items","description":"Comma-separated. For dropdown","type":"text","width":6},{"field":"format","name":"Date Format","description":"For date","type":"text","width":3},{"field":"default","name":"Default Value","description":"For all types","type":"text","width":3}]}]},{"name":"M2020 Specific","components":[{"field":"variables.mtttt","name":"MTTTT","description":"MTTTT endpoint path that overrides MTTTT_HOST env and provides backwards compatibility.","type":"text","width":12}]},{"components":[{"field":"variables.mttttInfoLink","name":"MTTTT Info Link","description":"Powered by link destination.","type":"text","width":12}]},{"components":[{"field":"variables.mttttHostPath","name":"MTTTT Host Path","description":"Path to append to MTTTT_HOST env /mttt/sites/JEZ.","type":"text","width":12}]},{"components":[{"field":"variables.mttttWithCreds","name":"MTTTT With Creds","description":"Only show DEM if associated layer is on.","type":"checkbox","width":4,"defaultChecked":false},{"field":"variables.scienceIntent","name":"Science Intent","description":"Only show DEM if associated layer is on.","type":"checkbox","width":4,"defaultChecked":true}]}]}}} \ No newline at end of file +{"Identifier":{"defaultIcon":"map-marker","description":"Mouse over the map for a by-pixel legend of a raster.","descriptionFull":{"title":"Mouse over to query underlying datasets. This will read the raw values from a geo-referenced dataset, which can be any bit-depth (8,16,32). You can set up multiple file to return values from.","example":{"[Layer_Name]":{"url":"(str) path_to_data/data.tif","bands":"(int) how many bands to query from","sigfigs":"(int) how many digits after the decimal","unit":"(str) whatever string unit","timeFormat":"(str) for formatting injected '{starttime}' and '{endtime}' in url. See syntax in https://d3js.org/d3-time-format#locale_format"},"...":{}}},"hasVars":true,"name":"Identifier","toolbarPriority":1,"separatedTool":true,"paths":{"IdentifierTool":"essence/Tools/Identifier/IdentifierTool"},"config":{"rows":[{"components":[{"field":"separatedTool","name":"Separated Tool","description":"If true, this tool will live outside the left-hand toolbar and be independently accessible.","type":"checkbox","width":3,"defaultChecked":true},{"field":"variables.justification","name":"Justification","description":"The legend will display on the right side of the screen if set to right, otherwise default to the left side","type":"dropdown","width":2,"options":["left","right"]}]},{"components":[{"field":"variables.layers","name":"Layers","description":"Only show DEM if associated layer is on.","type":"objectarray","width":12,"object":[{"field":"name","name":"Layer Name or UUID","description":"This is the layer name exactly as it appears in the Layers section in the configuration.","type":"text","width":4},{"field":"url","name":"URL to .tif","description":"This can be a relative path to a file under the Mission name or a full url path. The former is preferred is the file is large. Can use '{starttime}' and '{endtime}' if the layer is time enabled. If this field is left empty, the Identifier Tool will try to best-match the hovered-over pixel color with this layer's legend (if any).","type":"text","width":8},{"field":"bands","name":"Bands","description":"Number of bands from which to query.","type":"number","min":0,"step":1,"width":2},{"field":"sigfigs","name":"SigFigs","description":"Number of significant figures to use after the decimal of returned values.","type":"number","min":0,"step":1,"width":2},{"field":"unit","name":"Unit","description":"A string that is appended to your returned value. e.g. ' m' would be appended on a raw value ('41') and show '41 m'. If it was 'm', it would return '41m', without a space.","type":"text","width":2},{"field":"scalefactor","name":"Scale Factor","description":"A number for which to multiply the raw value by for display purposes only. Useful, for instance, if the underlying dataset is in units that are off by factor's of 10 from what's desired to be shown to users.","type":"number","width":2},{"field":"timeFormat","name":"Time Format","description":"A string for formatting the injected '{starttime}' and '{endtime}' in the url. See syntax in https://d3js.org/d3-time-format#locale_format","type":"text","width":4}]}]}]}},"Layers":{"defaultIcon":"layers","description":"Hierarchically toggle layers on and off and alter their opacities.","descriptionFull":{"title":"Allows users to toggle on and off layers, download them, filter their features and change some parameters such as opacity.","example":{"expanded":"(bool) is initial state expanded [default false]"}},"hasVars":true,"name":"Layers","toolbarPriority":1,"paths":{"LayersTool":"essence/Tools/Layers/LayersTool"},"expandable":true,"config":{"rows":[{"components":[{"field":"variables.expanded","name":"Expanded","description":"Whether all layer groupings default to being expanded (as opposed to being collapsed).","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Legend":{"defaultIcon":"map-legend","description":"Show a chart legend that maps colors and symbols to meaning.","descriptionFull":{"title":"A layer can be configured with a legend by pointing its Legend field to a .csv file or by including a JSON legend array into the layer's Raw Variables. The Legend Tool renders symbologies and gradient scales for any properly configured on layer.","example":{"displayOnStart":true,"justification":"right"}},"hasVars":true,"name":"Legend","toolbarPriority":2,"separatedTool":true,"paths":{"LegendTool":"essence/Tools/Legend/LegendTool"},"config":{"rows":[{"components":[{"field":"separatedTool","name":"Separated Tool","description":"If true, this tool will live outside the left-hand toolbar and be independently accessible.","type":"checkbox","width":3,"defaultChecked":true},{"field":"variables.displayOnStart","name":"Display on Start","description":"Whether the expanded legend should automatically be displayed on start.","type":"checkbox","width":3,"defaultChecked":false},{"field":"variables.justification","name":"Justification","description":"The legend will display on the right side of the screen if set to right, otherwise default to the left side","type":"dropdown","width":2,"options":["left","right"]}]}]}},"Info":{"defaultIcon":"information-variant","description":"Display the geojson properties field of a clicked feature.","descriptionFull":{"title":"Lists out the geojson properties of any clicked feature. Any clicked feature will open the Info tool and display the data in JSON formatting. Some layer 'kinds' disable opening the Info tool and displaying data automatically, like the 'Waypoints' kind layer.","example":{"sortAlphabetically":true}},"hasVars":true,"name":"Info","toolbarPriority":3,"paths":{"InfoTool":"essence/Tools/Info/InfoTool"},"expandable":true,"config":{"rows":[{"components":[{"field":"variables.sortAlphabetically","name":"Sort Alphabetically","description":"Whether to sort the feature's fields alphabetically instead of listing them in their native order.","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Sites":{"defaultIcon":"pin","description":"A button bar to navigate between various map locations.","descriptionFull":{"title":"A button bar to quickly navigate between preset map locations.","example":{"sites":[{"name":"(str) Name of site","code":"(str) Unique identifier. Can match header layer to toggle it's sublayers","view":["(num) Latitude","(num) Longitude","(num) Zoom level"]},{"...":"..."}]}},"hasVars":true,"name":"Sites","toolbarPriority":4,"paths":{"SitesTool":"essence/Tools/Sites/SitesTool"},"config":{"rows":[{"components":[{"field":"variables.sites","name":"Sites","description":"","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"Name of site","type":"text","width":4},{"field":"code","name":"Code","description":"Unique identifier. Can match header layer to toggle its sublayers.","type":"text","width":2},{"field":"view.0","name":"Latitude","description":"","type":"number","width":2},{"field":"view.1","name":"Longitude","description":"","type":"number","width":2},{"field":"view.2","name":"Zoom Level","description":"","type":"number","min":0,"step":1,"width":2}]}]}]}},"Isochrone":{"defaultIcon":"circle-double","description":"Find the range of locations accessible to an explorer within a given time.","descriptionFull":{"title":"Given a user-defined starting point, render a shaded region where colors indicate minimum travel time or resource expenditure to reach a given location. Hover over the region to view the least costly path from the start to the cursor. Costs are calculated based on selectable and configurable models, which may each require multiple different tilesets as input.","example":{"data":{"DEM":[{"name":"Unique Name 1","tileurl":"Layers/Example/{z}/{x}/{y}.png","minZoom":8,"maxNativeZoom":18,"resolution":256,"interpolateSeams":true},{"...":"..."}],"slope":[{"...":"..."}],"cost":[{"...":"..."}]},"interpolateSeams":false,"models":["Traverse Time","Isodistance","..."]}},"hasVars":true,"name":"Isochrone","toolbarPriority":10,"paths":{"IsochroneTool":"essence/Tools/Isochrone/IsochroneTool"},"config":{"rows":[{"name":"Data Sources","components":[{"field":"variables.data.DEM","name":"Elevation (DEM)","description":"Configure DEM data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"components":[{"field":"variables.data.slope","name":"Slope","description":"Configure Slope data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"components":[{"field":"variables.data.obstacle","name":"Obstacle","description":"Configure Obstacle map data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"components":[{"field":"variables.data.cost","name":"Cost","description":"Configure Cost data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"components":[{"field":"variables.data.shade","name":"Shade","description":"Configure Shade data tilesets to be used by the specified models for computations.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"A unique name.","type":"text","width":4},{"field":"tileurl","name":"DEM Tile URL","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"Minimum zoom of the specified tileset.","type":"number","min":0,"step":1,"width":2},{"field":"maxNativeZoom","name":"Max Native Zoom","description":"Maximum (native) zoom of the specified tileset.","type":"number","min":0,"step":1,"max":40,"width":2},{"field":"resolution","name":"Resolution","description":"Pixel dimension of the side of the tiles in the tileset. Generally a power of 2 between 32 and 256.","type":"number","min":0,"step":1,"width":2},{"field":"interpolateSeams","name":"Interpolate Seams","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams.","type":"checkbox","width":3,"defaultChecked":false}]}]},{"name":"Models","components":[{"field":"variables.models","name":"Enabled Models","description":"Comma-separated list of isochrone models to enable. Possible values are: 'Traverse Time', 'Isodistance', 'Example' ","type":"textarray","width":12}]},{"name":"Settings","components":[{"field":"variables.interpolateSeams","name":"Interpolate Seams (Global)","description":"Because '1bto4b' (the DEM tiling script) generates tiles with matching edges, data loaded and passed to models may have “seams,” or regularly-spaced pairs of identical rows and columns. Depending on the data type and model, these seams may or may not cause inaccurate results. The default behavior of the tool is therefore to attempt to correct these seams. Set this property to false to disable this behavior for all sources that do not explicitly set their own 'interpolateSeams' property to true.","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Viewshed":{"defaultIcon":"wifi-strength-2","description":"Realtime user generated viewsheds.","descriptionFull":{"title":"Renders dynamic tilesets based on line-of-sight visibilities from user defined source points. DEM tiles are used to generate these. At least one DEM tileset must be configured. curvature is optional and can be set to false to disable using the Major Radius to account for curvature during generations. cameraPresets are optional and the objects within only require the name field.","example":{"data":[{"name":"Unique Name 1","demtileurl":"Layers/Example/demtileset/{z}/{x}/{y}.png","minZoom":8,"maxNativeZoom":18},{"...":"..."}],"curvature":false,"cameraPresets":[{"name":"CAM A","height":2,"azCenter":0,"azFOV":70,"elCenter":-10,"elFOV":30},{"...":"..."}],"defaultObserverHeight":2,"defaultTargetHeight":0}},"hasVars":true,"name":"Viewshed","toolbarPriority":101,"paths":{"ViewshedTool":"essence/Tools/Viewshed/ViewshedTool","ViewshedTool_Manager":"essence/Tools/Viewshed/ViewshedTool_Manager","ViewshedTool_Algorithm":"essence/Tools/Viewshed/ViewshedTool_Algorithm"},"config":{"rows":[{"components":[{"field":"variables.data","name":"Layer specific DEMs","description":"Only show DEM if associated layer is on.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"User-friendly name for DEM","type":"text","width":2},{"field":"demtileurl","name":"DEM Path","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"","type":"number","min":0,"step":1,"width":1},{"field":"maxNativeZoom","name":"Maximum Native Zoom","description":"","type":"number","min":0,"step":1,"width":1}]}]},{"components":[{"field":"variables.cameraPresets","name":"Camera Presets","description":"Only show DEM if associated layer is on.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"Camera Name","type":"text","width":10},{"field":"height","name":"Height","description":"Height in meters","type":"number","min":0,"width":2},{"field":"azCenter","name":"Azimuth Center","description":"","type":"number","width":3},{"field":"azFOV","name":"Azimuth FOV","description":"","type":"number","width":3},{"field":"elCenter","name":"Elevation Center","description":"","type":"number","width":3},{"field":"elFOV","name":"Elevation FOV","description":"","type":"number","width":3}]}]},{"components":[{"field":"variables.curvature","name":"Curvature","description":"Whether to account for planetary curvature while computing viewsheds.","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Shade":{"defaultIcon":"sun-angle-outline","description":"Realtime user generated sun and orbiter masks.","descriptionFull":{"title":"Shades the ground when line-of-sights to an orbiting target are occluded.","example":{"dem":"Data/missionDEM.tif","data":[{"name":"User-friendly name for DEM","demtileurl":"pathToDEMTiles/{z}/{x}/{y}.png","minZoom":8,"maxNativeZoom":18}],"sources":[{"name":"User-friendly name for orbiter or body that 'casts shadows'","value":"NAIF SPICE Spacecraft name or ID"},{"name":"...","value":"..."}],"observers":[{"name":"User-friendly name for observer for spacecraft time computations. Set to null to turn off time converting.","value":"SPICE Spacecraft name or ID","frame":"SPICE reference frame. i.e. IAU_MARS","body":"SPICE planet body. i.e. MARS"}],"defaultHeight":0,"observerTimePlaceholder":null,"utcTimeFormat":null}},"hasVars":true,"name":"Shade","toolbarPriority":102,"paths":{"ShadeTool":"essence/Tools/Shade/ShadeTool","ShadeTool_Manager":"essence/Tools/Shade/ShadeTool_Algorithm","ShadeTool_Algorithm":"essence/Tools/Shade/ShadeTool_Algorithm"},"config":{"rows":[{"components":[{"field":"variables.dem","name":"DEM path","description":"A path to a DEM.tif. This is used to get the current center elevation. This can/should be the same file used for the Measure Tool and the Coordinate's elevation.","type":"text","width":12}]},{"components":[{"field":"variables.data","name":"Layer specific DEMs","description":"At minimum, the Shade tool requires at least one 'data' source. A data source describes a DEM tileset (see /auxiliary/gdal2customtiles or /auxiliary/1bto4b) and allows users to select it by name to generate shade maps over.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"User-friendly name for DEM","type":"text","width":2},{"field":"demtileurl","name":"DEM Path","description":"","type":"text","width":8},{"field":"minZoom","name":"Minimum Zoom","description":"","type":"number","min":0,"step":1,"width":1},{"field":"maxNativeZoom","name":"Maximum Native Zoom","description":"","type":"number","min":0,"step":1,"width":1}]}]},{"components":[{"field":"variables.sources","name":"Sources","description":"An array of objects with the properties 'name' and 'value'. 'name' is the display name for the Source Entity dropdown. 'value' is the SPICE spacecraft ID that gets passed to the backend ll2aerll.py script. Ensure the right kernels for the configured source entities/targets exist in /private/api/spice/kernels.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"User-friendly name for orbiter or body that 'casts light'","type":"text","width":4},{"field":"value","name":"Value","description":"NAIF SPICE Spacecraft name or ID","type":"text","width":4}]}]},{"components":[{"field":"variables.observers","name":"Observers","description":"An array of objects with the properties 'name' and 'value'. 'name' is the display name for the Source Entity dropdown. 'value' is the SPICE spacecraft ID that gets passed to the backend chronos.py scripts. Ensure the right kernels for the configured observers exist in /private/api/spice/kernels and that there is a proper chronos setup file for each observer's value private/api/spice/chronosSetups/chronos-{lowercased_observer_value}.setup.","type":"objectarray","width":12,"object":[{"field":"name","name":"Name","description":"User-friendly name for observer for spacecraft time computations","type":"text","width":3},{"field":"value","name":"Value","description":"NAIF SPICE Spacecraft name or ID","type":"text","width":3},{"field":"frame","name":"Frame","description":"SPICE reference frame. i.e. 'IAU_MARS'","type":"text","width":3},{"field":"body","name":"Body","description":"SPICE planet body. i.e. 'MARS'","type":"text","width":3}]}]},{"components":[{"field":"variables.defaultHeight","name":"Default Height","description":"Sets a default for the 'Height' parameter. Height in meters above the surface to use when calculating line-of-sight shading. For instance, a point on the surface (0m) may not be visible to a 'Source Entity', say the Mars Reconnaissance Orbiter (MRO), but 2m above that point may be. This value does not only apply to the center longitude and latitude but to all points on the visible terrain. Gradually increasing this value shows the shade map n-meters above the surface. The regular default is 0 meters.","type":"number","min":0,"width":4},{"field":"variables.observerTimePlaceholder","name":"Observer Time Placeholder","description":"Sets the placeholder information for when the observer time's input box is cleared. Useful for denoting the expected time format to be inputted. For example “SOL DDDD HH:MM:SS”. Default null.","type":"text","width":4},{"field":"variables.utcTimeFormat","name":"UTC Time Format","description":"Sets the placeholder information for when the observer time's input box is cleared. Useful for denoting the expected time format to be inputted. Uses d3 time syntax (https://d3js.org/d3-time-format#locale_format). Example for day-of-year: '%Y-%j %H:%M:%S'. Defaults to times like so: 2023 SEP 06 19:27:05.","type":"text","width":4}]}]}},"Chemistry":{"defaultIcon":"flask","description":"Display chemistry percentages via graphs of a clicked point.","descriptionFull":{},"hasVars":false,"name":"Chemistry","paths":{"ChemistryTool":"essence/Tools/Chemistry/ChemistryTool"}},"Curtain":{"defaultIcon":"waves","description":"Curtain views of Ground Penetrating Radar data.","descriptionFull":{"title":"Vertical imagery aligned under terrain for visualizing data from ground penetrating radar.","example":{"withCredentials":false}},"hasVars":true,"name":"Curtain","paths":{"CurtainTool":"essence/Tools/Curtain/CurtainTool"},"config":{"rows":[{"components":[{"field":"variables.withCredentials","name":"With Credentials","description":"","type":"checkbox","width":3,"defaultChecked":false}]}]}},"Kinds":{"defaultIcon":"palette-swatch","description":"Not a real tool but plugin to configure different layer interactions.","descriptionFull":{},"hasVars":false,"name":"Kinds","kinds":["info","waypoint","chemistry_tool","draw_tool"],"paths":{"Kinds":"essence/Tools/Kinds/Kinds"}},"Measure":{"defaultIcon":"tape-measure","description":"Measure distances and generates elevation profiles.","descriptionFull":{"title":"Specify a path to a Digital Elevation Model (dem) .tif. Measure distances and generates elevation profiles. Can also query specific bands at specific points of images and generate profiles of them. If multiple dems are specified, a dropdown will be present for users to toggle between them.","example":{"dem":"(str) path to Data/defaultDEM.tif","layerDems":{"[layer_name]":"(str) path/to/layers/dem.tif"},"onlyShowDemIfLayerOn":true,"defaultMode":"segment || continuous || continuous_color"}},"hasVars":true,"name":"Measure","paths":{"MeasureTool":"essence/Tools/Measure/MeasureTool"},"config":{"rows":[{"components":[{"field":"variables.dem","name":"DEM path","description":"Path to a primary DEM (such as Data/defaultDEM.tif). Required if Layer Specific DEMs is unset.","type":"text","width":12}]},{"components":[{"field":"variables.layerDems","name":"Layer Specific DEMs","description":"Object of layer names and the paths to their DEMs. Users may switch between DEMs to profile via a dropdown. The dropdown only renders if there is more than one DEM configured overall.","type":"objectarray","width":12,"object":[{"field":"layer","name":"Layer Name","description":"","type":"text","width":4},{"field":"dem","name":"DEM Path","description":"","type":"text","width":8}]}]},{"components":[{"field":"variables.onlyShowDemIfLayerOn","name":"Only Show DEM If On","description":"If true, hides the configured Layer Specific DEMs of off layers from the tool's DEM selection dropdown. If false, all Layer Specific DEMs, even with invalid layer names, always show in the dropdown.","type":"checkbox","width":2,"defaultChecked":false}]},{"components":[{"field":"variables.defaultMode","name":"Default Mode","description":"Which measurement mode to default to. Options are 'segment', 'continuous' and 'continuous_color'","type":"dropdown","width":2,"options":["segment","continuous","continuous_color"]}]}]}},"Draw":{"defaultIcon":"pencil","description":"Advanced drawing","descriptionFull":{"title":"","example":{"intents":["Polygon_1_Alias","Polygon_2_Alias","Polygon_3_Alias","Line_Alias","Point_Alias","All_Alias"],"defaultDrawClipping":"over || under || off","defaultPublicFilter":false,"defaultYoursOnlyFilter":true,"defaultOnFilter":false,"leadsCanEditFileInfo":false,"hoverLengthOnLines":false,"templates":{"myTemplate":[{"type":"slider","field":"a","min":0,"max":100,"step":1,"default":0},{"type":"number","field":"b","min":0,"max":100,"step":1,"required":true,"default":3},{"type":"text","field":"c","minLength":2,"maxLength":4,"required":true,"regex":null,"default":null},{"type":"textarea","field":"d","maxLength":10,"required":true,"default":"hi"},{"type":"checkbox","field":"e","default":true},{"type":"dropdown","field":"f","items":["Yes","No","Maybe"],"default":"No"},{"type":"incrementer","field":"g","default":"ID-#"},{"type":"date","field":"h","format":"HH:mm:ss","default":"now"}]}}},"hasVars":true,"name":"Draw","toolbarPriority":1001,"paths":{"DrawTool":"essence/Tools/Draw/DrawTool"},"tests":{"DrawToolTest":"essence/Tools/Draw/DrawTool.test"},"expandable":true,"config":{"rows":[{"name":"Intent Aliases","description":"There are five files that are group editable with the correct permission. The group authentication is set an environment variable in the .env file during startup. These files are meant as collaborative layers that a only a few people will manage and contribute to do to the potential of race conditions on who did the last edit.","components":[{"field":"variables.intents.0","name":"Polygon 1 Alias","description":"","type":"text","width":2},{"field":"variables.intents.1","name":"Polygon 2 Alias","description":"","type":"text","width":2},{"field":"variables.intents.2","name":"Polygon 3 Alias","description":"","type":"text","width":2},{"field":"variables.intents.3","name":"Line Alias","description":"","type":"text","width":2},{"field":"variables.intents.4","name":"Point Alias","description":"","type":"text","width":2},{"field":"variables.intents.5","name":"All Alias","description":"","type":"text","width":2}]},{"components":[{"field":"variables.defaultDrawClipping","name":"Default Draw Clipping","description":"Default clipping mode for drawing. Drawing a polygon Over another would clip away that other polygon. Drawing a polygon Under another would have that polygon clip away the newly drawn one. When the clipping mode is Off, no clipping occurs. Users may freely change the clipping mode.","type":"dropdown","width":3,"options":["over","under","off"]},{"field":"variables.leadsCanEditFileInfo","name":"Leads Can Edit File Info","description":"If true, lead roles can edit the file info, (name, description, tags, folder, make private) of any user's public file.","type":"checkbox","width":3,"defaultChecked":false},{"field":"variables.hoverLengthOnLines","name":"Hover Length On Lines","description":"If true, the hover text for line features will include the total length of the line in meters.","type":"checkbox","width":3,"defaultChecked":false}]},{"components":[{"field":"variables.defaultPublicFilter","name":"Default Public Filter","description":"When the DrawTool first opens, filter the file list down to only public files or not.","type":"checkbox","width":4,"defaultChecked":false},{"field":"variables.defaultYoursOnlyFilter","name":"Default Yours Only Filter","description":"When the DrawTool first opens, filter the file list down to only files you own or not.","type":"checkbox","width":4,"defaultChecked":true},{"field":"variables.defaultOnFilter","name":"Default On Filter","description":"When the DrawTool first opens, filter the file list down to only files that are on or not. ","type":"checkbox","width":4,"defaultChecked":false}]},{"components":[{"field":"variables.templates","name":"Default File Property Templates","description":"Templates create forms for feature properties. For instance, all features in a given draw file could, in the feature's edit panel, have the field “Reviewed” be togglable via a checkbox. Users may make their own templates too but the ones configured here are promoted and cannot be delete.","type":"objectarray","width":12,"object":[{"field":"name","name":"Template Name","description":"","type":"text","width":4},{"field":"name","name":"Property Field Name","description":"","type":"text","width":4},{"field":"type","name":"Component","description":"","type":"dropdown","width":2,"options":["slider","number","text","textarea","checkbox","dropdown","incrementer","date"]},{"field":"required","name":"Required","description":"Field requires entry.","type":"checkbox","width":2,"defaultChecked":false},{"field":"min","name":"Min Value","description":"For Slider and Number","type":"number","width":4},{"field":"max","name":"Max Value","description":"For Slider and Number","type":"number","width":4},{"field":"step","name":"Step Size","description":"For Slider and Number","type":"number","width":4},{"field":"minLength","name":"Min Length","description":"For Text and Textarea","type":"number","width":4},{"field":"maxLength","name":"Max Length","description":"For Text and Textarea","type":"number","width":4},{"field":"regex","name":"Regex","description":"For Text and Textarea","type":"text","width":3},{"field":"items","name":"Dropdown Items","description":"Comma-separated. For dropdown","type":"text","width":6},{"field":"format","name":"Date Format","description":"For date","type":"text","width":3},{"field":"default","name":"Default Value","description":"For all types","type":"text","width":3}]}]}]}}} \ No newline at end of file diff --git a/configure/src/components/Tabs/Layers/Layers.js b/configure/src/components/Tabs/Layers/Layers.js index c3745b9e..0f94a6d7 100644 --- a/configure/src/components/Tabs/Layers/Layers.js +++ b/configure/src/components/Tabs/Layers/Layers.js @@ -29,6 +29,7 @@ import LanguageIcon from "@mui/icons-material/Language"; // Tile import GridViewIcon from "@mui/icons-material/GridView"; // Vector tile import ViewInArIcon from "@mui/icons-material/ViewInAr"; // Model import AirIcon from "@mui/icons-material/Air"; // Velocity +import ImageIcon from '@mui/icons-material/Image'; // Image import AddIcon from "@mui/icons-material/Add"; import VisibilityIcon from "@mui/icons-material/Visibility"; @@ -386,6 +387,9 @@ export default function Layers() { case "velocity": iconType = ; color = "#24807c"; + case "image": + iconType = ; + color = "#b0518f"; break; default: } diff --git a/configure/src/components/Tabs/Layers/Modals/LayerModal/LayerModal.js b/configure/src/components/Tabs/Layers/Modals/LayerModal/LayerModal.js index b0bde1fd..39e09412 100644 --- a/configure/src/components/Tabs/Layers/Modals/LayerModal/LayerModal.js +++ b/configure/src/components/Tabs/Layers/Modals/LayerModal/LayerModal.js @@ -45,6 +45,7 @@ import tileConfig from "../../../../../metaconfigs/layer-tile-config.json"; import vectorConfig from "../../../../../metaconfigs/layer-vector-config.json"; import vectortileConfig from "../../../../../metaconfigs/layer-vectortile-config.json"; import velocityConfig from "../../../../../metaconfigs/layer-velocity-config.json"; +import imageConfig from "../../../../../metaconfigs/layer-image-config.json"; const useStyles = makeStyles((theme) => ({ Modal: { @@ -196,6 +197,10 @@ const LayerModal = (props) => { config = velocityConfig; break; + case "image": + config = imageConfig; + break; + default: break; } diff --git a/configure/src/core/Maker.js b/configure/src/core/Maker.js index 27ac9e46..dff281b6 100644 --- a/configure/src/core/Maker.js +++ b/configure/src/core/Maker.js @@ -256,6 +256,9 @@ const getComponent = ( }} value={value != null ? value : getIn(directConf, com.field, "")} onChange={(e) => { + updateConfiguration(forceField || com.field, e.target.value, layer); + }} + onBlur={(e) => { let v = e.target.value; // remove surrounding whitespace, " hi " -> "hi" if (typeof v === "string") v = v.trim(); @@ -280,6 +283,39 @@ const getComponent = ( )} ); + case "textnotrim": + inner = ( + { + updateConfiguration(forceField || com.field, e.target.value, layer); + }} + /> + ); + return ( +
+ {inlineHelp ? ( + <> + {inner} +
+ + ) : ( + + {inner} + + )} +
+ ); case "button": inner = (