Vizzuality/landgriffon

View on GitHub
api/src/modules/geo-regions/geo-regions.service.ts

Summary

Maintainability
C
1 day
Test Coverage
C
75%
import { Injectable, NotFoundException } from '@nestjs/common';
import {
  AppBaseService,
  JSONAPISerializerConfig,
} from 'utils/app-base.service';
import {
  GeoRegion,
  geoRegionResource,
} from 'modules/geo-regions/geo-region.entity';
import { AppInfoDTO } from 'dto/info.dto';
import { GeoRegionRepository } from 'modules/geo-regions/geo-region.repository';
import { CreateGeoRegionDto } from 'modules/geo-regions/dto/create.geo-region.dto';
import { UpdateGeoRegionDto } from 'modules/geo-regions/dto/update.geo-region.dto';
import { LocationGeoRegionDto } from 'modules/geo-regions/dto/location.geo-region.dto';
import { AdminRegionsService } from 'modules/admin-regions/admin-regions.service';
import { MaterialsService } from 'modules/materials/materials.service';
import { GetEUDRGeoRegions } from 'modules/geo-regions/dto/get-geo-region.dto';
import {
  GetEUDRFeaturesGeoJSONDto,
  GetFeaturesGeoJsonDto,
} from 'modules/geo-regions/dto/get-features-geojson.dto';
import { GeoFeaturesService } from 'modules/geo-regions/geo-features.service';

@Injectable()
export class GeoRegionsService extends AppBaseService<
  GeoRegion,
  CreateGeoRegionDto,
  UpdateGeoRegionDto,
  AppInfoDTO
> {
  constructor(
    protected readonly geoRegionRepository: GeoRegionRepository,
    private readonly adminRegionService: AdminRegionsService,
    private readonly materialsService: MaterialsService,
    private readonly geoFeatures: GeoFeaturesService,
  ) {
    super(
      geoRegionRepository,
      geoRegionResource.name.singular,
      geoRegionResource.name.plural,
    );
  }

  get serializerConfig(): JSONAPISerializerConfig<GeoRegion> {
    return {
      attributes: ['name', 'theGeom'],
      keyForAttribute: 'camelCase',
    };
  }

  async getGeoRegionById(id: string): Promise<GeoRegion> {
    const found: GeoRegion | null = await this.geoRegionRepository.findOneBy({
      id,
    });

    if (!found) {
      throw new NotFoundException(`geo region with ID "${id}" not found`);
    }

    return found;
  }

  /**
   *
   * @param newGeoRegionValues
   * Creates a new geo-region row and generates a 50km radius as multipolygon geometry
   * by given coordinates
   *
   * @return generated geo-regions id
   */

  async saveGeoRegionAsRadius(
    newGeoRegionValues: LocationGeoRegionDto,
  ): Promise<string> {
    const previouslyExistingGeoRegion: GeoRegion[] =
      await this.geoRegionRepository.getGeomRadiusByHashedName({
        lat: newGeoRegionValues.coordinates.lat,
        lng: newGeoRegionValues.coordinates.lng,
      });
    if (previouslyExistingGeoRegion.length) {
      return previouslyExistingGeoRegion[0].id;
    }
    return this.geoRegionRepository.saveGeoRegionAsRadius(newGeoRegionValues);
  }

  async saveGeoRegionAsPoint(
    newGeoRegionValues: LocationGeoRegionDto,
  ): Promise<string> {
    const previouslyExistingGeoRegion: GeoRegion[] =
      await this.geoRegionRepository.getGeomPointByHashedName({
        lat: newGeoRegionValues.coordinates.lat,
        lng: newGeoRegionValues.coordinates.lng,
      });
    if (previouslyExistingGeoRegion.length) {
      return previouslyExistingGeoRegion[0].id;
    }
    return this.geoRegionRepository.saveGeoRegionAsPoint(newGeoRegionValues);
  }

  async deleteGeoRegionsCreatedByUser(): Promise<void> {
    await this.geoRegionRepository.delete({ isCreatedByUser: true });
  }

  async getGeoRegionsFromSourcingLocations(
    options: GetEUDRGeoRegions,
  ): Promise<GeoRegion[]> {
    if (options.originIds) {
      options.originIds =
        await this.adminRegionService.getAdminRegionDescendants(
          options.originIds,
        );
    }
    if (options.materialIds) {
      options.materialIds = await this.materialsService.getMaterialsDescendants(
        options.materialIds,
      );
    }

    return this.geoRegionRepository.getGeoRegionsFromSourcingLocations(options);
  }

  async getGeoJson(
    dto: GetFeaturesGeoJsonDto | GetEUDRFeaturesGeoJSONDto,
  ): Promise<any> {
    return this.geoFeatures.getGeoFeatures(dto);
  }
}