Pertanyaan menarik! Ini adalah sesuatu yang ingin saya coba sendiri, jadi cobalah.
Anda dapat melakukan ini di PostGRES / POSTGIS dengan fungsi yang menghasilkan seperangkat poligon.
Dalam kasus saya, saya memiliki tabel dengan satu fitur (MULTILINESTRING) yang mewakili jalur kereta api. Perlu menggunakan CRS dalam meter, saya menggunakan osgb (27700). Saya telah melakukan 4km x 2km 'halaman'.
Di sini, Anda dapat melihat hasilnya ... hal-hal hijau adalah jaringan jalan, terpotong ke penyangga 1 km di sekitar rel, yang sesuai dengan ketinggian poligon dengan baik.
Inilah fungsinya ...
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' ;
Menggunakan fungsi ini
Ini sebuah contoh; 4km x 2km halaman, epsg: 27700 dan 10% tumpang tindih
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
Setelah menjalankan ini, Anda dapat mengekspor dari PgAdminIII ke file csv. Anda dapat mengimpor ini ke QGIS, tetapi Anda mungkin perlu mengatur CRS secara manual untuk layer - QGIS tidak menggunakan SRID di EWKT untuk mengatur layer CRS untuk Anda: /
Menambahkan atribut bearing
Ini mungkin lebih mudah dilakukan dalam postgis, bisa dilakukan dalam ekspresi QGIS tetapi Anda harus menulis beberapa kode. Sesuatu seperti ini...
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));
Peringatan
Agak sedikit diretas, dan hanya memiliki kesempatan untuk menguji pada satu dataset.
Tidak 100% yakin dua simpul mana yang harus Anda pilih pada pembaruan atribut bantalan itu query
.. mungkin perlu bereksperimen.
Saya harus mengakui bahwa saya tidak tahu mengapa saya perlu melakukan formula berbelit-belit untuk memutar poligon agar sesuai dengan segmen garis saat ini. Saya pikir saya bisa menggunakan output dari ST_Azimuth () di ST_Rotate (), tetapi sepertinya tidak.