A tonne more changes, including new nocodb admin section, search for database, code cleanups, and debugging
This commit is contained in:
@@ -95,6 +95,78 @@ async function reverseGeocode(lat, lng) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward geocode address to get coordinates (for search - returns multiple results)
|
||||
* @param {string} address - Address to search
|
||||
* @param {number} limit - Maximum number of results to return
|
||||
* @returns {Promise<Array>} Array of geocoding results
|
||||
*/
|
||||
async function forwardGeocodeSearch(address, limit = 5) {
|
||||
// Create cache key
|
||||
const cacheKey = `search:${address.toLowerCase()}:${limit}`;
|
||||
|
||||
// Check cache first
|
||||
const cached = geocodeCache.get(cacheKey);
|
||||
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
||||
logger.debug(`Geocoding search cache hit for ${cacheKey}`);
|
||||
return cached.data;
|
||||
}
|
||||
|
||||
try {
|
||||
// Add delay to respect rate limits
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
logger.info(`Forward geocoding search: ${address}`);
|
||||
|
||||
const response = await axios.get('https://nominatim.openstreetmap.org/search', {
|
||||
params: {
|
||||
format: 'json',
|
||||
q: address,
|
||||
limit: limit,
|
||||
addressdetails: 1,
|
||||
'accept-language': 'en',
|
||||
countrycodes: 'ca' // Limit to Canada for this application
|
||||
},
|
||||
headers: {
|
||||
'User-Agent': 'NocoDB Map Viewer 1.0 (contact@example.com)'
|
||||
},
|
||||
timeout: 15000
|
||||
});
|
||||
|
||||
if (!response.data || response.data.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Process all results
|
||||
const results = response.data.map(item => processGeocodeResponse(item));
|
||||
|
||||
// Cache the results
|
||||
geocodeCache.set(cacheKey, {
|
||||
data: results,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
return results;
|
||||
|
||||
} catch (error) {
|
||||
logger.error('Forward geocoding search error:', error.message);
|
||||
|
||||
if (error.response?.status === 429) {
|
||||
throw new Error('Rate limit exceeded. Please try again later.');
|
||||
} else if (error.response?.status === 403) {
|
||||
throw new Error('Access denied by geocoding service');
|
||||
} else if (error.response?.status === 500) {
|
||||
throw new Error('Geocoding service internal error');
|
||||
} else if (error.code === 'ECONNABORTED') {
|
||||
throw new Error('Geocoding request timeout');
|
||||
} else if (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
|
||||
throw new Error('Cannot connect to geocoding service');
|
||||
} else {
|
||||
throw new Error(`Geocoding search failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward geocode address to get coordinates
|
||||
* @param {string} address - Address to geocode
|
||||
@@ -202,6 +274,9 @@ function processGeocodeResponse(data) {
|
||||
lat: parseFloat(data.lat),
|
||||
lng: parseFloat(data.lon)
|
||||
},
|
||||
// Backward compatibility
|
||||
latitude: parseFloat(data.lat),
|
||||
longitude: parseFloat(data.lon),
|
||||
boundingBox: data.boundingbox || null,
|
||||
placeId: data.place_id || null,
|
||||
osmType: data.osm_type || null,
|
||||
@@ -232,6 +307,7 @@ function clearCache() {
|
||||
module.exports = {
|
||||
reverseGeocode,
|
||||
forwardGeocode,
|
||||
forwardGeocodeSearch,
|
||||
getCacheStats,
|
||||
clearCache
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user