42 votes

Calcul du cadre de délimitation à une certaine distance d'une coordonnée lat / longue en Java

Compte tenu de coordonnées (lat, long), je suis en train de calculer un carré de la boîte englobante qui est une fonction de la distance (par exemple 50 km) à l'abri de la coordonner. Donc comme entrée j'ai lat, long et à distance et en sortie je voudrais deux coordonnées, l'un étant le sud-ouest (en bas à gauche) coin et un sont le nord-est (en haut à droite) coin. J'ai vu un couple de réponses ici qu'essayer de répondre à cette question en Python, mais je suis à la recherche d'une implémentation de Java en particulier.

Juste pour être clair, je compte sur l'aide de l'algorithme sur Terre et je n'ai pas besoin d'accueillir un rayon variable.

Il n'a pas à être très précis (+/-20% est très bien), et il va seulement être utilisé pour calculer les boîtes englobantes sur de petites distances (pas plus de 150 km). Donc, je suis heureux de sacrifier un peu de précision pour un algorithme efficace. Toute aide est très appréciée.

Edit: j'aurais du être plus clair, je suis vraiment après un carré, pas un cercle. Je comprends que la distance entre le centre d'un carré et les différents points le long de la place du périmètre n'est pas une valeur constante comme c'est avec un cercle. Je suppose que ce que je veux dire, c'est une place où si vous tracez une ligne à partir du centre d'un des quatre points sur le périmètre qui résulte en une ligne perpendiculaire à un côté du périmètre, puis ces 4 lignes ont la même longueur.

59voto

J'ai écrit un article sur la recherche des coordonnées de délimitation:

http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates

L'article explique les formules et fournit également une implémentation Java. (Il montre également pourquoi la formule d'IronMan pour la longitude min / max est inexacte.)

16voto

IronMan Points 61
 double R = 6371;  // earth radius in km

double radius = 50; // km

double x1 = lon - Math.toDegrees(radius/R/Math.cos(Math.toRadians(lat)));

double x2 = lon + Math.toDegrees(radius/R/Math.cos(Math.toRadians(lat)));

double y1 = lat + Math.toDegrees(radius/R);

double y2 = lat - Math.toDegrees(radius/R);
 

Bien que je recommande également JTS.

4voto

novalis Points 887
import com.vividsolutions.jts.geom.Envelope;

...
Envelope env = new Envelope(centerPoint.getCoordinate());
env.expandBy(distance_in_degrees); 
...

Maintenant env contient votre enveloppe. Ce n'est pas vraiment un "carré" (quoi que cela signifie sur la surface d'une sphère), mais elle devrait faire.

Vous devriez noter que la distance en degrés dépend de la latitude du point central. Au niveau de l'équateur, de 1 degré de latitude est d'environ 111km, mais à New York, c'est seulement à environ 75 km.

La chose vraiment cool, c'est que vous pouvez mettre tous vos points en com.vividsolutions.jts.index.strtree.STRtree , puis l'utiliser pour calculer rapidement les points à l'intérieur de cette Enveloppe.

2voto

Un cadre de délimitation carré à une distance d'un point? Cela ressemble plus à un cercle pour moi.

Pour des distances bien inférieures à un rayon de la Terre, vous pouvez facilement vous rapprocher en rejetant la courbure de la Terre et en disant simplement X miles dans les deux sens à partir de l'endroit où vous vous trouvez.

1voto

susheel Points 11
 double R = 6371; // earth radius in km
double radius = 50; // km
double x1 = lon - Math.toDegrees(radius/R/Math.cos(Math.toRadians(lat)));
double x2 = lon + Math.toDegrees(radius/R/Math.cos(Math.toRadians(lat)));
double y1 = lat + Math.toDegrees(radius/R);
double y2 = lat - Math.toDegrees(radius/R);
 

Bien que je recommande également JTS.

Cela calcule, mais Google Earth n'accepte pas et ne mappe pas le modèle 3D.

 /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package assetmap;




 public class Main {

 public double degrees;
 public double pi= 3.1416;
 public static double lon=80.304737;
 public static double lat=26.447521;
 public static double x1,x2,y1,y2;


 public static void main(String[] args) {

 double R = 6371; // earth radius in km 26.447521

 double radius = 0.300; // km

 x1 =   (lon - Math.toDegrees(radius / R / Math.cos(Math.toRadians(lat))));

 x2 =    (lon + Math.toDegrees(radius / R / Math.cos(Math.toRadians(lat))));

 y1 =   (lat + Math.toDegrees(radius / R));

 y2 =   (lat - Math.toDegrees(radius / R));


 System.out.println(x1+"---|"+x2+"---|"+y1+"|---|"+y2);


 }

}
 

Il imprime

 80.30172366789824---|80.30775033210176---|26.450218964817754|---|26.444823035182242
 

KML:

 <?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Placemark>
    <name>United Nations Headquarters</name>
    <Region>
        <LatLonAltBox>
            <north>26.447251203518224</north>
            <south>26.447790796481772</south>
            <east>80.30503833321018</east>
            <west>80.30443566678983</west>
            <minAltitude>0</minAltitude>
            <maxAltitude>30</maxAltitude>
            <altitudeMode>absolute</altitudeMode>
        </LatLonAltBox>
        <Lod>
            <minLodPixels>128</minLodPixels>
            <maxLodPixels>-1</maxLodPixels>
            <minFadeExtent>0</minFadeExtent>
            <maxFadeExtent>0</maxFadeExtent>
        </Lod>
    </Region>
    <Model id="model_1">
        <altitudeMode>absolute</altitudeMode>
        <Location>
            <longitude>80.304737</longitude>
            <latitude>26.447521</latitude>
            <altitude>0.406173708576</altitude>
        </Location>
        <Orientation>
            <heading>0</heading>
            <tilt>0</tilt>
            <roll>0</roll>
        </Orientation>
        <Scale>
            <x>10</x>
            <y>10</y>
            <z>10</z>
        </Scale>
        <Link>
            <href>un.dae</href>
        </Link>
        <ResourceMap>
            <Alias>
                <targetHref>_01.jpg</targetHref>
                <sourceHref>../images/_01.jpg</sourceHref>
            </Alias>
            <Alias>
                <targetHref>_02.jpg</targetHref>
                <sourceHref>../images/_02.jpg</sourceHref>
            </Alias>
            <Alias>
                <targetHref>_04.jpg</targetHref>
                <sourceHref>../images/_04.jpg</sourceHref>
            </Alias>
            <Alias>
                <targetHref>_05.jpg</targetHref>
                <sourceHref>../images/_05.jpg</sourceHref>
            </Alias>
            <Alias>
                <targetHref>_06.jpg</targetHref>
                <sourceHref>../images/_06.jpg</sourceHref>
            </Alias>
            <Alias>
                <targetHref>_07.jpg</targetHref>
                <sourceHref>../images/_07.jpg</sourceHref>
            </Alias>
            <Alias>
                <targetHref>_08.jpg</targetHref>
                <sourceHref>../images/_08.jpg</sourceHref>
            </Alias>
            <Alias>
                <targetHref>_09.jpg</targetHref>
                <sourceHref>../images/_09.jpg</sourceHref>
            </Alias>
        </ResourceMap>
    </Model>
</Placemark>
</kml>
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X