Encontrando polígonos sem ângulos retos usando o Open Source GIS ou o ArcGIS for Desktop?


8

Agora estamos digitalizando alguns edifícios na área especificada.

A regra obrigatória para este trabalho - na maioria dos casos, os edifícios devem ter ângulos retos.

Estamos usando o QGIS com ferramentas CAD para este trabalho, mas às vezes cometemos erros e criamos polígonos com uma forma irregular.

Alguém sabe como podemos encontrar esses polígonos sem ângulos retos usando GIS ou ArcGIS de código aberto?

Respostas:


5

Não conheço uma ferramenta existente para fazer isso, mas você pode escrever uma no ArcPy ou usando GDAL / OGR nas seguintes linhas:

  • Para cada polígono ...
    • Obtenha a geometria
    • Siga o enrolamento do polígono e calcule o ângulo interno em cada vértice
    • Se qualquer ângulo não for 90 graus, adicione o FID / OID (ou algum outro atributo) a uma lista de rejeições
  • Imprimir a lista de rejeições

3
+1 Tendo escrito um código semelhante, eu recomendaria uma pequena modificação. Um ângulo estendido por segmentos de linha extremamente pequenos não cria problemas (visuais). Além disso, ângulos muito próximos a 90 graus também não devem ser um problema. Isso sugere calcular o produto interno de cada borda com seu antecessor. Compare o valor absoluto do resultado com um limite (pequeno positivo). Sinalize polígonos onde esse limite é excedido. Isso permite simultaneamente grandes desvios de 90 graus para arestas pequenas, bem como pequenos desvios para arestas grandes. Como bônus, você não precisa calcular ângulos.
whuber

Alguém tentou implementar a segunda linha da resposta @MappaGnosis?
b_jugger 21/02

2

Abaixo está uma abordagem possível. A função retorna verdadeiro ou falso, dependendo se o polígono tiver ângulos abaixo de um determinado tamanho ou estiver dentro de um intervalo em torno de um ângulo alvo. Lembre-se de que esta é uma abordagem muito simples e assume a digitalização em linha reta. Testo um círculo, mas não testo curvas ou outras possibilidades que possam atrapalhar a função.

angleTarget = ângulo desejado (ex. 90).

edgeVariance = waffle permitido de linha reta (por exemplo, alteração de direção de 0,5 graus permitida).

angleVariance = desvio permitido do ângulo desejado (ex. 1, se 91 graus estiver 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;
    }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.