Daha çox

PyQGIS ilə bərabər bərabər ölçülü poliqonların yaradılması

PyQGIS ilə bərabər bərabər ölçülü poliqonların yaradılması


Növbəti addımda AtlasCreator üçün istifadə etmək üçün bir xətt boyunca çoxbucaqlar yaratmaq istərdim.

ArcMap-da Strip Map Index Xüsusiyyətləri adlı bir vasitə var.

Bu alətlə çoxbucaqlılarımın hündürlüyünü və enini seçə bilərəm (8 km x 4km deyək) və onları xətt boyunca avtomatik olaraq istehsal / çevirə bilərəm.

Hər çoxbucaqlının yaradılan xüsusiyyətlərindən biri də Atlas Generator-da şimal oxlarımı döndərməyim lazım olan fırlanma bucağıdır.

QGIS-də / PyQGIS ilə bu vəzifəni necə həll edəcəyinə dair bir fikri varmı?

Xüsusi bir eklentinin içərisində istifadə edilə bilən GRASS- və ya SAGA-alqoritmləri və ya bir prossessing-toolbox modeli də yaxşı olardı.

Yalnız bir çap xəritəsi olaraq bütün çoxbucaqlı / ölçüləri olan bir xəritə yazdırmaq istədiyim üçün yalnız çap ölçülərinə deyil, eyni zamanda çoxbucaqların özünə də ehtiyacım var. QGIS-Plugin-də istifadə edilə bilən bir PyQGIS həlli axtarıram QGIS xaricində bir proqram yükləməyə ehtiyac olmadan (PostGIS / Oracle kimi RDBMS yoxdur).


Maraqlı sual! Özümü sınamaq istədiyim bir şeydir, ona görə də icazə verin.

Bunu PostGRES / POSTGIS-də bir çox poliqon yaradan bir funksiya ilə edə bilərsiniz.

Mənim vəziyyətimdə, bir dəmir yolu xəttini təmsil edən bir xüsusiyyətə sahib olan bir Cədvəlim var (ÇOX YARIŞLI). Metrlərdə bir CRS istifadə etməlidir, mən osgb (27700) istifadə edirəm. 4km x 2km 'səhifələr' etdim.

Burada nəticəni görə bilərsiniz ... yaşıl şeylər dəmir yolu ətrafında çoxbucaqlıların hündürlüyünə yaxşı uyğun gələn 1 km-lik bir buferə kəsilmiş yol şəbəkəsidir.

Budur funksiya ...

FUNKSİYANI YARATIN VƏ DƏYİŞDİN getAllPages (wid float, hite float, srid integer, üst-üstə düşən float) SETOF həndəsəsini $ BODY $ DECLARE səhifə həndəsəsi kimi QAYAR; - hər bir səhifəni yaradılan xətt şəklində saxlayır; - xətt həndəsəsini başlanğıc nöqtəsi həndəsəsini tutur; son nöqtə həndəsi; azimut üzmək; - fırlanma açısı lənətləri üzür: = 0.0; - xəttin sol kənarı ilə addım şamandıra nə qədərdir; stepnudge üzmək; əyri həndəsə; - səhifələrin əyri həndəsi olması üçün istifadə olunur; əyri üzmək; nömrələr üzmək; BEGIN - LineString istifadə edərkən ST_LineMerge zəngini buraxın - bunu masanızla əvəz edin. Traced_osgb-dan ST_LineMerge (geom) IN xəttinə SEÇİN; nömrələr: = ST_Length (myline) / wid; addım: = 1.0 / ədədi; stepnudge: = (1.0-üst-üstə düşmə) * addım; ÜÇÜN 1-də… tökmə (ədədlər tam ədəd kimi) LOOP - cari xətt seqmentinin başlanğıc nöqtəsini işləyin: = ST_SetSRID (ST_Line_Interpolate_Point (myline, curs), srid); son nöqtə: = ST_SetSRID (ST_Line_Interpolate_Point (myline, curs + step), srid); əyri xətt: = ST_SetSRID (ST_MakeLine (başlanğıc nöqtəsi, son nöqtə), srid); - CRS cərəyanının mənşəyində uyğun ölçülü bir çoxbucaqlı olun: = ST_SetSRID (ST_Extent (ST_MakeLine (ST_MakePoint (0.0_.0), ST_MakePoint (wid, hite))), srid); - sonra aşağıya doğru irəliləyin, beləliklə orta xətt cari xətt seqmenti cəriməsi ilə uyğunlaşsın: = ST_Translate (currpoly, 0.0, -hite / 2.0); - Bucağı uyğunlaşdırmaq üçün döndürün - Bu bitin necə işlədiyini qətiyyən bilmirəm. qıvrım: = -ST_Azimuth (başlanğıc nöqtəsi, son nöqtə) - (PI () / 2.0) + PI (); curppoly: = ST_Rotate (əyri, əyri); - sonra cari seqment cərəyanının başlanğıcına keçin: = ST_Translate (currpoly, ST_X (başlanğıc nöqtəsi), ST_Y (başlanğıc nöqtəsi)); səhifə: = müxalifət; SONRAKI səhifəni geom olaraq QAYDAR; - növbəti nəticə lənətlərini verin: = curs + stepnudge; SON DÖNGÜ; QAYIT; END $ BODY $ LANGUAGE 'plpgsql';

