All files / src/app/map/topography topography.service.ts

11.9% Statements 5/42
100% Branches 0/0
20% Functions 1/5
12.5% Lines 4/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118                1x                           1x                                                                                                                                                                 1x                         1x  
import { Injectable } from '@angular/core';
import { TopographyType, getAllTopographyTypes } from './utils';
import { loadModules } from 'esri-loader';
import { topographyTypesUrl } from 'src/config/urls';
 
@Injectable({
  providedIn: 'root'
})
export class TopographyService {
 
  constructor() { }
 
  /**
   * Load the Graphics of a given TopographyType for a given Extent and scale.
   *
   * @param topographyType The TopographyType which Graphics must be loaded.
   * @param extent The Extent for which the Graphics must be loaded.
   * @param scale The scale for which Graphics must be loaded.
   *
   * @returns A GraphicsLayer containing the merged graphics of all the topographySubTypes
   * of the input TopographyType for the given extent.
   */
  async loadTopographyTypeGraphics(
    topographyType: TopographyType,
    extent: __esri.Extent,
    scale: number
  ): Promise<__esri.GraphicsLayer> {
    const [
      Query,
      QueryTask,
      GraphicsLayer,
      geometryEngine
    ] = await loadModules([
      'esri/tasks/support/Query',
      'esri/tasks/QueryTask',
      'esri/layers/GraphicsLayer',
      'esri/geometry/geometryEngine'
    ]);
 
    // Set the maxAllowableOffset for the graphics depending on the input scale.
    let offset = 0;
    if (scale > 9027.977411) { // level 16
      throw new Error('Unable to load graphics for such a large map scale !');
    } else if (scale > 4513.988705) { // level 17
      offset = 2;
    } else if (scale > 2256.994353) { // level 18
      offset = 1;
    }
 
    // Build the query to send to the application's ArcGIS server.
    const query = new Query({
      geometry: extent.clone(),
      returnGeometry: true,
      where: topographyType.topographySubTypes.map(
        (type) => `type = '${type}'`
      ).join(' OR '),
      maxAllowableOffset: offset
    });
 
    const queryTask = new QueryTask({
      url: topographyTypesUrl
    });
 
    const featureSet: __esri.FeatureSet = await queryTask.execute(query);
    const graphics: __esri.Graphic[] = featureSet.features;
 
    const topographyTypeGraphics = new GraphicsLayer({
      id: topographyType.name,
      visible: false
    });
 
    if (graphics.length === 0) {
      return topographyTypeGraphics;
    }
 
    const graphicsClones = graphics.map((graphic) => graphic.clone());
 
    // Only keep graphics that are inside the input Extent.
    const resultsPromises = graphicsClones.map(
      async (graphic) => graphic.geometry = await geometryEngine.intersect(graphic.geometry, extent) as __esri.Geometry,
    );
    await Promise.all(resultsPromises);
 
    // Merge all graphics from the same TopographyType into a single instance of __esri.Graphic.
    const mergedGraphics = graphics[0].clone();
    const geometriesOfAllGraphics = graphicsClones.map((graphic) => graphic.geometry);
    mergedGraphics.geometry = await geometryEngine.union(geometriesOfAllGraphics);
 
    // Set the symbol for the graphics of the TopographyType.
    mergedGraphics.symbol = topographyType.symbol;
    topographyTypeGraphics.add(mergedGraphics);
 
    return topographyTypeGraphics;
  }
 
  /**
   * Load the Graphics of all TopographyTypes for a given extent and scale.
   *
   * @param extent The Extent for which the TopographyTypes' graphics must be loaded.
   * @param scale The scale for which the graphics must be loaded.
   *
   * @returns A list of GraphicsLayer containing the graphics for the different TopographyTypes.
   */
  async loadAllTopographyTypesGraphics(
    extent: __esri.Extent,
    scale: number
  ): Promise<__esri.GraphicsLayer[]> {
    const topographyTypes = await getAllTopographyTypes();
 
    const graphicsLayersPromises = topographyTypes.map(
      topographyType => this.loadTopographyTypeGraphics(topographyType, extent, scale)
    );
    const graphicsLayers = await Promise.all(graphicsLayersPromises);
 
    return graphicsLayers;
  }
}