ArcPy kullanarak çokgenin her iki tarafının yönünü hesaplamak?


9

Güneş ışığına maruz kalma oranlarını hesaplayabilmem için her bir çizginin bir çokgendeki yönünü incelemek istiyorum. Her çokgen bir binayı temsil eder ve ilişkili bir yüksekliğe sahiptir. Şimdilik sadece yönlendirmeyi düşünmek istiyorum ve daha sonra gölgeleme sorunlarını ele alacağım.

Düşündüğüm bir yaklaşım, çokgeni çizgilere ayırmak ve her çizginin yönünü hesaplamaktı, ancak zorluk şu ki o çizginin dış yüzünü tanımlamak zorundayım. Çokgenlerin çoğu düz çizgileri olan basit dört taraflı şekiller olsa da, bunun böyle olmadığı küçük bir sayı vardır (sadece dikkate almak istediğim, ancak henüz çözmek zorunda değilim).

Python'u tanıyorum ve bunu bir senaryodan yapmayı planlıyorum.


1
Bu sorunun cevabını yardım edin: gis.stackexchange.com/questions/1886/…
Sean

@Sean - teşekkürler, evet bu genel olarak yardımcı olur. Bunu yapmak için kullanılabilecek belirli ArcGIS komutlarına aşina değilim. Ayrıca, bir çokgendeki çizginin iç / dış yüzünün ne olduğunu bilmek sorunu hala devam etmektedir.
djq

'Oryantasyon' dediğinde, bunu benim için yeterince iyi tanımladın --- örneğin mükemmel bir altıgenin oryantasyonu nedir?
Dan S.

@ S. Dan S. Cevabımı, çokgendeki her satırın yönünü içerecek şekilde düzenledim.
djq

üzgünüm cevaplar - Dün ödülü düzgün bir şekilde atayamadım.
djq

Yanıtlar:


6

Sadece çoğunluk oryantasyonu istiyorsanız, yukarıdaki @Mapperz'in cevabına göz atın.

Aksi takdirde, dediğiniz gibi, Çokgen Çizgiye aracını kullanarak çokgenleri çizgilere bölebilirsiniz . Bu, dış çokgen yoksa alanın -1 olduğu bir sol ve sağ FID alanı ekler - bu, binalarınız bitişik veya üst üste biniyorsa olsa da biraz muckinge neden olabilir.