Bu funksiyadan istifadə

Budur bir nümunə; 4km x 2km səhifə, epsg: 27700 və 10% üst-üstə düşür

getAllPages-dən st_asEwkt (getallpages) seçin (4000.0, 2000.0, 27700, 0.1);

Bunu işlədikdən sonra PgAdminIII-dən bir CSV sənədinə ixrac edə bilərsiniz. Bunu QGIS-ə idxal edə bilərsiniz, ancaq CRS-i təbəqə üçün əl ilə təyin etməyiniz lazım ola bilər - QGIS sizin üçün CRS qatını təyin etmək üçün EWKT-də SRID istifadə etmir: /

Rulman atributu əlavə olunur

Postgisdə bunu etmək çox güman ki, daha asandır, QGIS ifadələrində edilə bilər, ancaq bir kod yazmalısınız. Bu kimi bir şey…

cədvəl səhifələrini aşağıdakı kimi yaradın (getAllPages-dən getallpages seçin (4000.0, 2000.0, 27700, 0.1)); cədvəl səhifələrini dəyişdirin sütun daşıyıcısı şamandıra əlavə edin; səhifələrin yenilənməsi = ST_Azimuth (ST_PointN (getallpages, 1), ST_PointN (getallpages, 2));

Xəbərdarlıqlar

Bir az hücuma məruz qaldı və yalnız bir verilənlər bazasında test etmək şansı var idi.

Bu daşıyıcı atributu yeniləməsi üçün hansı iki zirvəni seçməli olduğunuza 100% əmin deyilsorğu... təcrübə etmək lazım ola bilər.

Etiraf etməliyəm ki, çoxbucağı cari xətt seqmentinə uyğunlaşdırmaq üçün niyə belə qarmaqarışıq bir düstur etməyim lazım olduğuna dair heç bir fikrim yoxdur. ST_Azimuth () -dan ST_Rotate () içindəki çıxışı istifadə edə biləcəyimi düşünürdüm, amma görünmür.


@Steven Kays-ın PyQGIS-dəki cavabı.

Ssenarini işə salmadan əvvəl təbəqənizdəki sətirləri seçin. Şrift xətti tənzimləməni dəstəkləmir, ona görə də çoxsaylı sətirlə qat üzərində işləyə bilmir

