Shapely: geometriya obyektlari va amallar
Kirish
Shapely — Python'da tekislikdagi geometriya obyektlarini yaratish, solishtirish va ular ustida amal bajarish uchun ochiq kodli kutubxonadir. U C tilida yozilgan GEOS kutubxonasiga tayanadi; QGIS, PostGIS va GeoPandas ham geometrik amallarni xuddi shu GEOS orqali bajaradi.
GeoPandas jadvalidagi har bir geometriya aslida Shapely obyekti. Shuning uchun Shapely'ni tushunish bufer, kesishma yoki "nuqta poligon ichidami?" kabi savollarning kod darajasida qanday yechilishini ko'rsatadi. Kutubxona pip install shapely buyrug'i bilan o'rnatiladi; GeoPandas o'rnatilganda u avtomatik ravishda birga keladi.
Geometriya turlari
Shapely OGC Simple Features standartidagi asosiy turlarni beradi: Point (nuqta), LineString (chiziq) va Polygon (poligon). Ularning to'plam shakllari — MultiPoint, MultiLineString va MultiPolygon — bir nechta qismdan iborat obyektni ifodalaydi, masalan orollardan tashkil topgan tuman.
from shapely import Point, LineString, Polygon
quduq = Point(420350, 4575120)
quvur = LineString([(420000, 4575000), (420600, 4575300)])
uchastka = Polygon([(420200, 4575000), (420500, 4575000),
(420500, 4575250), (420200, 4575250)])
print(uchastka.area, quvur.length) # 75000.0 670.82...
Poligonning tashqi chegarasi yopiq bo'lishi kerak; ichida teshik (masalan, uchastka ichidagi hovuz) bo'lsa, u alohida ichki halqa sifatida beriladi.
Geometriyani matn ko'rinishida saqlash va almashish uchun WKT (Well-Known Text) formati ishlatiladi: print(quduq.wkt) buyrug'i POINT (420350 4575120) qatorini qaytaradi. Xuddi shu qator PostGIS so'rovida yoki QGIS'dagi ifodada ham tushuniladi, shuning uchun WKT dasturlar orasida geometriyani tekshirishning qulay usulidir.

Fazoviy predikatlar
Fazoviy predikat (spatial predicate) — ikki geometriya o'rtasidagi munosabat haqidagi "ha/yo'q" savoli. Eng ko'p ishlatiladiganlari:
| Predikat | Savol |
|---|---|
intersects | Ikki obyektning umumiy nuqtasi bormi? |
contains / within | Biri ikkinchisining to'liq ichidami? |
touches | Faqat chegarada tegib turadimi? |
disjoint | Umuman umumiy nuqta yo'qmi? |
print(uchastka.contains(quduq)) # True
print(quvur.intersects(uchastka)) # True
Predikatlar filtrlashda ishlatiladi: masalan, faqat suv himoya zonasiga tushgan uchastkalarni tanlash.

Geometrik amallar
Predikat savolga javob beradi, geometrik amal esa yangi geometriya yaratadi:
intersection— ikki obyektning umumiy qismi (kesishma);union— ikkalasini bitta obyektga qo'shish (birlashma);difference— birinchisidan ikkinchisini ayirish (ayirma);buffer(d)— obyekt atrofidadmasofadagi zona (bufer).
from shapely import box
zona = quduq.buffer(100) # 100 m sanitariya zonasi
tegishli = uchastka.intersection(zona) # uchastkaning zona ichidagi qismi
print(round(tegishli.area)) # 31365
qoshni = box(420500, 4575000, 420700, 4575250) # qo'shni uchastka
print(uchastka.touches(qoshni)) # True
print(uchastka.union(qoshni).area) # 125000.0
print(round(uchastka.difference(zona).area)) # 43635
Bufer aniq aylana emas, ko'pburchak: standart holatda har chorak aylana 16 ta kesma bilan ifodalanadi. Shuning uchun maydon π·100² = 31 416 m² emas, 31 365 m² chiqadi; aniqroq natija kerak bo'lsa quduq.buffer(100, quad_segs=64) yoziladi.
Amallar natijasini darhol tekshirish foydali: bo'sh geometriya (is_empty) yoki kutilmagan tur (masalan, poligon o'rniga chiziq) mantiqiy xatoni ko'rsatadi.

