Menemukan poligon tanpa sudut kanan menggunakan Open Source GIS atau ArcGIS untuk Desktop?

8

Sekarang kami mendigitalkan beberapa bangunan di area tertentu.

Aturan wajib untuk pekerjaan ini - dalam banyak kasus bangunan harus memiliki sudut siku-siku.

Kami menggunakan QGIS dengan alat CAD untuk pekerjaan ini, tetapi terkadang kami membuat kesalahan dan membuat poligon dengan bentuk yang tidak teratur.

Adakah yang tahu bagaimana kita bisa menemukan poligon seperti itu tanpa sudut kanan menggunakan open source GIS atau ArcGIS?

imatvej
sumber

Jawaban:

5

Saya tidak tahu alat yang ada untuk melakukan ini, tetapi Anda dapat menulis satu di ArcPy atau menggunakan GDAL / OGR di sepanjang baris berikut:

  • Untuk setiap poligon ...
    • Dapatkan geometri
    • Ikuti belitan poligon dan hitung sudut internal di setiap titik
    • Jika ada sudut yang tidak 90 derajat, tambahkan FID / OID (atau atribut lainnya) ke daftar tolak
  • Cetak daftar tolak
MappaGnosis
sumber
3
+1 Setelah menulis kode yang serupa, saya akan merekomendasikan sedikit modifikasi. Sudut yang terbentang oleh segmen garis yang sangat kecil tidak menimbulkan masalah (visual). Juga, sudut yang sangat dekat dengan 90 derajat seharusnya tidak menjadi masalah juga. Ini menyarankan untuk menghitung produk dalam dari setiap sisi dengan pendahulunya. Bandingkan nilai absolut hasil dengan ambang (positif kecil). Tandai poligon tempat ambang tersebut dilampaui. Ini sekaligus memungkinkan penyimpangan besar dari 90 derajat untuk tepi kecil serta penyimpangan kecil untuk tepi besar. Sebagai bonus, Anda tidak harus menghitung sudut.
whuber
Adakah yang mencoba menerapkan jawaban kedua @MappaGnosis?
b_jugger
2

Di bawah ini adalah salah satu pendekatan yang mungkin. Fungsi mengembalikan benar atau salah tergantung jika poligon memiliki sudut di bawah ukuran tertentu atau berada dalam kisaran di sekitar sudut target. Perlu diingat bahwa ini adalah pendekatan yang sangat sederhana dan mengasumsikan digitalisasi garis lurus. Saya menguji lingkaran, tetapi tidak menguji kurva atau kemungkinan lain yang bisa meningkatkan fungsi.

angleTarget = sudut yang diinginkan (mis. 90).

edgeVariance = wafel yang diizinkan dari garis lurus (mis. perubahan arah 0,5 derajat diizinkan).

angleVariance = penyimpangan yang diijinkan dari sudut yang diinginkan (mis. 1 jika 91 derajat OK).

Brian

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;
    }
Brian
sumber