Configuring the Cover Modeller Service
The windows service has no interface –all aspects of the service can however be edited or customised through the config file:
\Cover Modeller\Service\CoverModeller.config
The service reads all parameters from with the <configuration> node in the xml file.
CoverModeller.config is only read on start-up. To change the operation of a running service, the service should be restarted after any changes to the config file.
Here is an example config file. Click on any XML tag for more information:
<?xml version="1.0" encoding="utf-8" ?>
<configuration><liveViewFolder>c:\ProgramData\Cover Modeller\Live</liveViewFolder><scenarioViewFolder>c:\ProgramData\Cover Modeller\Scenario</scenarioViewFolder><swd>C:\Projects\OCX\SIS 9.0\DynamicCover\Test data\NottsWithHighways.swd</swd><outputAreasOverlay>1</outputAreasOverlay><ouputGeneralisationToleranceOnSwdOpen>10</ouputGeneralisationToleranceOnSwdOpen><outputGeneralisationToleranceOnOutput>50</outputGeneralisationToleranceOnOutput><applianceOverlay>2</applianceOverlay><applianceStatus Column="Status$"><value>Base</value>
<value>Available</value>
<value>On shift</value>
</applianceStatus><applianceId>Callsign$</applianceId><refreshSeconds>10</refreshSeconds><routingExpression>( _length# / CASE WHEN RoadClassification$ ='Unclassified' THEN 20
WHEN RoadClassification$ ='B Road' THEN 25
WHEN RoadClassification$ ='A Road' THEN 50
WHEN RoadClassification$ ='Motorway' THEN 60
WHEN RoadClassification$ ='Classified Unnumbered' THEN 20
WHEN RoadClassification$ ='Not Classified' THEN 20
WHEN RoadClassification$ ='Unknown' THEN 20 END )
* ( 60 / 1609.344)
</routingExpression><isoRouteSnapRadiusMetres>50</isoRouteSnapRadiusMetres><isoRoutes><value>5</value>
<!-- <value>7</value> -->
</isoRoutes><!-- isochrone method must be one of buffer, convex or isoroute --><isochrone Method="buffer"><bufferRadius>50</bufferRadius>
<bufferResolution>10</bufferResolution>
</isochrone><coincidentPointToleranceMetres>5.00</coincidentPointToleranceMetres><!-- verbosity should be normal, verbose or debug --><verbosity>normal</verbosity></configuration>
Two different output folders should be specified :
1. <liveViewFolder>
this is the folder into which the live view files are written:
-
Appliances.json
-
Coverage.json
-
Isochrones.json
2. <scenarioViewFolder>
-
Appliances.json is read by the service which will create the corresponding coverage and isochrones files:
-
Coverage.json
-
Isochrones.json
NOTE: If <scenarioViewFolder> is omitted from the config file, the service will not attempt to do any scenario operations.
<outputAreasOverlay>
must contain the index number of the overlay containing the output areas.
This overlay can be generalised to improve the speed of finding intersecting isochrones and to reduce the size of the output GeoJSON. Generalisation can be done in two places:
-
<outputGeneralisationToleranceOnSwdOpen>
contains the generalisation tolerance to be applied when the swd is loaded, i.e. prior to intersection calculation. -
<outputGeneralisationToleranceOnOutput>
contains the generalisation tolerance to be applied before export to GeoJSON, i.e. after the intersection calculation.
-
If either or both of these generalisations is not required, these nodes can be omitted (or assigned a tolerance value of 0.)
-
These generalisations are cumulative, i.e. if both are specified then the output generalisation is applied to the result of the input generalisation.
-
ouputGeneralisationToleranceOnSwdOpen is performed only once.
-
outputGeneralisationToleranceOnOutput has to be performed on every export.
<applianceOverlay>
must contain the index number of the overlay containing the appliances. Note that currently this is assumed to be a dynamic connection to a spatial table in a database. The appliance location is taken from the geometry object.
A range of values can be configured so that appliances are only considered if they have a relevant status value. These nodes are optional.
<applianceStatus Column="Status$">
<value>Base</value>
<value>Available</value>
<value>On shift</value>
</applianceStatus>
The column to inspect for a status value is specified through the Column attribute of the applianceStatus
node. This name must be the formula of the column in SIS Desktop.
In this example, appliances are only included in the calculation if Status$=”Base” or Status$=”Available” or Status$=”On shift”.
An appliance id or callsign can be configured with <applianceId>.
This name must be the formula of a column in SIS. If this is specified then this property will be included in the GeoJSON in GetAppliances().
The STA thread will attempt to perform the routing calculation at the frequency specified in <refreshSeconds>.
The routing calculation will initially perform a sis.CreateIsoRoute on each relevant appliance.
<coincidentPointToleranceMetres
> must contain a tolerance value. If an appliance location is within this tolerance of a point from which an existing isochrone was calculated then it will be treated as already calculated.
The following parameters are passed directly to sis.CreateIsoRoute:
<routingExpression>
must contain the routing expression. This must be appropriate to the topology which must be at least hittable in the swd.
<isoRouteSnapRadiusMetres>
must contain the value for the r argument to sis.CreateIsoRoute. Note, sis.CreateIsoRoute is called with a zero z value and so the r argument should be large enough to allow for z values in Highways data.
IsoRoutes will be calculated for each value defined on the <isoRoutes
> node. The example below will cause 5 and 7 minute isoroutes to be calculated.
<isoRoutes>
<value>5</value>
<value>7</value>
</isoRoutes>
‘Isochrones’ are created from the isoroutes. This is defined in the Method attribute on the isochrone node. There are three options:
FIELD | DESCRIPTION |
isoroute | use the isoroute as is (this leads to a very slow intersection calculation in calculating coverage) |
buffer | create a qzone buffer exactly as the Routing Tools add-in does |
convex | create a convex hull around the isoroute. |
In the case of “buffer”, the following parameters are passed through from the isochrone node to sis.CreateBufferFromItems: bufferRadius
and bufferResolution.
Running the Cover Modeller Service should populate the following files into the \Apps\CoverModeller\live\data folder:
- Appliances.json
- Coverge.json
- Isochrones.json
Shifts can be defined against each appliance to include a deployment time which might be affected by the type of shift. The process is similar to defining shifts in Cadcorp Workload Modeller
<shifts>
<shift Name="WholeTime">
<shift Name="Retained">
<element Day="Monday" Start="00:00:00" End="23:59:59" Mobilisation="4" />
<element Day="Tuesday" Start="00:00:00" End="23:59:59" Mobilisation="4" />
<element Day="Wednesday" Start="00:00:00" End="23:59:59" Mobilisation="4" />
<element Day="Thursday" Start="00:00:00" End="23:59:59" Mobilisation="4" />
<element Day="Friday" Start="00:00:00" End="23:59:59" Mobilisation="4" />
<element Day="Saturday" Start="00:00:00" End="23:59:59" Mobilisation="4" />
<element Day="Sunday" Start="00:00:00" End="23:59:59" Mobilisation="4" />
</shift>
<shift Name="DayShift">
<element Day="Monday" Start="00:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Monday" Start="08:00:00" End="17:59:59" Mobilisation="1.5" />
<element Day="Monday" Start="18:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Tuesday" Start="00:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Tuesday" Start="08:00:00" End="17:59:59" Mobilisation="1.5" />
<element Day="Tuesday" Start="18:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Wednesday" Start="00:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Wednesday" Start="08:00:00" End="17:59:59" Mobilisation="1.5" />
<element Day="Wednesday" Start="18:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Thursday" Start="00:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Thursday" Start="08:00:00" End="17:59:59" Mobilisation="1.5" />
<element Day="Thursday" Start="18:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Friday" Start="00:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Friday" Start="08:00:00" End="17:59:59" Mobilisation="1.5" />
<element Day="Friday" Start="18:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Saturday" Start="00:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Saturday" Start="08:00:00" End="17:59:59" Mobilisation="1.5" />
<element Day="Saturday" Start="18:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Sunday" Start="00:00:00" End="07:59:59" Mobilisation="3" />
<element Day="Sunday" Start="08:00:00" End="17:59:59" Mobilisation="1.5" />
<element Day="Sunday" Start="18:00:00" End="07:59:59" Mobilisation="3" />
</shift>
</shifts>
Define which vehicles use which shift:
<appliances><appliance applianceId="T19H9" Shift="DayOnly" /><appliance applianceId="T12P1" Shift="Wholetime" /><appliance applianceId="T16P1" Shift="Wholetime" /><appliance applianceId="T18P1" Shift="Wholetime" /><appliance applianceId="T22P1" Shift="Wholetime" /><appliance applianceId="T26P1" Shift="Wholetime" /></appliances>
Here Appliance T19H9 is on shift DayOnly. This means that from 8AM-6PM it has a mobilisation time of 1.5 minutes and the rest of the day it has a mobilisation time of 3 minutes.
So, if T19H9 is mobilized at 9AM a 5 minute isochrone will be based on a 3.5-minute isoroute and if it is mobilised at 9PM, a 5 minute isochrone will be based on a 2-minute isoroute.
The service is currently using DateTime so ensure you run it t 9AM and 9PM to see these differences.
If the service has its <verbosity> set to verbose, you will see shift warnings in the event logger if there are any.
Note: Shifts are used to define Mobilisation only- they do not control availability as they do in Workload Modeller.
If an appliance is not set up to have a shift or it is mobilised at a time not covered by the shift elements, it will have a mobilization of 0, i.e. exactly as before shifts were introduced.
You can define appliance status to prevent an appliance with a certain status level from being deployed. The status is held as an attribute on the SQL Server appliances overlay, but is configured as shown here.
<applianceStatus Column="Status$"
>
<value Isochrone="no">red</value>
<value Isochrone="yes" Mobilised=”yes”>amber</value>
<value>green</value>
</applianceStatus>
Three values have been defined here: red, amber and green.
<Isochrone>
Default is set to YES. Only appliances with ‘red’, ‘amber’, ‘green’ status are read from the SQL Server database and appear in appliances.json. However only ‘amber’ and ‘green’ appliances contribute to the isochones and coverage.
<Mobilised>
Default is set to NO. Only appliances with ‘red’, ‘amber’, ‘green’ status are read from the SQL Server database and appear in appliances.json.
STATUS | DESCRIPTION |
Red | appliances are shown but do not have an isochrone |
Amber | appliances are shown and have isochrones but as Mobilised is set to YES, mobilisation times are ignored |
Green | appliances are shown and have isochrones which are reduced to allow for the mobilisation time. |
Isochrone and Mobilisation attributes can be omitted from the <value>
XML node. If omitted the defaults are: Isochrone=yes/true and Mobilised=no/false.