Interesante pregunta. Es algo que he querido probar yo mismo, así que lo he intentado.
Esto se puede hacer en PostGRES/POSTGIS con una función que genera un conjunto de polígonos.
En mi caso, tengo una tabla con una característica (un MULTILINEAL) que representa una línea ferroviaria. Necesita usar un CRS en metros, estoy usando osgb (27700). He hecho "páginas" de 4km x 2km.
Aquí puedes ver el resultado... lo verde es la red de carreteras, recortada a un buffer de 1km alrededor del ferrocarril, que corresponde a la altura de los polígonos muy bien.
Esta es la función...
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' ;
Utilizando esta función
Este es un ejemplo; páginas de 4km x 2km, epsg:27700 y 10% de solapamiento
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
Después de ejecutar esto, puede exportar desde PgAdminIII a un archivo csv. Usted puede importar esto en QGIS, pero es posible que tenga que establecer el CRS manualmente para la capa - QGIS no utiliza el SRID en EWKT para establecer el CRS de la capa para usted :/
Añadir atributo de rodamiento
Esto es probablemente más fácil de hacer en postgis, se puede hacer en las expresiones de QGIS, pero tendrá que escribir algo de código. Algo como esto...
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));
Advertencias
Es un poco improvisado, y sólo tuve la oportunidad de probarlo en un conjunto de datos.
No estoy 100% seguro de cuáles son los dos vértices que debes elegir en esa actualización de atributos del rodamiento query
.. podría necesitar experimentar.
Debo confesar que no tengo ni idea de por qué tengo que hacer una fórmula tan enrevesada para rotar el polígono para que coincida con el segmento de línea actual. Pensé que podría utilizar la salida de ST_Azimuth() en ST_Rotate(), pero parece que no.