オープンソースGISまたはArcGIS for Desktopを使用して、直角でないポリゴンを検​​索しますか?


8

現在、指定されたエリアのいくつかの建物をデジタル化しています。

この作業の義務的なルール-ほとんどの場合、建物は直角でなければなりません。

この作業にはQGISとCADツールを使用していますが、間違えて不規則な形状のポリゴンを作成することもあります。

オープンソースのGISまたはArcGISを使用して、直角のないポリゴンをどのように見つけることができるかを誰かが知っていますか?

回答:


5

これを行うための既存のツールは知りませんが、ArcPyで記述したり、GDAL / OGRを使用して次のように記述したりできます。

  • 各ポリゴンについて...
    • ジオメトリを取得する
    • ポリゴンの曲がりを追跡し、各頂点の内角を計算します
    • いずれかの角度が90度でない場合は、拒否のリストにFID / OID(またはその他の属性)を追加します
  • 拒否のリストを印刷する

3
+1同様のコードを書いたら、少し変更することをお勧めします。非常に小さい線分がまたがる角度では、(視覚的な)問題は発生しません。また、90度に非常に近い角度でも問題になりません。これは、各エッジとその前身の内積を計算することを示唆しています。結果の絶対値を(小さな正の)しきい値と比較します。そのしきい値を超えているポリゴンにフラグを立てます。これにより、小さなエッジの場合は90度から大きくずれ、大きなエッジの場合はわずかにずれます。おまけとして、角度を計算する必要はありません。
whuber

@MappaGnosis回答の2行目を実装しようとした人はいますか?
b_jugger

2

以下は1つの可能なアプローチです。この関数は、ポリゴンに特定のサイズ未満の角度があるか、ターゲット角度の範囲内にあるかによって、trueまたはfalseを返します。これは非常に単純なアプローチであり、直線的なデジタル化を前提としています。私は円をテストしますが、曲線や、機能が作動する可能性のある他の可能性をテストしません。

angleTarget =希望する角度(例:90)。

edgeVariance =直線の許容ワッフル(例:0.5度の方向変更が許可されます)。

angleVariance =希望する角度の許容偏差(例:91度がOKの場合は1)。

ブライアン

private static bool AngleWithinTolerance(IPolygon pPoly, double angletarget, double edgeVariance, double angleVariance)
    {
        GeometryEnvironment geometryEnvironment = new GeometryEnvironment();
        IConstructAngle constructAngle = geometryEnvironment as IConstructAngle;
        IPointCollection ptcol = (IPointCollection)pPoly;
        double angle;

        //No circles!
        if (ptcol.PointCount < 3) return false;

        //Check angle made by last point first point and second point in the collection.
        angle = Math.Abs(constructAngle.ConstructThreePoint(ptcol.get_Point(ptcol.PointCount - 2), ptcol.get_Point(0), ptcol.get_Point(1)) * (180/3.14159250439667));
        if (angle < edgeVariance || (angle < angletarget + angleVariance & angle > angletarget - angleVariance))
        {
            //Angle at index 0 is OK - check all other points in collection.
            for (int x = 0; x != ptcol.PointCount - 2; x++)
            {
                angle = Math.Abs(constructAngle.ConstructThreePoint(ptcol.get_Point(x), ptcol.get_Point(x + 1), ptcol.get_Point(x + 2)) * (180 / 3.14159250439667));
                if (angle > edgeVariance & (angle > angletarget + angleVariance || angle < angletarget - angleVariance))
                {
                    return false;
                }
            }
        }
        else
        {
            return false;
        }
        //never failed.
        return true;
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.