From 1a08f465cb90a12ed46f1b3caf4a9cddbd65215f Mon Sep 17 00:00:00 2001 From: Foxino Date: Mon, 27 Nov 2023 12:36:45 +0000 Subject: [PATCH] Refactor code to use iterate method for iterating over tile grids --- .../modelling/components/area_component.ts | 7 ++--- .../components/mask_numeric_data_component.ts | 6 +--- .../components/ukceh_land_cover_component.ts | 7 ++--- .../projects/modelling/tile_grid.ts | 28 ++++++++++++++++++- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/javascript/projects/modelling/components/area_component.ts b/app/javascript/projects/modelling/components/area_component.ts index 1e8e3966..bc4bdd60 100644 --- a/app/javascript/projects/modelling/components/area_component.ts +++ b/app/javascript/projects/modelling/components/area_component.ts @@ -40,11 +40,8 @@ export class AreaComponent extends BaseComponent { const input = inputs['in'][0] as BooleanTileGrid - for (let x = input.x; x < input.x + input.width; ++x) { - for (let y = input.y; y < input.y + input.height; ++y) { - totalArea += input.get(x, y) ? getArea(fromExtent(tileGrid.getTileCoordExtent([input.zoom, x, y]))) : 0 - } - } + input.iterate((x, y, value) => totalArea += value ? getArea(fromExtent(tileGrid.getTileCoordExtent([input.zoom, x, y]))) : 0) + totalArea /= 1000000 } diff --git a/app/javascript/projects/modelling/components/mask_numeric_data_component.ts b/app/javascript/projects/modelling/components/mask_numeric_data_component.ts index a3731f3e..9ede01c1 100644 --- a/app/javascript/projects/modelling/components/mask_numeric_data_component.ts +++ b/app/javascript/projects/modelling/components/mask_numeric_data_component.ts @@ -45,11 +45,7 @@ export class MaskNumericDataComponent extends BaseComponent { const out = editorNode.meta.output = outputs['out'] = new NumericTileGrid(mask.zoom, mask.x, mask.y, mask.width, mask.height) - for (let x = mask.x; x < mask.x + mask.width; ++x) { - for (let y = mask.y; y < mask.y + mask.height; ++y) { - out.set(x, y, mask.get(x, y) ? num.get(x, y, mask.zoom) : 0) - } - } + mask.iterate((x, y, value) => out.set(x, y, value ? num.get(x, y, mask.zoom) : 0)) } else { diff --git a/app/javascript/projects/modelling/components/ukceh_land_cover_component.ts b/app/javascript/projects/modelling/components/ukceh_land_cover_component.ts index 23f59403..3ee85e14 100644 --- a/app/javascript/projects/modelling/components/ukceh_land_cover_component.ts +++ b/app/javascript/projects/modelling/components/ukceh_land_cover_component.ts @@ -128,11 +128,8 @@ export class UkcehLandCoverComponent extends BaseComponent { const out = outputs[habitat.mode] = new BooleanTileGrid(categoricalData.zoom, categoricalData.x, categoricalData.y, categoricalData.width, categoricalData.height) out.name = habitat.LC - for (let x = categoricalData.x; x < categoricalData.x + categoricalData.width; ++x) { - for (let y = categoricalData.y; y < categoricalData.y + categoricalData.height; ++y) { - out.set(x, y, categoricalData.get(x, y) === habitat.mode) - } - } + categoricalData.iterate((x, y, value) => out.set(x, y, value === habitat.mode)) + this.outputCache.set(habitat.mode, out) } } diff --git a/app/javascript/projects/modelling/tile_grid.ts b/app/javascript/projects/modelling/tile_grid.ts index f8cbff2c..47076df4 100644 --- a/app/javascript/projects/modelling/tile_grid.ts +++ b/app/javascript/projects/modelling/tile_grid.ts @@ -108,6 +108,15 @@ export class BooleanTileGrid extends TileGrid { } } + iterate(callback: (x: number, y: number, value: boolean) => void) { + const { x, y, width, height } = this + for (let i = x; i < x + width; i++) { + for (let j = y; j < y + height; j++) { + callback(i, j, this.get(i, j)) + } + } + } + get(x: number, y: number, zoom = this.zoom): boolean { if (zoom < this.zoom) { throw new TypeError("invalid zoom level") @@ -205,6 +214,15 @@ export class NumericTileGrid extends TileGrid { this.minMax = null } + iterate(callback: (x: number, y: number, value: number) => void) { + const { x, y, width, height } = this + for (let i = x; i < x + width; i++) { + for (let j = y; j < y + height; j++) { + callback(i, j, this.get(i, j)) + } + } + } + get(x: number, y: number, zoom = this.zoom): number { if (zoom < this.zoom) { throw new TypeError("invalid zoom level") @@ -236,7 +254,6 @@ export class NumericTileGrid extends TileGrid { } return this.minMax } - getStats(): tileGridStats { const [min, max] = this.getMinMax() @@ -276,6 +293,15 @@ export class CategoricalTileGrid extends TileGrid { if (labels) this.setLabels(labels) } + iterate(callback: (x: number, y: number, value: number) => void) { + const { x, y, width, height } = this + for (let i = x; i < x + width; i++) { + for (let j = y; j < y + height; j++) { + callback(i, j, this.get(i, j)) + } + } + } + get(x: number, y: number, zoom = this.zoom): number { if (zoom < this.zoom) { throw new TypeError("invalid zoom level")