Domanda interessante! È qualcosa che volevo provare da solo, quindi ho provato.
Puoi farlo in PostGRES / POSTGIS con una funzione che genera un insieme di poligoni.
Nel mio caso, ho una tabella con una caratteristica (una MULTILINESTRING) che rappresenta una linea ferroviaria. Deve usare un CRS in metri, sto usando osgb (27700). Ho fatto "pagine" di 4 km x 2 km.
Qui puoi vedere il risultato ... la sostanza verde è la rete stradale, agganciata a un buffer di 1 km attorno alla ferrovia, che corrisponde bene all'altezza dei poligoni.
Ecco la funzione ...
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' ;
Usando questa funzione
Ecco un esempio; Pagine da 4 km x 2 km, epsg: 27700 e sovrapposizione del 10%
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
Dopo averlo eseguito, è possibile esportare da PgAdminIII in un file CSV. Puoi importarlo in QGIS, ma potresti aver bisogno di impostare manualmente il CRS per il layer - QGIS non usa SRID in EWKT per impostare il layer CRS per te: /
Aggiunta dell'attributo cuscinetto
Questo è probabilmente più facile con Postgis, può essere fatto con espressioni QGIS ma dovrai scrivere del codice. Qualcosa come questo...
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));
Avvertenze
È un po 'compromesso e ha avuto solo la possibilità di testare su un set di dati.
Non sono sicuro al 100% di quali due vertici dovrai scegliere sull'aggiornamento dell'attributo di rilevamento query
.. potrebbe essere necessario sperimentare.
Devo confessare che non ho idea del motivo per cui devo fare una formula così contorta per ruotare il poligono in modo che corrisponda al segmento di linea corrente. Pensavo di poter usare l'output di ST_Azimuth () in ST_Rotate (), ma apparentemente no.