fromBytes static method
Create from bytes using vtzero decoder
Implementation
static VectorTileVtzero fromBytes({required Uint8List bytes}) {
final vtzTile = VtzTile.fromBytes(bytes);
final layers = <vt.VectorTileLayer>[];
try {
final vtzLayers = vtzTile.getLayers();
for (final vtzLayer in vtzLayers) {
final features = <vt.VectorTileFeature>[];
final keys = <String>[];
final values = <vt.VectorTileValue>[];
final vtzFeatures = vtzLayer.getFeatures();
for (final vtzFeature in vtzFeatures) {
// Get properties and build keys/values tables
final props = vtzFeature.getProperties();
final tags = <int>[];
props.forEach((key, value) {
// Add key to keys table if not exists
int keyIndex = keys.indexOf(key);
if (keyIndex == -1) {
keyIndex = keys.length;
keys.add(key);
}
// Add value to values table if not exists
final vtValue = _convertValue(value);
int valueIndex = values.indexWhere((v) => _valuesEqual(v, vtValue));
if (valueIndex == -1) {
valueIndex = values.length;
values.add(vtValue);
}
// Add key-value pair as tags
tags.add(keyIndex);
tags.add(valueIndex);
});
// Convert geometry type
vt.VectorTileGeomType? vtType;
switch (vtzFeature.geometryType) {
case VtzGeometryType.point:
vtType = vt.VectorTileGeomType.POINT;
break;
case VtzGeometryType.linestring:
vtType = vt.VectorTileGeomType.LINESTRING;
break;
case VtzGeometryType.polygon:
vtType = vt.VectorTileGeomType.POLYGON;
break;
default:
vtType = vt.VectorTileGeomType.UNKNOWN;
}
// Create closure that captures feature for lazy geometry decoding
final layerExtent = vtzLayer.extent;
final geomType = vtzFeature.geometryType;
// Create optimized feature with geometry decoder closure
features.add(
VectorTileFeatureVtzero(
geometryDecoder: (int x, int y, int z) {
return vtzFeature.toGeoJson(
extent: layerExtent,
tileX: x,
tileY: y,
tileZ: z,
);
},
geometryTypeVtz: geomType,
extent: vtzLayer.extent,
id: vtzFeature.id != null ? Int64(vtzFeature.id!) : Int64.ZERO,
tags: tags,
type: vtType,
geometryList: [], // Not needed - we use native toGeoJson
keys: keys,
values: values,
),
);
}
layers.add(
VectorTileLayerVtzero(
name: vtzLayer.name,
extent: vtzLayer.extent,
version: vtzLayer.version,
keys: keys,
values: values,
features: features,
),
);
// DON'T dispose features or layers - they're kept alive via closures
// vtzLayer.dispose();
}
// DON'T dispose tile - features still reference it via closures
// Note: The native objects stay in memory until VectorTileVtzero is garbage collected
// vtzTile.dispose();
return VectorTileVtzero(layers: layers);
} catch (e) {
// Only dispose tile on error - features/layers are already consumed
vtzTile.dispose();
rethrow;
}
}