it-swarm.com.de

Konvertieren von Breitengrad, Längengrad nach x, y

Ich möchte die GPS-Position (Breite, Länge) in x, y-Koordinaten umrechnen. Ich habe viele Links zu diesem Thema gefunden und angewendet, aber es gibt mir nicht die richtige Antwort!

Ich folge diesen Schritten, um die Antwort zu testen: (1) Erstens nehme ich zwei Positionen ein und berechne die Entfernung zwischen ihnen mithilfe von Karten. (2) Konvertieren Sie dann die beiden Positionen in x, y-Koordinaten. (3) Berechnen Sie dann erneut den Abstand zwischen den beiden Punkten in den x-, y-Koordinaten und prüfen Sie, ob bei Punkt (1) das gleiche Ergebnis erzielt wird oder nicht.

eine der Lösungen, die ich gefunden habe, ist die folgende, aber es gibt mir keine richtige Antwort!

latitude = Math.PI * latitude / 180;
longitude = Math.PI * longitude / 180;

// adjust position by radians
latitude -= 1.570795765134; // subtract 90 degrees (in radians)

// and switch z and y 
xPos = (app.radius) * Math.sin(latitude) * Math.cos(longitude);
zPos = (app.radius) * Math.sin(latitude) * Math.sin(longitude);
yPos = (app.radius) * Math.cos(latitude);

auch ich habe es versucht link aber immer noch nicht gut mit mir zusammenarbeiten!

irgendeine Hilfe, wie man von (Breite, Länge) nach (x, y) konvertiert?

Vielen Dank,

18
userInThisWorld

Es gibt keine genaue Lösung

Es gibt keine isometrische Karte von der Kugel zur Ebene. Wenn Sie Lat/Lon-Koordinaten von der Kugel in X/Y-Koordinaten in der Ebene konvertieren, können Sie nicht hoffen, dass durch diese Operation alle Längen erhalten bleiben. Sie müssen irgendeine Art von Verformung akzeptieren. Es gibt viele verschiedene Kartenprojektionen, mit denen unterschiedliche Kompromisse zwischen der Beibehaltung von Längen, Winkeln und Flächen erzielt werden können. Für kleinere Teile der Erdoberfläche ist transversaler Mercator durchaus üblich. Sie haben vielleicht von UTM gehört. Aber es gibt viele mehr .

Die von Ihnen angegebenen Formeln berechnen x/y/z, d. H. Einen Punkt im 3D-Raum. Aber selbst dort würden Sie nicht automatisch die richtigen Entfernungen erhalten. Die kürzeste Entfernung zwischen zwei Punkten auf der Oberfläche der Kugel würde durch diese Kugel verlaufen, wohingegen Entfernungen auf der Erde meist geodätische Längen sind, die der Oberfläche folgen. Sie werden also länger sein.

Annäherung für kleine Gebiete

Wenn der Teil der Erdoberfläche, den Sie zeichnen möchten, relativ klein ist, können Sie eine sehr einfache Näherung verwenden. Sie können einfach die horizontale Achse x verwenden, um die Länge λ zu bezeichnen, die vertikale Achse y, um die Breite φ zu bezeichnen. Das Verhältnis zwischen diesen sollte jedoch nicht 1: 1 sein. Verwenden Sie stattdessen cos (φ) als Seitenverhältnis, wobei φ bezeichnet einen Breitengrad in der Nähe der Mitte Ihrer Karte. Um Winkel (gemessen im Bogenmaß) in Längen umzurechnen, multiplizieren Sie außerdem mit dem Radius der Erde (der in diesem Modell als Kugel angenommen wird).

  • x = r λ cos (φ)
  • y = r φ

Dies ist einfach gleichwinklige Projektion . In den meisten Fällen können Sie cos (φ berechnen) nur einmal, was spätere Berechnungen von großen Punktzahlen wirklich billig macht.

39
MvG

Ich möchte Ihnen mitteilen, wie ich das Problem gelöst habe. Ich habe die gleichwinklige Projektion wie bei @MvG verwendet, aber diese Methode gibt Ihnen X- und Y-Positionen in Bezug auf den Globus (oder die gesamte Karte). Dies bedeutet, dass Sie globale Positionen erhalten. In meinem Fall wollte ich Koordinaten in einem kleinen Bereich (etwa 500 Quadratmeter) konvertieren, also bezog ich den Projektionspunkt auf weitere 2 Punkte, ermittelte die globalen Positionen und bezog mich auf lokale (Bildschirm-) Positionen, wie folgt:

Zuerst wähle ich 2 Punkte (oben links und unten rechts) um den Bereich, in den ich projizieren möchte, genau wie in diesem Bild:

enter image description here

Sobald ich den globalen Referenzbereich in lat und lng habe, mache ich dasselbe für Bildschirmpositionen. Die Objekte, die diese Daten enthalten, werden unten angezeigt.

//top-left reference point
var p0 = {
    scrX: 23.69,        // Minimum X position on screen
    scrY: -0.5,         // Minimum Y position on screen
    lat: -22.814895,    // Latitude
    lng: -47.072892     // Longitude
}
//bottom-right reference point
var p1 = {
    scrX: 276,          // Maximum X position on screen
    scrY: 178.9,        // Maximum Y position on screen
    lat: -22.816419,    // Latitude
    lng: -47.070563     // Longitude
}
var radius = 6.371;     //Earth Radius in Km

