Goal

In this tutorial, we create a basic HTML page containing a LuciadRIA map. Because of the limited support for module loading in web browsers we use webpack which bundles modules into a single artifact that is downloaded to the web browser. We use webpack-dev-server to serve the app.

Although webpack features prominently, the goal of this tutorial is to show how to integrate LuciadRIA into a web application. It doesn’t focus on the setup and use of webpack as such.

Project structure setup

As a first step, we create a new project directory with an index.html file and use webpack to serve this file. These steps are based on the webpack Getting Started tutorial:

We start by creating a directory, initializing npm, and installing webpack and the dev-server packages:

mkdir hello-world
cd hello-world
npm init -y
npm install webpack webpack-cli webpack-dev-server raw-loader --save-dev

We set up the standard webpack configuration, with a src directory for JavaScript sources and a dist directory for the output:

mkdir dist
mkdir src

# Already create some empty files, which we'll populate later
# The windows alternative for touch is type
# type nul > dist/index.html
# Alternatively, you can install touch as an npm package using `npm install --global touch-cli`.
touch dist/index.html #create an empty index.html file in the dist directory
touch src/index.js #create an empty index.js file in the src directory
touch webpack.config.js #create an empty webpack configuration file

We now need to make sure the web server serves the dist folder. For this, we add the following contents to the webpack.config.js file:

webpack.config.js file additions to serve the dist folder
const path = require('path');

module.exports = {
  devServer: {
    static: path.join(__dirname, 'dist')
  }
};

To test our setup, we add some contents to the index.html file in the dist folder

Initial contents of the dist/index.html file
<!doctype html>
<html lang="en">
  <head>
    <title>Hello world</title>
  </head>
  <body>
    <h1>Hello world</h1>
  </body>
</html>

The resulting folder and file structure looks like this:

hello-world
 |- dist
    |- index.html
 |- node_modules
 |- package.json
 |- package-lock.json
 | - src
     |- index.js
 |- webpack.config.js

To start the development server, we add a start:dev script in package.json:

Add an extra script to the package.json file
"scripts": {
  "start:dev": "webpack serve --mode development"
}

Now we can run

npm run start:dev

and browse to http://localhost:8080/ where we’re greeted by our web page.

Installing the LuciadRIA npm packages

Your LuciadRIA distribution comes with a number of NPM packages under the packages folder.

  • The @luciad/ria package has the core modules of the LuciadRIA library

  • The @luciad/geometry and @luciad/symbology packages are optional packages. Depending on the LuciadRIA tier you bought, you may not have access to them. Consult the LuciadRIA product tiers documentation for more information.

In this tutorial, we assume that these packages are already published in an npm registry. We’re going to install them using npm install.

# Install the LuciadRIA core package from your own private registry
npm install --registry http://my-private-registry:8073/ @luciad/ria

# Optional: if you purchased additional components, install them as well
# We won't be using any code from those packages in the remainder of this tutorial
# npm install  --registry http://my-private-registry:8073/ @luciad/ria-geometry
# npm install  --registry http://my-private-registry:8073/ @luciad/ria-milsym

We can now use the installed @luciad/ria package in our index.js file.

An alternative to using the --registry flag is defining the location in a .npmrc file:

; Set a new registry for a scoped package
@luciad:registry=http://my-private-registry:8073/

Consult the npm documentation for more information.

Adding a map to our application

First, we add a <div> to our index.html page to mark where we want our map. Because we’re updating the HTML file, we immediately trigger the loading of our JavaScript code.

The updated <body> element, containing a <div> for the map and the <script> tag for the JS in the dist/index.html file
<body>
  <h1>Hello world</h1>
  <!-- Create a div where our map should appear -->
  <div id="map"/>
  <!-- Load the javaScript file.
       main.js is the file that webpack will generate for the src/index.js file
  -->
  <script src="main.js"></script>
</body>

We also add some CSS to give this <div> a certain size. To keep things simple in this tutorial, we add the CSS directly to the header of our file:

CSS added to the header of the dist/index.html file
<style>
  #map {
    position: relative;
    width: 100%;
    height: 620px;
    overflow: hidden;
    border: 1px solid grey;
 }
