search method
Implementation
@override
Future<List<PowerMapSearchResult>> search(
String query, {
LatLng? proximity,
String lang = 'auto',
}) async {
final cleanLang = lang.toLowerCase();
final hasThai = RegExp(r'[\u0E00-\u0E7F]').hasMatch(query);
final hasEnglish = RegExp(r'[a-zA-Z]').hasMatch(query);
String primaryPath = _searchThPath;
String secondaryPath = _searchEnPath;
if (cleanLang == 'en') {
primaryPath = _searchEnPath;
secondaryPath = _searchThPath;
} else if (cleanLang == 'th') {
primaryPath = _searchThPath;
secondaryPath = _searchEnPath;
} else {
// auto mode
if (hasEnglish && !hasThai) {
primaryPath = _searchEnPath;
secondaryPath = _searchThPath;
} else {
primaryPath = _searchThPath;
secondaryPath = _searchEnPath;
}
}
try {
List<dynamic> primaryData = await _fetchPath(primaryPath, query, proximity);
// Fallback: If proximity search returned < 3 results, query nationwide (without proximity)
if (proximity != null && primaryData.length < 3) {
try {
final nationwideData = await _fetchPath(primaryPath, query, null);
if (nationwideData.isNotEmpty) {
final existingGids = primaryData
.map((e) => (e['_source'] ?? e)['gid'])
.where((gid) => gid != null)
.toSet();
for (final nwItem in nationwideData) {
final nwGid = (nwItem['_source'] ?? nwItem)['gid'];
if (nwGid == null || !existingGids.contains(nwGid)) {
primaryData.add(nwItem);
if (nwGid != null) existingGids.add(nwGid);
}
}
}
} catch (_) {}
}
// Perform secondary fetch if primary returned empty OR query has mixed script
if (primaryData.isEmpty || (cleanLang == 'auto' && hasThai && hasEnglish)) {
try {
List<dynamic> secondaryData = await _fetchPath(secondaryPath, query, proximity);
if (secondaryData.isEmpty && proximity != null) {
try {
secondaryData = await _fetchPath(secondaryPath, query, null);
} catch (_) {}
}
if (secondaryData.isNotEmpty) {
if (primaryData.isEmpty) {
primaryData = secondaryData;
} else {
final existingGids = primaryData
.map((e) => (e['_source'] ?? e)['gid'])
.where((gid) => gid != null)
.toSet();
for (final secItem in secondaryData) {
final secGid = (secItem['_source'] ?? secItem)['gid'];
if (secGid == null || !existingGids.contains(secGid)) {
primaryData.add(secItem);
if (secGid != null) existingGids.add(secGid);
}
}
}
}
} catch (_) {
// Ignore secondary fetch errors if primary succeeded
}
}
return primaryData
.map((item) => PowerMapSearchResult.fromJson(item, lang: lang, query: query))
.toList();
} catch (e) {
if (e is PowerMapException) rethrow;
throw PowerMapException(
code: PowerMapException.network,
message: 'Search request failed due to a network error.',
details: e,
);
}
}