興味深い質問です!それは私が自分で試してみたいものでしたので、試してみました。
PostGRES / POSTGISでは、一連のポリゴンを生成する関数を使用してこれを行うことができます。
私の場合、鉄道線を表す1つの機能(MULTILINESTRING)を持つテーブルがあります。CRSをメートル単位で使用する必要があります。osgb(27700)を使用しています。4km x 2kmの「ページ」を作成しました。
ここでは、結果を見ることができます...緑色のものは道路網であり、鉄道の周りの1kmのバッファにクリップされています。これはポリゴンの高さにうまく対応しています。
ここに関数があります...
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' ;
この機能を使用する
以下に例を示します。4km x 2kmページ、epsg:27700および10%のオーバーラップ
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
これを実行した後、PgAdminIIIからcsvファイルにエクスポートできます。これをQGISにインポートできますが、レイヤーのCRSを手動で設定する必要があるかもしれません-QGISはEWKTのSRIDを使用してレイヤーCRSを設定しません:/
方位属性の追加
これはおそらくpostgisで簡単に実行でき、QGIS式で実行できますが、コードを記述する必要があります。このようなもの...
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));
注意事項
少しハッキングされており、1つのデータセットでテストする機会しかありませんでした。
そのベアリング属性の更新で選択する必要のある2つの頂点を100%確信することはquery
できません。実験する必要があるかもしれません。
現在のラインセグメントに一致するようにポリゴンを回転させるために、このような複雑な数式を実行する必要がある理由がわからないことを認めなければなりません。ST_Rotate()でST_Azimuth()の出力を使用できると思いましたが、一見そうではありません。