Update the point layout given dimension detail and the dimension's name.
| 226 | |
| 227 | // Update the point layout given dimension detail and the dimension's name. |
| 228 | bool PointLayout::update(Dimension::Detail dd, const std::string& name) |
| 229 | { |
| 230 | if (m_finalized) |
| 231 | throw pdal_error("Can't update layout after points have been added."); |
| 232 | |
| 233 | // If we have a list of allowed dimensions and this dimension isn't listed, return false. |
| 234 | if (m_allowedDimNames.size() && !Utils::contains(m_allowedDimNames, Utils::toupper(name))) |
| 235 | return false; |
| 236 | |
| 237 | Dimension::DetailList detail; |
| 238 | |
| 239 | // Update the list of used IDs. |
| 240 | bool used = Utils::contains(m_used, dd.id()); |
| 241 | for (auto id : m_used) |
| 242 | { |
| 243 | if (id == dd.id()) |
| 244 | detail.push_back(dd); |
| 245 | else |
| 246 | detail.push_back(m_detail[Utils::toNative(id)]); |
| 247 | } |
| 248 | if (!used) |
| 249 | detail.push_back(dd); |
| 250 | |
| 251 | // Find the dimension in the list that we're referring to with |
| 252 | // this update. |
| 253 | auto di = std::find_if(detail.begin(), detail.end(), |
| 254 | [dd](const Dimension::Detail& td){ return td.id() == dd.id(); }); |
| 255 | Dimension::Detail *cur = &(*di); |
| 256 | |
| 257 | { |
| 258 | auto sorter = [](const Dimension::Detail& d1, |
| 259 | const Dimension::Detail& d2) -> bool |
| 260 | { |
| 261 | if (d1.size() > d2.size()) |
| 262 | return true; |
| 263 | if (d1.size() < d2.size()) |
| 264 | return false; |
| 265 | return d1.id() < d2.id(); |
| 266 | }; |
| 267 | |
| 268 | // Sort dimensions based on size and then on ID. |
| 269 | int offset = 0; |
| 270 | std::sort(detail.begin(), detail.end(), sorter); |
| 271 | for (auto& d : detail) |
| 272 | { |
| 273 | d.setOffset(offset); |
| 274 | offset += (int)d.size(); |
| 275 | } |
| 276 | //NOTE - I tried forcing all points to be aligned on 8-byte boundaries |
| 277 | // in case this would matter to the optimized memcpy, but it made |
| 278 | // no difference. No sense wasting space for no difference. |
| 279 | m_pointSize = (size_t)offset; |
| 280 | } |
| 281 | |
| 282 | if (!used) |
| 283 | m_used.push_back(dd.id()); |
| 284 | |
| 285 | // Update the detail for the ID. |