Ko'p obyekt bilan ishlash
Real loyihada bitta quduq emas, minglab nuqta va yuzlab uchastka bo'ladi. 2022-yil dekabrida chiqqan Shapely 2.0 dan boshlab funksiyalar butun massiv ustida ishlaydi: shapely.contains(uchastkalar, quduq) har bir uchastkani bitta chaqiriqda tekshiradi va Python siklidan ancha tez ishlaydi.
Katta to'plamda har bir juftlikni solishtirish baribir sekin. Buning uchun fazoviy indeks (spatial index) — STRtree ishlatiladi. U har bir obyektning chegaralovchi to'rtburchagini daraxt tuzilmasiga joylaydi va so'rov vaqtida faqat yaqin turgan nomzodlarni qaytaradi; aniq predikat esa shu nomzodlar ustida tekshiriladi.
import shapely
from shapely import STRtree
uchastkalar = [uchastka, qoshni]
print(shapely.contains(uchastkalar, quduq)) # [ True False]
daraxt = STRtree(uchastkalar)
idx = daraxt.query(zona, predicate="intersects")
print(idx) # [0]
tanlangan = [uchastkalar[i] for i in idx]
query geometriyalarning o'zini emas, ularning ro'yxatdagi tartib raqamini qaytaradi; shu raqam bo'yicha atributlar jadvalidan kerakli satr olinadi.
GeoPandas'ning sjoin funksiyasi ichida aynan shu mexanizm ishlaydi. Shu sababli Shapely'dagi predikat va indeksni tushunish fazoviy birlashtirish qachon tez, qachon sekin ishlashini oldindan baholashga yordam beradi.
CRS va yaroqsiz geometriya
Shapely koordinata ma'lumotnoma tizimini bilmaydi: u faqat tekislikdagi sonlar bilan ishlaydi. Agar koordinatalar gradusda bo'lsa, buffer(100) 100 metr emas, 100 gradus zona yaratadi va maydon ham kvadrat gradusda chiqadi. Shu sababli masofa va maydon amallaridan oldin ma'lumot metrli proyeksiyaga o'tkaziladi — O'zbekistonning markaziy qismi uchun, masalan, UTM 42N (EPSG:32642). Buning uchun pyproj kutubxonasi ishlatiladi:
from pyproj import Transformer
from shapely.ops import transform
t = Transformer.from_crs("EPSG:4326", "EPSG:32642", always_xy=True)
nuqta_grad = Point(69.2401, 41.2995) # Toshkent, gradusda
xato = nuqta_grad.buffer(500) # radiusi 500 gradus — ma'nosiz
print(xato.bounds[0]) # -430.7599 (uzunlik -180 dan kichik)
nuqta_m = transform(t.transform, nuqta_grad) # metrga o'tkazildi
print(round(nuqta_m.buffer(500).area)) # 784137 m²
Ikkinchi xavf — yaroqsiz geometriya: o'zini kesib o'tgan poligon yoki takroriy nuqtalar amallarni xatoga yoki noto'g'ri natijaga olib keladi. is_valid bilan tekshiriladi, Shapely 2 qo'llanmasidagi make_valid funksiyasi esa geometriyani tuzatishga yordam beradi:
from shapely import is_valid_reason, make_valid
kapalak = Polygon([(0, 0), (2, 2), (2, 0), (0, 2)]) # o'zini kesib o'tadi
print(kapalak.is_valid) # False
print(is_valid_reason(kapalak)) # Self-intersection[1 1]
tuzatilgan = make_valid(kapalak)
print(tuzatilgan.geom_type, tuzatilgan.area) # MultiPolygon 2.0
Bu misolda yaroqsiz poligonning area qiymati 0 ga teng chiqadi, chunki ikki uchburchak qarama-qarshi yo'nalishda aylanadi va maydonlari bir-birini yo'qqa chiqaradi. Tuzatilgandan keyin ikki alohida uchburchak va to'g'ri maydon olinadi.
Xulosa
Shapely — Python'dagi geometrik tahlilning asosi: u obyekt yaratadi, ular orasidagi munosabatni tekshiradi va kesishma, birlashma yoki bufer orqali yangi geometriya hosil qiladi.
Natija ishonchli bo'lishi uchun ikki shart bajariladi: masofa va maydon amallari metrli CRSda bajariladi, geometriyalar esa amaldan oldin yaroqlilikka tekshiriladi.