read1Way method
List<Way>
read1Way(
- Readbuffer readBuffer,
- QueryParameters queryParameters,
- double tileLatitude,
- double tileLongitude,
- MapDatastore mapDataStore,
- List<
Tag> wayTags, - bool filterRequired,
- BoundingBox wayFilterBbox,
- MapfileSelector selector,
Reads a single way from the given readBuffer and returns it as a list
containing one or more Way objects.
A single way entry in the map file can result in multiple Way objects if
it consists of multiple data blocks (e.g., for multipolygons).
Implementation
List<Way> read1Way(
Readbuffer readBuffer,
QueryParameters queryParameters,
double tileLatitude,
double tileLongitude,
MapDatastore mapDataStore,
List<Tag> wayTags,
bool filterRequired,
BoundingBox wayFilterBbox,
MapfileSelector selector,
) {
List<Way> ways = [];
if (_mapFileHeader.getMapHeaderInfo().debugFile) {
// get and check the way signature
String signatureWay = readBuffer.readUTF8EncodedString2(SIGNATURE_LENGTH_WAY);
if (!signatureWay.startsWith("---WayStart")) {
throw MapFileException("invalid way signature: $signatureWay");
}
}
// get the size of the way (VBE-U)
int wayDataSize = readBuffer.readUnsignedInt();
if (wayDataSize < 0) {
throw MapFileException("invalid way data size: $wayDataSize");
}
/*int pos =*/
readBuffer.getBufferPosition();
if (queryParameters.useTileBitmask) {
// get the way tile bitmask (2 bytes)
int tileBitmask = readBuffer.readShort();
// check if the way is inside the requested tile
if ((queryParameters.queryTileBitmask! & tileBitmask) == 0) {
// skip the rest of the way and continue with the next way
readBuffer.skipBytes(wayDataSize - 2);
return ways;
}
} else {
// ignore the way tile bitmask (2 bytes)
readBuffer.skipBytes(2);
}
// get the special int which encodes multiple flags
int specialByte = readBuffer.readByte();
// bit 1-4 represent the layer
int layer = ((specialByte & WAY_LAYER_BITMASK) >> WAY_LAYER_SHIFT);
// bit 5-8 represent the number of tag IDs
int numberOfTags = (specialByte & WAY_NUMBER_OF_TAGS_BITMASK);
// get the tags from IDs (VBE-U)
List<Tag> tags = readBuffer.readTags(wayTags, numberOfTags);
//_log.info("processWays for ${wayTags.toString()} and numberofTags: $numberOfTags returned ${tags.length} items");
// get the feature bitmask (1 byte)
int featureByte = readBuffer.readByte();
// bit 1-6 enable optional features
bool featureName = (featureByte & WAY_FEATURE_NAME) != 0;
bool featureHouseNumber = (featureByte & WAY_FEATURE_HOUSE_NUMBER) != 0;
bool featureRef = (featureByte & WAY_FEATURE_REF) != 0;
bool featureLabelPosition = (featureByte & WAY_FEATURE_LABEL_POSITION) != 0;
bool featureWayDataBlocksByte = (featureByte & WAY_FEATURE_DATA_BLOCKS_BYTE) != 0;
bool featureWayDoubleDeltaEncoding = (featureByte & WAY_FEATURE_DOUBLE_DELTA_ENCODING) != 0;
// check if the way has a name
if (featureName) {
try {
tags.add(Tag(TAG_KEY_NAME, mapDataStore.extractLocalized(readBuffer.readUTF8EncodedString())!));
} catch (e) {
_log.warning(e.toString());
//tags.add(Tag(TAG_KEY_NAME, "unknown"));
}
}
// check if the way has a house number
if (featureHouseNumber) {
try {
tags.add(Tag(TAG_KEY_HOUSE_NUMBER, readBuffer.readUTF8EncodedString()));
} catch (e) {
_log.warning(e.toString());
//tags.add(Tag(TAG_KEY_NAME, "unknown"));
}
}
// check if the way has a reference
if (featureRef) {
try {
tags.add(Tag(TAG_KEY_REF, readBuffer.readUTF8EncodedString()));
} catch (e) {
_log.warning(e.toString());
//tags.add(Tag(TAG_KEY_NAME, "unknown"));
}
}
List<int>? labelPosition;
if (featureLabelPosition) {
labelPosition = _readOptionalLabelPosition(readBuffer);
}
int wayDataBlocks = _readOptionalWayDataBlocksByte(featureWayDataBlocksByte, readBuffer);
if (wayDataBlocks < 1) {
throw MapFileException("invalid number of way data blocks: $wayDataBlocks");
}
for (int wayDataBlock = 0; wayDataBlock < wayDataBlocks; ++wayDataBlock) {
List<List<LatLong>> wayNodes = _processWayDataBlock(tileLatitude, tileLongitude, featureWayDoubleDeltaEncoding, readBuffer);
if (filterRequired && wayFilterEnabled && !wayFilterBbox.intersectsArea(wayNodes)) {
continue;
}
if (MapfileSelector.ALL == selector || featureName || featureHouseNumber || featureRef || wayAsLabelTagFilter(tags)) {
LatLong? labelLatLong;
if (labelPosition != null) {
labelLatLong = LatLong(
wayNodes[0][0].latitude + LatLongUtils.microdegreesToDegrees(labelPosition[1]),
wayNodes[0][0].longitude + LatLongUtils.microdegreesToDegrees(labelPosition[0]),
);
}
ways.add(Way(layer, tags, wayNodes, labelLatLong));
}
}
return ways;
}