test
This commit is contained in:
parent
a5851e71fb
commit
2a093e3126
4 changed files with 149 additions and 20 deletions
|
|
@ -8,21 +8,19 @@ import 'package:turf/turf.dart';
|
|||
class GeoMetadataLookup {
|
||||
final String apiUrl;
|
||||
final Directory cacheDir;
|
||||
final double distanceThreshold;
|
||||
final Distance distance = const Distance();
|
||||
|
||||
GeoMetadataLookup({
|
||||
required this.apiUrl,
|
||||
required this.cacheDir,
|
||||
this.distanceThreshold = 10.0, // Default 10 meters
|
||||
}) {
|
||||
if (!cacheDir.existsSync()) {
|
||||
cacheDir.createSync(recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> lookup(double latitude, double longitude) async {
|
||||
final String geohash = GeoHasher().encode(latitude, longitude, precision: 4);
|
||||
Future<List<Map<String, dynamic>>> lookup(double latitude, double longitude, {double distance = 10.0}) async {
|
||||
final String geohash = GeoHasher().encode(longitude, latitude);
|
||||
final File cacheFile = File('${cacheDir.path}/$geohash.geojson.gz');
|
||||
|
||||
if (!cacheFile.existsSync()) {
|
||||
|
|
@ -31,11 +29,11 @@ class GeoMetadataLookup {
|
|||
|
||||
final String geoJsonStr = utf8.decode(GZipCodec().decode(cacheFile.readAsBytesSync()));
|
||||
final Map<String, dynamic> geoJson = jsonDecode(geoJsonStr);
|
||||
return _findMetadata(latitude, longitude, geoJson);
|
||||
return _findMetadata(latitude, longitude, distance, geoJson);
|
||||
}
|
||||
|
||||
Future<void> _downloadGeoJson(String geohash, File cacheFile) async {
|
||||
final response = await http.get(Uri.parse('$apiUrl/$geohash.geojson.gz'));
|
||||
final response = await http.get(Uri.parse('$apiUrl$geohash'));
|
||||
if (response.statusCode == 200) {
|
||||
cacheFile.writeAsBytesSync(GZipCodec().encode(response.bodyBytes));
|
||||
} else {
|
||||
|
|
@ -43,8 +41,8 @@ class GeoMetadataLookup {
|
|||
}
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> _findMetadata(double latitude, double longitude, Map<String, dynamic> geoJson) {
|
||||
final Point point = Point(coordinates: Position(longitude, latitude));
|
||||
List<Map<String, dynamic>> _findMetadata(double latitude, double longitude, double distanceThreshold, Map<String, dynamic> geoJson) {
|
||||
final Position point = Position(longitude, latitude);
|
||||
List<Map<String, dynamic>> results = [];
|
||||
|
||||
for (var feature in geoJson['features']) {
|
||||
|
|
@ -59,19 +57,30 @@ class GeoMetadataLookup {
|
|||
.toList())
|
||||
.toList(),
|
||||
);
|
||||
if (booleanPointInPolygon(point, polygon)) {
|
||||
results.add({'type': 'polygon', ...properties});
|
||||
}
|
||||
}
|
||||
|
||||
else if (geometry['type'] == 'LineString') {
|
||||
final line = LineString(coordinates: (geometry['coordinates'] as List).map((p) => Position(p[0], p[1])).toList());
|
||||
if (_isPointNearLine(point, line)) {
|
||||
final line = LineString(
|
||||
coordinates: (geometry['coordinates'] as List)
|
||||
.map((p) => Position(p[0] as double, p[1] as double))
|
||||
.toList(),
|
||||
);
|
||||
if (_isPointNearLine(point, line, distanceThreshold)) {
|
||||
results.add({'type': 'line', ...properties});
|
||||
}
|
||||
}
|
||||
|
||||
else if (geometry['type'] == 'MultiLineString') {
|
||||
for (var lineCoords in geometry['coordinates']) {
|
||||
final line = LineString(coordinates: lineCoords.map((p) => Position(p[0], p[1])).toList());
|
||||
if (_isPointNearLine(point, line)) {
|
||||
final line = LineString(
|
||||
coordinates: (lineCoords as List)
|
||||
.map((p) => Position(p[0] as double, p[1] as double))
|
||||
.toList(),
|
||||
);
|
||||
if (_isPointNearLine(point, line, distanceThreshold)) {
|
||||
results.add({'type': 'multi_line', ...properties});
|
||||
break;
|
||||
}
|
||||
|
|
@ -81,12 +90,11 @@ class GeoMetadataLookup {
|
|||
return results;
|
||||
}
|
||||
|
||||
bool _isPointNearLine(Point point, LineString line) {
|
||||
bool _isPointNearLine(Position point, LineString line, double distanceThreshold) {
|
||||
for (var i = 0; i < line.coordinates.length - 1; i++) {
|
||||
final p1 = line.coordinates[i];
|
||||
final p2 = line.coordinates[i + 1];
|
||||
final double dist = distance.distance(
|
||||
LatLng(point.coordinates.lat.toDouble(), point.coordinates.lng.toDouble()),
|
||||
LatLng(point.lat.toDouble(), point.lng.toDouble()),
|
||||
LatLng(p1.lat.toDouble(), p1.lng.toDouble()),
|
||||
);
|
||||
if (dist <= distanceThreshold) return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue