119 lines
2.8 KiB
Dart
119 lines
2.8 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:aves_map/aves_map.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:latlong2/latlong.dart';
|
|
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart' as mbx;
|
|
|
|
class MapboxTracksLayer {
|
|
static const sourceId = 'aves-mapbox-tracks-source';
|
|
static const layerId = 'aves-mapbox-tracks-layer';
|
|
|
|
static Future<void> remove({
|
|
required mbx.MapboxMap mapboxMap,
|
|
required void Function(String message) log,
|
|
required String reason,
|
|
}) async {
|
|
final style = mapboxMap.style as dynamic;
|
|
|
|
log('remove tracks layer reason=$reason');
|
|
|
|
try {
|
|
await style.removeStyleLayer(layerId);
|
|
} catch (_) {
|
|
// Layer may not exist.
|
|
}
|
|
|
|
try {
|
|
await style.removeStyleSource(sourceId);
|
|
} catch (_) {
|
|
// Source may not exist.
|
|
}
|
|
}
|
|
|
|
static Future<void> update({
|
|
required mbx.MapboxMap mapboxMap,
|
|
required Set<List<LatLng>>? tracks,
|
|
required Color color,
|
|
required double width,
|
|
required void Function(String message) log,
|
|
required String reason,
|
|
}) async {
|
|
await remove(
|
|
mapboxMap: mapboxMap,
|
|
log: log,
|
|
reason: reason,
|
|
);
|
|
|
|
if (tracks == null || tracks.isEmpty) {
|
|
log('tracks skipped empty reason=$reason');
|
|
return;
|
|
}
|
|
|
|
final lineStrings = tracks
|
|
.map(
|
|
(track) => track
|
|
.where(
|
|
(point) =>
|
|
point.latitude.isFinite && point.longitude.isFinite,
|
|
)
|
|
.map(
|
|
(point) => [
|
|
point.longitude,
|
|
point.latitude,
|
|
],
|
|
)
|
|
.toList(),
|
|
)
|
|
.where((coordinates) => coordinates.length >= 2)
|
|
.toList();
|
|
|
|
if (lineStrings.isEmpty) {
|
|
log('tracks skipped no valid line strings reason=$reason');
|
|
return;
|
|
}
|
|
|
|
final geoJson = jsonEncode({
|
|
'type': 'FeatureCollection',
|
|
'features': [
|
|
{
|
|
'type': 'Feature',
|
|
'properties': {},
|
|
'geometry': {
|
|
'type': 'MultiLineString',
|
|
'coordinates': lineStrings,
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
log(
|
|
'add tracks layer '
|
|
'reason=$reason '
|
|
'tracks=${tracks.length} '
|
|
'segments=${lineStrings.length} '
|
|
'points=${lineStrings.fold<int>(0, (sum, line) => sum + line.length)}',
|
|
);
|
|
|
|
try {
|
|
await mapboxMap.style.addSource(
|
|
mbx.GeoJsonSource(
|
|
id: sourceId,
|
|
data: geoJson,
|
|
),
|
|
);
|
|
|
|
await mapboxMap.style.addLayer(
|
|
mbx.LineLayer(
|
|
id: layerId,
|
|
sourceId: sourceId,
|
|
lineColor: color.value,
|
|
lineWidth: width,
|
|
lineOpacity: 1.0,
|
|
),
|
|
);
|
|
} catch (e) {
|
|
log('tracks layer add failed reason=$reason error=$e');
|
|
}
|
|
}
|
|
}
|