Programming JMap Web extensions
Dernière mise à jour
Dernière mise à jour
K2 Geospatial 2022
Extensions are modular and usually offer functions suited for specific tasks. On its own, JMap Web provides a basic set of features. JMap Web extensions allow the customization and the inclusion of new features to deployments based on the JMap Web application template.
Just like JMap Pro extensions, JMap administrators may choose which extensions they want to include during the application deployment assistant. The selected extensions will be loaded as part of JMap Web’s initialization process.
Similar to a JMap Javascript library, a JMap Web extension consists of a collection of Javascript files, style sheets (CSS) and resources (images, sounds, etc.).
You can use the JMap Web extension builder tool to rapidly scaffold a Web extension’s files. Open a command line/terminal window or use a file browser and navigate to the tools / web extension builder directory of the JMap 7 SDK installed on your computer.
You will find a webextensionbuilder.xml
file. Open it in a text editor. Edit it in order to specify a list of arguments that will allow you to create your own extension. The following arguments are required:
Example of a modified webextensionbuilder.xml
file used to create your extension:
<project name="JMap 7 SDK - Web Extension Builder" basedir="." default="run">
<!-- set global properties for this build -->
<property file="../../sdk.properties"/>
<target name="run">
<java fork="true" classname="jmap.sdk.tools.webextensionbuilder.WebExtensionBuilder"
classpath="webextensionbuilder.jar;${sdk_classpath}">
<!-- Use default parameter values. Uncomment following line to use other parameters -->
<arg line="-fullname 'Web SDK Documentation Example' -namespace Example -version 1.0 -dest output"/>
</java>
</target>
</project>
From the terminal, invoke the ant script:
ant -f webextensionbuilder.xml
To create a JMap Web extension using Eclipse, the following should be installed on your system, make sure a Java Developer Kit is installed and configured as the default JRE in Eclipse:
You should also make sure that your JDK’s tools.jar file is added to Eclipse’s Ant Runtime Configuration:
Execute the build task by opening the webextensionbuilder.xml
file in Eclipse. Execute the run target.
After the ant script’s execution, you will have an extension’s boiler plate code at the specified location.
output
└── web_sdk_documentation_example
├── actions
── build.xml
├── readme.markdown
└── src
└── Example
└── SampleAction.java
├── assets
├── css
└── web_sdk_documentation_example.css
└── js
└── web_sdk_documentation_example.js
└── extension.json
7 directories, 6 files
By default and for demonstration purposes, an AJAX Dispatcher action called web_sdk_documentation_example_sample_action is included. For more details on AJAX Dispatcher actions, refer yourself to the Sending Server Requests and Custom Actions example.
Your extension’s generated CSS and Javascript assets will be loaded during the JMap initialization process.
All other CSS or Javascript resources will need to be loaded programmatically in the generated Javascript file (in this case the web_sdk_documentation_example.js file).
Since extension files are loaded at runtime, it is important that you do not rename or move the generated CSS and Javascript files. The name of those files should always be the extension’s short name as defined in the extension.json file.
The source code of the generated Javascript file includes comments that describe the required properties and functions that make up your JMap Web extension. It is recommend that you read the contents of this file so that you can familiarize yourself with its content.
Among the generated files is extension.json. This file will serve as a manifest for JMap Server. It must contain valid JSON. This file must not be removed or renamed.
As previously mentioned, a JMap.app global variable is defined during initialization. One of that object’s responsibility is to capture a reference to your application’s Map.
JMap.app.map is your application’s instance of the ol.Map class. JMap’s Javascript libraries use the OpenLayers API in order to accomplish many tasks. Tasks such as layer manipulation, operations on coordinates/bounds as well as managing the map’s controls and popups.
OpenLayers offers a large gallery of development examples. It is recommended that you use this resource throughout your development as a way to familiarize yourself with their API. The gallery and the API documentation are indispensable resources that you should consult frequently.
This portion of the documentation offers examples of several tasks that can be accomplished in JMap Web extensions.
Note: Knowledge of OpenLayer’s Class base type is strongly recommended before continuing with this documentation.
Several classes were developed in order to support various types of map interactions when touch/mouse events are performed. They are the following:
JMap.Html5Core.Tool.ToolManager: During the initialization process, a single instance of this class is produced and is made accessible via the JMap.app.clickToolManager variable. This object keeps track of all registered tools as well as the single currently activated tool. That object’s currentTool will be the recipient of the click and touch events.
JMap.Html5Core.Tool.Tool: Superclass from which all tools must inherit.
The following code creates a tool:
JMap.Html5Core.Tool.SampleTool = function(options){
var _this = this;
this.hasInterraction = true; this.name = 'SampleTool';
this.buttonDiv = document.createElement('div');
$(this.buttonDiv)
.attr({
'id' : 'SampleTool',
'class' : 'SampleToolClass'
})
.click( function(event){
JMap.app.clickToolManager.toggleUiTool(_this);
event.stopImmediatePropagation(); });
$('#JMapStandardToolBar').append(this.buttonDiv);
goog.base(this, options);
);
goog.inherits(JMap.Html5Core.Tool.SampleTool, JMap.Html5Core.Tool.Tool);
JMap.Html5Core.Tool.SampleTool.prototype.initializeInteraction = function() { this.interaction = new ol.interaction.Interaction({})
};
JMap.Html5Core.Tool.SampleTool.prototype.off = function()
{
goog.base(this, 'off');
};
JMap.Html5Core.Tool.SampleTool.prototype.on = function()
{
goog.base(this, 'on');
};
var sampleTool = new JMap.Html5Core.Tool.SampleTool({});
JMap.app.clickToolManager.addTool(sampleTool);
After it has been instantiated, you need to register it against the JMap.app.clickToolManager
and activate it.
JMap.app.clickToolManager.addTool(sampleTool);
JMap.app.clickToolManager.setCurrentTool(sampleTool);
If a tool was already activated at the time that toggleUiTool() was called, that tool will be deactivated.
OpenLayers offers multiple classes allowing the visualization of various data sources. The ol.layer.Vector and ol.source.Vector classes are particularly useful to display vector data features created programmatically.
The following code excerpt creates and adds a vector layer to an initialized application. Using your own custom tool, you will be able to create Point geometries wherever click events are performed.
JMap.Html5Core.Tool.SampleTool = function(options){
var _this = this;
this.hasInterraction = true;
this.name = 'SampleTool';
this.vectorLayer = null;
this.layerSource = null;
this.buttonDiv = document.createElement('div');
$(this.buttonDiv)
.attr({
'id' : 'SampleTool',
'class' : 'SampleToolClass'
})
.click( function(event){
JMap.app.clickToolManager.toggleUiTool(_this);
event.stopImmediatePropagation();
});
$('#JMapStandardToolBar').append(this.buttonDiv);
goog.base(this, options);
);
goog.inherits(JMap.Html5Core.Tool.SampleTool, JMap.Html5Core.Tool.Tool);
JMap.Html5Core.Tool.SampleTool.prototype.initializeInteraction = function() {
this.layerSource = new ol.source.Vector({
wrapX: false
});
this.vectorLayer = new ol.layer.Vector({ source: layerSource, });
this.interaction = new ol.interaction.Draw({
id: 'SampleToolInterraction',
source: this.source,
type: 'Point',
style: new ol.style.Style({})
});
};
JMap.Html5Core.Tool.SampleTool.prototype.off = function(){
JMap.app.map.removeLayer(this.vectorLayer);
goog.base(this, 'off');
};
JMap.Html5Core.Tool.SampleTool.prototype.on = function()
{
JMap.app.map.addLayer(this.vectorLayer);
goog.base(this, 'on');
};
var vectorLayerTool = new JMap.Html5Core.Tool.SampleTool({});
JMap.app.clickToolManager.addTool(vectorLayerTool);
Similarly, as described in the previous example, the following code will register your newly created tool against the JMap.app.clickToolManager and activate it.
JMap.app.clickToolManager.addTool(vectorLayerTool);
JMap.app.clickToolManager.setCurrentTool(vectorLayerTool);
Although vector data editing in JMap Web is now offered as part of JMap 7, the JMap Web public API does not offer methods to do so programmatically. However, you can use OpenLayers’s API to create, edit and delete your own features associated to your own vector layers that were created programmatically.
Here are a few links detailing OpenLayers’s vector data editing functions:
It is possible to define the appearance of your vector layer features. This is generally accomplished by associating a ol.style to your layer.
A Style may contain any of the properties described here in order to modify the appearance of layer features.
When in a production environment, it is recomended that your extension’s assets be minified in order to limit the number of HTTP requests on load. It also allows you to obfuscate your code up to a certain extent. We use Google’s Closure Compiler and recommend it.
As previously mentioned, if your extension has dependencies, they will need to be loaded programmatically in your extension’s generated javascript file.
OpenLayers’s API documentation is generated by parsing the source code’s comments. This means that methods and properties may not appear in the docs if they are not properly commented. Directly browsing OpenLayer’s source code may help you if something in their documentation is not clear.
Developers may want to operate differently when developing JMap Web extensions. The two following workflows tend to be preferred.
The developer works in the generated extension’s folder. They usualy modify the extension’s assets, copy the extension files to the $JMAP_HOME$
/extensions/web directory, update their applications and test their changes in the updated application.
The developer works directly in the deployed application’s files.
Both approaches have their own pros and cons.
The first technique, while slower, allows for a safer and more incremental process. Keeping track of code changes is easier.
The second technique is faster, however you will need to consistently merge your changes to your version controlled checkout. This approach may also lead to data loss if you ever update your application and your changes were not included in your $JMAP_HOME$
/extensions/web directory.
fullname
{String} The complete human-readable name of the extension. This is what the JMap administrators and users will see. A simplified shortname will be derived from this value. The shortname will notably be used as a name for various files.
namespace
{String} The name of your extension’s Javascript namespace (a global object variable). If you plan on having several of your extensions deployed at once, you may specify a namespace that contains at most one period “.” in order to seperate the items of your namespace. Example: MyCompany.HelloWorld.
version
{String} Your extension’s version number. No specific format is required.
dest
Location on disk where the extension will be created.