Map experiments

This commit is contained in:
cracklesparkle
2024-09-06 17:56:42 +09:00
parent 3994989994
commit ddacbcd837
9 changed files with 1098 additions and 134 deletions

View File

@ -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;