• Willkommen im Geoclub - dem größten deutschsprachigen Geocaching-Forum. Registriere dich kostenlos, um alle Inhalte zu sehen und neue Beiträge zu erstellen.

[dev] 4 verschiedene getDistance() in CWPoint

UncleOwen

Geocacher
In CWPoint gibt es 4 verschiedene Methoden zur Abstandsberechnung:

Code:
(1)public double getDistance (CWPoint dest)
(2)public double getDistance (double latDecD, double lonDecD)
(3)public double getDistanceRad (double latDecD, double lonDecD)
(4)public double getDistanceRad (CWPoint ll)

Der Javadoc (und den Funktionsnamen) zufolge berechnen (1) und (2) die Entfernung zwischen 2 Punkten in km, (3) und (4) die Entfernung in RAD (was soll das sein? Bogenmaß? Das wäre dann aber keine Entfernung, sondern ein Winkel...)

Schaut man sich jetzt die Implementierungen an, dann ist
(1) ein Aufruf einer Library-Funktion,
(2) ein Aufruf von (1)
(3) eine Berechnung
(4) ein Aufruf von (2)(!)
Letzteres hat mich stutzig gemacht. Ist das richtig so? Sollte nicht lieber (3) aufgerufen werden (damit die Funktion das macht, was sie dokumentiert?) Oder sollten alle Aufrufer von (4) auf (1) geändert werden, und (3) und (4) rausfliegen ((3) wird nirgendwo anders aufgerufen)?
 

MiK

Geoguru
getDistanceRad wird nur an einer Stelle (bei der Kartenauswahl) benutzt und dort ist der absolute Wert uninteressant, sondern es werden immer nur zwei Abstände verglichen. Deswegen wurde das wohl früher über die schnellere (evtl. ungenauere) Berechnung des Bogenmaßes gemacht. Wann und warum das so geändert wurde, weiß ich nicht mehr. Aus Performancegründen sollte man wohl eher die alte Rechnung wieder aktivieren. Ich denke evtl. Fehler wegen der Missachtung des Ellipsoiden spielt an dieser Stelle keine große Rolle.
 
OP
U

UncleOwen

Geocacher
Danke für die Erklärung.

Wenn ich das richtig verstehe, berechnet getDistanceRad also die BogenLÄNGE (Abstand zwischen 2 Punkten auf der durch einen Kreis angenäherten Erdkugel) in km und nicht das BogenMASS (Abstand zwischen 2 Punkten auf dem Einheitskreis).
 

MiK

Geoguru
Soweit ich das sehe, fließt da kein Erdradius in die Rechnung ein. Die Angabe ist also wirklich im Bogenmaß (Einheitskreis/-kugel).
 
OP
U

UncleOwen

Geocacher
Hmm, hast Recht. Dann ists aber noch deutlicher falsch, dass das eine getDistanceRad einfach nur getDistance aufruft.
 

MiK

Geoguru
Ja, ist es. Aber wie gesagt für die Stelle irrelevant, da nur getestet wird, welche Distanz größer ist. Sauber ist das auf alle Fälle nicht. Wurde wohl gemacht, als die km genauer gemacht wurde. Da man dabei keine Rad-Variante implementiert hat, hat man einfach die km-Variante genommen. (Das ist jetzt nur eine Vermutung.)
Man müsste jetzt klären, ob die Genauigkeit der Ellipsoid-km-Variante hier nötig ist. Wenn ja, sollte man sie direkt verwenden und die Rad-Varianten entfernen. Ansonsten sollte man in beiden Fällen von getDistanceRad die einfache Rad-Berechnung verwenden.
 

pfeffer

Geowizard
also da sollte dringend was geändert werden.
Mapslist ruft getDistanceRad auf, um einen Geschwindigkeitsvorteil zu erhalten. Die Genauigkeit kann ruhig 30m falsch sein. Aber es wird beim suchen der am besten passenden Karte aufgerufen - und zwar für jede Karte, die irgendwie in Frage kommt, also in einer Schleife.
Und dann wird auch noch CWPoint instanziert - was vermutlich erheblich Zeit kostet.
Ich ändere das mal. Ich vermute, das war ein auto-complete-Fehler beim Programmieren. getDistanceRad(CWPoint) sollte natürlich getDistanceRad(lat, lon) aufrufen.

Gruß,
Pfeffer.
 
