Создание указателя для чтения из двоичного файла .las выдает ошибку bad_alloc

В настоящее время я пишу код для чтения в .las (файл данных LIDAR). После прочтения в файле я создал указатель для перебора всех точек. Тем не менее, это дает мне ошибку bad_alloc.

Единственное, о чем я могу думать, это то, что заголовок не того размера, который указан в заголовке файла las. Я дважды проверил свой заголовок, и я не думаю, что вижу что-то не так.

Все переменные заголовка в заголовке и PointRecord3 происходят из этого документация, страницы 3 и 10 соответственно.

ОБНОВЛЕНИЕ: количество читаемых пунктов составляет 402 673 112. Тем не менее, когда я открываю его в другом программном обеспечении LIDAR для двойной проверки, и количество баллов составляет всего 5,104,152. Я полагаю, что причина этого в том, что я отфильтровал облако в другом программном обеспечении, прежде чем открыть его в C ++, тем самым уменьшив количество точек.

Вот мой код:

#ifndef POINTCLOUD_H
#define POINTCLOUD_H
#pragma once
#include <string>class PointCloud
{
public:
PointCloud(const std::string &path);

private:
struct __attribute__((packed)) Header {

char magic[4];
uint16_t fileourceID;
uint16_t globalEncoding;
uint32_t guiData1;
uint16_t guiData2;
uint16_t guiData3;
uint8_t guiData[8];
uint8_t versionMaj, versionMin;
char systemIdentifer[32];
char genSoftware[32];
uint16_t creationDay, creationYear;
uint16_t headerSize;
uint32_t pointDataOffset;
uint32_t numVarLenRecords;
uint8_t pointDataRecordFormat;
uint16_t pointDataRecordLen;
uint32_t numberOfPoints;
uint32_t numPointsByReturn[5];
double scaleX, scaleY, scaleZ;
double offX, offY, offZ;
double minX, minY, minZ;
double maxX, maxY, maxZ;
};

struct __attribute__((packed)) PointRecord3 {
uint32_t X, Y, Z;
uint16_t intensity;
uint8_t flags;
uint8_t classification;
uint8_t scanAngleRank;
uint8_t userData;
uint16_t pointSourceID;
double gpsTime;
uint16_t red;
uint16_t green;
uint16_t blue;
};#include "PointCloud.h"#include <fstream>
#include <iostream>
#include <string>
#include <assert.h>

using namespace std;

PointCloud::PointCloud(const string &path)
{
read(path);
}

void PointCloud::read(const string &path) {
ifstream in(path.c_str(), ios::binary );
if(in.is_open()){
Header header;
in.read((char *)&header, sizeof(header));

assert(header.versionMaj == 1 && header.versionMin == 2);
cout << "headerSize " << header.headerSize << " == " << sizeof(header) << " size of header struct" <<endl;

cout << "FILE TYPE: LAS " << (int)header.versionMaj << "." << (int)header.versionMin << endl;
cout << "POINT DATA OFFSET: " << (int)header.pointDataOffset <<endl;
cout << "POINT DATA RECORD FORMAT: " << (int)header.pointDataRecordFormat <<endl;
cout << "NUMBER OF POINTS: " << (int)header.numberOfPoints << endl;PointRecord3 *points = new PointRecord3[header.numberOfPoints];

in.seekg(header.pointDataOffset);
for(uint32_t i = 0; i < header.numberOfPoints; i++) {
in.read((char *) (points + i), sizeof(*points));
}
if(in.good()) {

throw runtime_error("error");
}

delete points;} else {
cout << "file not opened" << endl;

}

}

Любая помощь будет оценена спасибо!

Также вот вывод заголовка файла LAS:

file signature:             'LASF'
file source ID:             0
global_encoding:            0
project ID GUID data 1-4:   00000000-0000-0000-0000-000000000000
version major.minor:        1.2
system identifier:          'EXPORT'
generating software:        'RiSCAN_PRO'
file creation day/year:     317/2018
header size:                227
offset to point data:       313
number var. length records: 1
point data format:          3
point data record length:   34
number of point records:    5104152
number of points by return: 5104152 0 0 0 0
scale factor x y z:         0.00025 0.00025 0.00025
offset x y z:               267805 3197054 13
min x y z:                  267804.25250 3196596.64500 -1.89000
max x y z:                  268760.27000 3197586.23000 23.33000
variable length header record 1 of 1:
reserved             43707
user ID              'LASF_Projection'
record ID            34735
length after header  32
description          'GeoKeyDirectoryTag (mandatory)'
GeoKeyDirectoryTag version 1.1.0 number of keys 3
key 1025 tiff_tag_location 0 count 1 value_offset 2 - GTRasterTypeGeoKey: RasterPixelIsPoint
key 1024 tiff_tag_location 0 count 1 value_offset 3 - GTModelTypeGeoKey: ModelTypeGeocentric
key 2048 tiff_tag_location 0 count 1 value_offset 4326 - GeographicTypeGeoKey: GCS_WGS_84
reporting minimum and maximum for all LAS point record entries ...
X               -2989    3821075
Y            -1829412    2128911
Z              -59559      41318
intensity       32767      32768
return_number       1          1
number_of_returns   1          1
edge_of_flight_line 0          0
scan_direction_flag 1          1
classification      0          0
scan_angle_rank     0          0
user_data           0          0
point_source_ID     0          0
gps_time 0.000000 0.000000
Color R 0 0
G 0 0
B 0 0
number of first returns:        5104152
number of intermediate returns: 0
number of last returns:         5104152
number of single returns:       5104152
overview over number of returns of given pulse: 5104152 0 0 0 0 0 0
histogram of classification of points:
5104152  never classified (0)

1

Решение

Я понял. В результате C ++ добавил несколько дополнительных байтов, в результате чего моя структура заголовка была на 5 байтов больше, чем фактический заголовок файла. Я исправил это, добавив #pragma pack (push, 1).

#ifndef POINTCLOUD_H
#define POINTCLOUD_H
#pragma pack (push, 1)
#include <string>struct float3
{
float x, y, z;

};

class PointCloud
{
public:
PointCloud(const std::string &path);

private:

struct __attribute__((packed)) Header
{

char fileSig[4];
uint16_t fileourceID;
uint16_t globalEncoding;
uint32_t guiData1;
uint16_t guiData2;
uint16_t guiData3;
uint8_t guiData[8];
uint8_t versionMaj, versionMin;
char systemIdentifer[32];
char genSoftware[32];
uint16_t creationDay, creationYear;
uint16_t headerSize;
uint32_t pointDataOffset;
uint32_t numVarLenRecords;
uint8_t pointDataRecordFormat;
uint16_t pointDataRecordLen;
uint32_t numberOfPoints;
uint32_t numPointsByReturn[5];
double scaleX, scaleY, scaleZ;
double offX, offY, offZ;
double minX, minY, minZ;
double maxX, maxY, maxZ;
};

struct __attribute__((packed)) PointRecord3
{
uint32_t X, Y, Z;
uint16_t intensity;
uint8_t flags;
uint8_t classification;
uint8_t scanAngleRank;
uint8_t userData;
uint16_t pointSourceID;
double gpsTime;
uint16_t red;
uint16_t green;
uint16_t blue;
};void read(const std::string &path);
};#endif // POINTCLOUD_H
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]