@seasketch/geoprocessing
Version:
Geoprocessing and reporting framework for SeaSketch 2.0
83 lines • 3.86 kB
JavaScript
import { isSketchCollection } from "../helpers/index.js";
import { createMetric } from "../metrics/index.js";
import { getHistogram } from "./geoblaze/index.js";
import { featureEach } from "@turf/turf";
/**
* Calculates sum of overlap between sketches and a categorical raster with numeric values representing feature classes
* If sketch collection, then calculate overlap for all child sketches also
* @deprecated use rasterMetrics instead
*/
export async function overlapRasterClass(
/** metricId value to assign to each measurement */
metricId,
/** Cloud-optimized geotiff, loaded via loadCog or geoblaze.parse(), representing categorical data (multiple classes) */
raster,
/**
* single sketch or collection. If undefined will return sum by feature class for the whole raster.
* Supports polygon or multipolygon. Will remove overlap between sketches, but will not remove overlap within Multipolygon sketch
*/
sketch,
/** Object mapping numeric category IDs (as strings e.g. "1") in the raster to their string names for display e.g. "Coral Reef" */
mapping,
/** Dimension to assign category name when creating metrics, defaults to classId */
metricCategoryDimension = "classId") {
if (!mapping)
throw new Error("Missing category mapping");
// Get histogram for each feature, whether sketch or sketch collection
const histoPromises = [];
const histoFeatures = [];
// await results and create metrics for each sketch
const sketchMetrics = [];
if (sketch) {
featureEach(sketch, async (feat) => {
// accumulate geoblaze promises and features so we can create metrics later
histoPromises.push(getHistogram(raster, feat));
histoFeatures.push(feat);
});
for (const [index, curHisto] of (await Promise.all(histoPromises)).entries()) {
const histoMetrics = histoToMetrics(metricId, histoFeatures[index], curHisto, mapping);
sketchMetrics.push(...histoMetrics);
}
}
// Calculate overall if sketch collection or no sketch
if (!sketch || isSketchCollection(sketch)) {
const overallHisto = await getHistogram(raster, sketch);
const overallHistoMetrics = histoToMetrics(metricId, sketch, overallHisto, mapping, metricCategoryDimension);
sketchMetrics.push(...overallHistoMetrics);
}
return sketchMetrics;
}
/** Returns metrics given histogram and sketch */
const histoToMetrics = (metricId, sketch, histo,
/** Object mapping numeric category IDs to their string counterpart */
mapping,
/** Dimension to assign category name when creating metrics, defaults to classId */
metricCategoryDimension = "classId") => {
const metrics = [];
const categoryIds = Object.keys(mapping);
// Initialize complete histogram with zeros
const finalHisto = Object.keys(mapping).reduce((histoSoFar, curCategory) => ({ ...histoSoFar, [curCategory]: 0 }), {});
// Merge in calculated histogram which will only include non-zero
if (histo) {
for (const categoryId of Object.keys(histo)) {
finalHisto[categoryId] = histo[categoryId];
}
}
// Create one metric record per class
for (const categoryId of categoryIds) {
metrics.push(createMetric({
metricId,
[metricCategoryDimension]: mapping[categoryId], // resolve category name and assign to metric
sketchId: sketch ? sketch.properties.id : null,
value: histo[categoryId] || 0, // should never be undefined but default to 0 anyway
extra: sketch
? {
sketchName: sketch.properties.name,
...(isSketchCollection(sketch) ? { isCollection: true } : {}),
}
: {},
}));
}
return metrics;
};
//# sourceMappingURL=overlapRasterClass.js.map