Home
Categories
Dictionary
Glossary
Download
Project Details
Changes Log
What Links Here
FAQ
License

Map ontology FillOntology module



This article presents the fillOntology module used in the map ontology tutorial.

Overview

The fillOntology module is responsible to:
  • Fill the Ontology with the flightplan, and the waypoints
  • Fill and update the Ontology with the aircraft position
  • Update the Ontology depending on the notification of the alert service
Note that we will use the Jena model mapping to bridge the content of the tacticalEnv model with the Jena module, so the first step is to specify the XML file defining this bridge.

Ontology model

We will use the following ontology:
mapOntologyowl
This ontology has the following elements:
  • Aircraft: the aircraft
  • FlightPlan: the FlightPlan, which contains Waypoints
  • Waypoint: the Waypoints
  • Alarm: the Alarms

In this tutorial we won't use all the classes defined in the Ontology. We left the implementation of the remaining concepts in our Ontology for the curious reader.

Elements geometry

The following elements are subclasses of the Geosparql Feature class, because they have a geometrical position:
  • Aircraft: the aircraft
  • Waypoint: the Waypoints

mapOntologyfeature

Aircraft

The Aircraft has:
  • A Label
  • A Geometry (the Aircraft is a subclass of Feature), which in this case specify the latitude and longitude of the Aircraft
  • One FlightPlan that the Aircraft follows
  • One or several Alarms

mapOntologyowlaircraft
The Aircraft refer to a Aircraft in the tacticalEnv model.

Alarm

An Alarm has:
  • An AlarmNumber: the number of the Alarm
  • An AlarmMessage: the message of the Alarm
  • A link to an AlarmType ( WhiteAlarm, AmberAlarm, or RedAlarm). The AlarmType represents the danger of the Alarm

mapOntologyowlalerts

Flightplan

An FlightPlan has:
  • A Label, which is the name of the FlightPlan
  • Links to the list of Waypoints which define the FlightPlan
The FlightPlan refer to a FlightPlan in the tacticalEnv model.

Waypoint

A Waypoint has:
  • A Label, which is the name of the Waypoint
  • A Geometry (the Waypoint is a subclass of Feature), which in this case specify the latitude and longitude of the Waypoint
  • A link to a WaypointType ( NAV or ATT). NAV are navigation points (used for example to define the FlightPlan), and ATT are landing waypoints

mapOntologyowlwpt
The Waypoint refer to a Waypoint in the tacticalEnv model.

Specify the Jena model mapping

We want to bridge our ontology to the tacticalEnv model: As you can see, the Aircraft and the Waypoint will directly come from Java classes, whereas the Alarm will have to be constructed from the content of a service. The mappings will be specified through a Jena model mapping.

Aircraft, Flightplan, and Waypoints mapping

These notions will be mapped to Java classes, becasue all three notions correspond to a class in the tacticalenvModel.
mapontologybridge1
For the Aircraft:
  • The name of the Aircraft will be mapped to the Label DataProperty on the Thing class
  • The position of the Aircraft will be mapped to the geometry on the Aircraft class
This gives us the following declarations in the model mapping:
        <classTypes>           
            <class path="org.da.protoframework.tacticalenv.common.model.Aircraft" nameMethod="getName">
                <type object="track" />        
            </class>                                           
        </classTypes> 
        <object name="track" className="Aircraft">
            <geometry />          
            <dataProperty name="label" property="Label" isName="true"/>  
        </object>
For the Waypoint:
  • The name of the Waypoint will be mapped to the Label DataProperty on the Thing class
  • The position of the Waypoint will be mapped to the geometry on the Waypoint class
  • The type of the Waypoint will be mapped to the hasWaypointType property on the Waypoint class. As there is only one Waypoint type of course, this mapping will have a cardinality of one
  • The Flightplan of the Waypoint will be mapped to the isWaypointFrom property on the Waypoint class. As there is only one Flightplan for one Waypoint in our case, this mapping will have a cardinality of one
This gives us the following declarations in the model mapping:
        <classTypes>                           
            <class path="org.da.protoframework.tacticalenv.common.model.Waypoint" nameMethod="getName">
                <type object="waypoint" />        
            </class>                          
        </classTypes>     
        <object name="waypoint" className="Waypoint">  
            <geometry />          
            <dataProperty name="label" property="Label" isName="true"/>
            <property name="hasWaypointType" eltRef="WaypointType"  property="hasWaypointType" cardinality="one"  />   
            <property name="isWaypointFrom" eltRef="flightplan"  property="isWaypointFrom" cardinality="one"  />            
        </object>
For the FlightPlan:
  • The name of the FlightPlan will be mapped to the Label DataProperty on the Thing class
  • The list of Waypoints in the Flightplan will be mapped to the hasWaypoint property on the Flightplan class. As there are as many Waypoints per one Flightplan, this mapping will have a cardinality of unbound