</style>

The complete dist/index.html file

<!doctype html>
<html lang="en">
  <head>
    <title>Hello world</title>
    <style>
      #map {
        position: relative;
        width: 100%;
        height: 620px;
        overflow: hidden;
        border: 1px solid grey;
     }
    </style>
  </head>
  <body>
    <h1>Hello world</h1>
    <div id="map"/>
    <script src="main.js"></script>
  </body>
</html>

Now it’s time to write our first lines of LuciadRIA code. In the src/index.js file, we need to create a new @luciad/ria/view/WebGLMap instance, and tell it to appear in that <div>:

import {WebGLMap} from "@luciad/ria/view/WebGLMap.js";

//Create a new map instance, and display it in the div with the "map" ID
const map = new WebGLMap("map");

That’s it. We created our first LuciadRIA map.

If you visit the web page at this point, you bump into two problems, though:

  • We didn’t install the LuciadRIA license in our application yet, resulting in an error because the license can’t be found.

  • The map doesn’t contain any data, so the page doesn’t show anything.

Installing and activating the license

To activate the license, we must pass the contents of the license file to the License class:

  1. Copy the luciadria_development.txt license file to the src folder.

  2. Create a new src/license-loader.js file

  3. Add the following contents to it:

    The src/license-loader.js file:
    import {setLicenseText} from "@luciad/ria/util/License.js";
    import license from 'raw-loader!./luciadria_development.txt';
    
    setLicenseText(license);

    We’re using the webpack raw-loader to load the contents of the license file as a string.

  4. Import the LicenseLoader in the src/index.js file.

    import "./license-loader";

    Make sure that this import is the first import. You must load the license before you trigger any other LuciadRIA code.

Adding some data to the map

Now that the license is installed, it’s time to add some data to the map so that we can see the map. For this tutorial, we connect to a public WMS server and display a dataset from that server.

We request the 92c09725-a9c5-46fb-bffd-d9e23b4abbf2 dataset from the https://sampleservices.luciad.com/wms server. Once we have a connection to the server, we store the data in a layer and add it to our map.

import {WMSTileSetModel}  from "@luciad/ria/model/tileset/WMSTileSetModel.js";
import {RasterTileSetLayer} from "@luciad/ria/view/tileset/RasterTileSetLayer.js";

//Add some WMS data to the map
const server = "https://sampleservices.luciad.com/wms";
const dataSetName = "4ceea49c-3e7c-4e2d-973d-c608fb2fb07e";
WMSTileSetModel.createFromURL(server, [{layer: dataSetName}])
.then(model => {
  //Once the data is available, create a layer for it
  const layer = new RasterTileSetLayer(model);
  //and add the layer to the map
  map.layerTree.addChild(layer);
});

Consult the WMS documentation for more information on how to deal with WMS data in LuciadRIA.

This results in:

hello world

Full code

The src/index.js file
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";

//Create a new map instance, and display it in the div with the "map" id
const map = new WebGLMap("map");

//Add some WMS data to the map
const server = "https://sampleservices.luciad.com/wms";
const dataSetName = "4ceea49c-3e7c-4e2d-973d-c608fb2fb07e";
WMSTileSetModel.createFromURL(server, [{layer: dataSetName}])
.then(model => {
  //Once the data is available, create a layer for it
  const layer = new RasterTileSetLayer(model);
  //and add the layer to the map
  map.layerTree.addChild(layer);
});
The src/license-loader.js file
import {setLicenseText} from "@luciad/ria/util/License.js";
import license from 'raw-loader!./luciadria_development.txt';

setLicenseText(license);
The dist/index.html file
<!doctype html>
<html lang="en">
  <head>
    <title>Hello world</title>
    <style>
      #map {
        position: relative;
        width: 100%;
        height: 620px;
        overflow: hidden;
        border: 1px solid grey;
     }
    </style>
  </head>
  <body>
    <h1>Hello world</h1>
    <div id="map"/>
    <script src="main.js"></script>
  </body>
</html>
The webpack.config.js file
  const path = require('path');

  module.exports = {
    devServer: {
      static: path.join(__dirname, 'dist')
    }
  };