AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Suche nach einer passenden Datenstruktur

Ein Thema von xedrei · begonnen am 22. Feb 2016 · letzter Beitrag vom 22. Feb 2016
Antwort Antwort
Benutzerbild von xedrei
xedrei

Registriert seit: 6. Jun 2013
6 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Suche nach einer passenden Datenstruktur

  Alt 22. Feb 2016, 17:20
Hallo zusammen,

mit TChart zeiche ich eine (x,y)-Punktenwolke. Die Koordinaten sind float-Werte, also z.B. (-123.43,-546.34). Ich will nun zu jeder Koordinate beim Laden der Daten aus der Datenbank einen Wert speichern, so dass ich dann auf die Werte mit was ähnlichem wie Werte[X,Y] zugreifen kann.

Mit welcher Datenstruktur wäre so was möglich?

Vielen Dank für Eure Hilfe!
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Suche nach einer passenden Datenstruktur

  Alt 22. Feb 2016, 17:27
Hallo,
da du float-Werte hast, finde ich keine einfache Datenstruktur.
Also einfach was eigenes und deine Werte[x,y] wird dann eine function Werte(x,y: Double).

Du musst nur aufpassen, wegen Double-Vergleich.
Hast du in deiner DB keinen PrimKey für diese Werte?
Dann würde ich den zusätzlich mit in die DB-Struktur mit dazunehmen.

Ich bin mir nicht sicher, ob nicht das AddXY (?) das TCharts nicht auch mit Objekten ähnlich AddObject der TStringList arbeiten kann,
dann packst du deine ChartItem ja in ein Object+TObjectList.


Heiko
Heiko
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#3

AW: Suche nach einer passenden Datenstruktur

  Alt 22. Feb 2016, 18:32
eine Tabelle mit 3 Spalten
x: Decimal
y: Decimal
wert: Dazu hast Du keine Angaben gemacht.

Welche Typen Du exakt nehmen musst, hängt wohl von der DB ab, die Du verwendest. Wenn Du wahlfrei auf die Werte zugreifen musst, darf bei Abfrage und Speichern keine weitere Rundung stattfinden. Also müssen Datentypen und ihre Genauigkeit entsprechend klar sein.
Einen Primärschlüssel sehe ich hier nicht, weil überhaupt nichts über Eindeutigkeit der Werte gesagt wurde.
Wenn der Zugriff nicht exakt sein muss, sondern Ranges reichen, ist die Rundungsproblematik egal.
Gruß, Jo
  Mit Zitat antworten Zitat
hanvas

Registriert seit: 28. Okt 2010
168 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Suche nach einer passenden Datenstruktur

  Alt 22. Feb 2016, 19:23
