You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不连接数据库时将PostGIS ST_MakeValid应用于Boost.Geometry多边形?

Answer

Great question! If you want to replicate PostGIS's ST_MakeValid functionality for Boost.Geometry polygons without connecting to a PostgreSQL database, you can use Boost.Geometry's built-in validation and correction tools. Here's how to do it step by step:

Step 1: Check Polygon Validity

First, confirm if your polygon is invalid and understand the root cause. Boost.Geometry's is_valid function returns validity status along with a human-readable error message.

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <iostream>
#include <string>

namespace bg = boost::geometry;
typedef bg::model::point<double, 2, bg::cs::cartesian> Point;
typedef bg::model::polygon<Point> Polygon;

int main() {
    // Load your polygon from WKT
    Polygon poly;
    bg::read_wkt("POLYGON((0 0, 10 0, 10 11, 11 10, 0 10))", poly);

    // Check validity and get error details
    std::string error_msg;
    bool is_valid = bg::is_valid(poly, error_msg);

    if (!is_valid) {
        std::cout << "Polygon is invalid: " << error_msg << std::endl;
    } else {
        std::cout << "Polygon is already valid!" << std::endl;
        return 0;
    }

Step 2: Apply Basic Corrections

Start with bg::correct—this fixes common simple invalidities like:

  • Unclosed polygon rings
  • Incorrect ring orientation (violating the right-hand rule)
  • Duplicate consecutive vertices

Add this code right after checking validity:

// Fix basic issues with boost::geometry::correct
    bg::correct(poly);

    // Re-check validity after basic correction
    is_valid = bg::is_valid(poly, error_msg);
    if (is_valid) {
        std::cout << "Polygon fixed with basic correction!" << std::endl;
        // Convert back to WKT if needed
        std::string corrected_wkt;
        bg::write_wkt(corrected_wkt, poly);
        std::cout << "Corrected WKT: " << corrected_wkt << std::endl;
        return 0;
    }

Step 3: Fix Complex Invalidities (e.g., Self-Intersections)

If basic correction isn't enough (like with self-intersecting polygons), use the buffer(0) trick—this is a widely used workaround in Boost.Geometry to resolve self-intersections, mirroring how ST_MakeValid handles such cases.

For scenarios where correction splits the polygon into multiple shapes, use a multi_polygon to capture all valid results:

// Handle complex issues like self-intersections with buffer(0)
    typedef bg::model::multi_polygon<Polygon> MultiPolygon;
    MultiPolygon corrected_multi;

    // Buffer with 0 distance to auto-resolve self-intersections
    bg::buffer(poly, corrected_multi, bg::strategy::buffer::distance_symmetric<double>(0.0));

    // Verify and output all corrected polygons
    std::cout << "Corrected into " << corrected_multi.size() << " valid polygon(s):" << std::endl;
    for (const auto& corrected_poly : corrected_multi) {
        if (bg::is_valid(corrected_poly, error_msg)) {
            std::string wkt;
            bg::write_wkt(wkt, corrected_poly);
            std::cout << "- " << wkt << std::endl;
        } else {
            std::cout << "- Failed to validate a corrected sub-polygon: " << error_msg << std::endl;
        }
    }

    return 0;
}

Key Notes

  • Boost.Geometry doesn't have a direct 1:1 equivalent to ST_MakeValid, but combining bg::correct and the buffer(0) trick covers most common invalid polygon scenarios.
  • The buffer strategy can be customized for edge-case resolution, but the default symmetric 0-distance buffer works for most use cases.
  • Always re-validate after correction to ensure the final geometry is valid.

内容的提问来源于stack exchange,提问作者sergio campo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:11:11