conversion fix, bugfixes
This commit is contained in:
parent
6eb21e5886
commit
ab4accfc8c
1 changed files with 61 additions and 15 deletions
|
|
@ -35,26 +35,52 @@ class RugReefer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Map<String, dynamic>>> lookup(double latitude, double longitude, {double distanceThreshold = 10.0}) async {
|
Future<Map<String, Map<String, List<String>>>> lookup(double latitude, double longitude, {double distanceThreshold = 10.0}) async {
|
||||||
final String geohash = GeoHasher().encode(latitude, longitude, precision: 4);
|
final String geohash = GeoHasher().encode(longitude, latitude, precision: 4);
|
||||||
|
print("Generated geohash: $geohash");
|
||||||
|
|
||||||
final jsonMap = await loadJsonFromAssets(categoryMap);
|
final jsonMap = await loadJsonFromAssets(categoryMap);
|
||||||
|
print("Loaded JSON Map from Assets");
|
||||||
|
|
||||||
List<Map<String, dynamic>> rawData = kIsWeb
|
try {
|
||||||
? await _lookupWeb(geohash, latitude, longitude, distanceThreshold)
|
List<Map<String, dynamic>> rawData = kIsWeb
|
||||||
: await _lookupFile(geohash, latitude, longitude, distanceThreshold);
|
? await _lookupWeb(geohash, latitude, longitude, distanceThreshold)
|
||||||
|
: await _lookupFile(geohash, latitude, longitude, distanceThreshold);
|
||||||
|
|
||||||
return _processMetadata(rawData, jsonMap, latitude, longitude, distanceThreshold);
|
print("Raw Data from lookup: ${jsonEncode(rawData)}");
|
||||||
|
|
||||||
|
final processedData = _processMetadata(rawData, jsonMap, latitude, longitude, distanceThreshold);
|
||||||
|
print("Processed Data: ${jsonEncode(processedData)}");
|
||||||
|
|
||||||
|
return processedData;
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
print("Error in lookup: $e");
|
||||||
|
print("StackTrace: $stackTrace");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<List<Map<String, dynamic>>> _lookupFile(String geohash, double latitude, double longitude, double distanceThreshold) async {
|
Future<List<Map<String, dynamic>>> _lookupFile(String geohash, double latitude, double longitude, double distanceThreshold) async {
|
||||||
|
await _initCacheDir();
|
||||||
final File cacheFile = File('${cacheDir?.path}/$geohash.geojson.gz');
|
final File cacheFile = File('${cacheDir?.path}/$geohash.geojson.gz');
|
||||||
|
|
||||||
|
print("Checking cache file: ${cacheFile.path}");
|
||||||
|
|
||||||
if (!cacheFile.existsSync() || await _isCacheExpired(geohash)) {
|
if (!cacheFile.existsSync() || await _isCacheExpired(geohash)) {
|
||||||
|
print("Cache file missing or expired, downloading...");
|
||||||
await _downloadGeoJson(geohash, cacheFile);
|
await _downloadGeoJson(geohash, cacheFile);
|
||||||
} else {
|
} else {
|
||||||
|
print("Cache file found, updating last access time");
|
||||||
await _updateLastAccessTime(geohash);
|
await _updateLastAccessTime(geohash);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String geoJsonStr = utf8.decode(GZipCodec().decode(cacheFile.readAsBytesSync()));
|
final String geoJsonStr = utf8.decode(GZipCodec().decode(cacheFile.readAsBytesSync()));
|
||||||
return jsonDecode(geoJsonStr)['features'];
|
print("Read from cache: ${geoJsonStr.length} characters");
|
||||||
|
|
||||||
|
// ✅ Explicitly cast to List<Map<String, dynamic>>
|
||||||
|
final List<dynamic> decodedJson = jsonDecode(geoJsonStr)['features'];
|
||||||
|
return decodedJson.cast<Map<String, dynamic>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Map<String, dynamic>>> _lookupWeb(String geohash, double latitude, double longitude, double distanceThreshold) async {
|
Future<List<Map<String, dynamic>>> _lookupWeb(String geohash, double latitude, double longitude, double distanceThreshold) async {
|
||||||
|
|
@ -114,22 +140,29 @@ class RugReefer {
|
||||||
return jsonDecode(jsonString);
|
return jsonDecode(jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Map<String, dynamic>> _processMetadata(List<Map<String, dynamic>> features, Map<String, dynamic> jsonMap, double latitude, double longitude, double distanceThreshold) {
|
Map<String, Map<String, List<String>>> _processMetadata(
|
||||||
|
List<Map<String, dynamic>> features,
|
||||||
|
Map<String, dynamic> jsonMap,
|
||||||
|
double latitude,
|
||||||
|
double longitude,
|
||||||
|
double distanceThreshold) {
|
||||||
|
|
||||||
final Position point = Position(longitude, latitude);
|
final Position point = Position(longitude, latitude);
|
||||||
Map<String, Map<String, List<String>>> groupedObjects = {};
|
Map<String, Map<String, List<String>>> groupedObjects = {"in": {}, "by": {}};
|
||||||
|
|
||||||
for (var feature in features) {
|
for (var feature in features) {
|
||||||
final geometry = feature['geometry'];
|
final geometry = feature['geometry'];
|
||||||
final metadata = Map<String, dynamic>.from(feature['properties']['tags'] ?? {})..removeWhere((_, v) => v == null);
|
final metadata = Map<String, dynamic>.from(feature['properties']['tags'] ?? {})..removeWhere((_, v) => v == null);
|
||||||
String? mainKey;
|
String? mainKey;
|
||||||
|
|
||||||
|
// Determine spatial category: "in" (Polygon) or "by" (LineString)
|
||||||
switch (geometry['type']) {
|
switch (geometry['type']) {
|
||||||
case 'Polygon':
|
case 'Polygon':
|
||||||
final polygon = Polygon(
|
final polygon = Polygon(
|
||||||
coordinates: (geometry['coordinates'] as List)
|
coordinates: (geometry['coordinates'] as List)
|
||||||
.map((ring) => (ring as List)
|
.map((ring) => (ring as List)
|
||||||
.map((p) => Position(p[0].toDouble(), p[1].toDouble()))
|
.map((p) => Position(p[0].toDouble(), p[1].toDouble()))
|
||||||
.toList())
|
.toList())
|
||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
if (booleanPointInPolygon(point, polygon)) mainKey = 'in';
|
if (booleanPointInPolygon(point, polygon)) mainKey = 'in';
|
||||||
|
|
@ -143,25 +176,38 @@ class RugReefer {
|
||||||
if (_isPointNearLine(Point(coordinates: point), line, distanceThreshold)) mainKey = 'by';
|
if (_isPointNearLine(Point(coordinates: point), line, distanceThreshold)) mainKey = 'by';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainKey == null) continue;
|
if (mainKey == null) continue;
|
||||||
|
|
||||||
groupedObjects.putIfAbsent(mainKey, () => {});
|
|
||||||
for (var key in metadata.keys) {
|
for (var key in metadata.keys) {
|
||||||
|
var value = metadata[key];
|
||||||
|
|
||||||
for (var category in jsonMap.keys) {
|
for (var category in jsonMap.keys) {
|
||||||
var categoryMap = jsonMap[category];
|
var categoryMap = jsonMap[category];
|
||||||
|
|
||||||
if (categoryMap is Map && categoryMap.containsKey(key)) {
|
if (categoryMap is Map && categoryMap.containsKey(key)) {
|
||||||
var rule = categoryMap[key];
|
var rule = categoryMap[key];
|
||||||
if (rule is String || (rule is List && rule.contains(metadata[key])) || rule == true) {
|
|
||||||
|
if (rule is String && rule == value) {
|
||||||
groupedObjects[mainKey]!.putIfAbsent(category, () => []);
|
groupedObjects[mainKey]!.putIfAbsent(category, () => []);
|
||||||
groupedObjects[mainKey]![category]!.add(metadata[key]);
|
groupedObjects[mainKey]![category]!.add(value);
|
||||||
|
} else if (rule is List && rule.contains(value)) {
|
||||||
|
groupedObjects[mainKey]!.putIfAbsent(category, () => []);
|
||||||
|
groupedObjects[mainKey]![category]!.add(value);
|
||||||
|
} else if (rule == true) {
|
||||||
|
groupedObjects[mainKey]!.putIfAbsent(category, () => []);
|
||||||
|
groupedObjects[mainKey]![category]!.add(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return groupedObjects.entries.map((entry) => {entry.key: entry.value}).toList();
|
|
||||||
|
return groupedObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool _isPointNearLine(Point point, LineString line, double distanceThreshold) {
|
bool _isPointNearLine(Point point, LineString line, double distanceThreshold) {
|
||||||
for (final Position p in line.coordinates) {
|
for (final Position p in line.coordinates) {
|
||||||
if (distance(point, Point(coordinates: p), Unit.meters) <= distanceThreshold) {
|
if (distance(point, Point(coordinates: p), Unit.meters) <= distanceThreshold) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue