Originally Posted by
MMSoft
Wat gebeurd er als de routine 'LocationSensor1LocationChanged' alweer opgeroepen wordt als deze nog niet klaar is denken jullie ? Dat zou namelijk kunnen gebeuren als er veel data in de 'Arrayvar' staat. Gaat de App dan vast lopen denken jullie ?
Nee hoor. Het doorlopen van een array met veel data zal heel erg snel zijn. De vraag is echter hoe jij de melding geeft. Als je bijvoorbeeld een ShowMessage() geeft... ja, dan zou je een probleem kunnen krijgen omdat die de boel blokkeert. Maar als je een melding geeft en je keert gelijk terug dan denk ik dat dat geen probleem geeft. (Tevens denk ik dat er geen nieuwe LocationSensor1LocationChanged komt zolang de oude nog aan het lopen is maar dat weet ik niet zeker)
Het kan natuurlijk wel zo zijn dat LocationSensor1LocationChanged erg veel aangeroepen wordt. Bijvoorbeeld een centimeter binnen de 20km en weer een centimeter erbuiten (binnen 1 seconden ofzo). In dat geval is het misschien wel handig om de meldingen niet direct weer te geven maar eerst even intern op te slaan en pas met een timer om de 15 seconden weer te geven.
Het beste kun je dan in je Array, naast de Lat, Long en Txt een boolean opnemen Melding: Boolean. Die initialiseer je op false. En dan kun je in de LocationSensor1LocationChanged de boolean op true zetten als je binnen de straal komt. Dan hoef je in de timer alleen maar eenzelfde loop in te bouwen die bij true de melding geeft.
Weer het losse vuistje (alleen de wijzigingen t.o.v. de vorige code)
Delphi Code:
type
LocatieType = record
Lat, Long, Rad: Double;
Txt: String;
Melding: Boolean; // <---- deze toevoegen
end;
procedure TForm1.LocationSensor1LocationChanged(Sender: TObject;
const OldLocation, NewLocation: TLocationCoord2D);
var
Afstand1, Afstand2: Double;
Cnt: Integer;
begin
for Cnt := 0 to High(Locaties) do
begin
Afstand1 := HaversineDist(Locaties[Cnt].Lat, Locaties[Cnt].Long, OldLocation.Latitude, OldLocation.Longitude);
Afstand2 := HaversineDist(Locaties[Cnt].Lat, Locaties[Cnt].Long, NewLocation.Latitude, NewLocation.Longitude);
// geen if meer maar direct de Melding boolean met true of false vullen
Locaties[Cnt].Melding := (Afstand1 > Locaties[Cnt].Rad) and (Afstand2 <= Locaties[Cnt].Rad);
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
Cnt: Integer;
begin
// Timerloop die meldingen geeft indien Melding := true;
for Cnt := 0 to High(Locaties) do
if Locaties[Cnt].Melding then
ShowMessage(Locaties[Cnt].Txt);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Cnt: Integer;
begin
// .... zelfde code als voorheen
Locaties[Cnt].Lat := Query.FieldByName('Lat').asFloat;
Locaties[Cnt].Long := Query.FieldByName('Long').asFloat;
Locaties[Cnt].Rad := Query.FieldByName('Radius').asFloat;
Locaties[Cnt].Txt := Query.FieldByName('Tekst').asString;
Locaties[Cnt].Melding := false; // <---- deze toevoegen
// .... zelfde code als voorheen
end;
Edit:
Ook ben ik nog aan het kijken hoe ik de eerste keer (als het programma net opgestart is) de data het beste kan vergelijken omdat ik mij dan mogelijk al een of meerdere cirkels bevindt en dan wil ik deze data ook te zien krijgen.
Oja, als je dus bij het starten al de meldingen wilt hebben dan kun je je FormCreate aanpassen dat je .Melding niet op false zet maar al op true voor de locaties binnen de straal. Je Timer1Timer geeft daarna automatisch de meldingen voor de locaties binnen de straal zonder dat je LocationSensor1LocationChanged uitgevoerd hoeft te zijn.
Delphi Code:
procedure TForm1.FormCreate(Sender: TObject);
var
Afstand1, Afstand2: Double;
Cnt: Integer;
begin
// .... zelfde code als voorheen
Locaties[Cnt].Lat := Query.FieldByName('Lat').asFloat;
Locaties[Cnt].Long := Query.FieldByName('Long').asFloat;
Locaties[Cnt].Rad := Query.FieldByName('Radius').asFloat;
Locaties[Cnt].Txt := Query.FieldByName('Tekst').asString;
// extra code om bij het opstarten al de locaties-meldingen te geven
Afstand1 := HaversineDist(Locaties[Cnt].Lat, Locaties[Cnt].Long, OldLocation.Latitude, OldLocation.Longitude);
Afstand2 := HaversineDist(Locaties[Cnt].Lat, Locaties[Cnt].Long, NewLocation.Latitude, NewLocation.Longitude);
// geen if meer maar direct de Melding boolean met true of false vullen
Locaties[Cnt].Melding := (Afstand1 > Locaties[Cnt].Rad) and (Afstand2 <= Locaties[Cnt].Rad);
// .... zelfde code als voorheen
end;
Bookmarks