diff --git a/lib/services/location_service.dart b/lib/services/location_service.dart index b3b6bb4a8..1f35000b9 100644 --- a/lib/services/location_service.dart +++ b/lib/services/location_service.dart @@ -8,6 +8,7 @@ import "package:photos/core/constants.dart"; import "package:photos/core/event_bus.dart"; import "package:photos/events/location_tag_updated_event.dart"; import "package:photos/models/api/entity/type.dart"; +import "package:photos/models/file/file.dart"; import "package:photos/models/local_entity_data.dart"; import "package:photos/models/location/location.dart"; import 'package:photos/models/location_tag/location_tag.dart'; @@ -43,8 +44,19 @@ class LocationService { ); } - List getAllCities() { - return _cities; + Future>> getFilesInCity( + List allFiles, + String query, + ) async { + final result = await _computer.compute( + getCityResults, + param: { + "query": query, + "cities": _cities, + "files": allFiles, + }, + ); + return result; } Future>> getLocationTags() { @@ -81,14 +93,6 @@ class LocationService { } } - ///The area bounded by the location tag becomes more elliptical with increase - ///in the magnitude of the latitude on the caritesian plane. When latitude is - ///0 degrees, the ellipse is a circle with a = b = r. When latitude incrases, - ///the major axis (a) has to be scaled by the secant of the latitude. - double _scaleFactor(double lat) { - return 1 / cos(lat * (pi / 180)); - } - Future>> enclosingLocationTags( Location fileCoordinates, ) async { @@ -114,22 +118,6 @@ class LocationService { } } - bool isFileInsideLocationTag( - Location centerPoint, - Location fileCoordinates, - double radius, - ) { - final a = - (radius * _scaleFactor(centerPoint.latitude!)) / kilometersPerDegree; - final b = radius / kilometersPerDegree; - final x = centerPoint.latitude! - fileCoordinates.latitude!; - final y = centerPoint.longitude! - fileCoordinates.longitude!; - if ((x * x) / (a * a) + (y * y) / (b * b) <= 1) { - return true; - } - return false; - } - /// returns [lat, lng] List? convertLocationToDMS(Location centerPoint) { if (centerPoint.latitude == null || centerPoint.longitude == null) { @@ -248,6 +236,61 @@ Future> parseCities(Map args) async { return cities; } +Map> getCityResults(Map args) { + final query = (args["query"] as String).toLowerCase(); + final cities = args["cities"] as List; + final files = args["files"] as List; + + final matchingCities = cities.where( + (city) => city.city.toLowerCase().contains(query), + ); + + final Map> results = {}; + for (final city in matchingCities) { + final List matchingFiles = []; + final cityLocation = Location(latitude: city.lat, longitude: city.lng); + for (final file in files) { + if (file.hasLocation) { + if (isFileInsideLocationTag( + cityLocation, + file.location!, + defaultCityRadius, + )) { + matchingFiles.add(file); + } + } + } + if (matchingFiles.isNotEmpty) { + results[city] = matchingFiles; + } + } + return results; +} + +bool isFileInsideLocationTag( + Location centerPoint, + Location fileCoordinates, + double radius, +) { + final a = + (radius * _scaleFactor(centerPoint.latitude!)) / kilometersPerDegree; + final b = radius / kilometersPerDegree; + final x = centerPoint.latitude! - fileCoordinates.latitude!; + final y = centerPoint.longitude! - fileCoordinates.longitude!; + if ((x * x) / (a * a) + (y * y) / (b * b) <= 1) { + return true; + } + return false; +} + +///The area bounded by the location tag becomes more elliptical with increase +///in the magnitude of the latitude on the caritesian plane. When latitude is +///0 degrees, the ellipse is a circle with a = b = r. When latitude incrases, +///the major axis (a) has to be scaled by the secant of the latitude. +double _scaleFactor(double lat) { + return 1 / cos(lat * (pi / 180)); +} + class City { final String city; final String country; diff --git a/lib/services/search_service.dart b/lib/services/search_service.dart index 7b831480a..97fb16dbe 100644 --- a/lib/services/search_service.dart +++ b/lib/services/search_service.dart @@ -3,7 +3,6 @@ import "dart:math"; import "package:flutter/cupertino.dart"; import "package:intl/intl.dart"; import 'package:logging/logging.dart'; -import "package:photos/core/constants.dart"; import 'package:photos/core/event_bus.dart'; import 'package:photos/data/holidays.dart'; import 'package:photos/data/months.dart'; @@ -18,7 +17,6 @@ import "package:photos/models/file/extensions/file_props.dart"; import 'package:photos/models/file/file.dart'; import 'package:photos/models/file/file_type.dart'; import "package:photos/models/local_entity_data.dart"; -import "package:photos/models/location/location.dart"; import "package:photos/models/location_tag/location_tag.dart"; import 'package:photos/models/search/album_search_result.dart'; import 'package:photos/models/search/generic_search_result.dart'; @@ -620,7 +618,7 @@ class SearchService { for (EnteFile file in allFiles) { if (file.hasLocation) { for (LocalEntity tag in result.keys) { - if (LocationService.instance.isFileInsideLocationTag( + if (isFileInsideLocationTag( tag.item.centerPoint, file.location!, tag.item.radius, @@ -639,7 +637,7 @@ class SearchService { return false; } for (LocalEntity tag in locationTagEntities) { - if (LocationService.instance.isFileInsideLocationTag( + if (isFileInsideLocationTag( tag.item.centerPoint, file.location!, tag.item.radius, @@ -684,36 +682,9 @@ class SearchService { } Future> getCityResults(String query) async { - final startTime = DateTime.now().microsecondsSinceEpoch; - final List searchResults = []; - final cities = LocationService.instance.getAllCities(); - final matchingCities = []; - final queryLower = query.toLowerCase(); - for (City city in cities) { - if (city.city.toLowerCase().startsWith(queryLower)) { - matchingCities.add(city); - } - } final files = await getAllFiles(); - final Map> results = {}; - for (final city in matchingCities) { - final List matchingFiles = []; - final cityLocation = Location(latitude: city.lat, longitude: city.lng); - for (final file in files) { - if (file.hasLocation) { - if (LocationService.instance.isFileInsideLocationTag( - cityLocation, - file.location!, - defaultCityRadius, - )) { - matchingFiles.add(file); - } - } - } - if (matchingFiles.isNotEmpty) { - results[city] = matchingFiles; - } - } + final results = await LocationService.instance.getFilesInCity(files, query); + final List searchResults = []; for (final entry in results.entries) { searchResults.add( GenericSearchResult( @@ -723,9 +694,6 @@ class SearchService { ), ); } - final endTime = DateTime.now().microsecondsSinceEpoch; - _logger - .info("Time taken " + ((endTime - startTime) / 1000).toString() + "ms"); return searchResults; } @@ -745,7 +713,7 @@ class SearchService { for (EnteFile file in allFiles) { if (file.hasLocation) { for (LocalEntity tag in tagToItemsMap.keys) { - if (LocationService.instance.isFileInsideLocationTag( + if (isFileInsideLocationTag( tag.item.centerPoint, file.location!, tag.item.radius, diff --git a/lib/ui/viewer/location/dynamic_location_gallery_widget.dart b/lib/ui/viewer/location/dynamic_location_gallery_widget.dart index 3103fa143..04dbcd6a6 100644 --- a/lib/ui/viewer/location/dynamic_location_gallery_widget.dart +++ b/lib/ui/viewer/location/dynamic_location_gallery_widget.dart @@ -62,7 +62,7 @@ class _DynamicLocationGalleryWidgetState final stopWatch = Stopwatch()..start(); final copyOfFiles = List.from(result.files); copyOfFiles.removeWhere((f) { - return !LocationService.instance.isFileInsideLocationTag( + return !isFileInsideLocationTag( InheritedLocationTagData.of(context).centerPoint, f.location!, selectedRadius, diff --git a/lib/ui/viewer/location/location_screen.dart b/lib/ui/viewer/location/location_screen.dart index cdfa7f92b..374d70cb9 100644 --- a/lib/ui/viewer/location/location_screen.dart +++ b/lib/ui/viewer/location/location_screen.dart @@ -205,7 +205,7 @@ class _LocationGalleryWidgetState extends State { final stopWatch = Stopwatch()..start(); final filesInLocation = allFilesWithLocation; filesInLocation.removeWhere((f) { - return !LocationService.instance.isFileInsideLocationTag( + return !isFileInsideLocationTag( centerPoint, f.location!, selectedRadius,