Implement location search

This commit is contained in:
Vishnu Mohandas 2020-06-03 19:41:34 +05:30
parent 8e257ae78f
commit 694c0c22d4
6 changed files with 131 additions and 5 deletions

View file

@ -20,6 +20,8 @@ class PhotoDB {
static final columnLocalId = 'local_id';
static final columnTitle = 'title';
static final columnDeviceFolder = 'device_folder';
static final columnLatitude = 'latitude';
static final columnLongitude = 'longitude';
static final columnRemoteFolderId = 'remote_folder_id';
static final columnRemotePath = 'remote_path';
static final columnThumbnailPath = 'thumbnail_path';
@ -57,6 +59,8 @@ class PhotoDB {
$columnUploadedFileId INTEGER NOT NULL,
$columnTitle TEXT NOT NULL,
$columnDeviceFolder TEXT NOT NULL,
$columnLatitude REAL,
$columnLongitude REAL,
$columnRemoteFolderId INTEGER DEFAULT -1,
$columnRemotePath TEXT,
$columnThumbnailPath TEXT,
@ -283,6 +287,8 @@ class PhotoDB {
photo.uploadedFileId == null ? -1 : photo.uploadedFileId;
row[columnTitle] = photo.title;
row[columnDeviceFolder] = photo.deviceFolder;
row[columnLatitude] = photo.latitude;
row[columnLongitude] = photo.longitude;
row[columnRemoteFolderId] = photo.remoteFolderId;
row[columnRemotePath] = photo.remotePath;
row[columnThumbnailPath] = photo.thumbnailPath;
@ -298,6 +304,8 @@ class PhotoDB {
photo.uploadedFileId = row[columnUploadedFileId];
photo.title = row[columnTitle];
photo.deviceFolder = row[columnDeviceFolder];
photo.latitude = row[columnLatitude];
photo.longitude = row[columnLongitude];
photo.remoteFolderId = row[columnRemoteFolderId];
photo.remotePath = row[columnRemotePath];
photo.thumbnailPath = row[columnThumbnailPath];

View file

@ -18,6 +18,8 @@ class Photo {
String thumbnailPath;
int createTimestamp;
int updateTimestamp;
double latitude;
double longitude;
Photo();
Photo.fromJson(Map<String, dynamic> json)
@ -37,6 +39,9 @@ class Photo {
photo.localId = asset.id;
photo.title = asset.title;
photo.deviceFolder = pathEntity.name;
final location = await asset.latlngAsync();
photo.latitude = location.latitude;
photo.longitude = location.longitude;
photo.createTimestamp = asset.createDateTime.microsecondsSinceEpoch;
if (photo.createTimestamp == 0) {
try {

View file

@ -0,0 +1,73 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:latlong/latlong.dart';
import 'package:photos/models/photo.dart';
import 'package:photos/photo_repository.dart';
import 'package:photos/ui/gallery.dart';
import 'package:photos/ui/loading_widget.dart';
class LocationSearchResultsPage extends StatefulWidget {
final LatLng location;
final String name;
LocationSearchResultsPage(this.location, this.name, {Key key})
: super(key: key);
@override
_LocationSearchResultsPageState createState() =>
_LocationSearchResultsPageState();
}
class _LocationSearchResultsPageState extends State<LocationSearchResultsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.name),
),
body: Container(
child: _getBody(),
),
);
}
FutureBuilder<List<Photo>> _getBody() {
return FutureBuilder<List<Photo>>(
future: _getResult(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Gallery(
snapshot.data,
Set<Photo>(),
);
} else {
return Center(child: loadWidget);
}
},
);
}
Future<List<Photo>> _getResult() async {
final photos = PhotoRepository.instance.photos;
final args = Map<String, dynamic>();
args['photos'] = photos;
args['location'] = widget.location;
args['maxDistance'] = 5000;
return await compute(_filterPhotos, args);
}
static List<Photo> _filterPhotos(Map<String, dynamic> args) {
List<Photo> photos = args['photos'];
LatLng location = args['location'];
int maxDistance = args['maxDistance'];
final result = List<Photo>();
for (final photo in photos) {
final distance = Distance().as(LengthUnit.Meter, location,
new LatLng(photo.latitude, photo.longitude));
if (distance < maxDistance) {
result.add(photo);
}
}
return result;
}
}

View file

@ -1,12 +1,18 @@
import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:latlong/latlong.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/face_search_manager.dart';
import 'package:photos/models/face.dart';
import 'package:photos/models/photo.dart';
import 'package:photos/photo_repository.dart';
import 'package:photos/ui/circular_network_image_widget.dart';
import 'package:photos/ui/face_search_results_page.dart';
import 'package:photos/ui/loading_widget.dart';
import 'package:photos/ui/location_search_results_page.dart';
class SearchPage extends StatefulWidget {
@override
@ -55,8 +61,14 @@ class _SearchPageState extends State<SearchPage> {
return LocationSearchResultWidget(suggestion['name']);
},
onSuggestionSelected: (suggestion) {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => ProductPage(product: suggestion)));
double latitude = suggestion['geometry']['location']['lat'];
double longitude = suggestion['geometry']['location']['lng'];
Navigator.pop(context);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => LocationSearchResultsPage(
new LatLng(latitude, longitude),
suggestion['name'],
)));
},
),
actions: <Widget>[
@ -108,9 +120,8 @@ class _SearchPageState extends State<SearchPage> {
}
void _routeToSearchResults(Face face, BuildContext context) {
final page = FaceSearchResultsPage(
face: face,
);
final page = FaceSearchResultsPage(face);
Navigator.pop(context);
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {

View file

@ -1,6 +1,13 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
ansicolor:
dependency: transitive
description:
name: ansicolor
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
archive:
dependency: "direct main"
description:
@ -64,6 +71,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
console_log_handler:
dependency: transitive
description:
name: console_log_handler
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
convert:
dependency: transitive
description:
@ -212,6 +226,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
latlong:
dependency: "direct main"
description:
name: latlong
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.1"
like_button:
dependency: "direct main"
description:
@ -483,6 +504,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.4.1"
validate:
dependency: transitive
description:
name: validate
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
vector_math:
dependency: transitive
description:

View file

@ -48,6 +48,7 @@ dependencies:
logging: ^0.11.4
flutter_image_compress: ^0.6.5+1
flutter_typeahead: ^1.8.1
latlong: ^0.6.1
dev_dependencies:
flutter_test: