import express, { Request, Response } from 'express' import { Redis } from 'ioredis' import dotenv from 'dotenv' import bodyParser from 'body-parser' import { SatelliteMapsProvider } from './interfaces/map' const axios = require('axios'); const cors = require('cors') const redis = new Redis({ port: Number(process.env.REDIS_PORT) || 6379, host: process.env.REDIS_HOST, password: process.env.REDIS_PASSWORD, }) dotenv.config() const app = express() const port = process.env.EMS_PORT // Middleware to parse JSON requests app.use(bodyParser.json()) const getTileUrl = (provider: string, x: string, y: string, z: string) => { if (provider === 'google') { return `https://khms2.google.com/kh/v=984?x=${x}&y=${y}&z=${z}`; } else if (provider === 'yandex') { return `https://core-sat.maps.yandex.net/tiles?l=sat&x=${x}&y=${y}&z=${z}&scale=1&lang=ru_RU`; } throw new Error('Invalid provider'); } app.get('/tile/:provider/:z/:x/:y', async (req, res) => { const { provider, x, y, z } = req.params; const cacheKey = `${provider}:${z}:${x}:${y}`; try { // Check if tile is in cache redis.get(cacheKey, async (err, cachedTile) => { if (err) { console.error('Redis GET error:', err); return res.status(500).send('Server error'); } if (cachedTile) { // If cached, return tile console.log('Tile served from cache'); const imgBuffer = Buffer.from(cachedTile, 'base64'); res.writeHead(200, { 'Content-Type': 'image/png', 'Content-Length': imgBuffer.length, }); return res.end(imgBuffer); } else { // Fetch tile from provider const tileUrl = getTileUrl(provider, x, y, z); const response = await axios.get(tileUrl, { responseType: 'arraybuffer', }); // Cache the tile in Redis const base64Tile = Buffer.from(response.data).toString('base64'); redis.setex(cacheKey, 3600 * 24 * 30, base64Tile); // Cache for 1 hour // Return the tile to the client res.writeHead(200, { 'Content-Type': 'image/png', 'Content-Length': response.data.length, }); return res.end(response.data); } }); } catch (error) { console.error('Error fetching tile:', error); res.status(500).send('Error fetching tile'); } }) app.get('/hello', cors(), (req: Request, res: Response) => { res.send('Hello, World!') }) // Route to store GeoJSON data app.post('/geojson', cors(), async (req: Request, res: Response) => { const geoJSON = req.body if (!geoJSON || !geoJSON.features) { return res.status(400).send('Invalid GeoJSON') } const id = `geojson:${Date.now()}`; redis.set(id, JSON.stringify(geoJSON), (err, reply) => { if (err) { return res.status(500).send('Error saving GeoJSON to Redis'); } res.send({ status: 'success', id }); }) }) // Route to fetch GeoJSON data app.get('/geojson/:id', cors(), async (req: Request, res: Response) => { const id = req.params.id; redis.get(id, (err, data) => { if (err) { return res.status(500).send('Error fetching GeoJSON from Redis'); } if (data) { res.send(JSON.parse(data)); } else { res.status(404).send('GeoJSON not found'); } }) }) app.listen(port, () => { console.log(`Server running on http://localhost:${port}`); })