Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
JMap Web’s design allows the embedding of JMap Web deployments into your own web applications. This section details the necessary steps to enable application embedding.
Your deployed JMap Web applications, as they are now being served by JMap’s embedded Tomcat instance, contain the libraries and web services required for application embedding. Your application’s files are located in the /applications/deployed directory of your JMap Server.
Among those files is the jmap directory. It contains all necessary resources required to embed your JMap deployment. This directory and its contents must be copied to your web server and be accessible by your web application’s pages.
JMap Web’s dependencies will be loaded as part of the initialization process prior to displaying the map. For more details regarding the initialization process refer to the JMap Web’s Initialization Process section of this document.
JQuery is required during the map initialization process and as such must be present in your application’s document.
Including JMap Web’s dependencies’s stylesheets will alter the styles of your document. Currently, there is unfortunately no way to avoid this.
In order to allow JMap Web Deployments to be embedded, a few tweaks to your deployment’s web.xml files are necessary.
Modifying the deployment’s web.xml file will require you to unload/load your deployment. This can be done in JMap Admin’s deployment section.
All modifications to your deployment’s files will be lost if you update the deployment or its template’s files.
Included in your deployed application’s directory is an embed_example.html file. It serves as an example of a JMap Web embedded application. Open that file in a text editor to see how application embedding is done.
You can copy that file to a separate web server in order to confirm that Cross-Origin Resource Sharing and the X-frame-options were properly enabled.
To display JMap Web in an iframe, simply add the iframe with the “scr” attribute pointing to the JMap Web deployment.
<!-- Add this if you use google maps features in your deployment -->
<iframe height="450px" width="600px" src="https://jmap7.jmaponline.net/montreal_web"></iframe>
You can also pass a sessionId, see the embed_example page on how to retreive a session Id from the REST API.
<!-- Add this if you use google maps features in your deployment -->
<iframe height="450px" width="600px" src="https://jmap7.jmaponline.net/montreal_web?sessionId=123456789"></iframe>
You will most likely be displaying the map from another origin, to allow the application to be displayed from another origin, the next step is to update your deployment and add your allowed origins in the advanced options.
If you encounter this message in the web console, make sure you allow the origin in the X-frame-options with options “Any” or “Allow-from”:
Refused to display 'https://jmap7.jmaponline.net/montreal_web/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
To have the application code ready you will need to add the following lines in the <head> portion of the document where you wish to embed your deployment.
*Note that the code in /jmap is available without login because it is allowed in the bypass filter of your deployment.
<!-- Add this if you use google maps features in your deployment --> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.36&key=YOURGOOGLEMAPKEY"></script> <link rel="stylesheet" href="[YourDeploymentAdress]/jmap/css/jmap.min.css"> <script type="text/JavaScript" src="[YourDeploymentAdress]/jmap/jmap.min.js"></script>
You might need to adjust the relative path mentioned above.•Including JQuery is not necessary if you already use it. JMap Web requires a minimum version of 2.2.4 to assure most functionalities
Be aware that this will replace your JQuery librairy, if you need to keep a specific version, consider using an iframe instead.
To initialize the map, you will need to provide an empty div into which the map will be created.
Note the JMap Web tool bar takes a static height of 45 pixels.
Include the following Javascript to trigger map initialization without Authorization.
The JMap.initialize function that is called above is the same as the one that was detailed previously here. You may customize the embedded application by specifying those same configuration properties in a mapConfig object literal supplied in the options argument.
If you enabled controlled access on your JMap Web deployment, you will need to authenticate as a JMap User prior to initializing the map.
The following is provided as an example and IS NOT a recommended way of authenticating yourself to JMap Server:
If your map is located within the div of a page that is hosted on a different Origin that of your JMap Server, you will need to modify the Cors filter options of your web.xml file.
Check the Tomcat documentation here
Instantiate and map the CORS filter, start by activating the Cross-Origin Ressource Sharing option in the Advanced Options of the Deployment’s Wizard and skip to the end.
Open the web.xml and look for the CorsFilter settings.
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,Cookie</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Example for a map embedded without Authorization requirements, needs to allow anonymous login.
<filter>
<filter-name>JMapLoginFilter_index</filter-name>
<!-- ... -->
<init-param>
<param-name>httpauthentication</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<!-- ... -->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,Origin,Cookie</param-value>
</init-param>
<init-param> <param-name>cors.exposed.headers</param-name>
<param-value>sessionId</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Example for a map embedded with Authorization requirement
Note that the wildcard (*) mark is not allowed in the origins list when you require authentication with Access-Control-Request-Headers, and credientials support must be set to true.
<filter>
<filter-name>JMapLoginFilter_index</filter-name>
<!-- ... -->
<init-param>
<param-name>httpauthentication</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- ... -->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://192.168.0.37:8081,https://www.google.com</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Authorization,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,x-auth-token,Cookie</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials,sessionId</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
In addition to executing code in the user’s browser, a JMap Web extension may define actions that can leverage JMap Server’s API. These actions will be registered against your deployment’s AJAX Dispatcher service and may be triggered via HTTP requests.
A JMap Web extension can contain several actions. You also may create additional non-action classes that will be referenced within your actions.
Create a class that inherits from AbstractHttpRequestAction. To follow along this example, the name of your class should be MyFirstAction.
package myextension;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jmap.http.ajax.servlets.AbstractHttpRequestAction;
public class MyFirstAction
extends AbstractHttpRequestAction
{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException
{
}
}
As you may have noticed, the action requires the HttpServletRequest and HttpServletResponse classes in order to compile. Add Tomcat server’s servlet-api JAR to your build path. That particular JAR file may be found within the $JMAP_HOME
$/tomcat/lib directory.
An action requires an execute
method. That method will be called whenever an HTTP request specifically requesting your action is received by the AJAX Dispatcher.
For the purposes of this example, the following is a typical Hello World! action.
package myextension;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jmap.http.ajax.servlets.AbstractHttpRequestAction;
public class MyFirstAction extends AbstractHttpRequestAction
{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response)
throws IOException
{
final PrintWriter writer = response.getWriter();
String name = request.getParameter("name");
if (name != null && name.trim() != "")
writer.print("Hello, " + name);
else
throw new IllegalArgumentException("Invalid argument. Must specify anameparameter.");
}
}
In order to be included as part of a JMap Web extension, your server-side Java code must be compiled and packaged as a single JAR file.
Copy your MyFirstAction.java file to your extension’s actions/src directory. Since the MyFirstAction class is defined within the myextension package, create a myextension directory under actions/src and put your MyFirstAction.java file in it. At this point, you should have the following items in your actions directory:
actions/
├── build.xml
├── readme.markdown
└── src
├── Example
└── SampleAction.java
└── myextension
└── MyFirstAction.java
3 directories, 4 files
Using the command line/terminal navigate to your extension’s actions directory and execute the following command.
ant -f build.xml
Once you have your JAR file, make sure it’s in your web extension’s actions directory.
As was the case when using the web extension builder tool, you may use Ant through Eclipse to produce your extension’s server jar file. This requires that a JDK is set as Eclipse’s default JRE and that the JDK’s tools.jar file is added to the Ant runtime configuration’s classpath. These steps were previously detailed here.
Open the your extension’s actions/build.xml file in Eclipse.
Execute the “package” ant target.
Once you have your JAR file, make sure it’s in your web extension’s actions directory.
As part of your extension, the extension.json file informs JMap Server about itself. You must now indicate that the extension contains actions. Open that file in a text editor.
The actions property is an array that can contain several object literals each describing individual actions.
The actions array’s object literals must have the following property keys:
This snippet is how you would represent the MyFirstAction action as part of the web_sdk_documentation_example extension that was created earlier:
{
"actions": [
{
"name": "hello",
"className": "myextension.MyFirstAction",
"version": "1.0.0"
}
],
"fullname": "Web SDK Documentation Example",
"namespace": "Example",
"shortname": "web_sdk_documentation_example",
"version": "1.0"
}
Your extension may include as many actions as you want. Just be sure to include them within your extension’s extension.json file.
As previously mentioned, your action’s execute method will be called once the AJAX Dispatcher receives an HTTP request that specifies your action’s name as a parameter.
$.ajax(JMap.app.ajaxDispatcher,{
data: {
"action": "hello", // The action name as defined in the extension.json file.
"name": "Developer" // The name parameter as expected by the action.
}
}).error(function(jqXHR, textStatus, errorThrown) {
alert(textStatus);
}).success(function(data, textStatus, jqXHR) {
alert(data);
});
This section details how to develop for JMap Web as well as how to integrate JMap Web into other web applications.
JMap Web is a web application that uses technologies such as HTML5, JavaScript, CSS and JSON. The JMap Web application is built on top of third-party JavaScript libraries including OpenLayers, jQuery and many others.
JMap Web provides a web application capable of interacting with JMap Server. Its user interface is primarily intended for use on laptop and desktop web browsers.
The key elements of a deployed JMap Web application are the following:
The client: Can be described as a (index.jsp). The client is considered the web page as it is rendered in the user’s web browser.
A : Provides access to the map’s tiles.
The AJAX Dispatcher: A web service to which HTTP requests are sent. The AJAX Dispatcher then dispatches the request to the appropriate “Action Handler”. This will be further discussed in the section of this document.
At the time of writing this document, JMap Web currently uses the following third-party Javascript libraries. Your extensions may leverage these libraries without any additional configuration. The following table includes a brief description of how JMap Web uses these libraries.
A JMap Javascript library essentially consists of a collection of Javascript files, styles sheets (CSS) and resources (images, sounds, etc.).
JMap Javascript libraries have been designed for use in different application templates of the “JMap Web” deployment type. By spreading the code across several libraries, code reuse is possible in various environments such as JMap Web. JMap Javascript libraries define unique behavior for specific contexts.
JMap Web uses the following JMap Javascript libraries:
core
desktop_ui
Reusable model classes are usually defined in the core library. As such, it is frequently used and is included in the vast majority of “JMap Web” application templates.
As for desktop_ui, it mostly contains classes that focus on user interface elements. It directly makes use of the DataTables, jQuery and Twitter Bootstrap Javascript libraries. All visual elements that are not managed by OpenLayers are defined within desktop_ui.
Included in JMap 7 is JMap Web’s public API which allows developers to easily integrate with JMap functionalities.
Before moving onto the creation of a JMap Web extension, this section will explain JMap Web’s initialization process.
The JMap Web application template’s files are located in $JMAP_HOME$
/applications/templates/html/web/index.jsp
This is the web document that will be served by JMap Server as the application is being requested by the user. Open this file in a text editor application. As you can notice, both jQuery and a jmap.min.js are loaded in the head portion of the document.
Further down, the map is initialized once the document is ready for manipulation.
var options = {
url: '$APPLICATION_PROTOCOL$://$APPLICATION_HOST$:$APPLICATION_WEBPORT$$PATH$',
language: '$LANGUAGE_CODE$',
embedded: true,
mapConfig: {
// Configuration properties
},
onMapInit: function() {
console.log('Map was initialized.');
}
};
$(document).ready(function() {
JMap.initialize(document.getElementById('map'), options);
});
The JMap.initialize function is defined in the jmap.min.js file. It loads all necessary dependencies and will then initialize all of the application’s required objects. Among those objects are the globally available JMap.app and JMap.app.map.
The mapConfig object may include the following properties to customize the application. The default value is identified in bold.
Once the map is successfully initialized, you may access it via Javascript by using the JMap.app global variable.
JMap Web supports the following query string parameters:
sessionId {Integer}
Makes the JMapWeb session log into an existing session and take its authentication values.
autozoom {String}
Zooms on a specified area or object on the initial view of a map. Two types of autoZooms can be used, region or object, the type is determined by the first argument: ‘type’.
In order to deploy an extension with your JMap Web deployment, you must first install the extension on your JMap Server. You install a JMap Web extension by copying its parent directory (named after the extension’s shortname) to the $JMAP_HOME$/
extensions/web directory.
As part of the JMap Web application deployment process, you should now see a list of Web extensions you may wish to include. Choose your newly created “Web SDK Documentation Example” and complete the wizard.
The JMap Web application template offers many actions to facilitate JMap Server interactions. This section will present some of them and how you can use them.
Note: The majority of actions require map state information as parameters. For the most part, these can be obtained using .
All examples in this section refer to a deployment based on the The World project. The deployment covers the project’s complete extent and includes the following layers: “Base” and “Cities”. Refer yourself to the following screen shots in order to create a similar deployment.
The extractelements action provides a list of a JMap layer’s elements.
The geometry request will extract elements that intersect or are contained within a supplied geometry.
The following is the list of parameters that can be provided to the extractelements action.
Performs an element extraction request for the “Cities” layer around the Scotland area.
$.ajax(JMap.app.ajaxDispatcher, {data: {
'action': 'extractelements',
'request': 'geometry',
'geometry': 'POLYGON((-6.378882 54.903806,-1.336158 54.903806,-1.336158 59.540037,-6.378882 59.540037,-6.378882 54.903806))',
'res': JMap.app.map.getResolution(),
'bbox': JMap.app.map.getExtent().toBBOX(),
'layers': 'Cities'
}}).success(function(data, textStatus, jqXHR) {
console.log(data);
});
{
"layerId": 7,
"elementAttributes": [
{
"sqlType": 12,
"name": "CITY"
},
{
"sqlType": 12,
"name": "COUNTRY"
},
{
"sqlType": 12,
"name": "CAP"
},
{
"sqlType": 4,
"name": "POP2000"
}
],
"elements": [
{ "centeredPoint": {
"x": -1.3899999735879476,
"y": 54.910001831054686
},
"bounds": {
"x": -1.3899999735879476,
"width": 0,
"y": 54.910001831054686,
"height": 0
},
"attributeValues": [
"Sunderland",
"UK - England and Wales",
"0",
181100
],
"geometry": "POINT(-1.3899999735879476 54.910001831054686)",
"id": 622
},
{
"centeredPoint": {
"x": -4.2699998496102864,
"y": 55.87000091552734
},
"bounds": {
"x": -4.2699998496102864,
"width": 0,
"y": 55.87000091552734,
"height": 0
},
"attributeValues": [
"Glasgow",
"Scotland",
"0",
610700
],
"geometry": "POINT(-4.2699998496102864 55.87000091552734)",
"id": 624
},
{
"centeredPoint": {
"x": -3.2200001357125814,
"y": 55.949998931884764
},
"bounds": {
"x": -3.2200001357125814,
"width": 0,
"y": 55.949998931884764,
"height": 0
},
"attributeValues": [
"Edinburgh",
"UK - England and Wales",
"0",
382600
],
"geometry": "POINT(-3.2200001357125814 55.949998931884764)",
"id": 625
},
{
"centeredPoint": {
"x": -2.9999998686837728,
"y": 56.469999389648436
},
"bounds": {
"x": -2.9999998686837728,
"width": 0,
"y": 56.469999389648436,
"height": 0
},
"attributeValues": [
"Dundee",
"Scotland",
"0",
148900
],
"geometry": "POINT(-2.9999998686837728 56.469999389648436)",
"id": 627
},
{
"centeredPoint": {
"x": -2.1000000117349202,
"y": 57.14999969482422
},
"bounds": {
"x": -2.1000000117349202,
"width": 0,
"y": 57.14999969482422,
"height": 0
},
"attributeValues": [
"Aberdeen",
"Scotland",
"0",
188500
],
"geometry": "POINT(-2.1000000117349202 57.14999969482422)",
"id": 628
},
{
"centeredPoint": {
"x": -1.6000000117349202,
"y": 54.99999816894531
},
"bounds": {
"x": -1.6000000117349202,
"width": 0,
"y": 54.99999816894531,
"height": 0
},
"attributeValues": [
"Newcastle upon Tyne",
"UK - England and Wales",
"0",
980000
],
"geometry": "POINT(-1.6000000117349202 54.99999816894531)",
"id": 1899
}
]
}
The layerinfo action provides details regarding layers of the deployment’s associated project.
The geteditablelayers request will return layer various layer details on which the currently authenticated user may perform data editing tasks.
This action does not require any parameters. Instead, it uses the current session information to perform this operation.
$.ajax(JMap.app.ajaxDispatcher, {
data: {
'action': 'layerinfo',
'request': 'geteditablelayers'
}
}).success(function(data, textStatus, jqXHR) {
console.log(data);
});
The server response exposes an array of editableLayers object literals. Each of the array’s objects contains the following keys:
forms are returned as an array of object literals. They have the following structure:
This is an example of a geteditablelayers response. You may have different results. In any case, they should reflect the state of your configured permissions and forms.
{
"editableLayers": [
{
"offset": {
"x": 9.5367431640625e-7,
"y": -3.186320304870577 },
"permissions": 0,
"id": 4,
"fields": [
{
"name": "COUNTRY",
"serverDataType": 12
},
{
"name": "CONTINENT",
"serverDataType": 12
},
{
"name": "POP_1994",
"serverDataType": 8
},
{
"name": "POP_GRW_RT",
"serverDataType": 8
},
{
"name": "POP_0_14",
"serverDataType": 8
},
{
"name": "POP_15_64",
"serverDataType": 8
},
{
"name": "POP_65PLUS",
"serverDataType": 8
},
{
"name": "POP_AREA",
"serverDataType": 8
}
],
"idFieldName": "JMAP_ID",
"forms": []
},
{
"offset": {
"x": 0.56195068359375,
"y": 13.687942504882812
},
"permissions": 0,
"id": 6,
"fields": [
{
"name": "LAKE_NAME",
"serverDataType": 12
},
{
"name": "VOLUME_CKM",
"serverDataType": 8
},
{
"name": "AREA_SKM",
"serverDataType": 8
}
],
"idFieldName": "JMAP_ID",
"forms": []
},
{
"offset": {
"x": 20.934576233500025,
"y": 10.050437668683657
},
"permissions": 0,
"id": 5,
"fields": [],
"idFieldName": "JMAP_ID",
"forms": []
},
{
"offset": {
"x": 16.215000694478334,
"y": 16.463705277985326
},
"permissions": 0,
"id": 3,
"fields": [
{
"name": "HYD_NAME", "
serverDataType": 12
},
{
"name": "LENGTH_KM",
"serverDataType": 4
}
],
"idFieldName": "JMAP_ID",
"forms": []
},
{
"offset": {
"x": 31.452202349999993,
"y": -14.421794805000005
},
"permissions": 0,
"id": 2,
"fields": [
{
"name": "CONTINENTNAME",
"serverDataType": 12
}
],
"idFieldName": "JMAP_ID",
"forms": []
},
{
"offset": {
"x": 1.6169597031546061,
"y": 8.079999999999998
},
"permissions": 15,
"id": 7,
"fields": [
{
"name": "CITY",
"serverDataType": 12
},
{
"name": "COUNTRY",
"serverDataType": 12
},
{
"name": "CAP",
"serverDataType": 12
},
{
"name": "POP2000",
"serverDataType": 4
}
],
"idFieldName": "JMAP_ID",
"forms": [
{
"permissions": 0,
"name": "Form",
"json": "{\"formSections\":[{\"name\":\"Section 1\",\"nbRows\":3,\"fields\":[{\"$ATTRIBUTE_NAME\":\"CITY\",\"$ROW\":0,\"$MASKFORMATTER\":\"\",\"$COL\":0,\"$INPUT_TYPE\":\"$INPUT\",\"$MULTILINE\":false,\"$PREFIX\":\"CITY\",\"$ALIGNMENT\":\"LEFT\",\"$REQUIRED\":true,\"$MAX_NUMBER_CHARACTERS\":255,\"$COLSPAN\":1,\"$WIDTH\":100,\"$TOOLTIP\":\"\",\"$ATTRIBUTE_SQL_TYPE\":12,\"$READ_ONLY\":false}]}",
"id": 1,
"type": "LAYER_ATTRIBUTES_FORM",
"uidAttributeName": null
}
]
}
]}
The loadformdata action provides external form data for a requested layer element.
loadformdata expects the following parameter:
This example refers to another project for which external forms were configured.
var data = { elementId: 6, formId: 2, layerId: 1,
listFields: [],
"mapValues": {
"MOBILE_JMAP_ID": 6,
"MOBILE_JMAP_GEOMETRY": "POINT(-8189010.0 5701129.5)",
"AUTHOR": "jrhaddad",
"CREATION_TIME": 1415767972000,
"MODIFICATION_TIME": 1418400517000,
"ABR_CODE": "342",
"ABR_NAME": "ES34F",
"ABR_LOC_TYPE": "Arrêt bus",
"ABR_WHEEL_CHAIR": "Non accessible",
"ABR_DATE_INSP": null,
"ABR_STATUS": null
}
};
$.ajax(JMap.app.ajaxDispatcher, {data: {
'action': 'loadformdata',
'data': JSON.stringify(data)
}}).success(function(data, textStatus, jqXHR) {
console.log(data);
});
The server responds by providing a two dimensional rows array of Javascript object literals representing field values. Each item in the rows array represents a row of data. Multiple rows are returned when obtaining data that was entered using a EXTERNAL_ATTRIBUTES_SUB_FORM type form.
{
"rows": [
[
{
"name": "insp_abribus.id_inspection",
"value": 5,
"type": 4
},
{
"name": "insp_abribus.id_abribus",
"value": 6,
"type": 4
},
{
"name": "insp_abribus.date_inspection",
"value": 1415854800000,
"type": 93
},
{
"name": "insp_abribus.etat",
"value": "Bon état",
"type": 12
},
{
"name": "insp_abribus.observations",
"value": "Tout est ok",
"type": 12
}
]
]
}
When using JMap 6.0 SDK’s webextensionbuilder tool (described in the Programming JMap Web Extensions section) to produce an extension’s boilerplate code, a SampleAction is provided as a starting point. A build.xml file is also provided. You can use that file with to compile and produce your extension’s JAR file.
After editing the extension.json file, be sure that it contains valid JSON. is an online JSON validator that can be used for that purpose.
The following example demonstrates how you can submit an HTTP Request to your action using . To test this, you can either include this snippet in your extension’s init function or copy and paste it in a browser’s Javascript console currently logging your deployed application.
In addition to the libraries previously mentioned, JMap Web also includes its own libraries based on . This allows JMap Web to benefit from object oriented programming paradigms in a Javascript context (which usually favors a more prototypal and functionnal approach).
The core library is written in . In addition to JMap model classes, it includes custom OpenLayers controls and layers, HTML5 functionality wrappers and more. The core library is JMap Web lowest level Javascript library. It handles general tasks such as the initialization process of the map. All other library is then loaded on top of it as an extension.
A generated documentation of the javascript API is available online at .
This section refers to the JMap Web application template as it is included when JMap Server is installed. The process, as briefly described here, differs when you choose to embed a JMap deployment within your existing web application. For more details, consult the section of this document.
The JMap.app object is an instance of the core library’s Application class. The JMap.app.map object is an instance of the class.
Map manipulation is possible by accessing the JMap.app.map global variable. This variable is the instance of in use and you can interact with it by using the .
Each element’s ID, geometry (supplied as a formatted string), attribute values, bounds and centered point are returned. The layer’s bound attributes are also included as well as their . An element’s attributes’s index corresponds to the layer’s attributes as configured in JMap Admin. If elements from many layers match the request parameters, an array of these object literals will be returned.
The name of the form field, its value and the data’s are returned.
name | {String} This is the name of the action as it will be registered against the AJAX Dispatcher. Must be unique within a single JMap Web deployment. HTTP requests must specify this value for the action request parameter. Does not need to correspond to your action’s class’s source file name. |
classname | {String} The fully qualified name of your class. Must include packages. |
version | {String} Specifies a version. Mostly useful for debugging purposes. |
Argument | Description |
map | Required {DOMElement|String} The element or id of an existing element in your page that will contain the map. |
options | Required {Object} Should at least provide a jmapUrl {String} property. Supports the following property keys:
• url: Required. {String} The url of your JMap deployment.
• language: {String} Set a language between French (fr), Spanish (es) or English (en), the default choice is English
• mapConfig: {Object} Additional map configuration options.
• embedded: {true} Makes some JMap Web components behave better visually.
• onMapInit: {Function} Handler to be called once the map initialisation process is completed. Useful to add new |
mapConfig properties | Description |
Map Options |
|
displayUnits | null | ’m’ | ’km’ | ’ft’ | ’mi’ | ’in’ | ’°’ {String} The map unit. Defaults to the JMap project’s value. |
initialZoom | null {Array} Map coordinates that describe bounds: [left, bottom, right, top] |
mapUnits | null | ’m’ | ’km’ | ’ft’ | ’mi’ | ’in’ | ’°’ {String} The map unit. Defaults to the JMap project’s value. |
maximumExtent | null {Array} Map coordinates that describe bounds: [left, bottom, right, top] |
projection | null {Object} If supplied, it must contain a string code property that corresponds to an EPSG code |
Additional Map Layers |
|
addShowPositionLayer | true | false |
Services on Launch |
|
activateGeolocationServiceOnLaunch | true | false |
loadGoogleMapsApiOnLaunch | true | false - Will automatically be set to true if the deployment contains at least one Google layer or if any of the following is true: addGoogleDirections, addGoogleGeocoding, addGoogleStreetView. |
Map and Navigation Options |
|
addGeolocateButton | true | false |
addCoordinateZoomButton | true | false |
addInitialViewButton | true | false |
addRewindViewButton | true | false |
addMapOverview | true | false |
isMapOverviewMaximized | true | false |
addMousePosition | true | false |
addScaleBar | true | false |
addZoomButtons | true | false |
JMap Tools |
|
addInfoReportTool | true | false |
addMeasureTools | true | false |
addMeasureAreaTool | true | false |
addMeasureDistanceTool | true | false |
addMeasureCircularAreaTool | true | false |
addMouseOverTool | true | false |
addAnnotations | true | false |
JMap Edition Functionalities |
|
addEditionTools | true | false |
addEditionCreateElementTool | true | false - The addEditionTools property must also be set to true for this to take effect. |
addEditionModifyElementTool | true | false - The addEditionTools property must also be set to true for this to take effect. |
addEditionShowElementFormButton | true | false - The addEditionTools property must also be set to true for this to take effect. |
JMap Selection Functionalities |
|
addSelectionTools | true | false - The addSelectionTools property must also be set to true for this to take effect. |
addCircleSelectionTool | true | false - The addSelectionTools property must also be set to true for this to take effect. |
addLineSelectionTool | true | false - The addSelectionTools property must also be set to true for this to take effect. |
addPointSelectionTool | true | false - The addSelectionTools property must also be set to true for this to take effect. |
addRectangleSelectionTool | true | false - The addSelectionTools property must also be set to true for this to take effect. |
addShapeSelectionTool | true | false - The addSelectionTools property must also be set to true for this to take effect. |
Other Functionalities |
|
addFullScreenButton | true | false |
addLayersMainMenuItem | true | false |
addContextManager | true | false |
addContextManagerMenuItem | true | false |
isTabMenuFixedOnStart | true | false |
addLogo | true | false |
addMessageInfo | true | false |
addPrintButton | true | false |
addSearchMainMenuItem | true | false |
addSharingTools | true | false |
addSharingToolsSocialOptions | true | false |
addLogoutAsideMenuLink | true | false |
displayLogoutOption | true | false |
addPreferenceMenu | true | false |
continousZoom | true | false |
Third Party Functionalities |
|
addGoogleDirections | true | false |
addGoogleGeocoding | true | false |
addGoogleStreetView | true | false |
AutoZoom Types | Description |
Region | The user specifies the viewing area by specifying a rectangle… Syntax: “type;x;y;width;height” • type: {String} The type of this request. In this case, must be “region”. • x: {Number} The X value of the lower left coordinate of the rectangle. • y: {Number} The Y value of the lower left coordinate of the rectangle. • width: {Number} Width of the rectangle. • height: {Number} Height of the rectangle. Example: ?autozoom=region;9;39;20;20 |
Object | The user specifies an object to zoom to… Syntax: “type;layerName;field;value;maxScale” • type: {String} The type of this request. In this case, must be “object”. • layerName: {String} The name of the layer which contains the object to zoom to. • field: {String} The field that contains the value of the object to zoom to. • value: {Number | String} The specified value of the object to zoom to. If the field is a string, use ‘’. See example below. • maxScale: {Number, optional} The maximum scale the map should respect when displaying results. Number value example: ?autozoom=object;citiesLayer;city_id;1032 String value example: ?autozoom=object;citiesLayer;city_name;’montreal’;15 |
id | {Number} The form’s unique ID. |
json | {String} A JSON representation of the form’s configuration. |
name | {String} The form’s name as defined in JMap Admin. |
permissions | {Number} An integer between 0 and 7 (inclusive) that describes the current user’s permissions towards the form. A form’s permissions only concerns external forms. Layer attributes forms’s permissions are defined as part of the layer permissions. • 0x000: None. • 0x001: May add data in external forms. • 0x010: May edit data in external forms. • 0x100: May delete data from external forms. |
type | {String} Identifies the form type. One of the following: • LAYER_ATTRIBUTES_FORM • LAYER_ATTRIBUTES_SUB_FORM • EXTERNAL_ATTRIBUTES_FORM • EXTERNAL_ATTRIBUTES_SUB_FORM |
uidAttributeName | {String} Only concerns external forms. Is the name of the layer’s attribute that will be used as a foreign key to establish child-parent relationships. |
data | {String} required JSON String that represents a Javascript object literal composed of the following properties: • elementId: {Number} The element (for which data is requested)’s unique ID. • formId: {Number} The external form’s ID. • layerId: {Number} The layer (on which the element exists/the form is configured)’s ID. • listFields: {Array[Strings]} A list of form fields for which you want values. An empty array will return data for all fields. • mapValues: Javascript object literal that contains the element’s layer’s layer attributes form’s fields values. |
Bibliothèque | Description |
jQuery plugin that easily enables the creation of powerful HTML tables for data representation. This is primarily used to display search results. |
Displays content in a “lightbox” style interface. JMap Web uses fancyBox to display the full size version of documents included in mouseover popups. |
Necessary to access Google Maps’s Roadmap, Terrain, Satellite and Hybrid base layers. |
jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. |
Library of user interface components relying on the jQuery framework. Currently, JMap Web uses a custom build that includes only the autocomplete component. |
Library used to parse, validate, manipulate, and display dates in JavaScript. |
Styles the appearance of scroll bars for overflowing mouseover popups. Its primary function is to allow a more consistent appearance in various browsers. |
This is JMap Web’s most important library. OpenLayers allows JMap Web to display a map and manage the vast majority the user’s interaction with it. |
Proj4js is a library that’s used to translate geographic coordinates from one map projection system to another. Proj4js is used by OpenLayers, but isn’t included with it.In order to perform transformations for named projections (ex: “EPSG:3857”), projections must be defined in Proj4js. By default, only a small number of projections are defined. JMap Web includes a Proj4js projection definition file for each projection that’s supported by JMap Server. Those projection definitions will be loaded into memory as they are required. |
«Front-end framework» used to create user interface elements |
“Paper” theme for Bootstrap |
Date/time picker widget based on Twitter Bootstrap. |
JQuery multiselect plugin based on Twitter Bootstrap. |
request | {String} “geometry” requiredThis string identifies the type of request that’s being issued to the action. Other types of requests may be added to this action in the future. |
geometry |
res | {Number} required The map’s current resolution. |
bbox | {String} requiredThe map’s current extent as it’s displayed in the browser at the time of the request. Specified in a bounding box format (example: “-100,-50,100,50”). |
drill | {Boolean} default: false Indicates whether or not you wish to continue analyzing the layer stack once the first match is found. |
layers | {String} requiredSpecifies for which layer(s) you want to perform the element extraction.Many layers may be requested at once. In that case, you should separate the elements of your layer list using commas. Use the drill parameter accordingly in order to obtain elements across multiple layers. |
fields |
forms | {Array} The layer’s configured forms. |
id | {Number} The layer’s ID. |
idFieldName | {String} The name of the layer attribute that serves as an identifier. |
offset | {Object} An object literal that contains the layer’s current offset. |
permissions | {Number} An integer between 0 and 15 (inclusive) that describes the current user’s permissions towards the layer. The following bit masks signify different permissions. • 0x0000: None. • 0x0001: May add layer elements. • 0x0010: May edit layer elements. • 0x0100: May delete layer elements. • 0x1000: May edit layer elements’s attributes. |
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.
(v1.10.13)
(v2.1.5)
(v3)
(v2.2.4)
(v1.12.1)
(v2.18.1)
(v3.1.5)
(v4.1.1)
(0.14.0)
This library powered by facilitates the use of Google Maps in OpenLayers 3.
(v2.4.3)
(3.3.7)
(3.3.7)
(v4.15.35)
(v0.9.13)
{String} requiredA string defining the region for which to execute the element extraction process.
{Array} Array of object literals exposing the name bound layer fields as well as their .
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.