This gives us the following declarations in the model mapping:
        <classTypes>                      
            <class path="org.da.protoframework.tacticalenv.common.model.Flightplan" nameMethod="getName">
                <type object="flightplan" />        
            </class>                                          
        </classTypes>     
        <object name="flightplan" className="FlightPlan">         
            <dataProperty name="label" property="Label" isName="true"/>    
            <property name="waypoint" eltRef="waypoint"  property="hasWaypoint" inverseProperty="isWaypointFrom" cardinality="unbound" inverseCardinality="one" />  
        </object>

Alerts mapping

mapontologybridge2
As there is no class for the Alerts, we will not be able to define a Java class mapping. The mapping will be:
        <object name="alarm" className="Alarm">       
            <dataProperty name="number" property="AlarmNumber"/>      
            <dataProperty name="message" property="AlarmMessage"/>   
            <property name="type" eltRef="alarmType" property="hasAlarmType" cardinality="one" />   
        </object>

Complete mapping declaration

The complete mapping declaration is: objectMappings.xml

Create the FillOntology module

To fill the Ontology, we must:
  • Use the mapping declaration to create the Jena operations
  • Update the Ontology for each service notification
Now we will create our module, responsible to:
  • Fill the Ontology with the flightplan, and the waypoints
  • Fill and update the Ontology with the aircraft position
  • Update the Ontology depending on the notification of the alert service

Specify the module interfaces

The fillOntology module has the following module configuration:
        <application name="fillOntology">
            <deployment>
                <lib url="FillOntology.jar" />
            </deployment>
            <modules>
                <module name="fillOntology">
                    <implementation path="org.da.owl.FillOntology" >
                        <initEntryPoint method="init" />
                        <defaultReceiveEntryPoint method="subscribe" />
                    </implementation>            
                    <interfaces>
                        <eventReceived service="alert" />   
                        <eventReceived service="flightplansModel" uri="http://dassault-aviation.com/tacticalenv"/>
                        <eventReceived service="waypointsModel" uri="http://dassault-aviation.com/tacticalenv"/>  
                        <subscribe service="aircraftsModel" uri="http://dassault-aviation.com/tacticalenv"/>  
                        <requestSend service="applyOperations" uri="http://dassault-aviation.com/jena" />  
                    </interfaces>
                </module>
            </modules>      
        </application>
It will be notified from the following services:
  • The flightplansModel and waypointsModel services to set the flightplan and the Waypoints
  • The aircraftsModel service to update the position of the Aircraft
  • The alert service to receive the alerting status
It will invoke the applyOperations service[1]
See Jena applyOperations service for more information about this service
to update the Ontology.

Module initialization


We will create an Object mapping during our module initialization using our mapping XML specification:
      public void init(Module module) {
         mappings = new ObjectMappings();
         URL url = this.getClass().getResource("objectMappings.xml");
         mappings.parse(module, url, true);
         // here we create operations for the Waypoints and the Flightplan, the Aircraft, and the Alerts
         wptOp = new ElementsOperations(module, mappings);
         acOp = new ElementsOperations(module, mappings);
         alertOp = new ElementsOperations(module, mappings);
      }     

Handle the service notifications

The following code will handle the notification from the flightplansModel, waypointsModel, aircraftsModel, and alert services.
      public synchronized void subscribe(ServiceInstance service) {
         NamespaceKey key = service.getKey();  
         if (key.equals(ENV_WAYPOINTS)) {
           this.waypointsReceived = true;
           if (flightplansReceived) {
             receiveWaypointsAndFlightPlans(service);
           }
         } else if (key.equals(ENV_FLIGHTPLANS)) {
           this.flightplansReceived = true;
           if (waypointsReceived) {
             receiveWaypointsAndFlightPlans(service);
           }
         } else if (key.equals(ENV_AIRCRAFTS)) {
           if (waypointsReceived && flightplansReceived) {
             receiveAircrafts(service);
           }
         } else if (service.getName().equals("alert")) {
           receiveAlert(service);
         }
      }        
As you can see, we will update the Ontology with the content of both the Waypoints and the Flightplan when both the tacticalEnv model flightplansModel and waypointsModel have been notified.

Waypoints and Flightplans notification

The following method update the Ontology with the Flightplans and Waypoints definition:
      private void receiveWaypointsAndFlightPlans(ServiceInstance service) {
         // waypoints
         Waypoints waypoints = (Waypoints) envWaypointsService.getDataValue("waypoints");
         Iterator<Waypoint> it = waypoints.getWaypoints().values().iterator();
         while (it.hasNext()) {
           Waypoint waypoint = it.next();
           // this method will ensure that the Waypoint individual will be created
           // we don't need to set the Label of the Waypoint, because it is already taken care of in the mappings            
           MappedElement elt = wptOp.addElement(waypoint);
           float latitude = waypoint.getLatitude();
           float longitude = waypoint.getLongitude();
           // will create the geometry of the Waypoint individual in the Ontology
           elt.setPosition(latitude, longitude);
           // specifies the hasWaypointType property, which links to the appropriate WaypointType element
           String type = waypoint.getType();
           if (type.equals("NAV")) {
             elt.addProperty("hasWaypointType", "NAV");
           } else if (type.equals("ATT")) {
             elt.addProperty("hasWaypointType", "ATT");
           }
         }

         // flightplans
         Flightplans flightplans = (Flightplans) envFlightplansService.getDataValue("flightplans");
         Iterator<Flightplan> it2 = flightplans.getFlightplans().values().iterator();
         while (it2.hasNext()) {
           Flightplan fp = it2.next();
           // this method will ensure that the Flightplan individual will be created
           // we don't need to set the Label of the Flightplan, because it is already taken care of in the mappings        
           MappedElement flightplanElt = wptOp.addElement(fp);
           Iterator<String> it3 = fp.getWaypoints().iterator();
           while (it3.hasNext()) {
             String name = it3.next();
             // specifies a hasWaypoint property, which links to one Waypoint individual
             flightplanElt.addProperty("waypoint", name);
           }
         }
         // handle the creation of the operations. All the effective Ontology update will be done in the Jena Module
         Operations operations = wptOp.create();
         applyOperations.setDataValue("operations", operations);
         applyOperations.invoke();
      }        
