2011-12-19 19 views
5

Esta es la situación:Comprobar si el usuario está cerca de punto de control de ruta con GPS

Tengo un GPS ruta predeterminada que el usuario se ejecutará. La ruta tiene algunos puntos de control y el usuario debe pasar cerca de todos ellos (considérelos como un punto de control de un juego de carreras, que evita que el usuario tome accesos directos). Necesito asegurarme de que el usuario pase por todos los puntos de control. quiero para determinar un área que será considerada dentro de un radio de un punto de control, pero no quiero que sea sólo una zona radial, que debería ser un área teniendo en cuenta la forma de la trayectoria. ¿No lo entendiste? Yo tampoco. Mire esta imagen mal dibujada para comprenderla mejor: Route example

Las líneas negras representan la ruta predeterminada, la bola azul es el punto de control y el polígono azul es el área deseada. La línea verde es un usuario más preciso, y la línea roja es un usuario menos preciso (un tipo borracho conduciendo tal vez? Jaja). Ambas líneas deben estar dentro del polígono, pero un usuario que omita totalmente la ruta no debería.

ya vi en algún lugar aquí una función para comprobar es el usuario se encuentra dentro de un polígono como este, pero necesito saber cómo calcular el polígono.

¿Alguna sugerencia?

EDIT:

estoy considerando el uso de la función distanceTo sencilla() para simplemente dibujar un círculo imaginario y comprobar si el usuario está ahí. Eso es bueno porque es tanto fácil de implementar y entender, y malo porque para asegurarse de que el usuario más erronic pasa whithin el puesto de control que iba a necesitar un gran radio, por lo que el usuario correcto entrar en la zona de control antes de lo esperado.

Y para que ustedes entiendan mejor la situación, esto es para una aplicación que se supone debe usarse en tráfico (automóvil o autobús), y los puntos de control deben ser puntos de referencia o puntos que dividen su ruta, por ejemplo, en algún lugar donde el atasco de tráfico comienza o se detiene.

+0

¿Por qué necesita un polígono en lugar de usar el círculo interno? – SERPRO

Respuesta

2

Se podía comprobar la distancia entre los dos, suponiendo que conoce la localización geográfica del punto de control.

utilizar la función distanceTo y la configuración de un umbral sin embargo muchos metros el usuario tiene que ser desde el puesto de control para seguir adelante.

Editar

Puesto que usted quiere evitar distanceTo, aquí hay una pequeña función que escribí hace un tiempo para comprobar si un punto está en un polígono:

public boolean PIP(Point point, List<Point> polygon){ 
    boolean nodepolarity=false; 
    int sides = polygon.size(); 
    int j = sides -1; 
    for(int i=0;i<sides;i++){ 
     if((polygon.get(i).y<point.y && polygon.get(j).y>=point.y) ||(polygon.get(j).y<point.y && polygon.get(i).y>=point.y)){ 
      if (polygon.get(i).x+(point.y-polygon.get(i).y)/(polygon.get(j).y-polygon.get(i).y)*(polygon.get(j).x-polygon.get(i).x)<point.x) { 
       nodepolarity=!nodepolarity; 
      } 
     } 
    j=i; 
    } 
    return nodepolarity; //FALSE=OUTSIDE, TRUE=INSIDE 
} 

List<Point> polygon es una lista de los puntos que componen un polígono

Este utiliza el Ray casting algorithm para determinar cuántas intersecciones un rayo hace a través del polígono.

Todo lo que necesita hacer es crear el 'límite' alrededor del área que necesita con los GeoPoints traducidos a píxeles utilizando el método toPixels.

Almacene esos puntos en una lista <> de puntos, y debe estar todo listo.

+0

Eso es exactamente lo que estoy tratando de evitar, si hago esto pierdo algo de precisión, pero lo investigaré si no encuentro nada más. –

+0

@RodrigoCastro See edit – MrZander

+0

