Geometry* Ring::cloneAs( const Geometry::Type& newType ) const { if ( newType == TYPE_LINESTRING ) { LineString* line = new LineString( &this->asVector() ); if ( line->size() > 1 && line->front() != line->back() ) line->push_back( front() ); return line; } else return Geometry::cloneAs( newType ); }
std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRenderedFeatures(const QueryParameters& parameters) const { std::unordered_map<std::string, std::vector<Feature>> result; if (renderTiles.empty() || parameters.geometry.empty()) { return result; } LineString<double> queryGeometry; for (const auto& p : parameters.geometry) { queryGeometry.push_back(TileCoordinate::fromScreenCoordinate( parameters.transformState, 0, { p.x, parameters.transformState.getSize().height - p.y }).p); } mapbox::geometry::box<double> box = mapbox::geometry::envelope(queryGeometry); auto sortRenderTiles = [](const RenderTile& a, const RenderTile& b) { return a.id.canonical.z != b.id.canonical.z ? a.id.canonical.z < b.id.canonical.z : a.id.canonical.y != b.id.canonical.y ? a.id.canonical.y < b.id.canonical.y : a.id.wrap != b.id.wrap ? a.id.wrap < b.id.wrap : a.id.canonical.x < b.id.canonical.x; }; std::vector<std::reference_wrapper<const RenderTile>> sortedTiles; std::transform(renderTiles.cbegin(), renderTiles.cend(), std::back_inserter(sortedTiles), [](const auto& pair) { return std::ref(pair.second); }); std::sort(sortedTiles.begin(), sortedTiles.end(), sortRenderTiles); for (const auto& renderTileRef : sortedTiles) { const RenderTile& renderTile = renderTileRef.get(); GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min); if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT) { continue; } GeometryCoordinate tileSpaceBoundsMax = TileCoordinate::toGeometryCoordinate(renderTile.id, box.max); if (tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) { continue; } GeometryCoordinates tileSpaceQueryGeometry; tileSpaceQueryGeometry.reserve(queryGeometry.size()); for (const auto& c : queryGeometry) { tileSpaceQueryGeometry.push_back(TileCoordinate::toGeometryCoordinate(renderTile.id, c)); } renderTile.tile.queryRenderedFeatures(result, tileSpaceQueryGeometry, parameters.transformState, parameters.layerIDs); } return result; }