Kompass-Abfrage

Hallo,

ich habe eine DB mit einer Spalte (direction), die Gradzahlen enthält (0-360°) als Double Werte.

Ich bekomme von meiner Anwendung einen Grad-Wert x und möchte nun alle Einträge haben, wo direction - 10 <= x <= direction + 10 ist.

Momentan sieht meine Anfrage so aus:

SELECT * FROM table WHERE
(abs(direction - $X) <= 10) OR (abs(direction - $X -360) <= 10) OR (abs(direction - $X +360) <= 10)

Das läuft soweit ok, nur bei nicht-integer-Werten für $X gibt er “invalid syntax for integer” aus. Warum brauche ich denn da zwingend einen Integer-Wert? Und wie geht das anders?

Ich habe auch PostGIS zu laufen, falls es da schon sowas wie eine Kompass-Funktion gibt, was ich glatt vermutet hätte. Hab aber keine gefunden.

Gruß S-Man

Was genau enthält Deine Variable? Vielleicht ein Komma statt Punkt?


Andreas

Nachtrag: vielleicht kannst/solltest Du auch mit Funktionen wie degrees(), radians() und pi() hantieren, um Winkel (um die es ja geht) besser darzustellen. Das könnte Dir das rumgemache mit den Fallunterscheidungen ersparen.

Andreas, zu lange aus der Schule, um das genau mathematisch herbeten zu können …

Nein, ist schon ein Punkt :slight_smile: Die Fehlermeldung bezieht sich ausdrücklich auf integer.

Danke für den Hinweis mit den Funktionen. Werd mal schauen, ob mir das was bringt.

Ich hab versucht, diese Fehlermeldung zu provozieren. Ohne Erfolg. Am nächsten war da noch:

test=*# SELECT * FROM kompass WHERE (abs(direction - 9,1) <= 10) OR (abs(direction - 9,1 -360) <= 10) OR (abs(direction - 9,1 +360) <= 10);
ERROR:  function abs(double precision, integer) does not exist                                                                             
ZEILE 1: SELECT * FROM kompass WHERE (abs(direction - 9,1) <= 10) OR ...

Andreas

Hm, vllt liegts doch am PHP-Code, aber das wär komisch, da die Fehlermeldung tatsächlich nur kommt, wenn ich die SQL Anweisung so baue… Momentan helfe ich mir mit einem round(), was nicht so viel ausmacht. Aber doof isses schon. mit trigonometrie komme ich imho nicht weiter, glaube ich, da ich ja Winkel habe und keine Strecken brauche, sondern einen neuen Winkel…
Ich kann ja mal den kompletten code zeigen:

$query = pg_query_params("
   SELECT * FROM table WHERE ((abs(direction - $1) <= 9) OR (abs(direction - $1 -360) <= 9) OR (abs(direction - $1 +360) <= 9))", 
array( round($_POST['orientation'])))

Nun, da weiß oder sehe ich immer noch nicht, was als reines SQL rauskommt …


Andreas

Ohne round im php-teil, der ja mein WorkAround ist, kommt das gewünschte zurück, solange
$_POST[‘orientation’] ein integer ist,

sonst diese Fehlermeldung:
Warning: pg_query_params() [function.pg-query-params]: Query failed: ERROR: invalid input syntax for integer: “3.2” in download_screen.php on line

Hilft das?

Ja. 3.2 ist kein INT.

Andreas

Ja, davon rede ich ja die ganze Zeit :slight_smile:

Ich verstehe nicht, warum man einen Integer braucht. Ich wüsste gern, wie das mit Doubles funktioniert :wink:

Ich vermute ein PHP-Problem, aber da bin ich kein Experte drin…

Vermutlich aber wird das, was PHP übergibt, als INT deklariert, auch wenn es ein FLOAT ist. Irgendwie so halt … was steht im Log von PG?

Andreas

Oh sorry, da hab ich glatt die Seite2 üersehen… Forenlesen will gelernt sein gg Falls du noch mitliest… Wo lese ichd en Log denn aus?

  1. Kommt halt drauf an, wie es konfiguriert ist.

Btw.: #46408 [Bgs]: Locale number format settings can cause pg_query_params to

Andreas

Du könntest versuchen, die Zahl direkt in ein double zu casten, vielleicht merkt er dann, dass er ein double und kein int nehmen soll.

davon abgesehen sieht diese “formel” ziemlich falsch aus - da sind z.B. ORs drinnen … das macht ja garkeinen sinn …

lass dich mal hier von der “winkel-differenz” inspirieren … da kommt dann halt ein wert raus den du pruefen kannst ob abs(d) <= 10 etc. ist

du koenntest dir soeine fkt. auch in postgres bauen …

CREATE OR REPLACE FUNCTION winkel_differenz(a double, b double)
  RETURNS double AS $$
BEGIN
    ...
END $$  LANGUAGE 'plpgsql' IMMUTABLE COST 1;