As they will only be received once, we only create the indivduals in the Ontology. We don't need to update their position because the position of the Flightplan and the Waypoints won't be updated.

Aircrafts notification

The following method update the Ontology with the Aircrafts definition:
      private void receiveAircrafts(ServiceInstance service) {
         applyOperations.setDataStringValue("reqSchema", SCHEMA);

         Aircrafts envAircrafts = (Aircrafts) service.getValue("aircrafts");
         Iterator<Aircraft> it = envAircrafts.getAircrafts().values().iterator();
         while (it.hasNext()) {
           Aircraft aircraft = it.next();
           if (aircraft.getName().equals("falcon")) {
             float latitude = aircraft.getLatitude();
             float longitude = aircraft.getLongitude();
             // this method will ensure that the Aircraft individual will be created
             // we don't need to set the Label of the Aircraft, because it is already taken care of in the mappings
             MappedElement elt = acOp.addElement(aircraft);
             if (!acReceived) {
               // will create the geometry of the Aircraft individual in the Ontology
               elt.setPosition(latitude, longitude);
             } else {
               // will update the geometry of the Aircraft individual in the Ontology
               acOp.updateElementPosition("track", aircraft.getName(), latitude, longitude);
             }
           }
         }
         // handle the creation of the operations. All the effective Ontology update will be done in the Jena Module
         Operations operations = acOp.create();
         acOp.clearOperations();
         applyOperations.setDataValue("operations", operations);
         applyOperations.invoke();
         acReceived = true;
      }      
We will create the falcon Aircraft for the first notification, then for further notifications we will just update the existing Individual position.

Alerts notification

Alerts do not correspond to a Java clas, so we need in this case to handle the fields directly. The alert service contains the alert itself and its status:
      <event name="alert">  
         <data name="alert" type="alert" desc="the alert"/> 
         <data name="status" type="alertStatus" desc="the alert status"/>  
      </event>
The associated types are:
      <enumType name="alertType" >  
         <enumValue name="WARNING" />
         <enumValue name="CAUTION" />               
         <enumValue name="ADVISORY" />                      
      </enumType>    
      <enumType name="alertStatus" >  
         <enumValue name="NEW" />
         <enumValue name="REMOVED" />                                
      </enumType>        
      <structType name="alert">
         <field name="number" type="int" />
         <field name="type" type="alertType" />
         <field name="content" type="string" />       
      </structType>
We will use the Alert number, type, and status:
  • The number field specifies the name of the Alarm individual to create or remove
  • The type field specifies the AlarmType individual on which we must link to
  • The status data specifies if we need to create the individual or remove an existing one
      private void receiveAlert(ServiceInstance service) {
         List<Object> alertObj = service.getData("alert").getValueAsStructure();
         int number = alertType.getFieldValueAsInt("number", alertObj);
         String alarmType = alertType.getFieldValueAsString("type", alertObj);
         int status = service.getData("status").getValueAsInt();
         applyOperations.setDataStringValue("reqSchema", SCHEMA);
         // create an alarm
         MappedElement elt = alertOp.addElement("alarm", "alarm" + number);
         // add the AlarmNumber dataProperty
         elt.addDataProperty("number", number);
         // specifies the hasAlarmType property, which links to the appropriate AlarmType element
         switch (alarmType) {
           case "WARNING":
             elt.addProperty("type", "RedAlarm");
             break;
           case "CAUTION":
             elt.addProperty("type", "AmberAlarm");
             break;
           case "ADVISORY":
             elt.addProperty("type", "WhiteAlarm");
             break;
         }
         // if status == 1 the Alarm was removed from the Alarm list
         if (status == 1) {
            // in this case, the existing Alarm element will be deleted from the Ontology rather than created
           elt.setRemoved(true);
         }
         // handle the creation of the operations. All the effective Ontology update will be done in the Jena Module
         Operations operations = alertOp.create();
         alertOp.clearOperations();
         applyOperations.setDataValue("operations", operations);
         applyOperations.invoke();
      }      

Notes

  1. ^ See Jena applyOperations service for more information about this service

See also


Categories: tutorials

Copyright 2017-2020 Dassault Aviation. All Rights Reserved. Documentation and source under the LGPL v3 licence