Thaanks, ya casi termino de crear el área (de hecho, cambié la definición de lo que quería después de pensar más sobre eso). Edité la pregunta con una nueva (y mejor) imagen que muestra lo que quiero. –

1

Sé que esta es una vieja pregunta, pero tal vez sería útil para alguien.

Este es un método más simple, con mucho menos cómputo necesario. Esto no se desencadenaría la primera vez que el usuario ingrese en el área del umbral, solo obtiene el punto más cercano donde el usuario ha pasado cerca del punto de control AND (s) con el que se ha acercado lo suficiente.

La idea es mantener una lista de 3 elementos de distancias para cada punto de control, con las últimas tres distancias (por lo que sería [d (t), d (t-1), d (t-2) ]). Esta lista debe rotarse en cada cálculo de distancia.

Si en cualquier cálculo de distancia la distancia d (t-1) anterior es menor que la actual d (t) y mayor que la d (t-2) anterior, entonces el punto móvil ha pasado el punto de control. Si esto fue un pase real, o solo fue una falla, puede decidirse comprobando la distancia real d (t-1).

private long DISTANCE_THRESHOLD = 2000; 

private Checkpoint calculateCheckpoint(Map<Checkpoint, List<Double>> checkpointDistances) 
{ 
    Map<Checkpoint, Double> candidates = new LinkedHashMap<Checkpoint, Double>(); 
    for (Checkpoint checkpoint: checkpointDistances.keySet()) 
    { 
     List<Double> distances = checkpointDistances.get(checkpoint); 
     if (distances == null || distances.size() < 3) 
      continue; 
     if (distances.get(0) > distances.get(1) && distances.get(1) < distances.get(2) && distances.get(1) < (DISTANCE_THRESHOLD)) //TODO: make this depend on current speed 
      candidates.put(checkpoint, distances.get(1)); 
    } 

    List<Entry<Checkpoint, Double>> list = new LinkedList<Entry<Checkpoint,Double>>(candidates.entrySet()); 
    Collections.sort(list, comp); 

    if (list.size() > 0) 
     return list.get(0).getKey(); 
    else 
     return null; 
} 

Comparator<Entry<Checkpoint, Double>> comp = new Comparator<Entry<Checkpoint,Double>>() 
{ 
    @Override 
    public int compare(Entry<Checkpoint, Double> o1, Entry<Checkpoint, Double> o2) 
    { 
     return o1.getValue().compareTo(o2.getValue()); 
    } 
}; 

La función obtiene un parámetro - un Map<Checkpoint, List<Double>> con los puestos de control y la lista de los últimos tres distancias. Emite el Checkpoint más cercano aprobado o null (si no había ninguno). El DISTANCE_THRESHOLD debe elegirse sabiamente. El Comparator es solo para poder ordenar los puntos de control en función de su distancia al usuario para obtener el más cercano.

Naturalmente, esto tiene algunos defectos menores, p. si el punto móvil se mueve entrecruzado, o el movimiento de error de la precisión del GPS es conmensurable con la velocidad real del usuario, entonces esto daría varias marcas de aprobación, pero esto afectaría casi cualquier algoritmo.

+0

Gracias, no estoy trabajando más en el proyecto original pero esto probablemente me ayude con un próximo proyecto sobre el seguimiento de autobuses. –

+0

Y creo que probablemente sería una buena idea mantener más de 3 puntos en la memoria al mismo tiempo para verificar inconsistencias, lo que puede sugerir fallas en el GPS, en lugar de datos reales que indiquen que el usuario ha salido del área –

+1

@ rodrigo- castro Sí, los 3 puntos son el mínimo absoluto para resolver el problema. Más puntos disminuirían la probabilidad de error, pero complicarían el código. Tal vez esto debería dejarse en algún algoritmo más inteligente (tal vez el chip GPS mismo), que filtraría el jitter de la medición y proporcionaría solo los datos de movimiento real/efectivo. Entonces este es otro problema. :) – Tylla

Cuestiones relacionadas