Skip to content

Latest commit

 

History

History
207 lines (154 loc) · 7.47 KB

packages.md

File metadata and controls

207 lines (154 loc) · 7.47 KB

HOW TO USE packages

Package Support

The viewer allows loading packages to extend the viewer's functionalities.

The viewer also supports few core packages such as a basemap panel, details panel, layers panel, overview map.

You can see an example package here

Creating a package using vanilla javascript

To create a package, start by creating a JavaScript file preferably with the packages name.

The package requires to be written inside an immediately invoked function expression IIFE

(function () {
  // create package class
})();

Inside this function you need to create a class that will be used to initialize the package

(function () {
  class Test {}
})();

The class implements 1 constant translations and 2 hooks added, removed that will be accessed and called directly from the viewer, it will also automatically get access to api, createElement, react, props, translate and makeStyles.

The translations constant is an optional object, if defined then any translations provided will be passed to the core viewer translation instance (i18next) and will extend the current translations. Supported translations are for languages English and French and written as en and fr keys.

(function () {
  class Test {
    translations = {
      en: {
        testMessage: "Hello",
      },
      fr: {
        testMessage: "Bonjour",
      },
    };
  }
})();

The added hook is a required function that is called from the viewer immediately after the package has been loaded. In this function you can create a react component and use the core viewer API calls.

As mentioned this class will automatically get access to few objects

api is an object used to call any available API function from the core viewer.

createElement is an essential function to create React HTML elements see for an example usage, createElement is part of React which takes 3 arguments, the first is the HTML element to create, an example would be a button, the second argument is the element attributes for example onClick or className or style..., the third argument is the element content / children for example Click here.

react is the an object to use React functions and hooks such as useState, useEffect etc... see for more information.

props is an object containing the package properties passed when loading the package see for more information.

translate is an object to access react-i18next functions including useTranslation which will allow for accessing the viewer translations see for more information.

makeStyles is an object that will allow the package to use material ui themeing and access the core viewer theme see

The removed hook is a required function that is called from the viewer when a call has been made to remove the package. Any cleanup code should be written here, for example removing added components.

Creating a React component

Using the added hook you can create and load a react component in the viewer

A react component can be a functional component or a class component see for more information on how to use each one.

Below is a simple example of a funcational component that will add a panel to the viewer on the app-bar that will have a counter as it's content

// counter.js
(function () {
    class Counter {
        // added panel
        panel = null;

        // optional
        translations = {
            'en': {
                count: 'Count',
            },
            'fr': {
                count: 'Compter',
            },
        };

        // required, called immediately after package loads
        added = {
            const { api, react, translate } = this;

            // get mapId passed from package properties when created
            const { mapId } = this.props;

            // used to create react element
            const h = this.createElement;

            const { useState } = react;
            const { useTranslation } = translate;

            // create a react functional component
            const Component = () => {
                const [count, setCount] = useState(0);

                // access translations
                const { t } = useTranslation();

                return h('button', {
                    onClick: () => setCount(count + 1)
                }, `${t('count')} ${count})`;
            }

            // button props
            const button = {
                tooltip: 'Counter',
                icon: '<i class="material-icons">add</i>',
            };

            // panel props
            const panel = {
                title: 'Counter',
                icon: '<i class="material-icons">add</i>',
                content: Component,
                width: 200,
            };

            // create a new button panel on the app-bar
            this.panel = api.map(mapId).createAppbarPanel(button, panel, null);
        };

        // removed is a function called when removing a package to cleanup
        removed = () => {
            const { mapId } = this.props;

            this.api.map(mapId).removeAppbarPanel(this.panel.id);
        };
    }

    // export this package
    window.packages = window.packages || {};
    window.packages.counter = Counter;
})();

A package needs to be exported before it can be loaded to the viewer. To export the package add this at the bottom of the package class, see example above for the example package.

// export this package
window.packages = window.packages || {};
window.packages.counter = Counter;

Loading the package

You can load a package by first importing it in a script tag in the <head> element of the page

<script src="./counter.js"></script>

Then after the core viewer API is ready you can add the package to the viewer init callback using the add API function. This function takes 3 arguments, the first is the package name (should be unique name), the second is the exported package class, the third is the package properties. package properties can be accessed using this.props inside the package added or removed functions.

cgpv.api.addPlugin(name, packageClass, props)

cgpv.init(function () {
  cgpv.api.addPlugin("counter", window.packages["counter"], {
    mapId: "mapLCC",
  });
});

Loading bundled core packages

The viewer is bundled with core packages, you can load them by passing their id in the map config object in the corePackages array as follows

<div
  id="mapWM"
  class="llwp-map"
  data-lang="en"
  data-config="{
        'map': {
          'interaction': 'dynamic',
          'viewSettings': {
            'zoom': 4,
            'center': [60, -100]
            'projection': 3857,
          },
          'basemapOptions': {
            'basemapId': 'transport',
            'shaded': false,
            'labeled': true
          }
        },
        'components': ['app-bar', 'nav-bar', 'north-arrow', 'overview-map', 'footer-bar'],
        'corePackages': ['details-panel', 'layers-panel', 'basemap-panel'],
        'theme': 'dark',
        'suportedLanguages': ['en']
      }"
></div>

Available package ids details-panel, layers-panel, basemap-panel, footer-panel