GeometryCollection operator()(const mapbox::geometry::line_string<int16_t>& geom) const {
     GeometryCoordinates coordinates;
     coordinates.reserve(geom.size());
     for (const auto& point : geom) {
         coordinates.emplace_back(point);
     }
     return { coordinates };
 }
예제 #2
0
static GeometryCoordinates fromClipperPath(const ClipperLib::Path& path) {
    GeometryCoordinates result;
    result.reserve(path.size() + 1);
    
    result.reserve(path.size());
    for (const auto& p : path) {
        using Coordinate = GeometryCoordinates::coordinate_type;
        assert(p.x >= std::numeric_limits<Coordinate>::min());
        assert(p.x <= std::numeric_limits<Coordinate>::max());
        assert(p.y >= std::numeric_limits<Coordinate>::min());
        assert(p.y <= std::numeric_limits<Coordinate>::max());
        result.emplace_back(Coordinate(p.x), Coordinate(p.y));
    }
    
    // Clipper does not repeat initial point, but our geometry model requires it.
    if (!result.empty()) {
        result.push_back(result.front());
    }
    
    return result;
}
예제 #3
0
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;
}
 GeometryCollection operator()(const mapbox::geometry::multi_line_string<int16_t>& geom) const {
     GeometryCollection collection;
     collection.reserve(geom.size());
     for (const auto& ring : geom) {
         GeometryCoordinates coordinates;
         coordinates.reserve(ring.size());
         for (const auto& point : ring) {
             coordinates.emplace_back(point);
         }
         collection.push_back(std::move(coordinates));
     }
     return collection;
 }
 GeometryCollection operator()(const mapbox::geometry::multi_polygon<int16_t>& geom) const {
     GeometryCollection collection;
     for (auto& polygon : geom) {
         for (auto& ring : polygon) {
             GeometryCoordinates coordinates;
             coordinates.reserve(ring.size());
             for (auto& point : ring) {
                 coordinates.emplace_back(point);
             }
             collection.push_back(std::move(coordinates));
         }
     }
     return collection;
 }