pfeffer schrieb:
Mapslist ruft getDistanceRad auf, um einen Geschwindigkeitsvorteil zu erhalten.
Das suchen in einer Liste von Koordinaten in Form von Lat Lon ist immer zeitraubend. GoogleMap hat da einen anderen Ansatz. Die Teilen die Karten in Quadranten auf die immer tiefer geschachtelt sind. Die Quadranten haben die Namen q r t s so eine Koordinate sieht dann so aus. trtqtqstssrqqsqstrs
kh

Die Länge des Strings bestimmt die Auflösung.

Diese Koordinatenstrings aller Karten kann man sortiert vorhalten und dann findet sich eine Passende Karte sehr schnell mit binärer Suche.

Auch kann man alle Cache Koordinaten so speichern und selbst bei einer langen Liste muss man nur die sichtbaren Caches anpacken.

Mit 20 Zeichen pro Koordinate sollte hinreichend sein um diese Verwaltung zu machen. Dies führt zusätzlichen Speicherbedarf, aber auch eine enorme Zeitersparnis beim Suchen.

Hier der notwenige Code
Code:
function MercatorToNormal(y: double): double;
begin
   y := -y * PI / 180; // convert to radians
   y := sin(y);
   y := (1 + y) / (1 - y);
   y := 0.5 * ln(y);
   y := y / (2 * PI); // scale factor from radians to normalized
   y := y + 0.5; // and make y range from 0 - 1
   result := y;
end;

function NormalToMercator(y: double): double;
begin
   y := y - 0.5;
   y := y * 2 * PI;
   y := exp(y * 2);
   y := (y - 1) / (y + 1);
   y := arcsin(y);
   y := y * -180 / PI;
   result := y;
end;

function WGS84toGOOGLE(lat, lon: double): MiniString;
var
   x, y: double;
   quad: MiniString;
   lookup: MiniString;
   digits: integer;
   i: integer;
begin
// now convert to normalized square coordinates
// use standard equations to map into mercator projection
   x := (180.0 + lon) / 360.0;
   y := MercatorToNormal(lat);
   quad := 't'; // google addresses start with t
   lookup := 'qrts'; // tl tr bl br
   for digits := 0 to 26 do begin
// make sure we only look at fractional part
      x := x - floor(x);
      y := y - floor(y);
      i := 1;
      if (x >= 0.5) then inc(i);
      if (y >= 0.5) then inc(i, 2);
      quad := quad + lookup[i];
// now descend into that square
      x := x * 2;
      y := y * 2;
   end;
   result := Quad;
end;

function GOOGLEtoWGS84(Value: MiniString; out lat, lon: double): boolean;
var
   x, y, Scale: double;
   i: integer;
   c: MiniChar;
begin
   x := 0.0;
   y := 0.0;
   scale := 1.0;
   Value := LowerCase(Value);
   for i := 2 to Length(Value) do begin // skip the first character
      Scale := Scale * 0.5;
      c := Value[i];
   //   q  r
   //   t  s
      case c of
         'q': ;
         'r': x := x + scale;
         't': y := y + scale;
         's': begin
               x := x + scale;
               y := y + scale;
            end;
      else
         Result := false;
         exit;
      end;
   end;

   lon := (x + scale * 0.5 - 0.5) * 360;
   lat := NormalToMercator(y + scale * 0.5);
   result := true;
end;
Möchte man die Auflösung wie vier Nachkommastellen bei Minute haben, dann muss man 27 Stellen nehmen.
 

MiK

Geoguru
Ohne jetzt die Details beider Implementierungen genau angeschaut zu haben: So etwas ähnliches machen wir schon. Die Karten werden schon nach einem solchen Prinzip benannt. Ich weiß aber nicht, ob wir schon an allen Stellen mögliche Vorteile davon nutzen.
 
MiK schrieb:
Ohne jetzt die Details beider Implementierungen genau angeschaut zu haben: So etwas ähnliches machen wir schon. Die Karten werden schon nach einem solchen Prinzip benannt. Ich weiß aber nicht, ob wir schon an allen Stellen mögliche Vorteile davon nutzen.
Haltet ihr die Koordinaten in einem Array vor und macht nur Bytevergleiche in den einzelnen Ebenen?

Für die Karten und den geladenen Caches?
 

pfeffer

