Цікаве запитання! Це те, що я хотів спробувати сам, тому подумав.
Це можна зробити в PostGRES / POSTGIS за допомогою функції, яка генерує набір багатокутників.
У моєму випадку у мене є таблиця з однією особливістю (МНОГОПОЛОЖЕННЯ), яка являє собою залізничну лінію. Для цього потрібно використовувати CRS в метрах, я використовую osgb (27700). Я зробив 4km x 2km 'сторінки'.
Тут ви можете побачити результат ... зелений матеріал - це дорожня мережа, обрізана на 1 км буфера навколо залізниці, що добре відповідає висоті полігонів.
Ось функція ...
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' ;
Використання цієї функції
Ось приклад; Сторінок 4 км х 2 км, epsg: 27700 та 10% перекриття
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
Після цього ви можете експортувати з PgAdminIII у файл csv. Ви можете імпортувати це в QGIS, але вам може знадобитися встановити CRS вручну для шару - QGIS не використовує SRID в EWKT для встановлення для вас рівня 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));
Коваджі
Це трохи взломано, і було лише шанс протестувати на одному наборі даних.
Не на 100% впевнений, які дві вершини вам потрібно буде вибрати для оновлення атрибута несучого query
.., можливо, доведеться експериментувати.
Я мушу зізнатися, що не маю поняття, чому мені потрібно робити таку складну формулу, щоб обертати багатокутник, щоб відповідати поточному відрізку лінії. Я думав, що можу використати висновок ST_Azimuth () у ST_Rotate (), але, схоже, ні.