Pergunta interessante! É algo que eu queria experimentar, então tentei.
Você pode fazer isso no PostGRES / POSTGIS com uma função que gera um conjunto de polígonos.
No meu caso, tenho uma tabela com um recurso (uma MULTILINESTRING) que representa uma linha ferroviária. Ele precisa usar um CRS em metros, estou usando osgb (27700). Eu fiz 4 km x 2 km 'páginas'.
Aqui, você pode ver o resultado ... o material verde é a rede de estradas, presa a um buffer de 1 km ao redor da ferrovia, o que corresponde muito bem à altura dos polígonos.
Aqui está a função ...
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 esta função
Aqui está um exemplo; Páginas de 4 km x 2 km, epsg: 27700 e 10% de sobreposição
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
Depois de executar isso, você poderá exportar do PgAdminIII para um arquivo csv. Você pode importar isso para o QGIS, mas pode ser necessário definir o CRS manualmente para a camada - o QGIS não usa o SRID no EWKT para definir o CRS da camada para você: /
Adicionando atributo de rolamento
Provavelmente, isso é mais fácil no postgis, pode ser feito nas expressões QGIS, mas você precisará escrever algum código. Algo assim...
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));
Ressalvas
É um pouco hackeado e só teve a chance de testar em um conjunto de dados.
Não tem 100% de certeza de quais dois vértices você precisará escolher nessa atualização de atributo do rolamento query
. Talvez seja necessário experimentar.
Devo confessar que não tenho ideia de por que preciso fazer uma fórmula tão complicada para girar o polígono para corresponder ao segmento de linha atual. Eu pensei que poderia usar a saída de ST_Azimuth () em ST_Rotate (), mas aparentemente não.