Hallo zusammen,
Mit welcher Datenstruktur wäre so was möglich?
Vielen Dank für Eure Hilfe!
Wenn es sich um ein dichtbesetztes Feld oder handelt nicht allzu viele Werte zu speichern sind dann geht das beispielsweise mit einem dynamischen Array [1], wenn es sich um eine dünnbesetztes, aber ansonsten sehr großes Feld handelt dass zu groß ist um im Speicher gehalten zu werden dann empfiehlt sich die direkte Implementierung nicht. In dem Fall google mal nach "sparse matrix" ( http://www.delphigroups.info/2/e3/21264.html, http://www.alglib.net/matrixops/sparse.php )

cu Ha-Jö


type TLine = array of double;
TMatrix = array of TLine;

function allocateMatrix (x,y : Integer): TMatrix;
var i : Integer;
begin
SetLength(result,y);
for i := 0 to y-1 do
SetLength(result[i],x);
end;

var m : TMatrix;

begin
m := allocateMatrix(10,10);
m[0,1] := 4.6;
m[2,2] := 3.2;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Suche nach einer passenden Datenstruktur

  Alt 22. Feb 2016, 19:33
Wenn man die einzelnen Daten auf der Datenbankseite nicht auswerten braucht, dann kann man auch alles in einem Blob-Feld speichern.

Der Zugriff auf die Daten selber erfolgt dann über eine Klasse.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von xedrei
xedrei

Registriert seit: 6. Jun 2013
6 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Suche nach einer passenden Datenstruktur

  Alt 22. Feb 2016, 22:10
Danke für Eure Antworten!

Vielleicht habe ich mich falsch ausgedrückt. Ich will die Werte nicht in der Datenbank speichern. Die Werte sind schon drin. Ich lese diese nur aus, und zwar genau drei Werte pro Zeile: (x,y) und ein Wert dazu. X,Y, und der Wert sind float. Die (x,y)-Punkte visualisiere ich mit einer TChart-Komponente als TPointsSeries. Soweit alles gut! Aber ich möchte zur Laufzeit im Programm, nicht in der Datenbank, eine Datenstruktur haben, die für jede Koordinate den Wert enthält, also z.B. [(345.65, 234.54) = 20.19], [(3.6, 24.4) = 15.22], ...

Ich möchte über die zwei Koordinaten einen Wert auslesen, und zwar mit einem möglichst kleinen Aufwand! Wie könnte man so was machen?
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#7

AW: Suche nach einer passenden Datenstruktur

  Alt 22. Feb 2016, 22:24
Du kannst dir selbst einen Index bauen. Wenn du deine Minimal- und Maximalwerte kennst (oder beim auslesen ermittelst), skalierst du (für den Index) die Werte auf 0..255. Dann kannst du ein 2D-Array 0..255 0..255 nehmen und darin dann Listen mit den Punkten speichern.

Wenn du dann zu gegebenen (Klick?) Koordinaten den nächstgelegenen Punkt suchst, kommen nur noch sehr begrenzte Punktmengen in Frage. Zuerst suchst du in dem Feld des Klicks nach Punkten. Ist da keiner drin, nimmst du die 8 Felder drum herum usw. Du solltest jedoch schauen, dass deine Index-Felder möglichst quadratisch sind, da du nach dem Fund noch alle andere Felder abprüfen musst, die näher dran sein könnten.
Idealerweise würdest du die Feinheit der Indexstruktur noch irgendwie an die Mächtigkeit der Punktmenge anpassen, oder gleich einen Quadtree verwenden.

Geändert von jfheins (22. Feb 2016 um 22:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Suche nach einer passenden Datenstruktur

  Alt 22. Feb 2016, 23:22
Würde ich schon mal gar nicht so machen.

Jeder Eintrag in so einer TPointSeries hat einen Index und über diesen Index würde ich auch auf die zusätzlichen Daten zugreifen.

Alle Punkte, die man darstellen möchte in eine Liste geben (die holt man so von der Datenbank ab), dann die Punkte in der Reihenfolge der Liste in die TPointSeries und schon passt der Index mit der Liste überein.

Jetzt fragt man nur noch, welchen Index hat der entsprechende Punkt und bekommt über die Liste die Zusatzinfos.

Also so ungefähr:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VclTee.TeeGDIPlus, VclTee.TeEngine,
  VclTee.Series, Vcl.ExtCtrls, VclTee.TeeProcs, VclTee.Chart, VclTee.BubbleCh,
  System.Generics.Collections, Vcl.StdCtrls;

type
  TData = class
  private
    FValX: Double;
    FValY: Double;
    FInfo: string;
  public
    property ValX: Double read FValX write FValX;
    property ValY: Double read FValY write FValY;
    property Info: string read FInfo write FInfo;
  end;

  TForm1 = class( TForm )
    Chart1: TChart;
    Series1: TPointSeries;
    Button1: TButton;
    procedure Chart1ClickSeries( Sender: TCustomChart; Series: TChartSeries;
      ValueIndex: Integer; Button: TMouseButton; Shift: TShiftState; X, Y: Integer );
    procedure Button1Click( Sender: TObject );
    procedure FormCreate(Sender: TObject);
  private
    FValues: TList<TData>;
    procedure SetValues( const Value: TList<TData> );
  public
    procedure BeforeDestruction; override;
    property Values: TList<TData> read FValues write SetValues;

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BeforeDestruction;
begin
  FreeAndNil( FValues );
  inherited;
end;

procedure TForm1.Button1Click( Sender: TObject );
var
  randomData: TObjectList<TData>;
  I : Integer;
  val : TData;
begin
  randomData := TObjectList<TData>.Create;

  for I := 1 to random( 50 ) + 10 do
    begin
      val := TData.Create;
      val.ValX := random * 100;
      val.ValY := random * 100;
      val.Info := 'Data ' + I.ToString;

      randomData.Add( val );
    end;

  Values := randomData;
end;

procedure TForm1.Chart1ClickSeries( Sender: TCustomChart; Series: TChartSeries;
  ValueIndex: Integer; Button: TMouseButton; Shift: TShiftState; X, Y: Integer );
begin
  ShowMessage( Values[ ValueIndex ].Info );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;
end;

procedure TForm1.SetValues( const Value: TList<TData> );
var
  val: TData;
begin
  if FValues <> Value
  then
    begin
      FValues.Free;
      FValues := Value;
      Series1.BeginUpdate;
      try
        Series1.Clear;
        if Assigned( FValues )
        then
          begin
            for val in FValues do
              begin
                Series1.AddXY( val.ValX, val.ValY, val.Info );
              end;
          end;
      finally
        Series1.EndUpdate;
      end;
    end;
end;

end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (22. Feb 2016 um 23:36 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz