Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@ fuchsia/build/
web/build/

# ───────────────────────────────
# IDE / Editor Settings
# IDE / Editor / AI Tool Settings
# ───────────────────────────────
.idea/
.idea/**/workspace.xml
.idea/**/tasks.xml
.vscode/
.claude/settings.local.json
# Swap files
*.swp
*.swo
Expand Down
25 changes: 24 additions & 1 deletion lib/dev_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const double kNavigationMinRouteDistance = 100.0; // meters - minimum distance b
const double kNavigationDistanceWarningThreshold = 20000.0; // meters - distance threshold for timeout warning (30km)

// Node display configuration
const int kDefaultMaxNodes = 500; // Default maximum number of nodes to render on the map at once
const int kDefaultMaxNodes = 2000; // Default maximum number of nodes to render on the map at once (clustering handles visual density)

// NSI (Name Suggestion Index) configuration
const int kNSIMinimumHitCount = 500; // Minimum hit count for NSI suggestions to be considered useful
Expand All @@ -163,8 +163,31 @@ const int kMaxReasonableTileCount = 20000;
const int kAbsoluteMaxTileCount = 50000;
const int kAbsoluteMaxZoom = 23;

// Direction cone zoom gating
const int kDirectionConeMinZoomLevel = 14;

// Direction cone arc smoothness
const int kDirectionConeArcPoints = 36; // points per 90 degrees
const int kDirectionConeMinArcPoints = 12; // minimum for narrow FOVs

// Node icon configuration
const double kNodeIconDiameter = 18.0;

// Node marker zoom scaling
const double kNodeIconReferenceZoom = 15.0;
const double kNodeIconScalePerZoom = 2.0; // px per zoom level
const double kNodeIconMinDiameter = 8.0;
const double kNodeIconMaxDiameter = 28.0;

/// Returns marker diameter scaled by current zoom level
double getScaledNodeDiameter(double zoom) {
final scaled = kNodeIconDiameter + (zoom - kNodeIconReferenceZoom) * kNodeIconScalePerZoom;
return scaled.clamp(kNodeIconMinDiameter, kNodeIconMaxDiameter);
}

// Clustering
const int kNodeClusterMaxZoomLevel = 13; // clustering active at zoom <= 13; disabled at zoom >= 14
const double kClusterIconDiameter = 32.0;
const double _kNodeRingThicknessBase = 2.5;
const double kNodeDotOpacity = 0.3; // Opacity for the grey dot interior
const Color kNodeRingColorReal = Color(0xFF3036F0); // Real nodes from OSM - blue
Expand Down
20 changes: 13 additions & 7 deletions lib/localizations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@
"offlineModeWarning": "Downloads im Offline-Modus deaktiviert. Deaktivieren Sie den Offline-Modus, um neue Bereiche herunterzuladen.",
"areaTooBigMessage": "Zoomen Sie auf mindestens Stufe {} heran, um Offline-Bereiche herunterzuladen. Downloads großer Gebiete können die App zum Absturz bringen.",
"downloadStarted": "Download gestartet! Lade Kacheln und Knoten...",
"downloadFailed": "Download konnte nicht gestartet werden: {}"
"downloadFailed": "Download konnte nicht gestartet werden: {}",
"offlineNotPermitted": "Der {}-Server erlaubt keine Offline-Downloads. Wechseln Sie zu einem Kachelanbieter, der Offline-Nutzung unterstützt (z. B. Bing Maps, Mapbox oder ein selbst gehosteter Kachelserver).",
"currentTileProvider": "aktuelle Kachel",
"noTileProviderSelected": "Kein Kachelanbieter ausgewählt. Bitte wählen Sie einen Kartenstil, bevor Sie einen Offlinebereich herunterladen."
},
"downloadStarted": {
"title": "Download gestartet",
Expand Down Expand Up @@ -292,13 +295,16 @@
"addProfileChoiceMessage": "Wie möchten Sie ein Profil hinzufügen?",
"createCustomProfile": "Benutzerdefiniertes Profil Erstellen",
"createCustomProfileDescription": "Erstellen Sie ein Profil von Grund auf mit Ihren eigenen Tags",
"importFromWebsite": "Von Webseite Importieren",
"importFromWebsite": "Von Webseite Importieren",
"importFromWebsiteDescription": "Profile von deflock.me/identify durchsuchen und importieren"
},
"mapTiles": {
"title": "Karten-Kacheln",
"manageProviders": "Anbieter Verwalten",
"attribution": "Karten-Zuschreibung"
"attribution": "Karten-Zuschreibung",
"mapAttribution": "Kartenquelle: {}",
"couldNotOpenLink": "Link konnte nicht geöffnet werden",
"openLicense": "Lizenz öffnen: {}"
},
"profileEditor": {
"viewProfile": "Profil Anzeigen",
Expand All @@ -325,7 +331,7 @@
},
"operatorProfileEditor": {
"newOperatorProfile": "Neues Betreiber-Profil",
"editOperatorProfile": "Betreiber-Profil Bearbeiten",
"editOperatorProfile": "Betreiber-Profil Bearbeiten",
"operatorName": "Betreiber-Name",
"operatorNameHint": "z.B. Polizei Austin",
"operatorNameRequired": "Betreiber-Name ist erforderlich",
Expand Down Expand Up @@ -520,15 +526,15 @@
"updateFailed": "Aktualisierung der verdächtigen Standorte fehlgeschlagen",
"neverFetched": "Nie abgerufen",
"daysAgo": "vor {} Tagen",
"hoursAgo": "vor {} Stunden",
"hoursAgo": "vor {} Stunden",
"minutesAgo": "vor {} Minuten",
"justNow": "Gerade eben"
},
"suspectedLocation": {
"title": "Verdächtiger Standort #{}",
"ticketNo": "Ticket-Nr.",
"address": "Adresse",
"street": "Straße",
"street": "Straße",
"city": "Stadt",
"state": "Bundesland",
"intersectingStreet": "Kreuzende Straße",
Expand All @@ -552,4 +558,4 @@
"metricDescription": "Metrisch (km, m)",
"imperialDescription": "Imperial (mi, ft)"
}
}
}
24 changes: 15 additions & 9 deletions lib/localizations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"submitAnyway": "Submit Anyway",
"nodeType": {
"alpr": "ALPR/ANPR Camera",
"publicCamera": "Public Surveillance Camera",
"publicCamera": "Public Surveillance Camera",
"camera": "Surveillance Camera",
"amenity": "{}",
"device": "{} Device",
Expand Down Expand Up @@ -181,7 +181,10 @@
"offlineModeWarning": "Downloads disabled while in offline mode. Disable offline mode to download new areas.",
"areaTooBigMessage": "Zoom in to at least level {} to download offline areas. Large area downloads can cause the app to become unresponsive.",
"downloadStarted": "Download started! Fetching tiles and nodes...",
"downloadFailed": "Failed to start download: {}"
"downloadFailed": "Failed to start download: {}",
"offlineNotPermitted": "The {} server does not permit offline downloads. Switch to a tile provider that allows offline use (e.g., Bing Maps, Mapbox, or a self-hosted tile server).",
"currentTileProvider": "current tile",
"noTileProviderSelected": "No tile provider is selected. Please select a map style before downloading an offline area."
},
"downloadStarted": {
"title": "Download Started",
Expand Down Expand Up @@ -329,13 +332,16 @@
"addProfileChoiceMessage": "How would you like to add a profile?",
"createCustomProfile": "Create Custom Profile",
"createCustomProfileDescription": "Build a profile from scratch with your own tags",
"importFromWebsite": "Import from Website",
"importFromWebsite": "Import from Website",
"importFromWebsiteDescription": "Browse and import profiles from deflock.me/identify"
},
"mapTiles": {
"title": "Map Tiles",
"manageProviders": "Manage Providers",
"attribution": "Map Attribution"
"attribution": "Map Attribution",
"mapAttribution": "Map attribution: {}",
"couldNotOpenLink": "Could not open link",
"openLicense": "Open license: {}"
},
"profileEditor": {
"viewProfile": "View Profile",
Expand All @@ -362,7 +368,7 @@
},
"operatorProfileEditor": {
"newOperatorProfile": "New Operator Profile",
"editOperatorProfile": "Edit Operator Profile",
"editOperatorProfile": "Edit Operator Profile",
"operatorName": "Operator name",
"operatorNameHint": "e.g., Austin Police Department",
"operatorNameRequired": "Operator name is required",
Expand Down Expand Up @@ -443,7 +449,7 @@
"mobileEditors": "Mobile Editors",
"iDEditor": "iD Editor",
"iDEditorSubtitle": "Full-featured web editor - always works",
"rapidEditor": "RapiD Editor",
"rapidEditor": "RapiD Editor",
"rapidEditorSubtitle": "AI-assisted editing with Facebook data",
"vespucci": "Vespucci",
"vespucciSubtitle": "Advanced Android OSM editor",
Expand Down Expand Up @@ -520,15 +526,15 @@
"updateFailed": "Failed to update suspected locations",
"neverFetched": "Never fetched",
"daysAgo": "{} days ago",
"hoursAgo": "{} hours ago",
"hoursAgo": "{} hours ago",
"minutesAgo": "{} minutes ago",
"justNow": "Just now"
},
"suspectedLocation": {
"title": "Suspected Location #{}",
"ticketNo": "Ticket No",
"address": "Address",
"street": "Street",
"street": "Street",
"city": "City",
"state": "State",
"intersectingStreet": "Intersecting Street",
Expand All @@ -552,4 +558,4 @@
"metricDescription": "Metric (km, m)",
"imperialDescription": "Imperial (mi, ft)"
}
}
}
20 changes: 13 additions & 7 deletions lib/localizations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@
"offlineModeWarning": "Descargas deshabilitadas en modo sin conexión. Deshabilite el modo sin conexión para descargar nuevas áreas.",
"areaTooBigMessage": "Amplíe al menos al nivel {} para descargar áreas sin conexión. Las descargas de áreas grandes pueden hacer que la aplicación deje de responder.",
"downloadStarted": "¡Descarga iniciada! Obteniendo mosaicos y nodos...",
"downloadFailed": "Error al iniciar la descarga: {}"
"downloadFailed": "Error al iniciar la descarga: {}",
"offlineNotPermitted": "El servidor {} no permite descargas sin conexión. Cambie a un proveedor de mosaicos que permita el uso sin conexión (p. ej., Bing Maps, Mapbox o un servidor de mosaicos propio).",
"currentTileProvider": "mosaico actual",
"noTileProviderSelected": "No hay proveedor de mosaicos seleccionado. Seleccione un estilo de mapa antes de descargar un área sin conexión."
},
"downloadStarted": {
"title": "Descarga Iniciada",
Expand Down Expand Up @@ -329,13 +332,16 @@
"addProfileChoiceMessage": "¿Cómo desea añadir un perfil?",
"createCustomProfile": "Crear Perfil Personalizado",
"createCustomProfileDescription": "Crear un perfil desde cero con sus propias etiquetas",
"importFromWebsite": "Importar desde Sitio Web",
"importFromWebsite": "Importar desde Sitio Web",
"importFromWebsiteDescription": "Explorar e importar perfiles desde deflock.me/identify"
},
"mapTiles": {
"title": "Tiles de Mapa",
"manageProviders": "Gestionar Proveedores",
"attribution": "Atribución del Mapa"
"attribution": "Atribución del Mapa",
"mapAttribution": "Atribución del mapa: {}",
"couldNotOpenLink": "No se pudo abrir el enlace",
"openLicense": "Abrir licencia: {}"
},
"profileEditor": {
"viewProfile": "Ver Perfil",
Expand All @@ -362,7 +368,7 @@
},
"operatorProfileEditor": {
"newOperatorProfile": "Nuevo Perfil de Operador",
"editOperatorProfile": "Editar Perfil de Operador",
"editOperatorProfile": "Editar Perfil de Operador",
"operatorName": "Nombre del operador",
"operatorNameHint": "ej., Departamento de Policía de Austin",
"operatorNameRequired": "El nombre del operador es requerido",
Expand Down Expand Up @@ -520,15 +526,15 @@
"updateFailed": "Error al actualizar ubicaciones sospechosas",
"neverFetched": "Nunca obtenido",
"daysAgo": "hace {} días",
"hoursAgo": "hace {} horas",
"hoursAgo": "hace {} horas",
"minutesAgo": "hace {} minutos",
"justNow": "Ahora mismo"
},
"suspectedLocation": {
"title": "Ubicación Sospechosa #{}",
"ticketNo": "No. de Ticket",
"address": "Dirección",
"street": "Calle",
"street": "Calle",
"city": "Ciudad",
"state": "Estado",
"intersectingStreet": "Calle que Intersecta",
Expand All @@ -552,4 +558,4 @@
"metricDescription": "Métrico (km, m)",
"imperialDescription": "Imperial (mi, ft)"
}
}
}
20 changes: 13 additions & 7 deletions lib/localizations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@
"offlineModeWarning": "Téléchargements désactivés en mode hors ligne. Désactivez le mode hors ligne pour télécharger de nouvelles zones.",
"areaTooBigMessage": "Zoomez au moins au niveau {} pour télécharger des zones hors ligne. Les téléchargements de grandes zones peuvent rendre l'application non réactive.",
"downloadStarted": "Téléchargement démarré ! Récupération des tuiles et nœuds...",
"downloadFailed": "Échec du démarrage du téléchargement: {}"
"downloadFailed": "Échec du démarrage du téléchargement: {}",
"offlineNotPermitted": "Le serveur {} ne permet pas les téléchargements hors ligne. Passez à un fournisseur de tuiles qui autorise l'utilisation hors ligne (par ex., Bing Maps, Mapbox ou un serveur de tuiles auto-hébergé).",
"currentTileProvider": "tuile actuelle",
"noTileProviderSelected": "Aucun fournisseur de tuiles sélectionné. Veuillez choisir un style de carte avant de télécharger une zone hors ligne."
},
"downloadStarted": {
"title": "Téléchargement Démarré",
Expand Down Expand Up @@ -329,13 +332,16 @@
"addProfileChoiceMessage": "Comment souhaitez-vous ajouter un profil?",
"createCustomProfile": "Créer Profil Personnalisé",
"createCustomProfileDescription": "Créer un profil à partir de zéro avec vos propres balises",
"importFromWebsite": "Importer depuis Site Web",
"importFromWebsite": "Importer depuis Site Web",
"importFromWebsiteDescription": "Parcourir et importer des profils depuis deflock.me/identify"
},
"mapTiles": {
"title": "Tuiles de Carte",
"manageProviders": "Gérer Fournisseurs",
"attribution": "Attribution de Carte"
"attribution": "Attribution de Carte",
"mapAttribution": "Attribution de la carte : {}",
"couldNotOpenLink": "Impossible d'ouvrir le lien",
"openLicense": "Ouvrir la licence : {}"
},
"profileEditor": {
"viewProfile": "Voir Profil",
Expand All @@ -362,7 +368,7 @@
},
"operatorProfileEditor": {
"newOperatorProfile": "Nouveau Profil d'Opérateur",
"editOperatorProfile": "Modifier Profil d'Opérateur",
"editOperatorProfile": "Modifier Profil d'Opérateur",
"operatorName": "Nom de l'opérateur",
"operatorNameHint": "ex., Département de Police d'Austin",
"operatorNameRequired": "Le nom de l'opérateur est requis",
Expand Down Expand Up @@ -520,15 +526,15 @@
"updateFailed": "Échec de la mise à jour des emplacements suspects",
"neverFetched": "Jamais récupéré",
"daysAgo": "il y a {} jours",
"hoursAgo": "il y a {} heures",
"hoursAgo": "il y a {} heures",
"minutesAgo": "il y a {} minutes",
"justNow": "À l'instant"
},
"suspectedLocation": {
"title": "Emplacement Suspect #{}",
"ticketNo": "N° de Ticket",
"address": "Adresse",
"street": "Rue",
"street": "Rue",
"city": "Ville",
"state": "État",
"intersectingStreet": "Rue Transversale",
Expand All @@ -552,4 +558,4 @@
"metricDescription": "Métrique (km, m)",
"imperialDescription": "Impérial (mi, ft)"
}
}
}
20 changes: 13 additions & 7 deletions lib/localizations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@
"offlineModeWarning": "Download disabilitati in modalità offline. Disabilita la modalità offline per scaricare nuove aree.",
"areaTooBigMessage": "Ingrandisci almeno al livello {} per scaricare aree offline. I download di aree grandi possono rendere l'app non reattiva.",
"downloadStarted": "Download avviato! Recupero tile e nodi...",
"downloadFailed": "Impossibile avviare il download: {}"
"downloadFailed": "Impossibile avviare il download: {}",
"offlineNotPermitted": "Il server {} non consente i download offline. Passa a un fornitore di tile che consenta l'uso offline (ad es., Bing Maps, Mapbox o un server di tile auto-ospitato).",
"currentTileProvider": "tile attuale",
"noTileProviderSelected": "Nessun provider di tile selezionato. Seleziona uno stile di mappa prima di scaricare un'area offline."
},
"downloadStarted": {
"title": "Download Avviato",
Expand Down Expand Up @@ -329,13 +332,16 @@
"addProfileChoiceMessage": "Come desideri aggiungere un profilo?",
"createCustomProfile": "Crea Profilo Personalizzato",
"createCustomProfileDescription": "Crea un profilo da zero con i tuoi tag",
"importFromWebsite": "Importa da Sito Web",
"importFromWebsite": "Importa da Sito Web",
"importFromWebsiteDescription": "Sfoglia e importa profili da deflock.me/identify"
},
"mapTiles": {
"title": "Tile Mappa",
"manageProviders": "Gestisci Fornitori",
"attribution": "Attribuzione Mappa"
"attribution": "Attribuzione Mappa",
"mapAttribution": "Attribuzione mappa: {}",
"couldNotOpenLink": "Impossibile aprire il link",
"openLicense": "Apri licenza: {}"
},
"profileEditor": {
"viewProfile": "Visualizza Profilo",
Expand All @@ -362,7 +368,7 @@
},
"operatorProfileEditor": {
"newOperatorProfile": "Nuovo Profilo Operatore",
"editOperatorProfile": "Modifica Profilo Operatore",
"editOperatorProfile": "Modifica Profilo Operatore",
"operatorName": "Nome operatore",
"operatorNameHint": "es., Dipartimento di Polizia di Austin",
"operatorNameRequired": "Il nome dell'operatore è obbligatorio",
Expand Down Expand Up @@ -520,15 +526,15 @@
"updateFailed": "Aggiornamento posizioni sospette fallito",
"neverFetched": "Mai recuperato",
"daysAgo": "{} giorni fa",
"hoursAgo": "{} ore fa",
"hoursAgo": "{} ore fa",
"minutesAgo": "{} minuti fa",
"justNow": "Proprio ora"
},
"suspectedLocation": {
"title": "Posizione Sospetta #{}",
"ticketNo": "N. Ticket",
"address": "Indirizzo",
"street": "Via",
"street": "Via",
"city": "Città",
"state": "Stato",
"intersectingStreet": "Via che Interseca",
Expand All @@ -552,4 +558,4 @@
"metricDescription": "Metrico (km, m)",
"imperialDescription": "Imperiale (mi, ft)"
}
}
}
Loading
Loading