PostGIS geometrisini yüzde büyüme


10

PostGIS geometrisi etrafında bir tampon eklemek için bir yol arıyorum, ancak tampon boyutu geometri boyutuna bağlı olmalıdır. Yani, her bir geometrinin% 5 oranında büyütülmesini istiyorum.

Fikir, kesişen geometriler arıyorum, ancak dikkate almak istediğim her biriyle ilişkili% 5'e kadar bir hata olabilir.

Bunu yapmanın en iyi yolunu bilen var mı?

Veritabanında bir milyon satır var, bu yüzden oldukça hızlı olmasını tercih ederim.


2
Neyin% 5'i? Çokgen kullandığınızı varsayarak, en büyük genişliğin% 5'i, en dar genişliği, sınırlayıcı kutusu, bir tepe noktasının sentroidden uzaklığı mı? Noktalar veya çizgiler hakkında konuşuyorsanız, daha da az mantıklı!
MerseyViking

Sanırım tepe-sentroid mesafesi - ya da muhtemelen alandaki% 5'lik bir artış da iyi olurdu. Geometri bu sınırlayıcı kutuyu dolduracak şekilde ölçeklendirilmişse sınırlayıcı kutunun artırılması iyidir. Tüm geometriler kapalı çokgenlerdir (büyük çoğunluğu dörtgendir).
James Baker

Yanıtlar:


8

Yorumlar,% 5'inin yüksek doğrulukla elde edilmesine gerek olmadığını göstermektedir. (Eğer varsa, bu bir alacak uzun bir milyon poligon tampon zaman!) Bu nedenle çağırmak olabilir Pizza İlke : doğrusal bir faktör yaparak 2D özelliğini rescaling a ederek bölgeyi rescales bir ^ 2.

Akıl yürütme şöyle devam eder:

  • Şekil çok kıvrımlı olmadığında - özellikle dışbükeyse - arabelleğe alma, şekli merkezi bir nokta etrafında yeniden ölçeklendirmeye benzer bir sonuç üretir. (Bununla birlikte, arabelleğe almanın diskler dışındaki herhangi bir şekil için yeniden ölçeklendirmeye eşdeğer olmadığını anlamak önemlidir . Bazı içbükey şekiller için, yeniden ölçekleme yoluyla hesaplanan bir "arabellek" aslında orijinal şeklin kendisinin parçalarını içermeyebilir! biz edecek şekilde bir gerçek tampon hesaplamak, ama sadece tahmin etmek için bir sezgisel olarak bu yaklaşık eşdeğerlik kullanırken ne kadar tarafından tampon.)

  • Arabelleğe alınan alan% 5 daha büyük olacaksa, bu nedenle yeniden ölçekleme miktarı 1.025'e yakın olan sqrt (1 + 5/100) olmalıdır: yani, şekli her yöne% 2.5 genişletmek istiyoruz .

  • Aynı şekilde, şeklin bir "çap" (tipik bir mesafeye eşit) olduğunu düşünürsek, yarıçapı % 2,5 oranında artmalıdır. Bu, çapın% 2.5 / 2 =% 1.25'ine eşittir.

  • Şeklin sınırlayıcı kutusundan tipik bir çapı tahmin edebiliriz. Diyelim ki kutunun yan uzunluklarının aritmetik veya geometrik ortalamasını kullanın.

Bu, aşağıdaki iş akışını önerir:

  1. Şeklin sınırlayıcı kutusunu edinin.

  2. E kutunun yan uzunluklarının ortalaması olsun .

  3. Şekli% 1.25 e tamponlayın ; yani, (5/100) / 4 * e .

Adım 1 ve 2 çok az hesaplama gerektirdiğinden, bu kendini mümkün olan en süratli çözümlerden biri olarak sunar. Doğruluk kontrolü olarak, (elbette) tamponlanmış şekillerin alanlarını hesaplayabilir ve istenen% 5 artışa ne kadar yakın olduklarını görmek için orijinal alanlarla karşılaştırabilirsiniz. Bazen arabelleğe alınan alanlar% 5'ten daha büyük olabilir, ancak daha az olmaları nadir olmalıdır ve onlar için kayda değer ölçüde daha az olmaları imkansızdır.

Örnekler

Bir kontrol ve örnek olarak, bazı basit şekilleri ele alalım.

  1. Yarıçap r'in bir diski, kenarları 2 r olan bir sınırlama kutusuna sahiptir . Formülümüz e = (5/100) / 4 * 2 * r = r / 40 değerini hesaplar . Tamponlu şekil açıkçası r + r / 40 = 1.025 r yarıçaplı bir eşmerkezli disktir . Eski alan pi * r ^ 2 iken yeni alan pi * (1.025 r ) ^ 2 = pi * 1.0506 * r ^ 2, bu% 5.06 daha büyük.

  2. Kenarları uzunlukları koordinatları eksenlerine paralel olan bir dikdörtgen r ve s verir e = ( r + s ) / 2. Dikdörtgeni arabelleğe almanın ek alanı, dört kenar genişliği (5/100) / 4 e = e / 80 = ( r + s ) / 160 kenarları çevreleyen artı köşelerdeki e / 80 yarıçapının dört çeyrek dairesinden gelir . Diğer alanlara göre küçük olacak çeyrek çemberleri ihmal ederek, toplam yeni alan eşittir

    2 ( r + s ) * ( r + s ) / 160 = ( r ^ 2 + s ^ 2 + 2 r * s ) / 80.

    Ne zaman r ve s çok farklı değiliz, biz anlayabiliriz r ^ 2 + s ^ 2 olduğu yaklaşık 2 r * s . Bu yaklaşım 4 toplam yeni bir alan kolaylaştırır R * ler orijinal alanın / 80 =% 5 r * s istendiği şekilde.


4

Sanırım ST_Scale ( http://postgis.net/docs/ST_Scale.html ) ve ST_Translate ( http://postgis.net/docs/ST_Translate.html ) bir arada kullanmak istiyorsunuz . Bunun bir örneğini PostGIS in Action'da ve benzer şekilde Bölüm 8'de bulabilirsiniz. Kitabınız yoksa, o bölümün kodunu buradan indirebilirsiniz:

http://www.postgis.us/chapter_08

Kitaptan pasaj Örnek 8.26'ya bakınız:

    -- Listing 8.26 Combining Scale and Translation to maintain centroid
    SELECT xfactor, yfactor, 
       ST_Translate(ST_Scale(hex.the_geom, xfactor, yfactor), 
       ST_X(ST_Centroid(the_geom))*(1 - xfactor), 
       ST_Y(ST_Centroid(the_geom))*(1 - yfactor) ) As scaled_geometry
    FROM 
 ( SELECT ST_GeomFromText('POLYGON((0 0,64 64,64 128,0 192,-64 128,-64 64,0 0))') As the_geom)  As hex
    CROSS JOIN (SELECT x*0.5 As xfactor 
        FROM generate_series(1,4) As x) As xf
    CROSS JOIN (SELECT y*0.5 As yfactor
        FROM generate_series(1,4) As y) As yf;

İşler. Şimdi de var gibi görünüyor ST_Transscaleama bir şekilde bu işi nasıl yapacağımı
anlayamıyorum

0

Bu partiye çok geç ama son zamanlarda bunu yapan özel bir PostGIS işlevi geliştirdim ve gerekirse küçülttüm:

ST_Dilate

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.