Geofencing: Difference between revisions
(→) |
(→) |
||
Line 61: | Line 61: | ||
=== Interactions === | === Interactions === | ||
Interactions can be "Entering", "Leaving" or " | Interactions can be "Entering", "Leaving", "Crossing" or "Appearing". When defining a rule, one or more interaction types can be combined using flags/bitwise or. | ||
==== "Entering" and "Leaving" ==== | ==== "Entering" and "Leaving" ==== | ||
Line 67: | Line 67: | ||
A track is considered "Entering" a shape if the previous position was outside of the object and the current position is inside the object. "Leaving" occurs when previous position was inside the shape, and current position is outside of the shape. "Entering" and "Leaving" are only defined for objects with an area, it does not apply to line type shapes without a buffer. | A track is considered "Entering" a shape if the previous position was outside of the object and the current position is inside the object. "Leaving" occurs when previous position was inside the shape, and current position is outside of the shape. "Entering" and "Leaving" are only defined for objects with an area, it does not apply to line type shapes without a buffer. | ||
{{Note|'''Entering''' occurs only when both current and previous positions are defined | {{Note|'''Entering''' occurs only when both current and previous positions are defined. The same goes for '''leaving'''}} | ||
==== "Crossing" ==== | ==== "Crossing" ==== | ||
A track is considering "Crossing" a shape if the geodesic line between previous and current position intersects an odd number of line segments of the shape. "Crossing" is only defined for line type objects, and is not valid for objects with an area. By monitoring "Entering" and "Leaving" type of interactions for a single track, a client can easily implement "Crossing" type events for shapes with area. | A track is considering "Crossing" a shape if the geodesic line between previous and current position intersects an odd number of line segments of the shape. "Crossing" is only defined for line type objects, and is not valid for objects with an area. By monitoring "Entering" and "Leaving" type of interactions for a single track, a client can easily implement "Crossing" type events for shapes with area. | ||
==== "Appearing" ==== | |||
A track is considering "Appearing" inside an area type shape if the track appears inside the object with no previous positions available. | |||
=== Filters === | === Filters === |
Revision as of 13:11, 19 October 2020
Geofencing allows the user to define geographical shapes that acts as virtual "fences". By defining interaction rules, it is possible to generate events based on how tracks interact with these shapes.
General
A geofence consists of the following components:
- A geographical shape. Various object types are supported, for instance lines, polygon areas, sectors and range circles
- Interaction type, one of entering, leaving or crossing
- Track filter
- Report template
When a track interacts with a geofence in accordance with a rule, a report is generated. A report template determines the contents of the report. Typically, the report includes:
- Time of interaction
- Track details
- Shape/object details
- Static information contained in the template, for instance textual warnings and importance of the event
The core geofencing component is the geofencing service. It is responsible for fetching tracks and fence objects from respective services, for handling rule setup and execution as well as for providing clients with events.
This example was generated using recorded AIS data and sample symbology. Notifications are displayed using the geofencing service diagnostic application.
Datasources
Data sources are set up using the IDataManagerServiceBase interface.
Each data source entry causes the geo fencing service to fetch data from that source. One data source refers to a tracklist within a specified service or to a draw object list within a single draw object service.
Note that tracks and objects are fetched at preset intervals and are not synchronized to track updates or draw object updates. By using versioning/generations, only changed tracks or draw objects are fetched.
The geofencing service is responsible for handling cases where the data sources are temporarily unavailable, for instance if a source service is restarted.
Rules
Rules define the circumstances that are required in order to trigger a geofencing event. In addition, a rule contains the information used to create the contents of the geofencing event.
Rules are added through IGeoFencingRuleServiceBase using the AddRule method:
GeoFenceRuleDef genericRuleDef = new GeoFenceRuleDef();
genericRuleDef.Id = Guid.Parse("{4BB9385F-E2B3-457B-AEF1-5B77950FF9D6}");
genericRuleDef.Actions = new List<ActionBaseDef> {
new NotificationActionDef { NotificationTemplate = template } };
genericRuleDef.Interactions =
GeoFenceInteractions.Entering |
GeoFenceInteractions.Leaving |
GeoFenceInteractions.Crossing;
genericRuleDef.GeoFenceConditionXml =
@"<fieldcondition op=""Eq"" field=""TriggerCode"" value=""1""/>";
fenceRuleServiceClient.AddRule(genericRuleDef);
Interactions
Interactions can be "Entering", "Leaving", "Crossing" or "Appearing". When defining a rule, one or more interaction types can be combined using flags/bitwise or.
"Entering" and "Leaving"
A track is considered "Entering" a shape if the previous position was outside of the object and the current position is inside the object. "Leaving" occurs when previous position was inside the shape, and current position is outside of the shape. "Entering" and "Leaving" are only defined for objects with an area, it does not apply to line type shapes without a buffer.
"Crossing"
A track is considering "Crossing" a shape if the geodesic line between previous and current position intersects an odd number of line segments of the shape. "Crossing" is only defined for line type objects, and is not valid for objects with an area. By monitoring "Entering" and "Leaving" type of interactions for a single track, a client can easily implement "Crossing" type events for shapes with area.
"Appearing"
A track is considering "Appearing" inside an area type shape if the track appears inside the object with no previous positions available.
Filters
Filters in a rule are used to connect a rule to a set of shapes and tracks. By default a rule applies to all tracks and shapes in the system. The example above contains the following filter:
genericRuleDef.GeoFenceConditionXml =
@"<fieldcondition op=""Eq"" field=""TriggerCode"" value=""1""/>";
This filter causes the rule to only consider shapes with the field "TriggerCode" set to "1". This allows setup of a single, generic rule that is only triggered for selected shapes.\ \ These filters are defined in the same way as track/draw object styling filters. Complex filters can be created by using nested conditions:
<compositecondition op="Or">
<speedcondition value="0kts" op="Eq"/>
<speedcondition value="" op="Undefined"/>
</compositecondition>
Templates
Templates define the contents of the report/event that is generated.
var template = new NotificationTemplateDef();
template.Heading = "[track.name]([track.type]) [interaction] [shape.Name]";
template.TrackFields.AddRange(new[] { "name", "type", "identity" });
template.GeoShapeFields.AddRange(new[] { "Name" });
In this example, the template generates a report heading by referencing fields in the track and shape that generated the event. This allows for generic templates. The event above might generate the event heading: "M/F Petter Wessel entering Langesund". Any text of the type [track.<field>
] is replaced with the responding track field. [shape.<field>
] is replaced with the contents of the corresponding shape field. Only fields included in the template TrackFields and GeoShapeFields can be referenced in this manner. In the above example, the following statement allows references to the track fields [track.name], [track.type] and [track.identity]:
template.TrackFields.AddRange(new[] { "name", "type", "identity" });
Note that defining these fields in the template requires advance knowledge of the field names actually included in the tracks with the exception of the following, predefined values:
Key | Description |
---|---|
[interaction] | Interaction type, one of "Entering", "Leaving" or "Crossing" |
[level] | Notification level, "Low", "Medium" or "High" |
[time] | UTC time on the format HH:mm:ssZ, 12:23:34Z |
[datetime] | ISO 8601 utc datetime, 2014-10-28T11:56:58Z |
[track.course] | Track course in degrees, 0 is north |
[track.speed] | Track speed in m/s |
[track.speedkts] | Track speed in knots |
Predefined notification values
By design, the notifications are mostly static and cannot be changed. For instance, the track name or the interaction type cannot be changed. However, various user interactions can take place. Example are acknowledging a notification or marking a notification as read. This is done by appending user data messages to the notification. These messages are composed of a user identifier, a field key and a field value. The template can add initial user data messages to the notification. These will be added using the user id "system". More on this in #Notifications
private void AddRuleWithPredefinedValues()
{
GeoFenceRuleDef r = new GeoFenceRuleDef();
var template = new NotificationTemplateDef { Heading =
"[track.name] [interaction] [shape.Name]" };
template.TrackFields.AddRange(new[] { "name" });
template.GeoShapeFields.AddRange(new[] { "Name" });
template.NotificationLevel = NotificationLevel.Medium;
// Any notification generated based on this rule will contain
// userdata region=national for user "system"
template.PredefinedValues.Add(new Tuple`<string, string>`("region","national"));
r.Id = Guid.Parse("{807821B5-7432-4B23-BBF6-1F3251EC497D}");
r.Actions = new List`<ActionBaseDef>`{
new NotificationActionDef { NotificationTemplate = template }};
r.Interactions = GeoFenceInteractions.Entering | GeoFenceInteractions.Leaving;
r.GeoFenceConditionXml =
@"`<fieldcondition op=""Contains"" field=""Name"" value=""territorialområde""/>`";
_ruleServiceClient.AddRule(enteringAndLeavingRuleDef);
}
The following filter definitions include notifications generated with the rule above:
<fieldcondition field="userdata/system/region" op="Eq" value="national"/>
<fieldcondition field="userdata/*/region" op="Eq" value="national"/>
Notifications
Notifications are added by the geofencing core when tracks interact with geo shapes according to predefined rules. Clients can read these notifications as well as append specific types of information to the notifications. Notifications are accessed through INotificationHandlingServiceBase.
Reading notifications
Notifications are read using the service method
NotificationQueryResult GetNotifications(string notificationConditionXml,
int lastKnownGeneration);
All notifications matching filter, with generation newer than lastKnownGeneration are retrieved from the service.
{% include callout.html content="The GeoFencing.Core library contains NotificationStore which can be used for a client side storage of notifications. The service tester app uses this technique." type="info" %}
Filtering
The filtering syntax used in notification filtering, is the same as used for for geofencing rules and for general track/draw object styling. Using "fieldcondition" in combination with "compositecondition" allows creation of powerful notification filters:
var result=notificationClient.GetNotifications(
@"<fieldcondition op=""Contains"" field=""heading"" value=""Oslo"" />", -1);
The condition xml-string can also be generated by creating the conditions programatically, and then using the WriteCondition-member of ConditionXmlParser:
FieldCondition c=new FieldCondition("track.somefield", "42", FieldOperator.Contains);
string xml=(new ConditionXmlParser()).WriteCondition(c);
var answer=notifications.GetNotifications(xml, -1);
Note that "fieldcondition" for notifications can be used with the following predefined field codes:
Field key | Description |
---|---|
id | Notification guid |
interaction | Entering, Leaving or Crossing |
trackid | Track identifier, unique within a tracklist |
tracklistid | Tracklist identifier |
geoshapeid | Geo shape identifier, unique within a geo shape list |
geoshapelistid | Geo shape list identifier |
geofencecondition | XML-representation of the geo shape/geo fence filter |
trackcondition | XML-representation of the track filter |
heading | Textual header of the notification |
description | Textual description of the notification |
level | Notification level, Low, Medium or High |
userdata | Refers to userdata for the notification. Format: "userdata/<user> or */<key> "
|
track.<field>
|
Refers to track field. Note that only fields defined in the notification rule can be referenced |
shape.<field>
|
Refers to geo shape field. Note that only fields defined in the notification rule can be referenced |
Condition interfaces can be found here: ICondition. Use Condition factory to create concrete conditions.
Service notification filtering
Service filters must be written using xml. Some samples:
<compositecondition op="And">
<compositecondition op="Or">
<fieldcondition op="NEq" field="level" value="Low" />
<agecondition value="20.0" op="Lt" />
</compositecondition>
<fieldcondition op="NEq" field="userdata/*/state" value="acknowledged" />
</compositecondition>
This filter extracts notification state not set to acknowledged (for any user). Messages older than 20 seconds with low notification level are not retrieved.
Client side filtering
After retrieving the notification, the client can perform further filtering if required. This can be done using conditions directly:
ICondition cond=new FieldCondition("SomeFieldName", "20", FieldOperator.Lt);
bool satisfied=cond.IsSatisfied(null, someNotification.GeoObjectAdapter);
One usage is for removing old notifications from the client:
// Assume client store containing notifications,
// List`<NotificationDefWrapper>` notifications
var ageCondition=new AgeCondition { Operator = FieldOperator.Gt, Age = 60 }
notificationClient.RemoveAll(a=>ageCondition.IsSatisfied(null,a.GeoObjectAdapter);
Notification user data
User data can be added from the template using SetNotificationUserData.
notificationClient.SetNotificationUserData(id,
new UserDataDefinition { Owner = "myself",
Key = "somefieldid",
Value = "1234" });
Logging
Notifications can be logged and restored from file. Use SetNotificationLogInformation to specify filetype ("xml" or "json") and filename.
Notifications are continously written to file as they are retrieved. It is also possible to restore old notification-logs using RestoreNotificationLog.
Track to track fences
It is possible to create moving geo fences by adding a moving range object to the geofencing service and associating it with a track. The moving range will then behave in the same manner as other geo shapes, and can be set up to generate notification events by using rules.
var mrd = new MovingRangeDef();
mrd.Id = Guid.Parse("{DCA13C9F-CE36-4B65-8710-313A312B36CC}");
mrd.TrackId = trackId;
mrd.ListId = listId;
mrd.Name = "Simple moving rangering";
mrd.RangeMeters = 1000;
mrd.Fields = new[]
{
new KeyValuePair`<string, string>`("fencetype", "moving range")
};
_fenceRuleServiceClient.SetRangeObject(mrd);
And a mathcing rule:
var genericRuleDef = new GeoFenceRuleDef();
var template = new NotificationTemplateDef {
Heading = "[track.name] [interaction] proximity to"+
"[shape.track.name] ([shape.fencetype])" };
template.TrackFields.AddRange(new[] { "name" });
template.GeoShapeFields.AddRange(new[] { "track.name", "rangename" });
template.NotificationLevel = NotificationLevel.Low;
genericRuleDef.Id = Guid.Parse("{4BB9385F-E2B3-457B-AEF1-5B77950FF9D8}");
genericRuleDef.NotificationTemplate = template;
genericRuleDef.Interactions = GeoFenceInteractions.Entering;
genericRuleDef.GeoFenceConditionXml =
@"`<fieldcondition op=""Eq"" field=""fencetype"" value=""moving range""/>`";
_fenceRuleServiceClient.AddRule(genericRuleDef);
Special considerations
- Each range object is associated with a single track. If that track is not present, the range ring will not be active
- A rule that includes the range object must be active, otherwise no notifications will be generated
- Defining lots of range objects with large ranges has the potential to create very many notifications
Notification template fields
Notification template fields behave the same way for dynamic range objects as for regular shapes, in addition the following replacements are supported:
Key | Description |
---|---|
[shape.track.<field> ]
|
Refers to trackfield of the track that controls the dynamic range |
[track.<field> ]
|
Refers to trackfield of the track that enters or leaves the dynamic range |
[shape.<field> ]
|
Refers to field of the dynamic range |
WCF service
The geofencing service is a WCF service that provides core geofencing functionality. The following service interfaces are provided:
Name | Description |
---|---|
IDataManagerServiceBase | Data source management |
IGeoFencingRuleServiceBase | Rule management |
INotificationHandlingServiceBase | Notification handling, including event log and restore |
WCF basic http binding is used by default.
Deployment and configuration
Service deployment and configuration is decided by the system integrator. Several scenarios are possible:
- Single geofencing service is used to service all clients. Rule and data source setup is performed by setup/admin function
- One geofencing service per client. This allows easy setup of personal notifications. Client is responsible for data source and rule setup
- Multiple services, multiple clients. Each geofencing service produces specific types of notifications. Using multiple data sources allows separation of data sources
Client sample
Use standard WCF app config to connect to one the required interfaces, or connect by using code:
var eaDataManager = new EndpointAddress(
"http://localhost:9004/GeoFencingService/DataManager");
var b = Binding b = new BasicHttpBinding();
var dataManagerClient = new DataManagerServiceClient(b, eaDataManager);
// In production code where automatic reconnects are required,
// use Connect() instead of ConnectAndWait()
dataManagerClient.ConnectAndWait();
dataManagerClient.GetDataSources();
Service paths for the geofencing interfaces are:
"http://<host>:<port>/GeoFencingService/DataManager"
"http://<host>:<port>/GeoFencingService/FenceRule"
"http://<host>:<port>/GeoFencingService/NotificationHandling"
Geofencing test client
The geofencing test client is distributed with the geofencing service. It can be used to inspect a running geofencing service and perform basic service monitoring.