OmniSciDB  b28c0d5765
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PdalLoader.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #ifdef HAVE_PDAL
20 #ifndef __CUDACC__
21 
22 #include <algorithm>
23 #include <cstring>
24 #include <filesystem>
25 #include <memory>
26 #include <string>
27 #include <unordered_map>
28 #include <vector>
29 
32 
33 #include <pdal/PointTable.hpp>
34 #include <pdal/PointView.hpp>
35 #include <pdal/SpatialReference.hpp>
36 #include <pdal/io/LasReader.hpp>
37 namespace PdalLoader {
38 
39 static std::mutex print_mutex;
40 
41 struct LidarMetadata {
42  std::string filename;
43  int32_t file_source_id;
44  int16_t version_major;
45  int16_t version_minor;
46  int16_t creation_year;
47  bool is_compressed;
48  int64_t num_points;
49  int16_t num_dims;
50  int16_t point_len;
51  bool has_time;
52  bool has_color;
53  bool has_wave;
54  bool has_infrared;
55  bool has_14_point_format;
56  int32_t specified_utm_zone;
57  bool is_transformed;
58  pdal::SpatialReference source_spatial_reference;
59  std::pair<double, double> source_x_bounds;
60  std::pair<double, double> source_y_bounds;
61  std::pair<double, double> source_z_bounds;
62  pdal::SpatialReference transformed_spatial_reference;
63  std::pair<double, double> transformed_x_bounds;
64  std::pair<double, double> transformed_y_bounds;
65  std::pair<double, double> transformed_z_bounds;
66 
67  LidarMetadata() : num_points(0) {}
68 
69  inline void updateBounds(const double x, const double y, const double z) {
70  transformed_x_bounds.first = std::min(transformed_x_bounds.first, x);
71  transformed_x_bounds.second = std::max(transformed_x_bounds.second, x);
72  transformed_y_bounds.first = std::min(transformed_y_bounds.first, y);
73  transformed_y_bounds.second = std::max(transformed_y_bounds.second, y);
74  transformed_z_bounds.first = std::min(transformed_z_bounds.first, z);
75  transformed_z_bounds.second = std::max(transformed_z_bounds.second, z);
76  }
77 
78  void print() const {
79  std::unique_lock<std::mutex> print_lock(print_mutex);
80  std::cout << std::endl << "-----Lidar Metadata-------" << std::endl;
81  std::cout << "# Points: " << num_points << std::endl;
82  std::cout << "X bounds: (" << transformed_x_bounds.first << ", "
83  << transformed_x_bounds.second << ")" << std::endl;
84  std::cout << "Y bounds: (" << transformed_y_bounds.first << ", "
85  << transformed_y_bounds.second << ")" << std::endl;
86  std::cout << "Z bounds: (" << transformed_z_bounds.first << ", "
87  << transformed_z_bounds.second << ")" << std::endl;
88  }
89 };
90 
91 struct LidarData {
92  double* x;
93  double* y;
94  double* z;
95  int32_t* intensity; // unsigned short per standard, but we don't have unsigned types so
96  // need to promote to 4 bytes
97  int8_t* return_num;
98  int8_t* num_returns;
99  int8_t* scan_direction_flag;
100  int8_t* edge_of_flight_line;
101  int16_t* classification;
102  int8_t* scan_angle_rank;
103 };
104 
105 static DataBufferCache data_cache;
106 static DataCache<LidarMetadata> metadata_cache;
107 
108 inline std::string make_cache_key(const std::string& filename,
109  const std::string& out_srs,
110  const std::string& attribute) {
111  return filename + " || " + out_srs + "|| " + attribute;
112 }
113 
114 std::shared_ptr<LidarMetadata> get_metadata_for_file(const std::string& filename,
115  const std::string& out_srs);
116 
117 std::pair<int64_t, std::vector<std::shared_ptr<LidarMetadata>>> get_metadata_for_files(
118  const std::vector<std::filesystem::path>& file_paths,
119  const std::string& out_srs);
120 
121 std::pair<int64_t, std::vector<std::shared_ptr<LidarMetadata>>> filter_files_by_bounds(
122  const std::vector<std::shared_ptr<LidarMetadata>>& lidar_metadata_vec,
123  const double x_min,
124  const double x_max,
125  const double y_min,
126  const double y_max);
127 
128 bool keys_are_cached(
129  const std::string& filename,
130  const std::string& out_srs,
131  const size_t num_records,
132  const std::vector<std::pair<std::string, size_t>>& sub_keys_and_byte_sizes);
133 
134 class PdalFileMgr {
135  public:
136  PdalFileMgr(const std::shared_ptr<LidarMetadata>& lidar_metadata,
137  const std::string& out_srs)
138  : lidar_metadata_(lidar_metadata), out_srs_(out_srs) {}
139 
140  void openAndPrepareFile();
141 
142  inline bool isReady() const { return is_ready_; }
143 
144  void readData(double* x,
145  double* y,
146  double* z,
147  int32_t* intensity,
148  int8_t* return_num,
149  int8_t* num_returns,
150  int8_t* scan_direction_flag,
151  int8_t* edge_of_flight_line_flag,
152  int16_t* classification,
153  int8_t* scan_angle_rank) {
154  readData(x,
155  y,
156  z,
157  intensity,
158  return_num,
159  num_returns,
160  scan_direction_flag,
161  edge_of_flight_line_flag,
162  classification,
163  scan_angle_rank,
164  lidar_metadata_->num_points);
165  }
166 
167  void readData(double* x,
168  double* y,
169  double* z,
170  int32_t* intensity,
171  int8_t* return_num,
172  int8_t* num_returns,
173  int8_t* scan_direction_flag,
174  int8_t* edge_of_flight_line_flag,
175  int16_t* classification,
176  int8_t* scan_angle_rank,
177  const int64_t num_points);
178 
179  private:
180  pdal::LasReader las_reader_;
181  pdal::PointTable point_table_;
182  pdal::PointViewSet point_view_set_;
183  pdal::PointViewPtr point_view_;
184 
185  const std::shared_ptr<LidarMetadata> lidar_metadata_;
186  const std::string out_srs_;
187  bool is_ready_{false};
188 };
189 
190 } // namespace PdalLoader
191 
192 #endif // __CUDACC__
193 #endif // HAVE_PDAL