//## Now I can calculate the global X and Y for each reference point ##\\

// This function converts lat and lng coordinates to GLOBAL X and Y positions
function latlngToGlobalXY(lat, lng){
    //Calculates x based on cos of average of the latitudes
    let x = radius*lng*Math.cos((p0.lat + p1.lat)/2);
    //Calculates y based on latitude
    let y = radius*lat;
    return {x: x, y: y}
}
// Calculate global X and Y for top-left reference point
p0.pos = latlngToGlobalXY(p0.lat, p0.lng);
// Calculate global X and Y for bottom-right reference point
p1.pos = latlngToGlobalXY(p1.lat, p1.lng);

/*
* This gives me the X and Y in relation to map for the 2 reference points.
* Now we have the global AND screen areas and then we can relate both for the projection point.
*/

// This function converts lat and lng coordinates to SCREEN X and Y positions
function latlngToScreenXY(lat, lng){
    //Calculate global X and Y for projection point
    let pos = latlngToGlobalXY(lat, lng);
    //Calculate the percentage of Global X position in relation to total global width
    pos.perX = ((pos.x-p0.pos.x)/(p1.pos.x - p0.pos.x));
    //Calculate the percentage of Global Y position in relation to total global height
    pos.perY = ((pos.y-p0.pos.y)/(p1.pos.y - p0.pos.y));

    //Returns the screen position based on reference points
    return {
        x: p0.scrX + (p1.scrX - p0.scrX)*pos.perX,
        y: p0.scrY + (p1.scrY - p0.scrY)*pos.perY
    }
}

//# The usage is like this #\\

var pos = latlngToScreenXY(-22.815319, -47.071718);
$point = $("#point-to-project");
$point.css("left", pos.x+"em");
$point.css("top", pos.y+"em");

Wie Sie sehen können, habe ich dies in Javascript gemacht, aber die Berechnungen können in jede Sprache übersetzt werden.

PS: Ich wende die konvertierten Positionen auf ein HTML-Element an, dessen ID "point-to-project" ist. Um diesen Code in Ihrem Projekt zu verwenden, müssen Sie dieses Element (als absolute Position formatiert) erstellen oder den Block "usage" ändern.

4
allexrm

Da diese Seite über Google angezeigt wird, während ich nach dem gleichen Problem gesucht habe, möchte ich eine praktischere Antwort geben. Die Antwort von MVG ist richtig, aber eher theoretisch.

Ich habe eine App zum Zeichnen von Tracks für das Fitbit ionic in Javascript erstellt. Der folgende Code beschreibt, wie ich das Problem gelöst habe.

//LOCATION PROVIDER
index.js
var gpsFix = false;
var circumferenceAtLat = 0;
function locationSuccess(pos){
  if(!gpsFix){
    gpsFix = true;
    circumferenceAtLat = Math.cos(pos.coords.latitude*0.01745329251)*111305;
  }
  pos.x:Math.round(pos.coords.longitude*circumferenceAtLat),
  pos.y:Math.round(pos.coords.latitude*110919), 
  plotTrack(pos);
}

plotting.js

plotTrack(position){

let x = Math.round((this.segments[i].start.x - this.bounds.minX)*this.scale);
let y = Math.round(this.bounds.maxY - this.segments[i].start.y)*this.scale; //heights needs to be inverted

//redraw?
let redraw = false;

//x or y bounds?
 if(position.x>this.bounds.maxX){
   this.bounds.maxX = (position.x-this.bounds.minX)*1.1+this.bounds.minX; //increase by 10%
   redraw = true;
 }
 if(position.x<this.bounds.minX){
   this.bounds.minX = this.bounds.maxX-(this.bounds.maxX-position.x)*1.1;
    redraw = true;
 };
 if(position.y>this.bounds.maxY){
   this.bounds.maxY = (position.y-this.bounds.minY)*1.1+this.bounds.minY; //increase by 10%
    redraw = true;
 }
 if(position.y<this.bounds.minY){
   this.bounds.minY = this.bounds.maxY-(this.bounds.maxY-position.y)*1.1;
    redraw = true;
 }
 if(redraw){
   reDraw();
 }
}


function reDraw(){

let xScale = device.screen.width / (this.bounds.maxX-this.bounds.minX);
let yScale = device.screen.height / (this.bounds.maxY-this.bounds.minY); 
if(xScale<yScale) this.scale = xScale; 
else this.scale = yScale;

//Loop trough your object to redraw all of them
}
2
Pieter Oskam

Es ist besser, in UTM-Koordinaten zu konvertieren und diese als x und y zu behandeln.

import utm
u = utm.from_latlon(12.917091, 77.573586)

Das Ergebnis ist (779260.623156606, 1429369.8665238516, 43, 'P'). Die ersten beiden können als x, y-Koordinaten behandelt werden. Das 43P ist die UTM-Zone, die für kleine Gebiete (Breite bis zu 668 km) ignoriert werden kann.

0
Krishna Nagaraj