Transformationsansatz für Lat-Lon-Werte

Moin !

gleich eines vorweg - bevor mich der erste gleich an den Pranger stellt und es Warnungen hagelt. Die nachfolgenden Schritte sind nur für den LOKALEN GEBRAUCH bestimmt und die Anwender sind sich der GEFAHR BEWUSST.

Es geht darum das die Karten immer Nordgerichtet erstellt werden und die allerwenigsten Tools es ermöglichen Kartenplots zu drehen. Zumindest geht es in Maperative nicht!

Also wollte ich einen einfachen mathematischen Ansatz aus der Vermessung nehmen und die Lon/Lat-Werte als Rechts bzw. Hochwert interpretieren.

Dann habe ich mir die passenden Formeln zusammengestellt und losgerechet - an diskreten Zahlenwerten passt es auch!

base_* ist ein Drehpunkt im Bereich der zu bearbeitenden Kartendaten (damit sollten geografische Verzerrungen weitestgehend zu vernachlässigen sein!)
*_angle sind die betreffenden trigonometrischen Werte des Drehwinkels

lon_new = base_lon + cos_angle * (lon_old - base_lon) - sin_angle * (lat_old - base_lat);
lat_new = base_lat + sin_angle * (lon_old - base_lon) + cos_angle * (lat_old - base_lat);

Wenn ich das aber für einen Bereich von Malaga mache, dann sieht das sehr merkwürdig aus:

Testbeispiel Malaga

https://www.openstreetmap.org/#map=16/36.7171595271139/-4.430921403805183

Wenn man in diesem Bereich ein Rechteck in JOSM zeichnet und dieses dreht, dann bleibt es erhalten in seiner Form.

Habe ich einen Gedankenfehler oder wird innerhalb von JOSM ein anderer Rechenansatz angewandt?

Gruß Jan

Na ja, Deine Formel ist ja eine simple 2D Drehung. Das lat/lon Koordinatensystem ist aber verzerrt.

Es müsste gehen, indem Du vor der Drehung entzerrst und nach der Drehung wieder verzerrst.

Der Verzerrfaktor war glaube ich der cosinus des Breitengrades.

Das ganze natürlich nur für kleine Gebiete, wo man die Erdkrümmung vernachlässigen kann.

Hi !

also wenn ich Dich richtig verstehe, dann macht das JOSM schon bei einer einfachen Drehung ?

Dann würde mich die “genaue” Formel interessieren die in JOSM steckt.

Kommt da einer ran - ich kenne mich mit dem System und Java nun einmal gar nicht aus.

Gruß Jan

Deine Idee ist schon ganz in Ordnung, bei kleinen Abständen kann man die Verzerrung ignorieren.
Das Problem ist, dass die Formel davon ausgeht, dass die Abstände in x und y Richtung gleich sind. Bei lat und lon sind Sie das aber nicht, da lat von -180 bis +180 geht, lon aber nur von -90 bis +90. Daher muss du deine Formeln entsprechend korrigieren:

lon_new = base_lon + cos_angle * (lon_old - base_lon)*2 - sin_angle * (lat_old - base_lat);
lat_new = base_lat + sin_angle * (lon_old - base_lon)*2 + cos_angle * (lat_old - base_lat);

Klappt das?

Edit: Erste Vermutung, ansonsten rechne ich die Transformationsmatrixen mal komplett neu aus.
(Stichpunkt: “Rotation um einen beliebigen Punkt”)

Lade mal einen Kreisverkehr in JOSM (rund), stelle die Projektion auf WGS84 (er wird oval), drehe den Kreisverkehr (gedrehtes Oval) und stell wieder um auf Mercator (immer noch oval…).

Ich glaube, JOSM abschreiben ist ein Holzweg. So wie ich das sehe, arbeitet JOSM mit Daten in der Wunschprojektion des Nutzers. Oft ist das Mercator oder was anderes winkeltreues und die Drehung klappt zufällig.

Grüße, Max

Bei Latitude bleibt 1 Grad immer so 111 km, egal ob am Äquator oder am Pol. Bei Longitude mußt du das mit dem Cosinus von Latitude multiplizieren.
Mein Vorschlag: transformiere die Werte zunächst in so ein Kilometer-basiertes Koordinatensystem (km ab Äquator, km ab Greenwich-Meridian), transformiere den Bezugspunkt ebenso, und mache dann deine Transformation. In unseren Breiten sollte selbst bei 100x100km die Verzerrung nicht auffallen.
Z.B. 50°N, 12°E => 5550 km N, 942 km E (und nicht etwa 1320 km E).

Probiers mal damit:

LatLon in eine rechteckige Plattkarte für base_lon/base_lat mit Koordinatenursprung im Drehpunkt umwandeln

x= lon - base_lon
y=(lat - base_lat)/cos(base_lat)

Drehung

x_new = cos_angle * ( x ) - sin_angle * (y);
y_new = sin_angle * ( x ) + cos_angle * (y);

Plattkarte zurück in LatLon

