How to use the TPEG2 module
How to use the TPEG2 module
The tpeg2 module defines a Java/Scala model for TPEG2 messages. There are marshallers and unmarshallers to read and write the XML and binary formats defined by the standard.
The binary format was designed for use cases with very limited bandwidth, so it is very efficient, and intended for production use. The XML markup representation is more verbose and generally used as a human readable format, such as for testing and debugging.
The main package of the module provides access to the marshalling and unmarshalling functionality.
There are sub-packages for each supported TPEG2 application/toolkit:
-
tpegdatatypesthe basic datatypes shared between all applications and toolkits following ISO 21219-2:2019. -
sfwthe Service Framework (SFW) types needed for framing application messages for reliable transmission following ISO 21219-5:2019. -
mmcthe types for the Message Management Container (MMC), which holds administrative information that allows a decoder to handle the message appropriately following ISO 21219-6:2019. -
lrcthe types to wrap location references in a generic way following ISO 21219-7:2017. -
snithe types used to express service and network information, including to describe the content of binary-encoded SFW frames following ISO 21219-9:2016. -
tecthe types used for the traffic event compact application following ISO 21219-15:2016. -
tfpthe types used for the traffic flow and prediction application following ISO 21219-18:2019. -
etlthe types used for extended TMC location references following TISA SP13003-20. -
olrthe types used for OpenLR location references following ISO 21219-22:2017. -
tmcthe types used for TPEG1 TMC Location Referencing following ISO 17572-2.
Working with TPEG2 data structures
Start working with the tpeg2 module by adding it to your project dependencies:
libraryDependencies ++= Seq("com.here.platform.location" %% "location-tpeg2" % "<version>")
<dependencies>
<dependency>
<groupId>com.here.platform.location</groupId>
<artifactId>location-tpeg2_${scala.compat.version}</artifactId>
</dependency>
</dependencies>dependencies {
compile group: 'com.here.platform.location', name: 'location-tpeg2_2.13', version:'<version>'
}The entrypoint for the TPEG2 marshalling functionality are
BinaryMarshallers
and
XmlMarshallers
respectively.
TPEG2 provides a whole protocol for transmitting data, that specifies how to
transmit messages in frames. What is normally send over the wire or the air is
thus packaged into
sfw.TransportFrames
before being streamed.
While the TransportFrame is thus normally the starting point for marshalling
and unmarshalling, some other important types can be individually marshalled and
unmarshalled to TPEG-Binary or TPEG XML.
For example
OpenLRLocationReference
can be individually unmarshalled from TPEG-Binary like this:
import com.here.platform.location.tpeg2.BinaryMarshallers
import com.here.platform.location.tpeg2.olr.OpenLRLocationReference
import java.io.ByteArrayInputStream
// Given the TPEG-Binary representation of an OpenLR location reference,
val tpegBinaryOpenLRReference: Array[Byte] =
Array(0x08, 0x28, 0x01, 0x10, 0x02, 0x24, 0x23, 0x09, 0x9B, 0x42, 0x25, 0x4F, 0xE2, 0x00,
0x09, 0x05, 0x04, 0x05, 0x03, 0x27, 0x00, 0x0A, 0x04, 0x03, 0x05, 0x76, 0x00, 0x00,
0xA0, 0x00, 0x29, 0x00, 0x09, 0x05, 0x04, 0x05, 0x03, 0xB3, 0x00, 0x01, 0x02, 0x00).map(
_.toByte)
// We can use a BinaryMarshaller to unmarshall the reference.
val reference: OpenLRLocationReference =
BinaryMarshallers.openLRLocationReference.unmarshall(
new ByteArrayInputStream(tpegBinaryOpenLRReference))
// Now we can use the reference object. Here we just use its string representation.
System.out.println(reference)import com.here.platform.location.tpeg2.javadsl.BinaryMarshallers;
import com.here.platform.location.tpeg2.olr.OpenLRLocationReference;
import java.io.ByteArrayInputStream;
// Given the TPEG-Binary representation of an OpenLR location reference,
final byte[] tpegBinaryOpenLRReference =
new byte[] {
(byte) 0x08, (byte) 0x28, (byte) 0x01, (byte) 0x10, (byte) 0x02, (byte) 0x24, (byte) 0x23,
(byte) 0x09, (byte) 0x9B, (byte) 0x42, (byte) 0x25, (byte) 0x4F, (byte) 0xE2, (byte) 0x00,
(byte) 0x09, (byte) 0x05, (byte) 0x04, (byte) 0x05, (byte) 0x03, (byte) 0x27, (byte) 0x00,
(byte) 0x0A, (byte) 0x04, (byte) 0x03, (byte) 0x05, (byte) 0x76, (byte) 0x00, (byte) 0x00,
(byte) 0xA0, (byte) 0x00, (byte) 0x29, (byte) 0x00, (byte) 0x09, (byte) 0x05, (byte) 0x04,
(byte) 0x05, (byte) 0x03, (byte) 0xB3, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x00
};
// We can use a BinaryMarshaller to unmarshall the reference.
final OpenLRLocationReference reference =
BinaryMarshallers.openLRLocationReference()
.unmarshall(new ByteArrayInputStream(tpegBinaryOpenLRReference));
// Now we can use the reference object. Here we just use its string representation.
System.out.println(reference);For debugging purposes, you can also unmarshall them from TPEG-ML as follows:
import com.here.platform.location.tpeg2.{BinaryMarshallers, XmlMarshallers}
import java.io.{ByteArrayInputStream, ByteArrayOutputStream}
import java.nio.charset.StandardCharsets
// Given the TPEG-ML representation of an OpenLR location reference,
val tpegML =
"""|<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|<olr:OpenLRLocationReference xmlns:olr="http://www.tisa.org/TPEG/OLR_0_1">
| <olr:version>1.0</olr:version>
| <olr:locationReference>
| <olr:optionPointAlongLineLocationReference>
| <olr:pointAlongLine>
| <olr:first>
| <olr:coordinate>
| <olr:longitude>629570</olr:longitude>
| <olr:latitude>2445282</olr:latitude>
| </olr:coordinate>
| <olr:lineProperties>
| <olr:frc olr:table="olr001_FunctionalRoadClass" olr:code="5"/>
| <olr:fow olr:table="olr002_FormOfWay" olr:code="3"/>
| <olr:bearing>
| <olr:value>39</olr:value>
| </olr:bearing>
| </olr:lineProperties>
| <olr:pathProperties>
| <olr:lfrcnp olr:table="olr001_FunctionalRoadClass" olr:code="5"/>
| <olr:dnp>
| <olr:value>118</olr:value>
| </olr:dnp>
| <olr:againstDrivingDirection>false</olr:againstDrivingDirection>
| </olr:pathProperties>
| </olr:first>
| <olr:last>
| <olr:coordinate>
| <olr:longitude>160</olr:longitude>
| <olr:latitude>41</olr:latitude>
| </olr:coordinate>
| <olr:lineProperties>
| <olr:frc olr:table="olr001_FunctionalRoadClass" olr:code="5"/>
| <olr:fow olr:table="olr002_FormOfWay" olr:code="3"/>
| <olr:bearing>
| <olr:value>179</olr:value>
| </olr:bearing>
| </olr:lineProperties>
| </olr:last>
| <olr:sideOfRoad olr:table="olr004_SideOfRoad" olr:code="1"/>
| <olr:orientation olr:table="olr003_Orientation" olr:code="2"/>
| </olr:pointAlongLine>
| </olr:optionPointAlongLineLocationReference>
| </olr:locationReference>
|</olr:OpenLRLocationReference>
|""".stripMargin
// We can use an XmlMarshaller to unmarshall the reference.
val ref = XmlMarshallers.openLRLocationReference.unmarshall(
new ByteArrayInputStream(tpegML.getBytes(StandardCharsets.UTF_8)))
// Now we can use the reference object. Here we use a BinaryMarshaller to write it as TPEG-Binary.
val outputStream = new ByteArrayOutputStream
BinaryMarshallers.openLRLocationReference.marshall(ref, outputStream)import com.here.platform.location.tpeg2.XmlMarshallers;
import com.here.platform.location.tpeg2.javadsl.BinaryMarshallers;
import com.here.platform.location.tpeg2.olr.OpenLRLocationReference;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
// Given the TPEG-ML representation of an OpenLR location reference,
final String tpegML =
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>"
+ "<olr:OpenLRLocationReference xmlns:olr=\"http://www.tisa.org/TPEG/OLR_0_1\">"
+ " <olr:version>1.0</olr:version>"
+ " <olr:locationReference>"
+ " <olr:optionPointAlongLineLocationReference>"
+ " <olr:pointAlongLine>"
+ " <olr:first>"
+ " <olr:coordinate>"
+ " <olr:longitude>629570</olr:longitude>"
+ " <olr:latitude>2445282</olr:latitude>"
+ " </olr:coordinate>"
+ " <olr:lineProperties>"
+ " <olr:frc olr:table=\"olr001_FunctionalRoadClass\" olr:code=\"5\"/>"
+ " <olr:fow olr:table=\"olr002_FormOfWay\" olr:code=\"3\"/>"
+ " <olr:bearing>"
+ " <olr:value>39</olr:value>"
+ " </olr:bearing>"
+ " </olr:lineProperties>"
+ " <olr:pathProperties>"
+ " <olr:lfrcnp olr:table=\"olr001_FunctionalRoadClass\" olr:code=\"5\"/>"
+ " <olr:dnp>"
+ " <olr:value>118</olr:value>"
+ " </olr:dnp>"
+ " <olr:againstDrivingDirection>false</olr:againstDrivingDirection>"
+ " </olr:pathProperties>"
+ " </olr:first>"
+ " <olr:last>"
+ " <olr:coordinate>"
+ " <olr:longitude>160</olr:longitude>"
+ " <olr:latitude>41</olr:latitude>"
+ " </olr:coordinate>"
+ " <olr:lineProperties>"
+ " <olr:frc olr:table=\"olr001_FunctionalRoadClass\" olr:code=\"5\"/>"
+ " <olr:fow olr:table=\"olr002_FormOfWay\" olr:code=\"3\"/>"
+ " <olr:bearing>"
+ " <olr:value>179</olr:value>"
+ " </olr:bearing>"
+ " </olr:lineProperties>"
+ " </olr:last>"
+ " <olr:sideOfRoad olr:table=\"olr004_SideOfRoad\" olr:code=\"1\"/>"
+ " <olr:orientation olr:table=\"olr003_Orientation\" olr:code=\"2\"/>"
+ " </olr:pointAlongLine>"
+ " </olr:optionPointAlongLineLocationReference>"
+ " </olr:locationReference>"
+ "</olr:OpenLRLocationReference>";
// We can use an XmlMarshaller to unmarshall the reference.
final OpenLRLocationReference ref =
XmlMarshallers.openLRLocationReference()
.unmarshall(new ByteArrayInputStream(tpegML.getBytes(StandardCharsets.UTF_8)));
// Now we can use the reference object. Here we use a BinaryMarshaller to write it as
// TPEG-Binary.
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BinaryMarshallers.openLRLocationReference().marshall(ref, outputStream);For full SFW (Service Framework) streams, deserialize
TransportFrame
as follows:
import com.here.platform.location.tpeg2.sfw.TransportFrame
import com.here.platform.location.tpeg2.tec.TECMessage
import com.here.platform.location.tpeg2.{BinaryMarshallers, Tpeg2Messages}
// Given the TPEG-Binary representation of an OpenLR location reference,
val inputStream: InputStream = loadTpegBinaryTransportFrames()
// We can use a BinaryMarshaller to get an iterator that unmarshalls TransportFrames.
val transportFrames: Seq[TransportFrame] =
BinaryMarshallers.transportFrames.unmarshall(inputStream).iterator.toSeq
// We can then use an extractor to get interesting information. E.g., here we get all TECMessages.
val tecMessages: Seq[TECMessage] =
Tpeg2Messages(transportFrames).filterTecMessages.applicationMessagesimport com.here.platform.location.tpeg2.Tpeg2Messages;
import com.here.platform.location.tpeg2.javadsl.BinaryMarshallers;
import com.here.platform.location.tpeg2.sfw.TransportFrame;
import com.here.platform.location.tpeg2.tec.TECMessage;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
// Given the TPEG-Binary representation of an OpenLR location reference,
final InputStream inputStream = loadTpegBinaryTransportFrames();
// We can use a BinaryMarshaller to get an iterator that unmarshalls TransportFrames.
final Iterator<TransportFrame> transportFrames =
BinaryMarshallers.transportFrames().unmarshall(inputStream);
// We can then use an extractor to get interesting information. E.g., here we get all
// TECMessages.
final List<TECMessage> tecMessages =
Tpeg2Messages.create(transportFrames).filterTecMessages().getApplicationMessages();Updated 21 days ago