Интересный вопрос! Это то, что я хотел попробовать сам, так что попробуй.
Вы можете сделать это в PostGRES / POSTGIS с помощью функции, которая генерирует набор полигонов.
В моем случае у меня есть таблица с одной функцией (MULTILINESTRING), которая представляет железнодорожную линию. Нужно использовать CRS в метрах, я использую osgb (27700). Я сделал "страницы" 4 км х 2 км.
Здесь вы можете увидеть результат ... зеленая полоса - это дорожная сеть, обрезанная до 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 x 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 (), но, похоже, нет.