lon_new=base_lon + x_new
lat_new=base_lat + y_new*cos(base_lat)

… allerdings ungetestet und ich verwechsel ganz oft x und y, lat und lon und sin und cos :wink:
… geht nicht am Nordpol!

Wenn umprojizieren in eine rechteckige Plattkarte nicht reicht, musst dir die Formeln für Mercator oder UTM suchen, oder eine Bibliothek dafür.

Grüße, Max

– snip – Edit und Quote verwechselt

Moin !

ich habe das versucht bei mir einzubauen… sieht jetzt so aus:

Vielleicht kann noch einmal einer raufschauen, weil ich den Hintergrund der Formel nicht kenne - aber das Ergebnis sieht nicht viel besser aus !

Gruß Jan

Nur mal vorsichtig gefragt… Du rechnest schon cos($config{base_lat}) mit base_lat in Bogenmaß? Ich vermute, das ist Perl und ich glaube, das rechnet so.

Und noch ne Korrektur, ich verwechsel auch manchmal / und *

x= lon - base_lon
y=(lat - base_lat)*cos(base_lat)                      <----- * statt /

x_new = cos_angle * ( x ) - sin_angle * (y);
y_new = sin_angle * ( x ) + cos_angle * (y);

lon_new=base_lon + x_new
lat_new=base_lat + y_new/cos(base_lat)                <----- / statt *

Hi !

Da ich von rechtwinkligen Koordinaten bei meiner Transformation ausgegangen war habe ich das hier vergessen!

Habe die Konvertierung mit

vor der Transformation und

ergänzt.

Die Formel lautet dann jetzt:

Aber jetzt beisst das Ergebnis förmlich in den Augen.

… und ja, ist Perl.

Gruß Jan

Dann tausch nochmal / und *, und falls es nichts hilft, warte auf ne bessere Formel, bin grad überfordert :wink:

ausgetauscht - aber noch nicht besser !

Gute Nacht vorerst.

Gruß Jan

Ja, oben muss “/” (y-Richtung muss gestreckt werden), unten “*”.

Also dieses Progrämmchen haut bei mir hin und rotiert um 45° mit Drehpunkt bei 11.5359E 48.1271N

$rho=180/3.1415927;

$angle=45/$rho;
$base_lon = 11.535951/$rho;
$base_lat = 48.127126/$rho;

$lon_old=$ARGV[0];
$lat_old=$ARGV[1];

$cos_angle=cos($angle);
$sin_angle=sin($angle);

$lon_old = $lon_old / $rho;
$lat_old = $lat_old / $rho;

$delta_x= $lon_old - $base_lon;
$delta_y=($lat_old - $base_lat) / cos($base_lat);

$x_new = $cos_angle * $delta_x  - $sin_angle * $delta_y;
$y_new = $sin_angle * $delta_x  + $cos_angle * $delta_y;

$lon_new=$base_lon + $x_new;
$lat_new=$base_lat + $y_new * cos($base_lat);

$lon_new = $lon_new * $rho;
$lat_new = $lat_new * $rho;

print " $lon_new $lat_new\n";

Input:

   11.535951   48.127126
   11.535771   48.154221
   11.578082   48.154101
   11.560655   48.140376
   11.579609   48.126706
   11.535951   48.127126

Output:

  11.535951 48.127126
  11.5071201551467 48.1462001016678
  11.5371656739326 48.1660851819675
  11.5393827447693 48.1481549512658
  11.5672668018948 48.1474347049245
  11.535951 48.127126

Ergebnis (dick markiert das Original, dünn rot das rotierte Fünfeck)

Moin !

so - ich habe es ausprobiert und mein Ergebnis war gestern abend mit Euren Formelansätzen schon korrekt und ich bin dem Problem ein Stück näher gekommen.

Ich habe vermutlich nur ein “besseres” Testbeispiel gehabt als Ihr!

osm-rotate-test2

Erfolgt die Berechnung östlich des 0-Meridian, dann ist alles OK - westlich dagegen “zerhaut” das negative Vorzeichen alles.

Entweder lebt man damit und wendet es nur im “richtigen” Bereich an - aber gerne würde ich das Problem schon “richtig” lösen.

Hat einer eine weiterführende Idee - mit einer temp. Additionskonstante für den Rechtswert wird man wohl nicht weiterkommen und zu große Verfälschungen einbauen.

Gruß Jan

Die Transformationsformeln sind auch für negative Winkel geeignet … da gibt es kein Problem.

Kommen die Daten vom Aufruf im Programm überhaupt richtig an? Oder interpretiert irgendwas das Minus als Optionskennung?

Was macht das Programm, wenn man die negativen Winkel positiv formuliert (durch Addieren von 360°)?

Weide

Bin zwar derzeit nicht an dem Rechner, aber Vorzeichen werden nicht als Option berücksichtigt!

Es sind genau die oben geposteten Formeln!

Ich werde später nochmal schauen und ggf. Musterwagen veröffentlichen!

Jan

Das Progrämmchen aus #16 kann auch in Malaga um 60° rotieren