Oradan satırlarınızı her tepe noktasında bölebilirsiniz (belki de Bölme'yi COGO satırlarına kullanın ) ve ardından satırların her birindeki açıları hesaplayabilirsiniz (potansiyel olarak COGO niteliklerini güncelleyerek ).

Açı alanınızın Kuzey'den hesaplandığını varsayarsak, yön, left_FID'in -1 olduğu yerde doğru olur ve sağ_FID -1 olduğunda yönü elde etmek için yalnızca 180 ° ekleyin. Daha sonra orijinal FID'ye dayanarak toplayabilir, uzunluğa bağlı olarak çoğunluk yönünü alabilirsiniz.

Çokgen çizgi aracı komut dosyasıdır, (bildiğim kadarıyla) COGO araçları değildir, bu yüzden orada kendiniz bir şey bulmanız gerekir.

Bu yardımcı olur umarım!


2
Utanmaz eklenti ve bir yorum: İlk olarak, bir Bilgi lisansınız yoksa , code.google.com/p/boundary-generator , Çokgen'den Satır aracına hemen hemen aynı şeyi yapar. İkincisi - bu size genel çokgenin genel yönelimlerine bakmaktan çok daha fazla bilgi verir ... örneğin, sonuçta ortaya çıkan tabloyu, her bir duvarın yönünü dikkate alarak çok daha hassas güneşe maruz kalma hesaplamaları yapmak için kullanabilirsiniz. .
Dan S.


5

Yön bulma

Bir komut dosyasında çokgen, bir halka (sıfır dış halka ve sıfır veya daha fazla iç halka) - her halka, döngüsel olarak sıralı bir vektör grubu (v [0], v 1 , ... , v [m-1], v [m] = v [0]). Her vektör bir tepe noktasının koordinatlarını verir (birbirini izleyen iki tepe noktası olmadan). Bundan, diğerlerinin de belirttiği gibi, normal vektörler (yani kenar yönlerine dik vektörler) elde etmek basittir:

n [i] = t (v [i + 1] - v [i]).

"T" işlemi bir vektörü saat yönünün tersine 90 derece döndürür :

t ((x, y)) = (y, -x).

Yalnızca bu normal vektörlerin yönleri önemlidir, bu nedenle birim uzunluğuna sahip olacak şekilde yeniden ölçeklendirin: bir vektör (x, y), s = Sqrt (x ^ 2 + y ^ 2) ( karşılık gelen kenarının uzunluğudur). Bundan sonra, bunun yapıldığını varsayalım. Ortaya çıkan birim normal vektörlerin bileşenlerini şöyle yazın

n [i] = (u [i], v [i]), i = 0, 1, ..., m-1.

Dışarıdan içeriden ayrımcılık

Belirttiğiniz gibi, bu yönlü bir belirsizlik bırakır: n [i] veya -n [i] mi kullanmalıyız? Hangisi dışa doğru işaret ediyor? Bu soru bulma eşdeğerdir derecesini ait Gauss haritası . Bunu hesaplamak için, bir halka etrafında yürürken normal yönlerin değiştiği açıları toplamalısınız. Normal vektörlerin birim uzunluğu olduğundan, birbirini izleyen iki kenar arasındaki açının kosinüsü

Cos (q_i) = n [i]. n [i + 1] = u [i] * u [i + 1] + v [i] * v [i + 1], i = 0, 1, ..., m-1.

(N [m] = n [0] tanımlayın.)

Birbirini izleyen iki kenar arasındaki açının sinüsü

Günah (q_i) = n [i]. t (n [i + 1]) = u [i] * v [i + 1] - v [i] * u [i + 1].

(Bu hesaplamaların yalnızca toplamlar, farklılıklar ve ürünler gerektirdiğini unutmayın.) Temel ters tanjant işlevinin (ATan2) bu tür (kosinüs, sinüs) çiftlere uygulanması, q_i açısını -180 ile 180 derece arasında verir. Bu açıları i = 0, 1, ..., n-1 için toplamak, halkanın 360 derecenin katı olması gereken toplam eğriliği üretir (kayan nokta hatasına kadar); kendiliğinden kesişmeyen kapalı bir halka için +360 veya -360 olacaktır. İlk durumda derece 1'dir ve ikinci durumda derece -1'dir. Dış halkanın derecesi +1 ve iç halkaların derecesi -1 olduğunda normallerin tümü dışa doğru yönlendirilir. Bu kurala göre gerektiğinde halka olarak halka yönlendirin. Yani, herhangi bir halkanın derecesi gerekli olanın zıttıysa, o halkanın tüm normallerini ortadan kaldırın. Şimdi güneşlenme hesaplamalarınıza devam edebilirsiniz.


Çok kapsamlı bir cevap için teşekkür ederim. 'Bir komut dosyasında, çokgen bir dizi halka olarak kullanılabilir' dediğinizde, çokgen nasıl kullanılabilir? Bazı python betiklerine aşina olsam da, çokgeni bu şekilde nasıl yorumlayacağımı bilmiyorum. Bunu yavaşça okuyorum ve anlamaya çalışıyorum, ancak bazı açıklamaları yazabileceğim sahte kodlara çevirmekte zorlanıyorum.
djq

Bu yanıtla ilgili birkaç not: Tipik GIS API'leri her zaman bir poligonun dışını her zaman saat yönünün tersine (IIRC) sunacaktır, bu da dışarıyı içeriden dışarıdan ayırmak zorunda kalmayacağınız anlamına gelir - sadece dış halkalarda saat yönünde rotasyonlar kullanın ve deliklerde saat yönünün tersine. Celenius için bir açıklama: 'halka seti' biti, ArcGIS'in pitonu dahil olmak üzere çoğu API'nin bir çokgeni kurucu çizgi segmentlerine nasıl ayırmanıza izin vermesidir - bir halka bunların kapalı bir eğrisidir. Çokgenler adaları ve delikleri destekleyebileceğinden, birden fazla yüzüğünüz olabilir ...
Dan S.

@ Keşke CBS'lerin bu tür tutarlı sunumları sürdürmesi olsaydı. Yıllar boyunca ESRI yazılımı, olumsuz ve olumlu yönelimli çokgenler arasında ileri geri dalgalandı ve onları yönlendirmeden bıraktı. Bu noktada, mevcut yaklaşımları ile ilgili belgelenmiş ifadelere bile güveneceğime emin değilim: Dikkatli olurum. Bir halkadaki tüm kenarları zaten işledikten sonra yönlendirmeyi kontrol etmek çok az maliyetlidir.
whuber

.. çok şükür ki, bu küçük IIRC feragatnamesini aldım. ;) Artık ESRI yığınında geometri düzeyinde şeyler yaptığım kadar değil.
Dan S.

@ S. S. - Bunun python'da nasıl programlanabileceği konusunda hala biraz belirsizim. Bunun için herhangi bir yönerge var mı?
djq

1

Can bu yardım?


Kazdık ilginç bir kağıt. Bununla birlikte, burada tarif edilen yöntemlerin hiçbiri bir güneşe maruz kalma hesaplaması ile ilgili değildir (hesaplama, burada böyle görünmeyen bir kaba yaklaşım olarak tasarlanmadığı sürece).
whuber

1

/ * Belki bu yardımcı olur:

Azimut - pi / 2, bir RHR poligonunun yanlarının dışa dönük yönüdür:

