const express = require('express'); const router = express.Router(); const rateLimit = require('express-rate-limit'); const { reverseGeocode, forwardGeocode, getCacheStats } = require('../services/geocoding'); // Rate limiter specifically for geocoding endpoints const geocodeLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 30, // limit each IP to 30 requests per windowMs message: 'Too many geocoding requests, please try again later.' }); /** * Reverse geocode endpoint * GET /api/geocode/reverse?lat=&lng= */ router.get('/reverse', geocodeLimiter, async (req, res) => { try { const { lat, lng } = req.query; // Validate input if (!lat || !lng) { return res.status(400).json({ success: false, error: 'Latitude and longitude are required' }); } const latitude = parseFloat(lat); const longitude = parseFloat(lng); if (isNaN(latitude) || isNaN(longitude)) { return res.status(400).json({ success: false, error: 'Invalid latitude or longitude' }); } if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180) { return res.status(400).json({ success: false, error: 'Coordinates out of range' }); } // Perform reverse geocoding const result = await reverseGeocode(latitude, longitude); res.json({ success: true, data: result }); } catch (error) { console.error('Reverse geocoding error:', error); const statusCode = error.message.includes('Rate limit') ? 429 : 500; res.status(statusCode).json({ success: false, error: error.message }); } }); /** * Forward geocode endpoint * GET /api/geocode/forward?address=
*/ router.get('/forward', geocodeLimiter, async (req, res) => { try { const { address } = req.query; // Validate input if (!address || address.trim().length === 0) { return res.status(400).json({ success: false, error: 'Address is required' }); } // Perform forward geocoding const result = await forwardGeocode(address); res.json({ success: true, data: result }); } catch (error) { console.error('Forward geocoding error:', error); const statusCode = error.message.includes('Rate limit') ? 429 : 500; res.status(statusCode).json({ success: false, error: error.message }); } }); /** * Get geocoding cache statistics (admin endpoint) * GET /api/geocode/cache/stats */ router.get('/cache/stats', (req, res) => { res.json({ success: true, data: getCacheStats() }); }); module.exports = router;