CustomElevationLayer with Typescript

908
1
Jump to solution
05-22-2018 04:03 AM
RichardReinicke
Occasional Contributor II

Hi,

in the past I was able to create a CustomElevationLayer with Exaggeration for an Esri Javascript 3D scene:
Custom Elevation Layer with Exaggeration 

Now I would like ro realize the same task with Typescript. The general patterns to use Esri API in Typescript are clear but I'm struggling when it comes to: 

BaseElevationLayer.createSubclass({...}) 

TypeScript compiler tells me that Property 'createSubclass' does not exist on type 'BaseElevationLayerConstructor' and I can see this clearly in the TypeDefinitions. This method appears nowhere.

So how can I create a custom ElevationLayer in Typescript? 

Does anybody has an idea?

0 Kudos
1 Solution

Accepted Solutions
RichardReinicke
Occasional Contributor II

I`ve been able to solve this on my own and I want to share my solution here. Probably it`s not the best one, so I`m open for improvements. 

     import { subclass, declared, property } from 'esri/core/accessorSupport/decorators';

     @subclass('hwrm.ExagerratedElevationLayer')
     export class ExaggeratedElevationLayer extends declared(BaseElevationLayer) {

         private _elevationLayer: ElevationLayer;
         private _spatialReference: SpatialReference;
         private _tileInfo: TileInfo;
         private _fullExtent: Extent;
         private _exaggeration: number;
         private _elevationServiceURL: string;

         @property()
         get elevationLayer(): ElevationLayer {
             return this._elevationLayer;
         };
         set elevationLayer(value: ElevationLayer) {
             const oldValue = this._get < ElevationLayer > ("elevationLayer");
             if (oldValue !== value) {
                 this._set("elevationLayer", value);
             }
         };

         @property()
         get spatialReference(): SpatialReference {
             return this._spatialReference;
         };
         set spatialReference(value: SpatialReference) {
             const oldValue = this._get < SpatialReference > ("spatialReference");
             if (oldValue !== value) {
                 this._set("spatialReference", value);
             }
         };

         @property()
         get tileInfo(): TileInfo {
             return this._tileInfo;
         };
         set tileInfo(value: TileInfo) {
             const oldValue = this._get < TileInfo > ("tileInfo");
             if (oldValue !== value) {
                 this._set("tileInfo", value);
             }
         };

         @property()
         get fullExtent(): Extent {
             return this._fullExtent;
         };
         set fullExtent(value: Extent) {
             const oldValue = this._get < Extent > ("fullExtent");
             if (oldValue !== value) {
                 this._set("fullExtent", value);
             }
         };

         @property()
         get exaggeration(): number {
             return this._exaggeration;
         };
         set exaggeration(value: number) {
             const oldValue = this._get < number > ("exaggeration");
             if (oldValue !== value) {
                 this._set("exaggeration", value);
             }
         };

         @property()
         get elevationServiceURL(): string {
             return this._elevationServiceURL;
         };
         set elevationServiceURL(value: string) {
             const oldValue = this._get < string > ("elevationServiceURL");
             if (oldValue !== value) {
                 this._set("elevationServiceURL", value);
             }
         };

         load(): IPromise < any > {

             let elevationLayer: ElevationLayer = new ElevationLayer({
                 url: this._get < string > ("elevationServiceURL")
             });

             this._set("elevationLayer", elevationLayer);
             return this.addResolvingPromise(this._get < ElevationLayer > ("elevationLayer").load());
         };

         fetchTile(level: number, row: number, col: number) {
             return this._get < ElevationLayer > ("elevationLayer").fetchTile(level, row, col)
                 .then(function(data) {
                     data.values.forEach(function(value: number, index: number, values: number[]) {
                         console.log(this);
                         values[index] = value * this._get < number > ("exaggeration");
                     }.bind(this));
                     return data;
                 }.bind(this));
         };

     }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I consumed my extended class like so:

let exaggeratedElevationLayer: HwrmLayers.HwrmLayers.ExaggeratedElevationLayer = new HwrmLayers.HwrmLayers.ExaggeratedElevationLayer();
exaggeratedElevationLayer.elevationServiceURL = this._config.elevationServiceURL;
exaggeratedElevationLayer.exaggeration = 10;
exaggeratedElevationLayer.fullExtent = this._fullExtent;
exaggeratedElevationLayer.tileInfo = this._tileInfo;
exaggeratedElevationLayer.spatialReference = this._tileInfo.spatialReference;

this._map.ground.layers.add(exaggeratedElevationLayer);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The 2 HwrmLayers in front derive from my individual code structure with import alias and namespace.

View solution in original post

0 Kudos
1 Reply
RichardReinicke
Occasional Contributor II

I`ve been able to solve this on my own and I want to share my solution here. Probably it`s not the best one, so I`m open for improvements. 

     import { subclass, declared, property } from 'esri/core/accessorSupport/decorators';

     @subclass('hwrm.ExagerratedElevationLayer')
     export class ExaggeratedElevationLayer extends declared(BaseElevationLayer) {

         private _elevationLayer: ElevationLayer;
         private _spatialReference: SpatialReference;
         private _tileInfo: TileInfo;
         private _fullExtent: Extent;
         private _exaggeration: number;
         private _elevationServiceURL: string;

         @property()
         get elevationLayer(): ElevationLayer {
             return this._elevationLayer;
         };
         set elevationLayer(value: ElevationLayer) {
             const oldValue = this._get < ElevationLayer > ("elevationLayer");
             if (oldValue !== value) {
                 this._set("elevationLayer", value);
             }
         };

         @property()
         get spatialReference(): SpatialReference {
             return this._spatialReference;
         };
         set spatialReference(value: SpatialReference) {
             const oldValue = this._get < SpatialReference > ("spatialReference");
             if (oldValue !== value) {
                 this._set("spatialReference", value);
             }
         };

         @property()
         get tileInfo(): TileInfo {
             return this._tileInfo;
         };
         set tileInfo(value: TileInfo) {
             const oldValue = this._get < TileInfo > ("tileInfo");
             if (oldValue !== value) {
                 this._set("tileInfo", value);
             }
         };

         @property()
         get fullExtent(): Extent {
             return this._fullExtent;
         };
         set fullExtent(value: Extent) {
             const oldValue = this._get < Extent > ("fullExtent");
             if (oldValue !== value) {
                 this._set("fullExtent", value);
             }
         };

         @property()
         get exaggeration(): number {
             return this._exaggeration;
         };
         set exaggeration(value: number) {
             const oldValue = this._get < number > ("exaggeration");
             if (oldValue !== value) {
                 this._set("exaggeration", value);
             }
         };

         @property()
         get elevationServiceURL(): string {
             return this._elevationServiceURL;
         };
         set elevationServiceURL(value: string) {
             const oldValue = this._get < string > ("elevationServiceURL");
             if (oldValue !== value) {
                 this._set("elevationServiceURL", value);
             }
         };

         load(): IPromise < any > {

             let elevationLayer: ElevationLayer = new ElevationLayer({
                 url: this._get < string > ("elevationServiceURL")
             });

             this._set("elevationLayer", elevationLayer);
             return this.addResolvingPromise(this._get < ElevationLayer > ("elevationLayer").load());
         };

         fetchTile(level: number, row: number, col: number) {
             return this._get < ElevationLayer > ("elevationLayer").fetchTile(level, row, col)
                 .then(function(data) {
                     data.values.forEach(function(value: number, index: number, values: number[]) {
                         console.log(this);
                         values[index] = value * this._get < number > ("exaggeration");
                     }.bind(this));
                     return data;
                 }.bind(this));
         };

     }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I consumed my extended class like so:

let exaggeratedElevationLayer: HwrmLayers.HwrmLayers.ExaggeratedElevationLayer = new HwrmLayers.HwrmLayers.ExaggeratedElevationLayer();
exaggeratedElevationLayer.elevationServiceURL = this._config.elevationServiceURL;
exaggeratedElevationLayer.exaggeration = 10;
exaggeratedElevationLayer.fullExtent = this._fullExtent;
exaggeratedElevationLayer.tileInfo = this._tileInfo;
exaggeratedElevationLayer.spatialReference = this._tileInfo.spatialReference;

this._map.ground.layers.add(exaggeratedElevationLayer);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The 2 HwrmLayers in front derive from my individual code structure with import alias and namespace.

0 Kudos