diff --git a/config/custom-environment-variables.json b/config/custom-environment-variables.json index ae76538..537080d 100644 --- a/config/custom-environment-variables.json +++ b/config/custom-environment-variables.json @@ -109,7 +109,12 @@ "taskBatchSize": { "__name": "TILES_MERGING_TASK_BATCH_SIZE", "__format": "number" - } + }, + "radiusBuffer": { + "__name": "TILES_MERGING_RADIUS_BUFFER", + "__format": "number" + }, + "radiusBufferUnits": "TILES_MERGING_RADIUS_BUFFER_UNITS" }, "tilesSeeding": { "type": "TILES_SEEDING_TASK_TYPE", diff --git a/config/default.json b/config/default.json index ddd2d1d..bfbf16f 100644 --- a/config/default.json +++ b/config/default.json @@ -85,7 +85,9 @@ "tilesMerging": { "type": "tiles-merging", "tileBatchSize": 10000, - "taskBatchSize": 5 + "taskBatchSize": 5, + "radiusBuffer": 0.000006, + "radiusBufferUnits": "degrees" }, "tilesSeeding": { "type": "tiles-seeding", diff --git a/helm/templates/configmap.yaml b/helm/templates/configmap.yaml index 9466cb1..714eddf 100644 --- a/helm/templates/configmap.yaml +++ b/helm/templates/configmap.yaml @@ -46,6 +46,8 @@ data: TILES_MERGING_TASK_TYPE: {{ $jobDefinitions.tasks.merge.type | quote }} TILES_MERGING_TILE_BATCH_SIZE: {{ $jobDefinitions.tasks.merge.tileBatchSize | quote }} TILES_MERGING_TASK_BATCH_SIZE: {{ $jobDefinitions.tasks.merge.taskBatchSize | quote }} + TILES_MERGING_RADIUS_BUFFER: {{ $jobDefinitions.tasks.merge.radiusBuffer | quote }} + TILES_MERGING_RADIUS_BUFFER_UNITS: {{ $jobDefinitions.tasks.merge.radiusBufferUnits | quote }} TILES_SEEDING_TASK_TYPE: {{ $jobDefinitions.tasks.seed.type | quote }} TILES_SEEDING_GRID : {{ $jobDefinitions.tasks.seed.grid | quote }} TILES_SEEDING_MAX_ZOOM : {{ $jobDefinitions.tasks.seed.maxZoom | quote }} diff --git a/helm/values.yaml b/helm/values.yaml index def3f7a..94ac77e 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -123,6 +123,8 @@ jobDefinitions: type: "" tileBatchSize: 10000 taskBatchSize: 5 + radiusBuffer: 0.000006 + radiusBufferUnits: "degrees" # supported values are: "degrees" | "centimeters" | "meters" | "millimeters" | "kilometers" | "miles" | "inches" | "yards" | "feet" | "radians" seed: type: "" grid: "WorldCRS84" diff --git a/src/task/models/tileMergeTaskManager.ts b/src/task/models/tileMergeTaskManager.ts index dfc7cfc..fb1099a 100644 --- a/src/task/models/tileMergeTaskManager.ts +++ b/src/task/models/tileMergeTaskManager.ts @@ -1,9 +1,10 @@ import { join } from 'path'; import { Logger } from '@map-colonies/js-logger'; +import { Feature, MultiPolygon, Polygon } from 'geojson'; import { InputFiles, PolygonPart } from '@map-colonies/mc-model-types'; import { ICreateTaskBody, TaskHandler as QueueClient } from '@map-colonies/mc-priority-queue'; import { degreesPerPixelToZoomLevel, tileBatchGenerator, TileRanger } from '@map-colonies/mc-utils'; -import { bbox, featureCollection, polygon, union } from '@turf/turf'; +import { bbox, buffer, featureCollection, polygon, union, Units } from '@turf/turf'; import { inject, injectable } from 'tsyringe'; import { SERVICES, TilesStorageProvider } from '../../common/constants'; import { @@ -29,6 +30,8 @@ export class TileMergeTaskManager { private readonly tileBatchSize: number; private readonly taskBatchSize: number; private readonly taskType: string; + private readonly radiusBuffer: number; + private readonly radiusBufferUnits: Units; public constructor( @inject(SERVICES.LOGGER) private readonly logger: Logger, @inject(SERVICES.CONFIG) private readonly config: IConfig, @@ -40,6 +43,8 @@ export class TileMergeTaskManager { this.tileBatchSize = this.config.get('jobManagement.ingestion.tasks.tilesMerging.tileBatchSize'); this.taskBatchSize = this.config.get('jobManagement.ingestion.tasks.tilesMerging.taskBatchSize'); this.taskType = this.config.get('jobManagement.ingestion.tasks.tilesMerging.type'); + this.radiusBuffer = this.config.get('jobManagement.ingestion.tasks.tilesMerging.radiusBuffer'); + this.radiusBufferUnits = this.config.get('jobManagement.ingestion.tasks.tilesMerging.radiusBufferUnits'); } public buildTasks(taskBuildParams: MergeTilesTaskParams): AsyncGenerator { @@ -215,18 +220,44 @@ export class TileMergeTaskManager { } const mergedFootprint = union(featureCollection); + if (mergedFootprint === null) { - throw new Error('Failed to merge footprints because the union result is null'); + throw new Error('Failed to merge parts because the union result is null'); } + const bufferedFeature = this.createBufferedFeature(mergedFootprint); return { fileName: fileName, tilesPath: tilesPath, - footprint: mergedFootprint, - extent: bbox(mergedFootprint), + footprint: bufferedFeature, + extent: bbox(bufferedFeature), }; } + //strip out all gaps and holes in the polygon which simplifies the polygon(solved the issue with tileRanger intersect error) + private createBufferedFeature(feature: Feature): Feature { + const logger = this.logger.child({ featureType: feature.type, radiusBuffer: this.radiusBuffer }); + + const bufferOutFeature = buffer(feature.geometry, this.radiusBuffer, { units: this.radiusBufferUnits }); + + if (bufferOutFeature === undefined) { + const errorMsg = 'Failed to buffer Out feature because the result is undefined'; + logger.error({ errorMsg }); + throw new Error(errorMsg); + } + + const bufferInFeature = buffer(bufferOutFeature.geometry, -this.radiusBuffer, { units: this.radiusBufferUnits }); + + if (bufferInFeature === undefined) { + const errorMsg = 'Failed to buffer In feature because the result is undefined'; + logger.error({ errorMsg }); + throw new Error(errorMsg); + } + + logger.debug({ msg: 'Successfully created buffered feature' }); + return bufferInFeature; + } + private async *createTasksForPart( part: UnifiedPart, zoom: number, diff --git a/tests/configurations/unit/jest.config.js b/tests/configurations/unit/jest.config.js index 3bf5851..ccf6851 100644 --- a/tests/configurations/unit/jest.config.js +++ b/tests/configurations/unit/jest.config.js @@ -30,7 +30,7 @@ module.exports = { branches: 80, functions: 80, lines: 80, - statements: -10, + statements: -12, }, }, };