Punktgitter 31x31 in rechteckigen Polygonen erzeugen

Hallo zusammen,

ich möchte ein 31x31 (961) grosses Punktgitter in einem rechteckigen Polygon (90° Winkel, 4 Ecken, genau 4 Knoten, i.e eine bounding box) erzeugen.

Die Abmessungen der Polygone sind verschieden, es muss also jweils eine x und y Auflösung für das Punktgitter erzeugt werden (Das Punktgitter soll wie gesagt immer 31x31 Punkte gross sein).

ich habe das bis jetzt mit generate_series implementiert, allerdings kann generate_series nur mit integern umgehen:

CREATE OR REPLACE FUNCTION makegrid(geometry, integer)
RETURNS geometry AS
$BODY$SELECT ST_Collect(st_setsrid(ST_POINT(x,y),$2)) FROM
generate_series((st_xmin($1))::int, (st_xmax($1))::int,(((abs(st_xmax($1)-st_xmin($1)))/32)::int)) as x
,generate_series((st_ymin($1))::int, (st_ymax($1))::int,(((abs(st_ymax($1)-st_ymin($1)))/32)::int)) as y
where st_intersects($1,st_setsrid(ST_POINT(x,y),$2))$BODY$
OWNER TO postgres;


Nun möchte ich das Ganze mit höherer Genauigkeit angehen, d…h. ich kann generate_series nicht mehr verwenden.

Die x,y auflösung habe ich mir folgendermassen überlegt:

xresolution := (abs(st_xmax($1)-st_xmin($1)))/32;
yresolution := (abs(st_ymax($1)-st_ymin($1)))/32;



Danach müssen die Punkte mit evtl einem geschachtelten loop o.ä (darin bin ich eher grotte) erzeugt werden:

–creating points:

{
for(x=st_xmin(geometry); x < st_xmax(geometry); x+=xresolution) {
for(y=st_ymin(geometry); y<st_ymax(geometry); y+=yresolution) {
if(st_contains(geometry, (st_point(x,y),epsg )=true) st_point(x,y),epsg ) else end;
–not sure about he else end here, i dont want to loose any points…
}
}
}


Kann mir jemand auf die Srpünge helfen? DANKE!

Ich würde hier nicht mit absoluten Koordinaten arbeiten sondern mit der Größe/Seitenlänge der Kacheln. Diese kannst du mit den Werten einer generator-Funktion (0-31) für x und y multiplizieren und zum 0-Punkt des Rasters addieren. Mit den so erzeugten Punkten kannst du dann die Rechtecke bilden.
Hoffe ich hab das halbwegs verständlich beschrieben, andernfalls mußt du noch etwas warten, ich brauche so eine Funktion auch für ein nebenläufiges Projekt :wink:

Gruß Uwe

Hi Uwe,also ich möchte für vorhandene Rechtecke eine Punktwolke erzeugen.

Was genau meinst du mit einer generator-funktion?

sonnige Grüße!

generate_series mein ich, manchmal überkommt mich der Python-Slang :wink:

Im Prinzip musst du nur das was du innerhalb deien generate_series tust ausserhalb machen. Du berechnest die notwendige Kantenlänge einer Zelle mit hoher Genauigkeit und muliplizierst sie mit einem Integer-Wert des Generators. Daraus kannst du die dann die genauen Koordinaten anhand des Ursprungs des Originalrechtecks berechnen.
Gruß Uwe

ja das ist logisch,

allerdings bekomme wenn ich das (mit meinen äusserst begrenzten plpgsql-Fähigkeiten) direkt umsetze einen Syntax error:

CREATE OR REPLACE FUNCTION makegrid(geometry, integer)
RETURNS geometry AS
$BODY$SELECT ST_Collect(st_setsrid(ST_POINT(x,y),$2)) FROM

(generate_series(1,31)((abs(st_xmax($1)-st_xmin($1)))/32)) as x,
(generate_series(1,31)
((abs(st_ymax($1)-st_ymin($1)))/32)) as y
where st_contains($1,st_setsrid(ST_POINT(x,y),$2))$BODY$
LANGUAGE sql VOLATILE
COST 100;

wie bekomme ich den wert vom Generator da sinnvoll rein,muss ich doch noch loopen?

Du erzeugst aus der übergebenen Geometrie mit xmax-xmin und ymax-ymin die jeweiligen Kantenlängenund schreibst die in zwei Variablen dx und dy. Dann legst du noch ein x0 und ein y0 an für die Ursprungs-Koordinaten.

das Pseudo-SQL sieht dann etwa so aus:

select st_geometryfromtext(‘POLYGON(’|| x0+(x-1)*dx ||’ ‘|| y0+(y-1)dy||’, '||x0+xdx||’ ‘||y0+(y-1)*dy||…restl.Punkte…|| x0+(x-1)*dx ||’ ‘|| y0+(y-1)*dy||’)’, )
from generate_series(1,31) as x, generate_series(1,31) as y

Jetzt so aus dem hohlen Bauch als erster Ansatz. Die Lücken darfst du füllen :wink:. Das Ergebnis kannst du natürlich noch als Collection erzeugen oder du gibst die einzelnen Polygone als Rows zurück. Wichtig ist, das das Polygon geschlossen ist (1.=letzer Punkt).

Grüße Uwe