| 535 | } |
| 536 | |
| 537 | FeatureType::GeomStat FeatureType::GetOuterGeometryStats() |
| 538 | { |
| 539 | CHECK(m_loadInfo && m_parsed.m_relations && !m_parsed.m_points, ()); |
| 540 | size_t const scalesCount = m_loadInfo->GetScalesCount(); |
| 541 | ASSERT_LESS_OR_EQUAL(scalesCount, DataHeader::kMaxScalesCount, ()); |
| 542 | FeatureType::GeomStat res; |
| 543 | |
| 544 | auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE); |
| 545 | if (headerGeomType == HeaderGeomType::Line) |
| 546 | { |
| 547 | size_t const pointsCount = m_points.size(); |
| 548 | if (pointsCount < 2) |
| 549 | { |
| 550 | // Outer geometry present. |
| 551 | ASSERT_EQUAL(pointsCount, 1, ()); |
| 552 | |
| 553 | PointsBufferT points; |
| 554 | |
| 555 | for (size_t ind = 0; ind < scalesCount; ++ind) |
| 556 | { |
| 557 | uint32_t const scaleOffset = m_offsets.m_pts[ind]; |
| 558 | if (IsRealGeomOffset(scaleOffset)) |
| 559 | { |
| 560 | points.clear(); |
| 561 | points.emplace_back(m_points.front()); |
| 562 | |
| 563 | ReaderSource<FilesContainerR::TReader> src(m_loadInfo->GetGeometryReader(ind)); |
| 564 | src.Skip(scaleOffset); |
| 565 | |
| 566 | serial::GeometryCodingParams cp = m_loadInfo->GetGeometryCodingParams(static_cast<int>(ind)); |
| 567 | cp.SetBasePoint(points[0]); |
| 568 | serial::LoadOuterPath(src, cp, points); |
| 569 | |
| 570 | res.m_sizes[ind] = static_cast<uint32_t>(src.Pos() - scaleOffset); |
| 571 | res.m_elements[ind] = static_cast<uint32_t>(points.size()); |
| 572 | } |
| 573 | } |
| 574 | // Retain best geometry. |
| 575 | m_points.swap(points); |
| 576 | } |
| 577 | CalcRect(m_points, m_limitRect); |
| 578 | } |
| 579 | m_parsed.m_points = true; |
| 580 | |
| 581 | // Points count can come from the inner geometry. |
| 582 | res.m_elements[scalesCount - 1] = static_cast<uint32_t>(m_points.size()); |
| 583 | return res; |
| 584 | } |
| 585 | |
| 586 | void FeatureType::ParseTriangles(int scale) |
| 587 | { |