#! python # kodlaşdırma: utf-8 # / questions / 173127 / qgis.core idxalından qq.core idxalından (QgsMapLayerRegistry, QgsGeometry, QgsField, QgsFeature, QgsPoint) bərabər ölçülü-çoxbucaqlı-piqgis ilə bərabər xətt yaradan PyQt4.QtCore idxal QVariant def getAllPages (qat, genişlik, hündürlük, sürüşmə, üst-üstə düşmə): layer.selectedFeatures (): geom = feature.geometry () if geom.type () <> QGis.Line: print "geometry type olmalıdır a LineString "return 2 page = QgsVectorLayer (" Polygon? crs = epsg: "+ str (srid), layer.name () + '_ id _' + str (feature.id ()) + '_ pages'," memory ") fid = QgsField ("fid", QVariant.Int, "int") bucağı = QgsField ("bucağı", QVariant.Double, "ikiqat") atributları = [fid, bucağı] pages.startEditing () pagesProvider = pages.dataProvider ( ) pagesProvider.addAttributes (attributes) curs = 0 numpages = geom.length () / (width) step = 1.0 / numpages stepnudge = (1.0-overlap) * step pageFeatures = [] r = 1 currangle = 0 while curs <= 1 : # print 'r =' + str (r) # print 'curs =' + str (curs) startpoint = geom.interpolate (curs * geo m.length ()) endpoint = geom.interpolate ((curs + step) * geom.length ()) x_start = startpoint.asPoint (). x () y_start = startpoint.asPoint (). y () x_end = endpoint. asPoint (). x () y_end = endpoint.asPoint (). y () # print 'x_start:' + str (x_start) # print 'y_start:' + str (y_start) currline = QgsGeometry (). fromWkt ('LINESTRING ({} {}, {} {}) '. format (x_start, y_start, x_end, y_end)) currpoly = QgsGeometry (). fromWkt (' POLYGON ((0 0, 0 {height}, {width} {height}) , {width} 0, 0 0)) '. format (hündürlük = hündürlük, en = eni)) currpoly.translate (0, -height / 2) azimuth = startpoint.asPoint (). azimuth (endpoint.asPoint ()) currangle = (startpoint.asPoint (). azimuth (endpoint.asPoint ()) + 270)% 360 # çap 'azimut:' + str (azimuth) # print 'currangle:' + str (currangle) currpoly.rotate (currangle, QgsPoint (0,0)) currpoly.translate (x_start, y_start) currpoly.asPolygon () page = currpoly curs = curs + stepnudge feat = QgsFeature () feat.setAttributes ([r, currangle]) feat.setGeometry (page) pageFeatures .append (feat) r = r + 1 pagesPro vider.addFeatures (pageFeatures) pages.commitChanges () QgsMapLayerRegistry.instance (). addMapLayer (pages) return 0 layer = iface.activeLayer () getAllPages (layer, 500, 200, 2154, 0.4)

Fərqli həllər var. Və bu sadə polyline və çox sayda seçilmiş şəxslə işləyə bilər

blok diaqram:

  1. Parametrlər

    1. nəsil üçün oriyentasiya seçin və indeksi oxuyun (soldan sağa, şimaldan cənuba ...)
    2. obyekt ölçüsünü təyin edin
    forma = (4000,8000) # (,)
    1. superpozisiya koefini təyin edin (standart olaraq 10%?)
  2. içində
    1. Polyline sifariş etmək (başlanğıc və bitmə nöqtələrini müqayisə edin) sifariş etmək, oriyentasiya seçiminizdən asılıdır> xüsusiyyət sinfi üçün sifariş vertices yaradın OrderNodes
  3. OrderNodes-də loop

    1. sizi lövbər kimi ilk nöqtəyə çevirin

    2. hər bir təpə üçün onu x, y, id üzərinə əlavə edin və bir vektor hesablayın

    3. superpozisiyanı azaldaraq (10% / 2)> 5% sol çoxbucaqla eyni ankraj nöqtəsi ilə 5% sağ çoxbucaqlı poliqon (uzunluq və vektor oriyentasiyası üzrə) yaradın
    4. Bir presedent vertex nöqtəsi çoxbucaqlı olduqda və ya len uzunluğu forma vermək üçün> olduqda dayandırın
    5. Əvvəlki yaxşı həlli ilə çoxbucaq yaradın və son yaxşı mövqeyi ilə lövbər nöqtəsini təyin edin
    6. Yeni döngə həyata keçirin və növbəti çoxbucaqlı obyekt yaratmaq üçün x, y, id-i sıfırlayın.

