This article is part of a series of tutorials that show you how to develop your first application:
Goal
In this tutorial, we create a basic HTML page containing a LuciadRIA map. We use webpack to bundle our JavaScript and HTML files, and webpack-dev-server to serve the app.
Note that the use of webpack isn’t required. LuciadRIA comes as a set of ES6 modules, and you can use the tool chain of your choosing to add LuciadRIA to your web application. LuciadRIA doesn’t impose any special requirements.
Although webpack features prominently, the goal of this tutorial is to show you how to integrate LuciadRIA into a web application. It doesn’t focus on the setup and use of webpack as such, nor on the project configuration for TypeScript. The use of webpack isn’t required. LuciadRIA comes as a set of ES6 modules, and you can use the tool chain of your choosing to add LuciadRIA to your web application. |
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 and the webpack TypeScript 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 typescript ts-loader --save-dev
We set up the standard webpack configuration, with the TypeScript sources in a src
directory and the output in a dist
directory.
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
touch dist/index.html #create an empty index.html file in the dist directory
touch src/index.ts #create an empty index.ts file in the src directory
touch webpack.config.js #create an empty webpack configuration file
For TypeScript, we need a tsconfig.json
file specifying the compiler options.
For now, we just tell the TypeScript compiler tsc
to create one for us:
npx tsc --init --target es2015 #this will create a tsconfig.json file
Depending on your project, you can change the settings in that file. For this tutorial, the default values are enough.
Now, we need to configure webpack in such a way that it transpiles our TypeScript code to JavaScript.
For this, we configure webpack to use the ts-loader
on all .ts
files.
We also specify what the entry file is, and where we want to locate the output.
Consult the webpack documentation for more information.
To make development easier, we also configure a development server that serves the contents of the dist
folder.
While it’s running, this dev-server automatically picks up changes we make to our TypeScript code, and re-transpiles them
to JavaScript.
webpack.config.js
file
const path = require('path');
module.exports = {
devtool: 'inline-source-map',
entry: './src/index.ts',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader'
}
]
},
resolve: {
extensions: [ '.ts', '.tsx', '.js' ]
},
devServer: {
static: path.join(__dirname, 'dist')
}
};
To test our setup, we add some contents to the index.html
file in the dist
folder
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 should look like
hello-world |- dist |- index.html |- node_modules |- package.json |- package-lock.json | - src |- index.ts |- tsconfig.json |- webpack.config.js
To actually start the development server, we add a start:dev
script in package.json
:
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 package from your own private registry
npm install --registry http://my-private-registry:8073/ @luciad/ria
# Optionally: if you have 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.ts
file.
An alternative to using the
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.
<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.ts 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:
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.ts
file we need to create a new @luciad/ria/view/WebGLMap
instance, and tell it to appear in that <div>
:
import {Map} 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’ll need to pass the contents of the license file to the License
class:
-
Copy the
luciadria_development.txt
license file to thesrc
folder. -
Create a new
src/license-loader.ts
file -
Add the following contents to it:
Thesrc/license-loader.ts
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.
-
Import the
LicenseLoader
in thesrc/index.ts
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.
Please note that |
Because TypeScript handles text file resources in a particular way, we also need to create a src/luciadria_development.txt.d.ts
file with the following contents:
src/luciadria_development.txt.d.ts
file
//See https://github.com/webpack-contrib/raw-loader/issues/56#issuecomment-507057511 and
//https://www.typescriptlang.org/docs/handbook/modules.html#wildcard-module-declarations
declare module "raw-loader!*" {
const content: string;
export default content;
}
Adding some data to the map
Now that we installed the license, 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 the 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
Full code
src/index.ts
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);
});
src/license-loader.ts
file
import {setLicenseText} from "@luciad/ria/util/License.js";
import license from "raw-loader!./luciadria_development.txt";
setLicenseText(license);
src/luciadria_development.txt.d.ts
file
//See https://github.com/webpack-contrib/raw-loader/issues/56#issuecomment-507057511 and
//https://www.typescriptlang.org/docs/handbook/modules.html#wildcard-module-declarations
declare module "raw-loader!*" {
const content: string;
export default content;
}
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>
webpack.config.js
file
const path = require('path');
module.exports = {
devtool: 'inline-source-map',
entry: './src/index.ts',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader'
}
]
},
resolve: {
extensions: [ '.ts', '.tsx', '.js' ]
},
devServer: {
static: path.join(__dirname, 'dist')
}
};