Goal

In this tutorial, we add two types of raster data to the map: image data and elevation data. We’re going to add imagery data from a WMS server, and elevation data from a LuciadFusion tile server.

Starting point

We take the code written in Hello World as our starting point, and expand from there. Note that the Hello World application already adds some image data. In this tutorial, we explain in greater detail how to add image data, and also show you how you add elevation data to the map.

Adding image data to the map

Step 1 - Create a raster model from image data

First, we need to create a raster data model. You can see a model as a collection of data. The LuciadRIA API offers several models, each for a specific kind of data. For raster data coming from a WMS server, we use a WMSTileSetModel. The WMSTileSetModel defines a tiling model on top of a WMS service. It sends image requests to the WMS service, but treat the images as tiles for display on the LuciadRIA map. With this approach, we can cache image data more efficiently.

To create a model, we must configure the model so that LuciadRIA can position the data on the map. A WMS server can tell us what these configuration settings are. To create a WMSTileSetModel, we just need the location of the server and the name of the dataset on the server:

const server = "https://sampleservices.luciad.com/wms";
const dataSetName = "4ceea49c-3e7c-4e2d-973d-c608fb2fb07e";

// Note: A dataset an a WMS server is called a "layer", not to be confused with a layer on the LuciadRIA Map.
WMSTileSetModel.createFromURL(server, [{layer: dataSetName}])
    .then(model => {/*...*/});

With WMSTileSetModel.createFromURL(), we first contact the server for the configuration information using a GetCapabilities request and then create a correctly configured WMSTileSetModel.

Step 2 - Create a layer for the model

LuciadRIA visualizes each model through a layer, to clearly separate the data model from its visual representation. If your model holds tiled raster data, you need to use a RasterTileSetLayer. Its constructor needs these parameters:

  • A model: the raster tile set model

  • Options for the layer: a JavaScript object containing layer-specific options. For more information, see the reference documentation for LayerConstructorOptions.

WMSTileSetModel.createFromURL(server, [{layer: dataSetName}])
    .then(model => {
      // Once the data is available, create a layer for it...
      const layer = new RasterTileSetLayer(model, {
        label: "Background data"
      });
    });

Step 3 - Add the layer to the map

Because the layer is responsible for visualizing the data in the model, we need to insert the layers into a map to make the data visible. You can use the LayerTree of the map for that. Basically, the map has a collection of layers. Through that collection, you can add layers to the map, retrieve layers from the map, and remove layers from the map. You can also specify a position for your layer inside the tree structure, at the bottom or at the top, for example, or above or below another layer. This code snippet shows you how to add the WMS layer to the map.

WMSTileSetModel.createFromURL(server, [{layer: dataSetName}])
    .then(model => {
      // Once the data is available, create a layer for it...
      const wmsLayer = new RasterTileSetLayer(model);
      // And add it to the map.
      map.layerTree.addChild(wmsLayer, "top");
    });

Adding elevation raster data

Step 1 - Make sure that you are working with a 3D map

LuciadRIA processes elevation data on a 3D map only. It ignores elevation data on a 2D map, so you must create a 3D map first.

const mapReference = getReference("EPSG:4978");
const map = new WebGLMap("map", {reference: mapReference});

Step 2 - Use a model with elevation data

You add elevation data to the map in the same way as you add image data. In this tutorial, we get our elevation data from LuciadFusion. LuciadFusion serves elevation data as raster tile set coverages. You can add those to a map through a FusionTileSetModel, in a similar way as you add a WMSTileSetModel with image data.

const elevationServer = "https://sampleservices.luciad.com/lts";
const elevationCoverage = "e8f28a35-0e8c-4210-b2e8-e5d4333824ec";

FusionTileSetModel.createFromURL(elevationServer, elevationCoverage)
    .then(function(model) {
      const elevationLayer = new RasterTileSetLayer(model, {
        label: "Elevation"
      });
      map.layerTree.addChild(elevationLayer);
    });

As you can see, creating the raster layer and adding that layer to the map is the same for elevation layers and image layers.

Final result

After adding both layers, you can enjoy this view when you navigate the map to the Los Angeles area:

A LuciadRIA map with elevation and image data

The full code

import "./license-loader";
import {WebGLMap} from "@luciad/ria/view/WebGLMap.js";
import {WMSTileSetModel} from "@luciad/ria/model/tileset/WMSTileSetModel.js";
import {RasterTileSetLayer} from "@luciad/ria/view/tileset/RasterTileSetLayer.js";
import {getReference} from "@luciad/ria/reference/ReferenceProvider.js";
import {FusionTileSetModel} from "@luciad/ria/model/tileset/FusionTileSetModel.js";

// Create a 3D Map
const mapReference = getReference("EPSG:4978");
const map = new WebGLMap("map", {reference: mapReference});

// Add image data
const server = "https://sampleservices.luciad.com/wms";
const dataSetName = "4ceea49c-3e7c-4e2d-973d-c608fb2fb07e";

// Note: A dataset an a WMS server is called a "layer", not to be confused with a layer on the LuciadRIA Map.
WMSTileSetModel.createFromURL(server, [{layer: dataSetName}])
    .then(model => {
      // Once the data is available, create a layer for it...
      const wmsLayer = new RasterTileSetLayer(model);
      // And add it to the map.
      map.layerTree.addChild(wmsLayer, "top");
    });

// Add elevation data
const elevationServer = "https://sampleservices.luciad.com/lts";
const elevationCoverage = "e8f28a35-0e8c-4210-b2e8-e5d4333824ec";

FusionTileSetModel.createFromURL(elevationServer, elevationCoverage)
    .then(function(model) {
      const elevationLayer = new RasterTileSetLayer(model, {
        label: "Elevation"
      });
      map.layerTree.addChild(elevationLayer);
    });