Bu təklif həqiqətən də aydın deyilsə və ya şərh verilsə dəyişdirə bilərsiniz.


İki cavab (göndərmə zamanı) dahiyanədir və yaxşı izah olunur. Bununla birlikdə bunun üçün ÇOX sadə, lakin təsirli bir həll yolu da var (Çaya əsaslanan təsadüfi bir Şimal istiqaməti deyil, ənənəvi şəkildə Şimalla uyğunlaşdırılmış bütün xəritələrinizi qəbul edəcəyinizi düşünürəm). Fırlanma istəsəniz, mümkündür, ancaq biraz daha mürəkkəbdir (aşağıya baxın).

Əvvəlcə buradakı yazıma nəzər yetirin. Bu, Atlas üçün xəritə örtükləri yaratmaq üçün necə etmə qaydasını verir. İstədiyiniz metod, uyğunlaşdırma üsulu 'İş Akışı 2' dir. Doğrusal xüsusiyyətinizi təpələrə və ya uzunluğa bölün və xüsusiyyətləri istənilən miqdarda bufer edin. Tampon etdiyiniz məbləğ qismən üst-üstə düşməni diktə edəcək (ancaq aşağıya baxın), amma daha da əhəmiyyətlisi bir sahə ilə bir xüsusiyyət yaradır. Xətləri bölmək üçün istənilən sayda plagindən istifadə edə bilərsiniz, lakin GRASS v.split.length və v.split.vert yaxşı seçimdir (Qenerasiya Alətləri qutusunda mövcuddur).

Map Composer-da Atlas Generation-ı aktivləşdirərək tamponlanmış təbəqənizi seçib yenidən maddələr nişanına keçin və xəritə obyektinizi seçin. 'Atlas tərəfindən idarə olunur' işarəsini yoxlayın və istifadə vəziyyətinizdə Margin xüsusiyyətini seçərdim. Bu, xəritələr arasındakı üst-üstə düşməyinizə nəzarət edəcəkdir (alternativ olaraq sabit miqyaslı seçim edə bilərsiniz).

Bəstəkarın üst alətlər panelindəki Önizləmə Atlas Düyməsini istifadə edərək Atlas'ı önizləyə və neçə səhifə istehsal edəcəyini görə bilərsiniz. Bütün səhifələri tək bir PDF şəklində və ya ayrı sənədlər şəklində ixrac etməyi seçə biləcəyinizi unutmayın.

Xəritənin xətt boyunca dönməsini təmin etmək üçün Xəritə Bəstəkarı Maddə xüsusiyyətlərində bir fırlanma sahəsi var. Bir ifadə qurmalısınız (fırlanma qutusunun sağındakı kiçik düyməni istifadə edin). Seçiminiz olaraq dəyişəni seçin və sonra Düzenle. Bir ifadə qurucusu açılır və orada atlas xüsusiyyətlərinin həndəsəsinə və ya sahələrinə daxil ola bilərsiniz. Daha sonra xüsusiyyətlərin fırlanmasına görə xəritəni döndərmək üçün bir ekspres qura bilərsiniz (hər bir satır seqmentinin başlanğıc və bitmə nöqtələrini və bir az trig istifadə edərək yatağı hesablaya bilərsiniz). Şimal oxunuzu döndərmək üçün eyni əməliyyatı təkrarlayın (eyni ifadədən və ya əvvəlcədən hesablanmış dəyişəndən istifadə edərək).


Bilirəm ki, bu köhnə bir sualdır, lakin bu məsələni həll etmək üçün yeni bir plagin yaradılmışdır. https://plugins.qgis.org/plugins/polystrip/

Mən yaradıcı deyiləm və plagin üçün kredit götürmürəm.


Videoya baxın: Four Advanced Field Calculator Tricks