Implement location search
This commit is contained in:
parent
8e257ae78f
commit
694c0c22d4
6 changed files with 131 additions and 5 deletions
|
@ -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];
|
||||
|
|
|
@ -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 {
|
||||
|
|
73
lib/ui/location_search_results_page.dart
Normal file
73
lib/ui/location_search_results_page.dart
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
28
pubspec.lock
28
pubspec.lock
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue