TPEG2

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:

  • tpegdatatypes the basic datatypes shared between all applications and toolkits following ISO 21219-2:2019.

  • sfw the Service Framework (SFW) types needed for framing application messages for reliable transmission following ISO 21219-5:2019.

  • mmc the 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.

  • lrc the types to wrap location references in a generic way following ISO 21219-7:2017.

  • sni the types used to express service and network information, including to describe the content of binary-encoded SFW frames following ISO 21219-9:2016.

  • tec the types used for the traffic event compact application following ISO 21219-15:2016.

  • tfp the types used for the traffic flow and prediction application following ISO 21219-18:2019.

  • etl the types used for extended TMC location references following TISA SP13003-20.

  • olr the types used for OpenLR location references following ISO 21219-22:2017.

  • tmc the 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:

SBT
Maven
Gradle
libraryDependencies ++= Seq(
  "com.here.platform.location" %% "location-tpeg2" % "0.21.788"
)
<dependencies>
    <dependency>
        <groupId>com.here.platform.location</groupId>
        <artifactId>location-tpeg2_${scala.compat.version}</artifactId>
        <version>0.21.788</version>
    </dependency>
</dependencies>
dependencies {
    compile group: 'com.here.platform.location', name: 'location-tpeg2_2.12', version:'0.21.788'
}

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.TransportFramess 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:

Scala
Java
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:

Scala
Java
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 TransportFrames as follows:

Scala
Java
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).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.applicationMessages
import 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();

results matching ""

    No results matching ""