I’ve data, and I Have a http server on cpp, i don’t want to create files, I want my cpp server to send files generated to the web client, if needed, I made this :
// Helper: Write a 32-bit little-endian value into a buffer.
void HttpServer::writeUint32LE(std::vector<char>& buffer, size_t offset, uint32_t value)
{
std::memcpy(buffer.data() + offset, &value, sizeof(uint32_t));
}
std::string HttpServer::generatePntsTile()
{
const uint32_t numPoints = 1000;
// Define extra bytes for RTC_CENTER (3 floats).
const uint32_t rtcCenterByteLength = 3 * sizeof(float); // 12 bytes
// Calculate the size for positions: 3 floats per point.
const uint32_t posByteLength = numPoints * 3 * sizeof(float);
// The RGB data will follow positions.
// Its byte offset is rtcCenterByteLength + posByteLength.
const uint32_t rgbByteOffset = rtcCenterByteLength + posByteLength;
// Create the feature table JSON including RTC_CENTER, POSITION, and RGB.
std::stringstream ss;
ss << "{\"POINTS_LENGTH\":" << numPoints
<< ",\"RTC_CENTER\":[0,0,0],"
<< "\"POSITION\":{\"byteOffset\":" << rtcCenterByteLength << "},"
<< "\"RGB\":{\"byteOffset\":" << rgbByteOffset << "}}";
std::string ftJson = ss.str();
// Pad the JSON string to an 8-byte boundary (using spaces).
size_t pad = (8 - (ftJson.size() % 8)) % 8;
std::string paddedFtJson = ftJson;
paddedFtJson.append(pad, ' ');
uint32_t featureTableJSONByteLength = static_cast<uint32_t>(paddedFtJson.size());
// Total binary length: RTC_CENTER + positions + RGB data.
uint32_t featureTableBinaryByteLength = rtcCenterByteLength + posByteLength + numPoints * 3 * sizeof(uint8_t);
const uint32_t headerByteLength = 28; // pnts header is 28 bytes.
uint32_t totalByteLength = headerByteLength + featureTableJSONByteLength + featureTableBinaryByteLength;
// Prepare a buffer to hold the entire file.
std::vector<char> buffer(totalByteLength, 0);
size_t offset = 0;
// Write header:
// 1. Magic: "pnts" (4 bytes)
buffer[offset++] = 'p';
buffer[offset++] = 'n';
buffer[offset++] = 't';
buffer[offset++] = 's';
// 2. Version (uint32_t, value 1)
writeUint32LE(buffer, offset, 1);
offset += 4;
// 3. ByteLength: total length of the tile.
writeUint32LE(buffer, offset, totalByteLength);
offset += 4;
// 4. FeatureTableJSONByteLength.
writeUint32LE(buffer, offset, featureTableJSONByteLength);
offset += 4;
// 5. FeatureTableBinaryByteLength.
writeUint32LE(buffer, offset, featureTableBinaryByteLength);
offset += 4;
// 6. BatchTableJSONByteLength (0)
writeUint32LE(buffer, offset, 0);
offset += 4;
// 7. BatchTableBinaryByteLength (0)
writeUint32LE(buffer, offset, 0);
offset += 4;
// Copy the padded Feature Table JSON.
std::memcpy(buffer.data() + offset, paddedFtJson.data(), paddedFtJson.size());
offset += paddedFtJson.size();
// Write binary feature table:
// Write RTC_CENTER: 3 floats, here [0,0,0].
float rtc_center[3] = { 0.0f, 0.0f, 0.0f };
std::memcpy(buffer.data() + offset, rtc_center, rtcCenterByteLength);
offset += rtcCenterByteLength;
// Seed random number generator.
std::srand(static_cast<unsigned int>(std::time(nullptr)));
// Generate binary point data.
// For each point, generate positions: x in [-50,50], y in [-50,50], z in [0,100].
for (uint32_t i = 0; i < numPoints; i++)
{
float x = static_cast<float>((std::rand() / (double)RAND_MAX) * 100.0 - 50.0);
float y = static_cast<float>((std::rand() / (double)RAND_MAX) * 100.0 - 50.0);
float z = static_cast<float>((std::rand() / (double)RAND_MAX) * 100.0);
std::memcpy(buffer.data() + offset, &x, sizeof(float));
offset += sizeof(float);
std::memcpy(buffer.data() + offset, &y, sizeof(float));
offset += sizeof(float);
std::memcpy(buffer.data() + offset, &z, sizeof(float));
offset += sizeof(float);
}
// Generate binary color data.
// For each point, generate 3 bytes (R, G, B).
for (uint32_t i = 0; i < numPoints; i++)
{
uint8_t r = static_cast<uint8_t>(std::rand() % 256);
uint8_t g = static_cast<uint8_t>(std::rand() % 256);
uint8_t b = static_cast<uint8_t>(std::rand() % 256);
buffer[offset++] = r;
buffer[offset++] = g;
buffer[offset++] = b;
}
// Return the binary data as a std::string (which can hold binary content).
return std::string(buffer.begin(), buffer.end());
}
// Generate a minimal tileset.json string for a single tile.
std::string HttpServer::generateTilesetJson()
{
// Use a local constant for PI.
const double PI = 3.14159265358979323846;
// Define the region in radians.
// Paris roughly: 2.35° lon, 48.8566° lat. Here we use a small bounding box around Paris.
double west = 2.30 * PI / 180.0;
double south = 48.80 * PI / 180.0;
double east = 2.40 * PI / 180.0;
double north = 48.90 * PI / 180.0;
double minHeight = 0.0;
double maxHeight = 200.0;
std::stringstream ss;
// Set fixed notation and precision for floating-point numbers.
ss << std::fixed << std::setprecision(8);
ss << "{\n"
<< " \"asset\": { \"version\": \"1.0\" },\n"
<< " \"geometricError\": 500,\n"
<< " \"root\": {\n"
<< " \"boundingVolume\": {\n"
<< " \"region\": [" << west << ", "
<< south << ", "
<< east << ", "
<< north << ", "
<< minHeight << ", "
<< maxHeight << "]\n"
<< " },\n"
<< " \"geometricError\": 500,\n" // non-zero to trigger tile loading
<< " \"refine\": \"ADD\",\n"
<< " \"content\": { \"uri\": \"content.pnts\" }\n"
<< " }\n"
<< "}\n";
return ss.str();
}
I have no error from cesium, but nothing is showing on the map above paris
any idea why ?