2016-01-09 1 views
1

Donc je travaille sur un projet final en langage Java, ce projet a un côté serveur (qui est sous ma responsabilité) et un client GUI (qui est sous la responsabilité de quelqu'un d'autre).Diviser une zone du globe donnée par 4 coordonnées de longitude en une grille équidistante?

En tant que serveur, je reçois constamment la coordination GPS (comme la longitude de latitude) des clients Android et je dois répondre avec leur emplacement équivalent sur une grille pré-allouée.

La grille est définie par 4 coordonnées LatLng qui me sont envoyées par le client GUI et la quantité de lignes de la grille à diviser par. Par exemple. Je reçois (35.000.35.000), (35.000.36.000), (36.000.36.000), (36.000.35.000) et 40x40.

La méthode actuelle que j'utilise est en calculant la distance en radians degrés pour la distance de latitude de la zone et la distance de longitude séparément, puis je le divise par 40 (comme dans l'exemple donné), chaque quotient est mon " cliquez sur ", une seule unité de distance que j'utilise plus tard.

Lorsque je reçois une nouvelle coordonnée je la divise par mon "clic" et fais un Math.floor, le quotient de cette opération est l'emplacement sur la grille. Mais quelque chose ne va pas, mes calculs sont apparemment incorrects, le client de l'interface graphique n'étant pas d'accord avec moi (généralement 1 grille nord/sud et 1 grille ouest/est). Il prend la carte (google-map) et la manipule .? image diviser simplement une zone rectangulaire Qu'est-ce que je fais mal est-il une meilleure façon de discrétisation la zone donnée par cette configuration

choses que j'ai déjà vérifier: 1. ce n'est pas une sorte de soupassement flotteur, je BigDecimal et SimpleLatLng.

  1. le client GUI est d'accord avec moi sur des endroits plus près du bloc de grille de 0x0 relative, il est donc pas d'habitude hors par une erreur.

EDIT: J'ai réussi à résoudre la plupart des erreurs, j'ai encore quelques erreurs dont je ne sais pas quelle partie du code peut être responsable.

EDIT 2: Le problème semble être résolu, la question ne recevait pas le roulement correct en premier lieu et en supposant que la grille était liée au nord, le code correct est attaché:

+0

Fractionnement dans une grille est complexe d'équidistance, il aurait besoin d'une transformation de coordonnées. Beaucoup plus facile, selon l'applictaion est de diviser par degrés. Ensuite, il est très facile de trouver la cellule de grille correcte. – AlexWien

Répondre

0

J'ai réussi à réponds-moi après avoir exploré et joué avec le code. Ceci est l'implémentation finale de cette solution telle qu'utilisée dans notre code de projets. Vous pouvez l'utiliser librement et nous espérons qu'il aidera d'autres à l'avenir:

import com.javadocmd.simplelatlng.LatLng; 
import com.javadocmd.simplelatlng.LatLngTool; 
import com.javadocmd.simplelatlng.util.LengthUnit; 
import java.awt.*; 
import java.util.LinkedList; 
import java.util.List; 

public class GridMap { 
private double lat_rad; 
private double lng_rad; 
private Polygon grid; 
private double factor = 100000; 
private List<LatLng> bounds = new LinkedList<>(); 

public GridMap(int lat_bin, int lng_bin, List<Double> coords) { 
    // coords should be (y_bot, x_bot;,y_up, x_bot;y_up, x_up;y_bot, x_up) 
    grid = new Polygon(); 
    for (int i = 0; i < coords.size(); i += 2) { 
     int nx = (int) Math.floor(factor * coords.get(i)); 
     int ny = (int) Math.floor(factor * coords.get(i + 1)); 
     grid.addPoint(nx, ny); 
     bounds.add(new LatLng(coords.get(i), coords.get(i + 1))); 
    } 
    lat_rad = LatLngTool.distance(bounds.get(0), bounds.get(1), LengthUnit.METER)/(lat_bin); 
    lng_rad = LatLngTool.distance(bounds.get(0), bounds.get(3), LengthUnit.METER)/(lng_bin); 
} 

public boolean inGrid(LatLng point) { 
    int lat = (int) Math.floor(factor * point.getLatitude()); 
    int lng = (int) Math.floor(factor * point.getLongitude()); 
    return grid.contains(lat, lng); 
} 

public Point toGrid(LatLng llp) { 
    if (inGrid(llp)) { 
     double lat = llp.getLatitude(); 
     double lng = llp.getLongitude(); 
     double rel_lat = bounds.get(0).getLatitude(); 
     double rel_lng = bounds.get(0).getLongitude(); 
     int ilat = (int) Math.floor(LatLngTool.distance(new LatLng(rel_lat, lng), bounds.get(0), LengthUnit.METER)/lat_rad); 
     int ilng = (int) Math.floor(LatLngTool.distance(new LatLng(lat, rel_lng), bounds.get(0), LengthUnit.METER)/lng_rad); 
     return new Point(ilat, ilng); 
    } 
    return new Point(-1, -1); 
} 

public LatLng toLatLng(Point gridLoc){ 
    double lat_dist = (gridLoc.getY() + 0.5) * lat_rad; 
    double lng_dist = (gridLoc.getX() + 0.5) * lng_rad; 
    double y_bearing = LatLngTool.initialBearing(bounds.get(0), bounds.get(1)); 
    double x_bearing = LatLngTool.initialBearing(bounds.get(1), bounds.get(2)); 
    LatLng startLatLng = new LatLng(bounds.get(0).getLatitude(), bounds.get(0).getLongitude()); 
    LatLng lat_llp = LatLngTool.travel(startLatLng, y_bearing, lat_dist, LengthUnit.METER); 
    return LatLngTool.travel(lat_llp, x_bearing, lng_dist, LengthUnit.METER); 
} 
}