| 217 | } |
| 218 | |
| 219 | void PMFFilter::processGround(PointViewPtr view) |
| 220 | { |
| 221 | // initialize bounds, rows, columns, and surface |
| 222 | BOX2D bounds; |
| 223 | view->calculateBounds(bounds); |
| 224 | size_t cols = static_cast<size_t>( |
| 225 | ((bounds.maxx - bounds.minx) / m_args->m_cellSize) + 1); |
| 226 | size_t rows = static_cast<size_t>( |
| 227 | ((bounds.maxy - bounds.miny) / m_args->m_cellSize) + 1); |
| 228 | |
| 229 | // initialize surface to NaN |
| 230 | std::vector<double> ZImin(rows * cols, |
| 231 | std::numeric_limits<double>::quiet_NaN()); |
| 232 | |
| 233 | // loop through all points, identifying minimum Z value for each populated |
| 234 | // cell |
| 235 | for (PointRef p : *view) |
| 236 | { |
| 237 | double x = p.getFieldAs<double>(Id::X); |
| 238 | double y = p.getFieldAs<double>(Id::Y); |
| 239 | double z = p.getFieldAs<double>(Id::Z); |
| 240 | int c = static_cast<int>(floor(x - bounds.minx) / m_args->m_cellSize); |
| 241 | int r = static_cast<int>(floor(y - bounds.miny) / m_args->m_cellSize); |
| 242 | size_t idx = c * rows + r; |
| 243 | if (z < ZImin[idx] || std::isnan(ZImin[idx])) |
| 244 | ZImin[idx] = z; |
| 245 | } |
| 246 | |
| 247 | // convert vector to PointView for indexing |
| 248 | PointViewPtr temp = view->makeNew(); |
| 249 | PointId i(0); |
| 250 | for (size_t c = 0; c < cols; ++c) |
| 251 | { |
| 252 | for (size_t r = 0; r < rows; ++r) |
| 253 | { |
| 254 | size_t cell = c * rows + r; |
| 255 | double val = ZImin[cell]; |
| 256 | if (std::isnan(val)) |
| 257 | continue; |
| 258 | PointRef p = temp->point(i++); |
| 259 | p.setField(Id::X, bounds.minx + (c + 0.5) * m_args->m_cellSize); |
| 260 | p.setField(Id::Y, bounds.miny + (r + 0.5) * m_args->m_cellSize); |
| 261 | p.setField(Id::Z, val); |
| 262 | } |
| 263 | } |
| 264 | |
| 265 | // build the 2D KD-tree |
| 266 | KD2Index& kdi = temp->build2dIndex(); |
| 267 | |
| 268 | // loop through all cells, and for each NaN, replace with elevation of |
| 269 | // nearest neighbor |
| 270 | std::vector<double> out = ZImin; |
| 271 | for (size_t c = 0; c < cols; ++c) |
| 272 | { |
| 273 | for (size_t r = 0; r < rows; ++r) |
| 274 | { |
| 275 | size_t idx = c * rows + r; |
| 276 | if (!std::isnan(out[idx])) |
nothing calls this directly
no test coverage detected