0

Hi I am looking to find a way of checking if a point exists inside a polygon from my c# code.I successfully implemented the same with javascript using Google maps geometry library as reference from this link.Now I need to do the same from c# code.Is google providing any webservices or dll for the same?

If not, can anyone suggest any third party api's or plugin's for the same purpose.I already tried some third party item's but didn't find any one giving accuracy like Google maps geometry library

Community
  • 1
  • 1
user136252
  • 41
  • 1
  • 1
  • 8

2 Answers2

0

This problem is trivial to program.

To simplify, first assume the test point to be at the origin. You need to check the parity of the number of intersections of the positive X-axis with the polygon edges.

Inside= False
for k in in 0..N-1:
    if (Y[k] > 0) != (Y[k+1] > 0):
        # The edge straddles the X-axis...
        if (Y[k] > 0) == (Y[k] * X[k+1] > Y[k+1] * X[k]):
            # ... and intersects it on the positive side
            Inside= not Inside

Take the indexes modulo N, so that N≡0.

For a test point not at the origin, it suffices to translate the coordinates of all polygon vertices, which you do on the fly without actually modifying the polygon.

enter image description here

If the polygon crosses the 180° meridian, repeat the point-in-polygon test with the longitude ± 360°.

0
private static bool EstaDentroDeZona(double latitudActual, double longitudActual, List<PuntoPorZona> listaPuntosPorZona)
    {
        Punto<double> vector1 = new Punto<double>();
        Punto<double> vector2 = new Punto<double>();



        int i = 0;
        double a = 0;

        for (i = 0; i < listaPuntosPorZona.Count - 1; i++)
        {
            vector1.X = Convert.ToDouble(listaPuntosPorZona[i].Latitud) - latitudActual;
            vector1.Y = Convert.ToDouble(listaPuntosPorZona[i].Longitud) - longitudActual;
            vector2.X = Convert.ToDouble(listaPuntosPorZona[i + 1].Latitud) - latitudActual;
            vector2.Y = Convert.ToDouble(listaPuntosPorZona[i + 1].Longitud) - longitudActual;

            a = a + Angulo(vector1, vector2);
        }

        double grados = a * 180 / Math.PI;
        return Math.Abs(grados) > 180;
    }

    private static double Angulo(Punto<double> v1, Punto<double> v2)
    {
        double angulo;
        double calculoModulos;
        double calculoProductoEscalar;
        calculoModulos = Modulo(v1) * Modulo(v2);
        calculoProductoEscalar = ProductoEscalar(v1, v2);

        if (ModuloDelProductoVectorialConSigno(v1, v2) > 0)
        {
            angulo = Math.Acos(calculoProductoEscalar / calculoModulos);
        }
        else
        {
            angulo = -1 * (Math.Acos(calculoProductoEscalar / calculoModulos));
        }
        return angulo;
    }

    private static double ProductoEscalar(Punto<double> punto1, Punto<double> punto2)
    {
        double productoEscalcar;
        productoEscalcar = (punto1.X * punto2.X) + (punto1.Y * punto2.Y);
        return productoEscalcar;
    }

    private static double Modulo(Punto<double> punto)
    {
        double modulo;
        modulo = Math.Sqrt(punto.X * punto.X + punto.Y * punto.Y);
        return modulo;
    }

    private static double ModuloDelProductoVectorialConSigno(Punto<double> v1, Punto<double> v2)
    {
        double angulo = ((v1.X * v2.Y) - (v1.Y * v2.X));
        return angulo;
    }

    private struct Punto<T>
    {
        T x;
        T y;

        public Punto(T a, T b)
        {
            x = a;
            y = b;
        }

        public T X
        {
            get { return x; }
            set { x = value; }
        }

        public T Y
        {
            get { return y; }
            set { y = value; }
        }
    }

Just translated to English methods

listaPuntoPorZona = Points of Polygon

Alimentador
  • 148
  • 1
  • 7