İşte bir PostGIS örneği, sondaki ifadeyi kullanarak bldg117862 tablosunu oluşturabilirsiniz. SRID, EPSG 2271'dir (PA StatePlane North Feet) ve geometri bir Multipolygon'dur. ArcGIS 10'da görselleştirmek için, bldg117862 tablosunu oluşturduktan sonra sorgu / alt sorguları postgis'e bir Sorgu Katmanı bağlantısına yapıştırın. * /

- === QUERY BAŞLANGIÇ ===

/ * Dış sorgu dış ortogonalleri yönlendirir ve kenarların orta noktasından kenarlarınkiyle eşit uzunlukta dışa doğru dikey çizgiler oluşturur.

Baskın bakan yön (ler), yönlendirmeye göre gruplanan, azalan düzende uzunluk / toplam olacaktır * /

Side_id olarak satır_kimliği, uzunluk, yön olarak derece (ortoaz), st_makeline (st_setsrid (st_line_interpolate_point (geom, .5), 2271), st_setsrid (st_makepoint (st_x (st_line_interpolate_point (geom, .5), 2271)) st_setsrid (st_makepoint (st_x (st_line_interpolate_point (geom, .5)) + (uzunluk * (sin ( orthoaz))), st_y (st_line_interpolate_point (geom, .5)) + (uzunluk * (cos (orthoaz)))), 2271))

- sonraki dış alt sorgu, kenarların nokta çiftlerinden çizgiler yapar, her segment için dışa dik olan azimutunu (ortoaz) hesaplar

(SELECT bldg2009gid, line_id, st_length (st_makeline (başlangıç ​​noktası, bitiş noktası)) :: sayısal olarak (10,2) uzunluk, azimut (başlangıç ​​noktası, bitiş noktası), azimut (başlangıç ​​noktası, bitiş noktası) - pi () / 2 ortoaz, st_makeline ( başlangıç ​​noktası, bitiş noktası)

/ * en içteki alt sorgu - bina çokgenlerini kenarların başlangıç ​​noktası / bitiş noktası nokta çiftlerine ayrıştırmak için genera_series () kullanın - note1 - tüm çokgen kenarlarının ortak yönelimini sağlamak için sağ kuralı zorlayın note2 - örnek, çokgen için geometri () çokgeni kullanır () kaldırılabilir */

(SELECT create_series (1, npoints (dış halka (geometryn (st_forceRHR (geom), 1))) - 1) line_id olarak, bldg2009gid olarak git, pointn (dış halka (geometryn (st_forceRHR (geom), 1)), create_series (1, npoint'ler (dış dize (geometryn (st_forceRHR (geom), 1))) - 1)) başlangıç ​​noktası, pointn (dış dize (geometryn (st_forceRHR (geom), 1)), create_series (2, npoints (dış dize (geometryn (st_forceRHR (geom), 1)), ), 1))))) bldg117862'den son nokta olarak) t1 olarak t2 olarak

- === SORGULANAN SONU ===

- bldg117862 tablosu oluşturma / ekleme ifadeleri

STANDARD_CONFORMING_STRINGS öğesini AÇIK olarak ayarlayın; DropGeometryColumn ('', 'bldg117862', 'geom') SEÇİN; DAMLA TABLOSU "bldg117862"; BAŞLA; TABLO OLUŞTUR "bldg117862" (gid seri PRIMARY KEY, "motherpin" varchar (14), "taxpin" varchar (14), "status" varchar (15), "alan" sayısal, "prev_area" sayısal, "pct_change" sayısal, "picture" varchar (133), "mappage" varchar (6), "sref_gid" int4, "e_adresi" varchar (19), "a_adresi" varchar (19), "çevre" sayısal, "kart" int4, "a_addnum" int4, "e_street" varchar (50), "a_street" varchar (50), "e_hsnum" varchar (10)); AddGeometryColumn ('', 'bldg117862', 'geom', '2271', 'MULTIPOLYGON', 2) SEÇİN; 0106000020DF080000010000000103000020DF080000010000000B0000008C721D6C98AC34415E2C5BB9D3E32541AE56DE17BEAC34410613E5A0A0E325411AB6C794AEAC3441BA392FE372E32541C89C38429DAC3441643857628AE325418C299A9095AC3441F66C29B573E32541983F02087EAC34413080AA9F93E325419BAC3C0A86AC3441AC1F3B3DABE32541803A40B974AC3441E8CF3DB9C2E325413E3758C186AC3441D0AAB0E7F7E325410AAAA5429BAC3441BA971217DCE325418C721D6C98AC34415E2C5BB9D3E32541' ); CREATE INDEX "bldg117862_geom_gist gist (" geom "gist_geometry_ops) kullanarak" ON "bldg117862"; SON;


0

Çizgi parçalarının yönünün bir poligonda sabit olduğu varsayılarak, bir vektörün her çizgi parçasına dik olan yönünü (istikametini) hesaplayabilirsiniz. Şu anda kodlamak için bash için zamanım yok ama matematik gerekiyorsa, kolayca temin edilebilir :-)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.