Interessante Frage! Es ist etwas, das ich selbst ausprobieren wollte, also habe ich es ausprobiert.
Sie können dies in PostGRES / POSTGIS mit einer Funktion tun, die eine Menge von Polygonen erzeugt.
In meinem Fall habe ich eine Tabelle mit einem Merkmal (MULTILINESTRING), das eine Eisenbahnlinie darstellt. Es muss ein CRS in Metern verwendet werden, ich verwende osgb (27700). Ich habe 4 km x 2 km Seiten erstellt.
Hier können Sie das Ergebnis sehen ... das Grüne ist das Straßennetz, das an einem 1 km langen Puffer um die Eisenbahn befestigt ist, der der Höhe der Polygone gut entspricht.
Hier ist die Funktion ...
CREATE OR REPLACE FUNCTION getAllPages(wid float, hite float, srid integer, overlap float) RETURNS SETOF geometry AS
$BODY$
DECLARE
page geometry; -- holds each page as it is generated
myline geometry; -- holds the line geometry
startpoint geometry;
endpoint geometry;
azimuth float; -- angle of rotation
curs float := 0.0 ; -- how far along line left edge is
step float;
stepnudge float;
currpoly geometry; -- used to make pages
currline geometry;
currangle float;
numpages float;
BEGIN
-- drop ST_LineMerge call if using LineString
-- replace this with your table.
SELECT ST_LineMerge(geom) INTO myline from traced_osgb;
numpages := ST_Length(myline)/wid;
step := 1.0/numpages;
stepnudge := (1.0-overlap) * step;
FOR r in 1..cast (numpages as integer)
LOOP
-- work out current line segment
startpoint := ST_SetSRID(ST_Line_Interpolate_Point(myline,curs),srid);
endpoint := ST_SetSRID(ST_Line_Interpolate_Point(myline,curs+step),srid);
currline := ST_SetSRID(ST_MakeLine(startpoint,endpoint),srid);
-- make a polygon of appropriate size at origin of CRS
currpoly := ST_SetSRID(ST_Extent(ST_MakeLine(ST_MakePoint(0.0,0.0),ST_MakePoint(wid,hite))),srid);
-- then nudge downwards so the midline matches the current line segment
currpoly := ST_Translate(currpoly,0.0,-hite/2.0);
-- Rotate to match angle
-- I have absolutely no idea how this bit works.
currangle := -ST_Azimuth(startpoint,endpoint) - (PI()/2.0) + PI();
currpoly := ST_Rotate(currpoly, currangle);
-- then move to start of current segment
currpoly := ST_Translate(currpoly,ST_X(startpoint),ST_Y(startpoint));
page := currpoly;
RETURN NEXT page as geom; -- yield next result
curs := curs + stepnudge;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
Verwendung dieser Funktion
Hier ist ein Beispiel; 4 km x 2 km große Seiten, epsg: 27700 und 10% Überlappung
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
Nachdem Sie dies ausgeführt haben, können Sie von PgAdminIII in eine CSV-Datei exportieren. Sie können dies in QGIS importieren, müssen das CRS jedoch möglicherweise manuell für den Layer festlegen. QGIS verwendet die SRID in EWKT nicht, um das Layer-CRS für Sie festzulegen: /
Lagerattribut hinzufügen
Dies ist wahrscheinlich einfacher in Postgis, es kann in QGIS-Ausdrücken gemacht werden, aber Sie müssen etwas Code schreiben. Etwas wie das...
create table pages as (
select getallpages from getAllPages(4000.0, 2000.0, 27700, 0.1)
);
alter table pages add column bearing float;
update pages set bearing=ST_Azimuth(ST_PointN(getallpages,1),ST_PointN(getallpages,2));
Vorbehalte
Es ist ein bisschen zusammen gehackt und hatte nur die Chance, an einem Datensatz zu testen.
Nicht 100% sicher, welche zwei Eckpunkte Sie für die Aktualisierung der query
Lagerattribute auswählen müssen. Möglicherweise müssen Sie experimentieren.
Ich muss zugeben, dass ich keine Ahnung habe, warum ich eine derart verschlungene Formel ausführen muss, um das Polygon so zu drehen, dass es mit dem aktuellen Liniensegment übereinstimmt. Ich dachte, ich könnte die Ausgabe von ST_Azimuth () in ST_Rotate () verwenden, aber anscheinend nicht.