Geowizard
das Problem bei uns ist folgendes:
Die Karten haben kein festes Raster, und keine festen Auflösungsstufen. Das bedeutet, wir können den String FFE1XXXXXXE nicht berechnen, sondern müssen den besten suchen.
Das machen wir so: die GPS-Koos werden umgerechnet in FFE1XXXXXXE und dann nach derjenigen Datei gesucht, bei der möglichst viele Stellen übereinstimmen (wenn die Karte mit der höchsten Auflösung gesucht wird).
Wir könnten sicher die Geschwindigkeit der Kartensuche erhöhen, ohne etwas Grundsätzliches zu ändern, indem beim Suchen nicht linear, sondern nach der Quick-Sort technik gesucht wird (und vorher die Karten sortiert werden).

Die grundsätzliche Variante sollte, wenn dann gleichzeitig einhergehen mit einem Umbau der MovingMap, so dass mehrere, kleinere Kacheln gleichzeitig angezeigt werden können. Dafür müsste man erst noch ein neues Bilddatenformat kreieren, damit wir nicht nochmehr Dateiien anlegen müssen.

Gruß,
Pfeffer.
 
pfeffer schrieb:
Die grundsätzliche Variante sollte, wenn dann gleichzeitig einhergehen mit einem Umbau der MovingMap, so dass mehrere, kleinere Kacheln gleichzeitig angezeigt werden können. Dafür müsste man erst noch ein neues Bilddatenformat kreieren, damit wir nicht nochmehr Dateiien anlegen müssen.
Das hat mich schon immer gewundert, das ihr das nicht angepackt habt. Nun findet man in 1000den Dateien mit Quicksearch in 0,001sec die passende Datei und das Betriebystem braucht dann 1sekunde um sich durch die FAT zu ackern. Zeiten frei erfunden, das Verhältnis könnte aber passen.
 

pfeffer

Geowizard
Du bist herzlich willkommen, entsprechende Tests durchzuführen (auf dem PC in java und auf dem PocketPC in Ewe) und entsprechendes zu programmieren, falls die Tests das ergeben.

Gruß,
Pfeffer.
 

pfeffer

Geowizard
also, DLLs ist nicht so eine gute Idee. Platformabhängige Sachen wollen wir vermeiden, wo es geht.
Aber: java ist einfach zu lernen und eclipse als Entwicklungsumgebung sehr komfortabel --> probier's einfach mal.

Gruß,
Pfeffer.
 
pfeffer schrieb:
also, DLLs ist nicht so eine gute Idee. Platformabhängige Sachen wollen wir vermeiden, wo es geht.
Aber: java ist einfach zu lernen und eclipse als Entwicklungsumgebung sehr komfortabel --> probier's einfach mal.

Gruß,
Pfeffer.
Java und schnelle Applikationen widersprechen sich für mich.
 

pfeffer

Geowizard
niemand zwingt Dich, bei der Cachewolfentwicklung mitzuarbeiten. Gute und kooperationswillige Programmierer sind aber immer willkommen.

Gruß,
Pfeffer.
 

TweetyHH

Geomaster
KoenigDickBauch schrieb:
Java und schnelle Applikationen widersprechen sich für mich.
Hmm, da stellt sich die Frage, welcher der folgenden Punkte bei dir zutrifft:
- Du hast noch Java 1.1 Installiert
- Dein PC hat wirklich nicht mehr als 64MB Ram insgesamt
- Du glaubst an die Marketingabteilungen von Firmen, die sich nicht trauen ihren C-Code umzustellen.
- Du hast dich LANGE nicht mehr mit Java beschäftigt ...
 

Harry1999

Geocacher
Das Maß der Dinge ist ein Windows Mobile Gerät ab ca. WinCE 4.2.
Gibt es ein JAVA dass auf WinCE4.2 kostenfrei läuft und mit dem PC-Java kompatibel ist?
Meiner Erfahrung nach ist auf 200Mhz Rechnern mehr die Qualität des Codes denn weniger die Sprache entscheidend.
On-Toppic: Hier wurde doch mal über 'ne Karten-Index-Datei diskutiert... ist das abschliessend verworfen worden? Einen Button "Karten Index erstellen" bzw. dessen Aufruf nach einem Karten-Import sollte doch akzeptabel sein, oder?
Ausserdem habe ich mit erschrecken festgestellt, dass diese Mini-SD-Karten ne grottige zugriffszeit pro Datei haben. (gefühlte 2 Sec. Pro Datei)
Grüße Harry1999
 
Oben