class GeometryTile extends AnyRef
Contains the road geometry data for a single tile.
In HERE Map Content, a road segment is the unbroken stretch of road between two intersections. The intersections are called nodes.
The geometry of a road segment is a line-string, a sequence of points, starting from the segment's start node and ending with its end node.
A segment geometry consists of a sequence of one or more adjacent segment geometry chunks. Each chunk is a pair of subsequent points of a segment geometry. That means, that the n-th chunk of a segment's geometry consists of points n and n+1 in that geometry.
Road Segment Geometries
Every GeometryTile t1
contains geometries for two kinds of segments.
- Segments that belong to tile
t1
(internal segments). - Segments that belong to some other tile
t2
but whose geometry is partially inside tilet1
(external segments).
These geometries are stored in segmentGeometryCoordinates in the following order:
- First, for the internal segments, stored in the same order as the Vertices corresponding to these segments in the GraphTile with the same ID.
- Then, for the external segments, ordered by the (tileId, localIndex) for each external segment.
To determine which points inside segmentGeometryCoordinates
constitute the geometry for a segment
we need to consult segmentGeometryFirstCoordinateIndices
. For example, the geometry of the segment
with index n starts at the point with index segmentGeometryFirstCoordinateIndices(n)
and ends at the point with index segmentGeometryFirstCoordinateIndices(n+1)
(exclusive).
This implies that the first entry of segmentGeometryFirstCoordinateIndices
will always be 0 and
the last entry will always be segmentGeometryCoordinates.length
.
Point Encoding
GeometryTiles contain points to represent segment geometries (in segmentGeometryCoordinates
)
and to represent bounding boxes (in boundingBoxCoordinates
).
All these points are stored as 64 bit integers. This representation consumes
a lot less memory than, for example a pair of doubles. More importantly, because integers are primitive types,
they usually don't need an object to be created for them and, as a consequence, are a lot faster to work with.
A point is usually represented by a GeoCoordinate object containing a longitude and a latitude.
In order to pack these coordinates into an integer, multiply each coordinate by 1000000 and convert it to an integer. The two integer coordinates then become the high (latitude) and low (longitude) bits of a long:
packed_representation = (latitude*1E6).toLong << 32) | (longitude*1E6).toLong & 0xFFFFFFFFL)
This packing means that the precision of each coordinate is one millionth of a degree, which is around 10 cm.
To reconstruct the original point, apply the inverse transformation:
latitude = (packed_representation >> 32) / 1E6 longitude = (packed_representation & 0xFFFFFFFFL).toInt / 1E6
External Segments
Every GeometryTile may contain some geometries for segments external to that tile (see above).
In order to find out which tile an external segment belongs to and what its index in that tile is,
you need to consult externalSegmentPartitions
and externalSegmentLocalIndices
.
These are parallel arrays that contain the tile ID and segment index, respectively, for each external segment.
External segments are always the last segments in a tile. That means, you can decide whether a
segment is external, just by looking at its index.
The segment with index n is external, if n >= internalSegmentCount
.
The ID of the tile that this external segment belongs to is externalSegmentPartitions(n - number_of_internal_segments)
and its index there externalSegmentLocalIndices(n - number_of_internal_segments)
.
The Spatial Index
In order to quickly find segments in a particular area, GeometryTiles contain a spatial index. The spatial index is a tree data structure where every internal node is associated with a bounding box around all its children. Using the bounding boxes while traversing the tree, you can quickly decide whether a sub-tree might contain segment geometries relevant to your search and avoid descending into it, if it does not.
A leaf node in the tree (a node without child nodes) points to a single chunk inside a segment geometry in this tile.
The structure of the tree is stored in indexTree
.
The tree contains indexTree.length - 1
nodes.
For a tree node with index m, the range from indexTree(m)
to indexTree(m+1)
(exclusive) contains
the indices of its child nodes. In particular, if indexTree(m) == indexTree(m+1)
, the node
is a leaf node. The node with index 0 is the tree's root node indexTree
.
The first entry in indexTree
is always 1 and the last entry always indexTree.length
.
Each node in indexTree
is associated with two values in indexValues
.
For an internal (non-leaf) tree node with index n, indexValues(2*n)
contains the index of a bounding
box in boundingBoxCoordinates
. Because two points are required for storing each bounding box,
the index of a bounding box will always be even.
For a leaf node with index n, indexValues(2*n)
contains a segment index in this tile and
indexValues(2*n+1)
a chunk index inside the geometry for that segment.
Cumulative Chunk Lengths
For every chunk in every segment geometry, cumulativeChunkLengths
contains the sum of the
length of that chunk and the lengths of all previous chunks in the segment (inclusive prefix sum).
The cumulative chunk lengths can be used to calculate the distance fraction for a point on a segment's geometry.
The distance fraction (or simply fraction) for a point on a segment is the ratio between
the distance you need to travel along a segment from the beginning of the segment to reach that point
and the length of the segment.
A segment whose geometry consists of p
points, always has p-1
chunks.
To retrieve the cumulative chunk length for the chunk with index c
in the segment with index n
,
you therefore need to use the following index into cumulativeChunkLengths
:
length_index = segmentGeometryFirstCoordinateIndices(n) - n + c cumulative_chunk_length = cumulativeChunkLengths(length_index)
The cumulative chunk length of a segment's last chunk is also the total length of the segment.
segment_length = cumulativeChunkLengths(segmentGeometryFirstCoordinateIndices(n + 1) - n - 2)
- Note
Although this object contains Arrays, you should treat it as immutable.
- Alphabetic
- By Inheritance
- GeometryTile
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Instance Constructors
-
new
GeometryTile(tileId: TileId, segmentGeometryFirstCoordinatesIndices: Array[Int], externalSegmentPartitions: Array[Int], externalSegmentLocalIndices: Array[Int], boundingBoxCoordinates: Array[Long], segmentGeometryCoordinates: Array[Long], indexTree: Array[Int], indexValues: Array[Int], cumulativeChunkLengths: Array[Int])
- segmentGeometryFirstCoordinatesIndices
The start index for each segment's geometry in segmentGeometryCoordinates
- externalSegmentPartitions
For each external segment, the ID of the tile it belongs to. An external segment is a segment that does not belong to this tile, but whose geometry is partially inside this tile
- externalSegmentLocalIndices
For each external segment, its index in the tile it belongs to. An external segment is a segment that does not belong to this tile, but whose geometry is partially inside this tile
- boundingBoxCoordinates
The bounding boxes used in this tile's index tree. Each bounding box is stored as a pair of points, one for the south-west corner and one for the north-east corner, in that order
- segmentGeometryCoordinates
The geometries (line-strings) for road segments in this tile. Each entry represents a point
- indexTree
The tree structure used as this tile's spatial index
- indexValues
The values associated with each node in this tile's spatial index
- cumulativeChunkLengths
The sum of the length of each segment geometry chunk and the lengths of all previous chunks in a segment's geometry, in millimeters
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
- Definition Classes
- AnyRef → Any
-
final
def
==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
- val boundingBoxCoordinates: Array[Long]
-
def
clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( ... ) @native()
- val cumulativeChunkLengths: Array[Int]
-
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- val externalSegmentLocalIndices: Array[Int]
- val externalSegmentPartitions: Array[Int]
-
def
finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
def
hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- val indexTree: Array[Int]
- val indexValues: Array[Int]
-
def
internalSegmentCount: Int
The number of segments in this tile.
The number of segments in this tile.
The number of internal segments is calculated as
segmentGeometryFirstCoordinatesIndices.length - externalSegmentPartitions.length - 1
. -
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- val segmentGeometryCoordinates: Array[Long]
- val segmentGeometryFirstCoordinatesIndices: Array[Int]
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
- val tileId: TileId
-
def
toString(): String
- Definition Classes
- AnyRef → Any
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... ) @native()