คำถามที่น่าสนใจ! มันเป็นสิ่งที่ฉันต้องการลองด้วยตัวเอง
คุณสามารถทำได้ใน PostGRES / POSTGIS ด้วยฟังก์ชันที่สร้างชุดรูปหลายเหลี่ยม
ในกรณีของฉันฉันมีตารางที่มีคุณลักษณะหนึ่งรายการ (MULTILINESTRING) ซึ่งแสดงถึงเส้นทางรถไฟ มันต้องใช้ 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' ;
ใช้ฟังก์ชั่นนี้
นี่คือตัวอย่าง; หน้า 4km x 2km, 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 () แต่ดูเหมือนจะไม่