Overview
Logger is an ol-ishare map that enables users to locate, and add a spatial reference to, their own information. This specialised map interface can be embedded within a CRM or other web application and requires two things: an iShare map profile and some Javascript knowledge.
Examples of its use include:
- Reporting on faulty assets (e.g. street lights; bins; park benches)
- Reporting potholes or issues related to public highways
- Reporting incidents of fly-tipping
- Reporting incidents of anti-social behaviour (e.g. graffiti; noise etc)
- Inviting comment on public consultations
Configuration of all layer data, background maps, and address gazetteers is done in iShare Studio in exactly the same way as for other maps - if appropriate, Logger can use a profile created for another purpose, without modification.
Logger uses map layers in three different ways, they are:
- target layers: these are used to determine where reports can be made on the map. If configured, a report will require a selection from one of the target layers, usually of point data (e.g. asset locations) or polygon data (e.g. constraining potholes to roads). If no target layers are configured then reports can be made anywhere on the map.
- context layers: context layers allow useful additional data to be added to a Logger report. Feature data from these layers that intersects with the selection from a target layer (or the chosen location when no target layer configured) will be included in a report.
- map layers: ordinary layers can be added to the map as with any other ol-ishare map. These do not get included in a report but might be useful to display to users, e.g. to highlight local landmarks. Any duplication with target or context layers will be ignored.
The report created by Logger is passed back to the embedding web application so that it can then submit the data, along with any other information entered by the user, into the relevant case management system. Reports can also be submitted into iShare for display on the map as ‘known incidents’.
Getting started
The following example shows how to create a Logger map for reporting on street lights.
Setup
Start with a HTML file which includes the required CSS and JavaScript, defines some basic styling and a map
element that will contain the map.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Logger map for reporting on street lights</title>
<meta
name="viewport"
content="initial-scale=1.0, user-scalable=no, width=device-width"
/>
<link rel="icon" href="data:;base64,iVBORw0KGgo=" />
<link
rel="stylesheet"
href="https://ol-ishare.services.astuntechnology.com/v1/apps/logger/logger.css"
/>
<style type="text/css">
html,
body {
height: 100%;
padding: 0;
margin: 0;
font-family: sans-serif;
font-size: small;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://ol-ishare.services.astuntechnology.com/v1/apps/logger/logger.js"></script>
<script>
// Logger code here...
</script>
</body>
</html>
CSS and JavaScript
The Logger CSS and JavaScript included in the page are bundles and include all dependencies such as OpenLayers.
CSS
The file logger.css
includes all styles required to display a Logger map with default styles for controls, etc. — you can override these styles in your own CSS included after logger.css
in the page.
<link
rel="stylesheet"
href="https://ol-ishare.services.astuntechnology.com/v1/apps/logger/logger.css"
/>
JavaScript
The file logger.js
exposes a single global variable oli
(short for ol-ishare) which exposes the ol-ishare JavaScript API. The constructor for the Logger map we will use shortly is available at oli.logger.LoggerMap
.
The fact that the logger.js bundles its dependencies means embedding a Logger map is a matter of including a single JS reference. However, it does also mean that the API is limited to that of Logger itself - the OpenLayers API isn't exposed. Should you require access to OpenLayers then you've two options:
- Use the ol-ishare UMD build which doesn't bundle its dependencies and hence requires
ol
to be available globally. - Use the ol-ishare ESM modules with the
ol
package to build your own application using Webpack, Rollup or similar build tools.
Create a LoggerMap
To create a LoggerMap
in the #map
element replace the empty <script>
element in your html page:
<script>
// Logger code here...
</script>
with the following JavaScript code:
<script>
var logger = new oli.logger.LoggerMap(
// LiteMap options
{
target: 'map',
iShareUrl: 'https://maps.demo.astuntechnology.com/',
profile: 'mapsources/ol-ishare',
layers: [],
view: {
easting: 500000,
northing: 150000,
zoom: 2000
}
},
// LoggerMap options
{
reportOn: [{ layer: 'Street_lights', idField: 'fid' }],
contextLayers: ['roadstrackspaths']
}
);
</script>
The above code creates a new LoggerMap
instance; the first object defines standard ol-ishare LiteMap options
which include:
target
- theid
of an element on the page in which the map will be creatediShareUrl
- the iShare Maps server to load data from (in this case the Astun Technology demo server)profile
- the iShare profile (also known as a MapSource) to load; the profile determines the available layerslayers
- the names of any layers to displayview
- the initial view of the map in the same coordinate system and units as the profile, in this case British National Grid in meters
ⓘ See the LiteMap options
documentation for full details of the available options.
The second object defines Logger options
:
reportOn
- a list of target layers present in the profile that a users can make a selection from; each layer is represented as an object with two properties:layer
, its name; andidField
, the column containing a unique ID (used to identify a given feature, e.g. an asset number). In this instance we are reporting on theStreet_lights
layer, specifying thefid
column.contextLayers
- (optional) names of layers from which to include details in a Report. Layers set here that are not already listed inmapOptions
will be added to the map.
ⓘ See the Logger options
documentation for full details.
At this point you should be able to open your html page in a browser and see a map showing street light features.
Logger events
A LoggerMap instance dispatches events for key interactions such as the user selecting a feature from a target layer. The LoggerMap class extends ol/Observable~Observable
which provides methods such as on
and un
to subscribe and unsubscribe to events of a given type
on an instance.
report
event
When a user clicks on a street light in the map, Logger will emit a report
event with an object containing all the selected map data.
To handle the report
event add the following inside the <script>
element directly below the JavaScript that creates the LoggerMap
.
// Event handler for the Logger#report event
logger.on('report', function (evt) {
console.info('Logger#report (event)');
console.info(' - evt', evt);
});
The above code adds a report
event handler to the LoggerMap
instance (stored in the logger
variable) as the first argument of the on
method. The second argument is a function that in turn accepts an evt
argument which provides information about the event.
ⓘ To see this in action, open your html page in a browser, open the browser's devtools Console tab and click on a street light on the map to see the evt
object logged in the Console.
The report
evt
argument has a report
property which is an instance of Report
and has the following properties:
location
- x, y coordinates of the clickselection
- information about the selected target feature including it'suniqueId
value,layer
and the entirefeature
itself in GeoJSON format.context
- object with a key per layer name incontextLayers
each of which is a GeoJSON FeatureCollection containing any features that intersect the location.
ⓘ The information provided by the report
is commonly what is passed onto the parent web application (CRM, forms package etc.).
nothingSelected
event
If the user does not click on a street light, then Logger emits a nothingSelected
event in case the embedding application wants to show a reminder or warning to the user.
To handle the nothingSelected
event add the following inside the <script>
element directly below JavaScript that handles the report
event.
logger.on('nothingSelected', function (evt) {
console.info('Logger#nothingSelected (event)');
});
ⓘ To see this in action, click on the map at a location without a street light, this should trigger the event which will be logged in the devtools Console.
Handle multiple candidate selections
There will be times when the user clicks on a location which intersects multiple target features. In this case it's common to display a list of these candidate features to the user to allow them to select one to report on.
Logger allows for a number of functions to be set in LoggerMap options
that allow the reporting workflow to be customised.
The LoggerMap options
.selectAction
property should be set to a function that will be called whenever multiple candidates are found, in order to determine which of them (if any) should be reported on.
To configure selectAction
, update LoggerMap by replacing those currently specified.
The existing LoggerMap options:
// LoggerMap options
{
reportOn: [{ layer: 'Street_lights', idField: 'fid' }],
contextLayers: ['roadstrackspaths']
}
Should be replaced with the following which also sets the selectAction
property:
// LoggerMap options
{
reportOn: [{ layer: 'Street_lights', idField: 'fid' }],
contextLayers: ['roadstrackspaths'],
selectAction: selectAction
}
We then need to define the selectAction
function that will be called by Logger, so add the following below the nothingSelected
event handler code:
function selectAction(location, targetLayers, contextDetails, select, abandon) {
console.info('Logger#selectAction');
console.info('Logger#selectAction arguments:');
console.info(' - location:', location);
console.info(' - targetLayers:', targetLayers);
console.info(' - contextDetails:', contextDetails);
// Get a list of target layers that contain results
var targetResultLayers = targetLayers.filter(function (l) {
return l.selections && l.selections.length;
});
// Call `selected` with the first result in the first layer.
// In a real implementation you might display the candidates to the user
console.info(
'Returning the first selection from the following candidates:',
targetResultLayers
);
selected({ selection: targetResultLayers[0].selections[0] });
}
The selectAction
function is given information about the location, selections from the target layers, and features from context layers. The selectAction function docs
provide a full list of arguments including the select
function which should be called in selectAction
with the selection to report on.
ⓘ To see the selectAction
function in action, zoom out so that you can see a cluster of street lights; clicking on the cluster should result in Logger identifying multiple candidate selections from the target layer, resulting in our selectAction
function being called. This will log its arguments to the browser's devtools console before selecting the first candidate from the selections. In a real application the list of candidates would probably be displayed to the user.
Showing selections on the map
When a user selects a report or is choosing from a list of candidates it can be useful to zoom to the selections on the map and/ or highlight a given selection visually. The LoggerMap documentation
provides details of methods such as highlightSelection
, zoomToSelections
etc..
Storage of reports in iShare
(Optional)(Compatible only with iShare v5.8.22 and above.)
In case there is a requirement to track Logger reports within iShare itself, ol-ishare provides Logger ReportsManager
. Adding ReportsManager to an application requires no additional resources, but it is configured and used independently of LoggerMap
.
To create a ReportsManager
object to store reports from the above LoggerMap
example add the following:
var streetlightReports = new oli.logger.ReportsManager({
iShareUrl: 'https://maps.demo.astuntechnology.com/',
profile: 'mapsources/ol-ishare',
layerName: 'Street_lights'
});
Then update the handler for the 'report'
event to store reports:
// Event handler for the Logger#report event
logger.on('report', function (evt) {
console.info('Logger#report (event)');
console.info(' - evt', evt);
});
streetlightReports.add(evt.report);
};
Upgrades
Changes since beta.1
Action options
The selectAction
option has been changed: the select
callback must now return a single CompletedSelection
object
Context layer options
The reportContext
has been removed, and the behaviour of the contextLayers
option has changed.
Previously the reportContext
option had to be true
in order for reports to contain data from context layers which, if not specified in contextLayers
would be all non-target layers. This was considered confusing and has been removed in favour of always explicitly configuring each context layer.
Selection layer and object names
In the beta.1 version, target layers were referred to as asset layers, and Selection objects were called Asset objects. These have been renamed to better reflect the more general use to which they can be put. In addition, two function parameters have been retired as being considered superfluous.
The following LoggerMap configuration options have been changed as a consequence:
Old name | New name | Notes |
---|---|---|
autoAssetPicker | (none) | The selectAction function can be used instead |
assetPicker | selectAction | |
noAssetSelected | (none) | Add to, or create, a handler for the nothingSelected event |
Changes since iShare Logger
Logger in ol-ishare is a ground-up rewrite of the most used capabilites of the decade-old Logger module in iShare, using lessons learned through many implementations, as well as modern technologies and development processes. As such it is a total replacement for the old Logger and does not have an upgrade path available from it.
In order to move from the old Logger to the new some implementation time will therefore be required. The remainder of this section outlines the major changes that will be needed.
Configuration changes
The old Logger required specialized map profiles with distinct and inflexible layer configuration. All Logger layer configuration within iShare should be recreated in a standard iShare MapSource.
Setup
There is no overlap between the setup for the two versions of Logger; treat a Logger upgrade as a new setup (due to all new embedded resources and a different way of creating a Logger map object).
Events
Interaction between the Logger map and the application in which it has been embedded is carried out through events. The way this works has changed substantially; jQuery is no longer used to emit or listen for events and the events themselves have been reworked or removed.
'logger_caseupdated'
The 'logger_caseupdated'
event is the way that the old Logger would communicate that a selection had been made on the map through providing case
objects. This is replaced by the 'report'
event and Report
objects:
case properties |
Equivalent in report event |
---|---|
lonlat |
location property |
fields.assetid |
The exact equivalent is the selection.uniqueId property, but selection is a much more detailed and structured data object. |
fields.caseid |
This has no direct correspondence in new Logger. 'Cases' as a concept have been removed as they were part of a paradigm that was little used in most implementations, where iShare/Logger would be part of the reporting workflow and would communicate through back-end web services. |
fields.description |
Literally the description property, but this was often used to pass through additional information that is now available in the selection object and module:ol-ishare/logger.Context context. |
'logger_setlayer'
There is currently no equivalent to this event, which was used to trigger a change in the Logger layer in use on the map.
'mapMoved'
There is no longer a custom Logger map event for map move events. Instead use the similar OpenLayers event 'moveend'
(logger.map.on('moveend', function(evt){});
), this returns an event object containing a reference to the map (evt.map
) from which details such as the centre point can be derived.