Skip to content

Interpolated layer

Raitis Berzins edited this page Jun 5, 2022 · 23 revisions

The interpolated layer is a combination of Openlayers (abbr. OL) Image layer and OL Vector layer that uses the HSLayers InterpolatedSource class as its source. InterpolatedSource extends the IDW (Inverse distance weighting interpolated source - Shepard's method) class of the ol-ext library, which inherits the OL ImageCanvas class. InterpolatedSource uses the OL Vector source class to provide the user the ability to define feature loading strategy and source loader functionality, to obtain the features. There is also an option to provide static features without using feature loader. To generate a raster image, displaying data interpolation, the user must provide value (weight), by which the image can be generated. As a result, collected features are parsed, weight values are normalized (between 0 and 100) and the image is drawn and displayed over the map. The user also has the option to change the color ramp. It can be either a string value – name representing one of the available color maps – or a function, which handles color selection for each feature's weight value.

InterpolatedSource options

Property Type Mandatory Default Value Description Example
maxFeaturesInCache
Number false The largest number that can be represented in JavaScript Maximum number of features to cache 300
maxFeaturesInExtent
Number false The largest number that can be represented in JavaScript Maximum number of features to load per extent change 100
features
Array<Feature<Geometry>> false undefined Static features see example below
weight
String true undefined Feature's property that holds a number value, and will be used to calculate interpolation 'myWeight'
loader
A callback function returning Array<Feature<Geometry>> false undefined Function used to load features from external source see example below
strategy
LoadingStrategy false undefined A function that determines which extents are loaded and which are not see example in the code
colorMap
A string containing one of colormap names or a callback function that takes number as parameter and returns Array<Number> false undefined A function that takes normalized weight value, creates number array, representing a color, and returns it 'jet','jet-reverse'

How to create an InterpolatedSource

const interpolatedSource = new InterpolatedSource({
        maxFeaturesInCache: 500,
        maxFeaturesInExtent: 100,
        features: [],
        weight: () => {
          return 'fac2020';
        },
        loader: async ({extent, projection}) => {
          interpolatedSource.cancelUrlRequest.next();
          const extentIn4326 = transformExtent(extent, projection, 'EPSG:4326');
          const url = this.hsUtilsService.proxify(
            interpolatedSource.createIDWSourceUrl(
              'Place Your feature service URL here',
              extentIn4326
            ),
            app.name
          );
          try {
            const response: any = await lastValueFrom(
              this.httpClient.get(url).pipe(
                takeUntil(interpolatedSource.cancelUrlRequest),
                catchError(async (e) => {})
              )
            );
            return interpolatedSource.parseFeatures(response, projection);
          } catch (error) {}
        },
        colorMap: 'jet',
      });

How to add Interpolated layer to the map

      const idwLayer = new ImageLayer({
        properties: {title: 'IDW layer'},
        source: interpolatedSource as any,
        opacity: 0.5,
      });

Vector layer is mandatory, otherwise nothing will be loaded with source loader

      const idwVectorLayer = new VectorLayer({
        properties: {
          showInLayerManager: false,
          visible: idwLayer.getVisible(),
        },
        style: new Style(),
        source: interpolatedSource.getSource(),
      });

Set vector layer's visibility based on image layer, needed so that the loader is disabled once the image layer is not visible on the map.

      idwLayer.on('change:visible', (e) => {
        idwVectorLayer.setVisible(e.target.getVisible());
      });

Add both layers as HsConfig default_layers.

Color map function

colorMap: (v: number) => {
//Make Your logic here and generate color
 let color = [0, 0, 0, 255];
          if (isNaN(v)) {
            return color;
          }
          switch (true) {
            case v < 20:
              color = [0, 0, 255, 255];
              break;
            case v < 40:
              color = [0, 125, 125, 255];
              break;
            case v < 60:
              color = [0, 255, 0, 255];
              break;
            case v < 80:
              color = [125, 125, 0, 255];
              break;
            case v <= 100:
            case v > 100:
              color = [255, 0, 0, 255];
              break;
            default:
              color = [0, 0, 0, 255];
          }
          return color;
}

Static features

getStaticFeatures(): Feature[] {
for (let i = 0; i < 100; ++i) {
        const coordinates = [
          2 * e * Math.random() - e,
          2 * e * Math.random() - e,
        ];
        features[i] = new Feature({
          geometry: new Point(coordinates),
          name: 'test',
          population: Math.round(Math.random() * 5000000),
          val: this.getRandomInt(0, 100),
        });
      }
 return features;
}
Clone this wiki locally