für eine Geocaching-Software brauche ich eine Kartendarstellung (die Vorstufen dazu sind http://www.lazarusforum.de/viewtopic.php?f=25&t=8844 und http://www.lazarusforum.de/viewtopic.php?f=25&t=8964 gewesen. Das funktioniert auch beides sehr zu meiner Zufriedenheit und Erwartung.
Allerdings brauche ich jetzt einen Denkanstoss für folgendes: Nach Eingabe von GPS-Koordinaten werden diese in Pixel-Koordinaten (x,y) umgerechnet. Das funktioniert, abgesehen von leichten Rundungsfehlern einwandfrei. Jetzt befindet sich meine Karte (eine PNG-Datei) in einem TImage und dieses wiederum in einer TScrollbox. Aber wenn ich diese Koordinaten nun einzeichnen lasse (bzw. ich setze ein TShape mit CacheAbstUmkreis.Left und CacheAbstUmkreis.Top auf diese Werte, dann liegt es ein gutes Stück neben den vorgesehenen (und durch einen eingezeichneten Referenzpunkt auf der Karte auch deutlich sichtbaren) Koordinaten.
Mein Verdacht ist, dass die Umrechnung der Koordinaten auf den Clientbereich der Scrollbox nicht funktioniert.
Ich versuche mal, die relevanten Routinen hier einzufügen. Außerdem hänge ich einen Screenshot an, der das Problem hoffentlich zeigt
Code: Alles auswählen
procedure TgcisMainForm.gcisWerkzeugeQuickShowkoordsClick(Sender: TObject);
var mapKoordsPxX, mapKoordsPxY : integer;
QuickKoordsLon,QuickKoordsLat : real;
SetzPunkt : TPoint;
begin
if ctQuickShowKoordsform.ShowModal = mrOk then
begin
// erstmal die Koordinaten holen
QuickKoordsLon:=ctQuickShowKoordsform.ctqskLaenge; // sind noch GPS-Koordinaten, allerdings berets eine real-Zahl
QuickKoordsLat:=ctQuickShowKoordsform.ctqskBreite;
// Nach der Berechnung der Position auf der Karte ...
CalcPointAsPixelFromKoords(gcis_map_KarteWertLinks,gcis_map_KarteWertOben,QuickKoordsLon,QuickKoordsLat,mapKoordsPxX, mapKoordsPxY); // Umrechnung auf Pixel-Koordinaten
{ ----> Ich vermute den Fehler}
SetzPunkt.x:=mapKoordsPxX;
SetzPunkt.y:=mapKoordsPxY;
SetzPunkt:=gcisMainScrollBox.ScreenToClient(SetzPunkt);
{<----- in diesem Abschnitt}
// ...kann dieser Punkt eingetragen werden
SetzePunktAufKarteMitKoordinaten(SetzPunkt.x,SetzPunkt.y);
end; // if ctQuickShowKoordsform.ModalResult = mrOk
end; // procedure TgcisMainForm.gcisWerkzeugeQuickShowkoordsClick
Code: Alles auswählen
procedure TgcisMainForm.SetzePunktAufKarteMitKoordinaten(XPixel, YPixel: integer);
var CacheAbstUmkreis : TShape;
CacheIcon : TShape;
MousePoint : TPoint;
CacheIconUmkreisGroessePixel : integer;
CacheAbstUmkreisGroessePixel : integer;
CacheIconGroessePixel : integer;
begin
CacheAbstUmkreisGroessePixel:=radius_DistCachesBoxes; // Konstante
CacheAbstUmkreis:=TShape.Create(self);
CacheAbstUmkreis.Caption:=txt_dbtemp_GCCode+IntToStr(FCacheKreisIndex); // txt_dbtemp_GCCode ist eine Konstante
CacheAbstUmkreis.Shape:=stCircle;
CacheAbstUmkreis.Width:=CacheAbstUmkreisGroessePixel; // Programm-interne Konstante
CacheAbstUmkreis.Height:=CacheAbstUmkreisGroessePixel;
CacheAbstUmkreis.Pen.Color:=clBlack;
CacheAbstUmkreis.Pen.Style:=psDot;
CacheAbstUmkreis.Brush.Style:=bsClear;
CacheAbstUmkreis.Left:=XPixel - (CacheAbstUmkreisGroessePixel div 2);
CacheAbstUmkreis.Top:=YPixel - (CacheAbstUmkreisGroessePixel div 2);
CacheAbstUmkreis.Parent:=gcisMainScrollBox;
CacheAbstUmkreis.OnClick:=@ShapeClick;
CacheAbstUmkreis.BringToFront;
inc(FCacheKreisIndex);
end; // procedure TgcisMainForm.SetzePunktAufKarteMitKoordinaten
Code: Alles auswählen
procedure CalcPointAsPixelFromKoords(mapLeftLon, mapToplat, latdec, londec : real; var pxX,pxY : integer);
var
KoordDistX, KoordDistY : real;
begin
// Abstände berechnen
KoordDistX:=CalcDistanceDecimalKoordsInKm(mapLeftLon,mapToplat,londec,mapToplat); // Berechnet den Abstand der beiden Koordinatenpaare (GPS-Koordinaten als real-Zahlen) in km
KoordDistY:=CalcDistanceDecimalKoordsInKm(mapLeftLon,mapToplat,mapLeftLon,latdec);
KoordDistX:=KoordDistX * 1000; // Um den Abstand
KoordDistY:=KoordDistY * 1000; // in Metern zu haben
// Abstände in Pixel umrechnen (über gcis_map_KartePixelProMeterBreite und gcis_map_KartePixelProMeterHoehe
pxX:=round(KoordDistX * gcis_map_KartePixelProMeterBreite); // gcis_map_KartePixelProMeterBreite wird über das Verhältnis von Kartenbreite in km zu Pixelzahl (KarteImage.Width) berechnet
pxY:=round(KoordDistY * gcis_map_KartePixelProMeterHoehe);
end; // procedure CalcPointAsPixelFromKoords
Über Denkanstösse würde ich mich sehr freuen...Vielen Dank und
Gruss
GU_Meyer