forked from VinokurovVE/tests
Map experiments
This commit is contained in:
102
ems/src/index.ts
102
ems/src/index.ts
@ -2,11 +2,107 @@ import express, { Request, Response } from 'express';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import axios from 'axios';
|
||||
import multer from 'multer'
|
||||
import sharp from 'sharp';
|
||||
import { pipeline } from 'stream';
|
||||
import pump from 'pump'
|
||||
import md5 from 'md5'
|
||||
import bodyParser from 'body-parser';
|
||||
import cors from 'cors'
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.EMS_PORT;
|
||||
const PORT = process.env.EMS_PORT || 5000;
|
||||
|
||||
const tileFolder = path.join(__dirname, '..', 'tiles');
|
||||
const tileFolder = path.join(__dirname, '..', 'public', 'tile_data');
|
||||
const uploadDir = path.join(__dirname, '..', 'public', 'uploads');
|
||||
|
||||
interface UploadProgress {
|
||||
receivedChunks: Set<number>;
|
||||
totalChunks: number;
|
||||
}
|
||||
|
||||
const uploadProgress: Record<string, UploadProgress> = {};
|
||||
|
||||
app.use(bodyParser.raw({
|
||||
type: 'application/octet-stream',
|
||||
limit: '100mb'
|
||||
}))
|
||||
|
||||
app.use(cors())
|
||||
|
||||
// Upload chunk handler
|
||||
app.post('/upload', (req: Request, res: Response) => {
|
||||
const chunkNumber = parseInt(req.headers['x-chunk-number'] as string, 10);
|
||||
const totalChunks = parseInt(req.headers['x-total-chunks'] as string, 10);
|
||||
const fileId = req.headers['x-file-id'] as string;
|
||||
|
||||
if (isNaN(chunkNumber) || isNaN(totalChunks) || !fileId) {
|
||||
return res.status(400).send('Invalid headers');
|
||||
}
|
||||
|
||||
const chunkDir = path.join(uploadDir, fileId);
|
||||
if (!fs.existsSync(chunkDir)) {
|
||||
fs.mkdirSync(chunkDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Save the chunk
|
||||
const chunkPath = path.join(chunkDir, `chunk-${chunkNumber}`);
|
||||
fs.writeFileSync(chunkPath, req.body);
|
||||
|
||||
// Initialize or update upload progress
|
||||
if (!uploadProgress[fileId]) {
|
||||
uploadProgress[fileId] = { receivedChunks: new Set(), totalChunks };
|
||||
}
|
||||
uploadProgress[fileId].receivedChunks.add(chunkNumber);
|
||||
|
||||
// Check if all chunks have been received
|
||||
if (uploadProgress[fileId].receivedChunks.size === totalChunks) {
|
||||
assembleChunks(fileId, chunkDir)
|
||||
.then(() => {
|
||||
delete uploadProgress[fileId]; // Clean up progress tracking
|
||||
res.status(200).send('File assembled successfully');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error assembling file:', error);
|
||||
res.status(500).send('Failed to assemble file');
|
||||
});
|
||||
} else {
|
||||
res.status(200).send('Chunk received');
|
||||
}
|
||||
});
|
||||
|
||||
// Assemble chunks into final file
|
||||
async function assembleChunks(fileId: string, chunkDir: string): Promise<void> {
|
||||
const finalPath = path.join(uploadDir, fileId);
|
||||
const chunks = fs.readdirSync(chunkDir).sort((a, b) => {
|
||||
const numA = parseInt(a.split('-')[1]);
|
||||
const numB = parseInt(b.split('-')[1]);
|
||||
return numA - numB;
|
||||
});
|
||||
|
||||
const writeStream = fs.createWriteStream(finalPath);
|
||||
for (const chunk of chunks) {
|
||||
const chunkPath = path.join(chunkDir, chunk);
|
||||
const data = fs.readFileSync(chunkPath);
|
||||
writeStream.write(data);
|
||||
fs.unlinkSync(chunkPath); // Remove chunk after writing
|
||||
}
|
||||
|
||||
writeStream.end(() => {
|
||||
fs.rmdirSync(chunkDir); // Remove temporary chunk directory
|
||||
});
|
||||
}
|
||||
|
||||
const storage = multer.diskStorage({
|
||||
destination: function (req, file, cb) {
|
||||
cb(null, path.join(__dirname, '..', 'public', 'uploads'))
|
||||
},
|
||||
filename: function (req, file, cb) {
|
||||
cb(null, file.originalname)
|
||||
}
|
||||
})
|
||||
|
||||
const upload = multer({ storage: storage })
|
||||
|
||||
const fetchTileFromAPI = async (provider: string, z: string, x: string, y: string): Promise<Buffer> => {
|
||||
const url = provider === 'google'
|
||||
@ -15,7 +111,7 @@ const fetchTileFromAPI = async (provider: string, z: string, x: string, y: strin
|
||||
|
||||
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
||||
return response.data;
|
||||
};
|
||||
}
|
||||
|
||||
app.get('/tile/:provider/:z/:x/:y', async (req: Request, res: Response) => {
|
||||
const { provider, z, x, y } = req.params;
|
||||
|
Reference in New Issue
Block a user