mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-10-10 18:03:54 +02:00
cleanup old node cache I forgot to delete in january
This commit is contained in:
1 parent
6c9abba15b
commit
4429663a03
4 files changed
+6
-183
No files matched your search
+3
-2
@@ -53,7 +53,7 @@ AppState (Coordinator)
|
|||||||
↕️
|
↕️
|
||||||
State Modules (AuthState, ProfileState, etc.)
|
State Modules (AuthState, ProfileState, etc.)
|
||||||
↕️
|
↕️
|
||||||
Services (MapDataProvider, NodeCache, Uploader)
|
Services (MapDataProvider, NodeDataManager, NodeSpatialCache, Uploader)
|
||||||
↕️
|
↕️
|
||||||
External APIs (OSM, Overpass, Tile providers)
|
External APIs (OSM, Overpass, Tile providers)
|
||||||
```
|
```
|
||||||
@@ -926,7 +926,8 @@ lib/
|
|||||||
├── services/ # Business logic
|
├── services/ # Business logic
|
||||||
│ ├── map_data_provider.dart
|
│ ├── map_data_provider.dart
|
||||||
│ ├── uploader.dart
|
│ ├── uploader.dart
|
||||||
│ └── node_cache.dart
|
│ ├── node_data_manager.dart
|
||||||
|
│ └── node_spatial_cache.dart
|
||||||
├── state/ # State management
|
├── state/ # State management
|
||||||
│ ├── app_state.dart
|
│ ├── app_state.dart
|
||||||
│ ├── auth_state.dart
|
│ ├── auth_state.dart
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ class MapDataProvider {
|
|||||||
_nodeDataManager.addOrUpdateNodes(nodes);
|
_nodeDataManager.addOrUpdateNodes(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NodeCache compatibility - alias for addOrUpdateNodes
|
/// Alias for addOrUpdateNodes (shorter name used by the upload queue)
|
||||||
void addOrUpdate(List<OsmNode> nodes) {
|
void addOrUpdate(List<OsmNode> nodes) {
|
||||||
addOrUpdateNodes(nodes);
|
addOrUpdateNodes(nodes);
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ class MapDataProvider {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NodeCache compatibility methods for upload queue
|
/// Pending-upload helpers used by the upload queue.
|
||||||
/// These all delegate to the singleton cache to ensure consistency
|
/// These all delegate to the singleton cache to ensure consistency
|
||||||
OsmNode? getNodeById(int nodeId) => NodeSpatialCache().getNodeById(nodeId);
|
OsmNode? getNodeById(int nodeId) => NodeSpatialCache().getNodeById(nodeId);
|
||||||
void removePendingEditMarker(int nodeId) => NodeSpatialCache().removePendingEditMarker(nodeId);
|
void removePendingEditMarker(int nodeId) => NodeSpatialCache().removePendingEditMarker(nodeId);
|
||||||
|
|||||||
@@ -1,178 +0,0 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:latlong2/latlong.dart';
|
|
||||||
import '../models/osm_node.dart';
|
|
||||||
import 'package:flutter_map/flutter_map.dart' show LatLngBounds;
|
|
||||||
|
|
||||||
const Distance _distance = Distance();
|
|
||||||
|
|
||||||
class NodeCache {
|
|
||||||
// Singleton instance
|
|
||||||
static final NodeCache instance = NodeCache._internal();
|
|
||||||
factory NodeCache() => instance;
|
|
||||||
NodeCache._internal();
|
|
||||||
|
|
||||||
final Map<int, OsmNode> _nodes = {};
|
|
||||||
|
|
||||||
/// Add or update a batch of nodes in the cache.
|
|
||||||
/// TODO: Consider moving to compute() if cache operations cause ANR
|
|
||||||
void addOrUpdate(List<OsmNode> nodes) {
|
|
||||||
for (var node in nodes) {
|
|
||||||
final existing = _nodes[node.id];
|
|
||||||
if (existing != null) {
|
|
||||||
// Preserve any tags starting with underscore when updating existing nodes
|
|
||||||
final mergedTags = Map<String, String>.from(node.tags);
|
|
||||||
for (final entry in existing.tags.entries) {
|
|
||||||
if (entry.key.startsWith('_')) {
|
|
||||||
mergedTags[entry.key] = entry.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_nodes[node.id] = OsmNode(
|
|
||||||
id: node.id,
|
|
||||||
coord: node.coord,
|
|
||||||
tags: mergedTags,
|
|
||||||
// Once a node is known to be constrained, keep it that way - see
|
|
||||||
// NodeSpatialCache.addOrUpdateNodes for the full explanation.
|
|
||||||
isConstrained: existing.isConstrained || node.isConstrained,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
_nodes[node.id] = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Query for all cached nodes currently within the given LatLngBounds.
|
|
||||||
List<OsmNode> queryByBounds(LatLngBounds bounds) {
|
|
||||||
return _nodes.values
|
|
||||||
.where((node) => _inBounds(node.coord, bounds))
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve all cached nodes.
|
|
||||||
List<OsmNode> getAll() => _nodes.values.toList();
|
|
||||||
|
|
||||||
/// Optionally clear the cache (rarely needed)
|
|
||||||
void clear() => _nodes.clear();
|
|
||||||
|
|
||||||
/// Remove the _pending_edit marker from a specific node
|
|
||||||
void removePendingEditMarker(int nodeId) {
|
|
||||||
final node = _nodes[nodeId];
|
|
||||||
if (node != null && node.tags.containsKey('_pending_edit')) {
|
|
||||||
final cleanTags = Map<String, String>.from(node.tags);
|
|
||||||
cleanTags.remove('_pending_edit');
|
|
||||||
|
|
||||||
_nodes[nodeId] = OsmNode(
|
|
||||||
id: node.id,
|
|
||||||
coord: node.coord,
|
|
||||||
tags: cleanTags,
|
|
||||||
isConstrained: node.isConstrained, // Preserve constraint information
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove the _pending_deletion marker from a specific node (when deletion is cancelled)
|
|
||||||
void removePendingDeletionMarker(int nodeId) {
|
|
||||||
final node = _nodes[nodeId];
|
|
||||||
if (node != null && node.tags.containsKey('_pending_deletion')) {
|
|
||||||
final cleanTags = Map<String, String>.from(node.tags);
|
|
||||||
cleanTags.remove('_pending_deletion');
|
|
||||||
|
|
||||||
_nodes[nodeId] = OsmNode(
|
|
||||||
id: node.id,
|
|
||||||
coord: node.coord,
|
|
||||||
tags: cleanTags,
|
|
||||||
isConstrained: node.isConstrained, // Preserve constraint information
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove a node by ID from the cache (used for successful deletions)
|
|
||||||
void removeNodeById(int nodeId) {
|
|
||||||
if (_nodes.remove(nodeId) != null) {
|
|
||||||
debugPrint('[NodeCache] Removed node $nodeId from cache (successful deletion)');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove temporary nodes (negative IDs) with _pending_upload marker at the given coordinate
|
|
||||||
/// This is used when a real node ID is assigned to clean up temp placeholders
|
|
||||||
void removeTempNodesByCoordinate(LatLng coord, {double tolerance = 0.00001}) {
|
|
||||||
final nodesToRemove = <int>[];
|
|
||||||
|
|
||||||
for (final entry in _nodes.entries) {
|
|
||||||
final nodeId = entry.key;
|
|
||||||
final node = entry.value;
|
|
||||||
|
|
||||||
// Only consider temp nodes (negative IDs) with pending upload marker
|
|
||||||
if (nodeId < 0 &&
|
|
||||||
node.tags.containsKey('_pending_upload') &&
|
|
||||||
_coordsMatch(node.coord, coord, tolerance)) {
|
|
||||||
nodesToRemove.add(nodeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final nodeId in nodesToRemove) {
|
|
||||||
_nodes.remove(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodesToRemove.isNotEmpty) {
|
|
||||||
debugPrint('[NodeCache] Removed ${nodesToRemove.length} temp nodes at coordinate ${coord.latitude}, ${coord.longitude}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove a specific temporary node by its ID (for queue item-specific cleanup)
|
|
||||||
void removeTempNodeById(int tempNodeId) {
|
|
||||||
if (tempNodeId >= 0) {
|
|
||||||
debugPrint('[NodeCache] Warning: Attempted to remove non-temp node ID $tempNodeId');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_nodes.remove(tempNodeId) != null) {
|
|
||||||
debugPrint('[NodeCache] Removed specific temp node $tempNodeId from cache');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a specific node by ID (returns null if not found)
|
|
||||||
OsmNode? getNodeById(int nodeId) {
|
|
||||||
return _nodes[nodeId];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if two coordinates match within tolerance
|
|
||||||
bool _coordsMatch(LatLng coord1, LatLng coord2, double tolerance) {
|
|
||||||
return (coord1.latitude - coord2.latitude).abs() < tolerance &&
|
|
||||||
(coord1.longitude - coord2.longitude).abs() < tolerance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find nodes within the specified distance (in meters) of the given coordinate
|
|
||||||
/// Excludes nodes with the excludeNodeId (useful when checking proximity for edited nodes)
|
|
||||||
/// Includes pending nodes to warn about potential duplicates
|
|
||||||
List<OsmNode> findNodesWithinDistance(LatLng coord, double distanceMeters, {int? excludeNodeId}) {
|
|
||||||
final nearbyNodes = <OsmNode>[];
|
|
||||||
|
|
||||||
for (final node in _nodes.values) {
|
|
||||||
// Skip the excluded node (typically the node being edited)
|
|
||||||
if (excludeNodeId != null && node.id == excludeNodeId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Include all nodes (real and pending) to catch potential duplicates
|
|
||||||
// Only skip nodes marked for deletion since they won't actually exist after processing
|
|
||||||
if (node.tags.containsKey('_pending_deletion')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final distance = _distance.as(LengthUnit.Meter, coord, node.coord);
|
|
||||||
if (distance <= distanceMeters) {
|
|
||||||
nearbyNodes.add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nearbyNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Utility: point-in-bounds for coordinates
|
|
||||||
bool _inBounds(LatLng coord, LatLngBounds bounds) {
|
|
||||||
return coord.latitude >= bounds.southWest.latitude &&
|
|
||||||
coord.latitude <= bounds.northEast.latitude &&
|
|
||||||
coord.longitude >= bounds.southWest.longitude &&
|
|
||||||
coord.longitude <= bounds.northEast.longitude;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -375,7 +375,7 @@ class NodeDataManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NodeCache compatibility methods
|
/// Pending-upload helpers used by the upload queue.
|
||||||
OsmNode? getNodeById(int nodeId) => _cache.getNodeById(nodeId);
|
OsmNode? getNodeById(int nodeId) => _cache.getNodeById(nodeId);
|
||||||
void removePendingEditMarker(int nodeId) => _cache.removePendingEditMarker(nodeId);
|
void removePendingEditMarker(int nodeId) => _cache.removePendingEditMarker(nodeId);
|
||||||
void removePendingDeletionMarker(int nodeId) => _cache.removePendingDeletionMarker(nodeId);
|
void removePendingDeletionMarker(int nodeId) => _cache.removePendingDeletionMarker(nodeId);
|
||||||
|
|||||||
Reference in new issue
Block a user