İlginç soru! Kendimi denemek istediğim bir şeydi, o yüzden bir şans verdi.
Bunu PostGRES / POSTGIS'te bir çokgen kümesi oluşturan bir işlevle yapabilirsiniz.
Benim durumumda, bir demiryolu hattını temsil eden tek bir özelliğe (ÇOKLU BİR GİRİŞ) sahip bir masam var. Metre cinsinden bir CRS kullanması gerekiyor, ben osgb kullanıyorum (27700). 4km x 2km 'sayfa' yaptım.
Burada sonucu görebilirsiniz ... yeşil alan, karayolu ağıdır ve demiryolunun etrafındaki 1 kilometreye kadar sıkıştırılmıştır, bu da çokgenlerin yüksekliğine güzel bir şekilde karşılık gelir.
İşte fonksiyon ...
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' ;
Bu işlevi kullanma
İşte bir örnek; 4km x 2km sayfalar, epsg: 27700 ve% 10 örtüşme
select st_asEwkt(getallpages) from getAllPages(4000.0, 2000.0, 27700, 0.1);
Bunu çalıştırdıktan sonra PgAdminIII'den bir csv dosyasına verebilirsiniz. Bunu QGIS'e içe aktarabilirsiniz, ancak CRS'yi katman için manuel olarak ayarlamanız gerekebilir - QGIS, CRS katmanını sizin için ayarlamak için EWKT'de SRID'yi kullanmaz: /
Rulman özelliği ekleme
Bu muhtemelen postgis'te daha kolaydır, QGIS ifadelerinde yapılabilir, ancak bir kod yazmanız gerekir. Bunun gibi bir şey ...
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));
Uyarılar
Bu biraz hack-birlikte ve sadece bir veri seti üzerinde test etmek için bir şansım vardı.
Bu rulman özniteliği güncellemesi için hangi iki köşeyi seçmeniz gerektiğinden% 100 emin değilsiniz query
... denemeniz gerekebilir.
İtiraf etmeliyim ki poligonu geçerli çizgi segmentiyle eşleşecek şekilde döndürmek için neden bu kadar kıvrımlı bir formül kullanmam gerektiğini bilmiyorum. ST_Azimuth () 'in çıkışını ST_Rotate ()' de kullanabileceğimi düşündüm, fakat görünüşte değil.