Question interessante! C'est quelque chose que j'ai voulu essayer moi-même, alors essayez-le.
Vous pouvez le faire dans PostGRES / POSTGIS avec une fonction qui génère un ensemble de polygones.
Dans mon cas, j'ai une table avec une caractéristique (un MULTILINESTRING) qui représente une ligne de chemin de fer. Il faut utiliser un CRS en mètres, j'utilise osgb (27700). J'ai fait 4 km 'pages'.
Ici, vous pouvez voir le résultat ... la substance verte est le réseau routier, attaché à un tampon de 1 km autour de la voie ferrée, ce qui correspond joliment à la hauteur des polygones.
Voici la fonction ...
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' ;
Utiliser cette fonction
Voici un exemple. 4 km x 2 km pages, epsg: 27700 et 10% de chevauchement
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
Après avoir exécuté ceci, vous pouvez ensuite exporter de PgAdminIII dans un fichier csv. Vous pouvez importer cela dans QGIS, mais vous aurez peut-être besoin de définir manuellement le CRS pour le calque - QGIS n'utilise pas le SRID dans EWKT pour définir le CRS du calque pour vous: /
Ajout d'un attribut de relèvement
Ceci est probablement plus facile à faire dans les postgis, cela peut être fait dans les expressions QGIS mais vous devrez écrire du code. Quelque chose comme ça...
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));
Mises en garde
C'est un peu bidouillé, et nous n'avons eu qu'une chance de tester sur un jeu de données.
Vous n'êtes pas sûr à 100% des deux sommets que vous devrez choisir pour cette mise à jour d'attribut de roulement query
.
Je dois avouer que je ne sais pas pourquoi je dois utiliser une formule aussi compliquée pour faire pivoter le polygone afin de le faire correspondre au segment de ligne actuel. Je pensais pouvoir utiliser la sortie de ST_Azimuth () dans ST_Rotate (), mais apparemment pas.