Class GeometryTile
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 theGraphTile
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
GeometryTile
s 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, GeometryTile
s 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)
param: segmentGeometryCoordinates The geometries (line-strings) for road segments in this tile. Each entry represents a point param: segmentGeometryFirstCoordinatesIndices The start index for each segment's geometry in segmentGeometryCoordinates param: 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 param: 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 param: 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 param: indexTree The tree structure used as this tile's spatial index param: indexValues The values associated with each node in this tile's spatial index param: 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
- Note:
- Although this object contains Arrays, you should treat it as immutable.
-
Constructor Summary
ConstructorsConstructorDescriptionGeometryTile
(TileId tileId, int[] segmentGeometryFirstCoordinatesIndices, int[] externalSegmentPartitions, int[] externalSegmentLocalIndices, long[] boundingBoxCoordinates, long[] segmentGeometryCoordinates, int[] indexTree, int[] indexValues, int[] cumulativeChunkLengths) -
Method Summary
Modifier and TypeMethodDescriptionlong[]
static ProjectionDistanceCalculator
The chunk length calculator used by the Optimized Map Compiler, and TiledGeometryPropertyMapstatic double
chunkLengthToMeters
(int chunkLength) Converts a length value fromGeometryTile
.cumulativeChunkLengths
to a value in meters.int[]
int[]
int[]
int[]
int[]
int
The number of segments in this tile.static int
metersToChunkLength
(double meters) Converts a length value in meters to a value suitable forGeometryTile
.cumulativeChunkLengths
.long[]
int[]
tileId()
-
Constructor Details
-
GeometryTile
public GeometryTile(TileId tileId, int[] segmentGeometryFirstCoordinatesIndices, int[] externalSegmentPartitions, int[] externalSegmentLocalIndices, long[] boundingBoxCoordinates, long[] segmentGeometryCoordinates, int[] indexTree, int[] indexValues, int[] cumulativeChunkLengths)
-
-
Method Details
-
chunkLengthToMeters
public static double chunkLengthToMeters(int chunkLength) Converts a length value fromGeometryTile
.cumulativeChunkLengths
to a value in meters. -
metersToChunkLength
public static int metersToChunkLength(double meters) Converts a length value in meters to a value suitable forGeometryTile
.cumulativeChunkLengths
. -
ChunkLengthCalculatorSinusoidalProjectionCenteredOnChunkFirstPoint
public static ProjectionDistanceCalculator ChunkLengthCalculatorSinusoidalProjectionCenteredOnChunkFirstPoint()The chunk length calculator used by the Optimized Map Compiler, and TiledGeometryPropertyMap -
tileId
-
segmentGeometryFirstCoordinatesIndices
public int[] segmentGeometryFirstCoordinatesIndices() -
externalSegmentPartitions
public int[] externalSegmentPartitions() -
externalSegmentLocalIndices
public int[] externalSegmentLocalIndices() -
boundingBoxCoordinates
public long[] boundingBoxCoordinates() -
segmentGeometryCoordinates
public long[] segmentGeometryCoordinates() -
indexTree
public int[] indexTree() -
indexValues
public int[] indexValues() -
cumulativeChunkLengths
public int[] cumulativeChunkLengths() -
internalSegmentCount
public int internalSegmentCount()The number of segments in this tile.The number of internal segments is calculated as
segmentGeometryFirstCoordinatesIndices.length - externalSegmentPartitions.length - 1
.
-