GeoPandas — Analiz Çalışmalarınıza Harita Arayüzleri Ekleme
Herhangi bir restorana ait bilgileri (verileri) sorgulamak istediğimizde genellikle aklımıza ilk olarak o yerin ismi, yemek konsepti, bulunduğu il, ilçe gibi bilgiler gelir. Ancak bu noktada bu tarz birçok çalışmada oldukça işimize yarayan ve çoğunlukla atlanılan bir veri türünden daha söz etmeliyiz.
- Coğrafi Veri
Coğrafi veri, bir yer veya coğrafi konum ile ilişkili olan herhangi bir veridir. Bu tür veriler, coğrafi bilgi sistemleri (CBS) aracılığıyla toplanır, işlenir, analiz edilir ve görselleştirilir. Coğrafi veri, birçok sektörde önemli bir rol oynar, çünkü konum bazlı karar verme süreçlerini geliştirir.
İşte coğrafi verinin bazı kullanım alanları:
Yerel Hükümetler: Yerel hükümetlerin hizmetlerinin planlanması ve kaynaklarının yönetilmesi gibi yerel kararlar verilmesinde önemli bir rol oynar.
Sağlık Sektörü: Hastalık salgınları ve sağlık hizmetlerinin planlanması ve yönetimi gibi sağlık konularında önemli bir role sahiptir.
Çevre Bilimi: Çevre bilimi alanında kullanılarak, doğal kaynakların kullanımı, çevre kirliliği ve iklim değişikliği gibi konularda önemli veriler sağlar.
İnşaat Sektörü: İnşaat sektöründe kullanılarak, arazi kullanım planlaması, bina tasarımı ve projelerin yönetimi gibi konularda önemli bir role sahiptir.
Bu tip nedenlerden dolayı, coğrafi veri, birçok sektörde oldukça önemli bir rol oynar.
Şimdi baştaki restoran senaryomuza geri dönelim. Restorana ait tüm bu bilgilerin yanında, örneğin restoranının ulaşabilirliğini test etmek için bir de bulunduğu konum bilgisine ihtiyacımız olacak.
Bu konum bilgisi kullanılan veri formatlarına göre zaman zaman farklılık gösterse de genellikle aşağıdaki şemada görüldüğü gibi geometry adında bir sütunda tutulur.
JSON veri formatını muhtemelen önceden duymuşsunuzdur. Eğer ilk defa duyuyorsanız, JSON aynı Python’daki sözlük yapısında olduğu gibi verileri bir anahtar/değer ilişkisini gözeterek tutan bir veri depolama formatıdır.
Ancak JSON formatındaki veriye içerisinde coğrafi bilgileri barındıran bir geometry sütunu eklerseniz, karşımıza çıkan yeni veri formatına GeoJSON adı verilir.
Coğrafi verinin önemini kavradığımıza ve GeoJSON formatını biraz tanıdığımıza göre coğrafi bilgileri çalışmalarımızda nasıl dahil edebiliriz ona bakalım. Bu tip çalışmaları yapabilmek için kullanılan birçok Python kütüphanesi vardır. Ancak bu bültenimizde biz sizlerle bu kütüphanelerin belki de en başlıcası olan GeoPandas kütüphanesinden yararlanacağız. İlk olarak kendimize örnek veri seti olarak New York’taki İlçe Sınırlarını ve Metro İstasyonlarının Konumlarını seçelim.
NOT: Bu çalışmada kullanılacak örnek veri setlerine aşağıdaki linklerden sizler de ulaşabilirsiniz. Veriyi GeoJSON formatında indirmeyi ihmal etmeyin!
- https://data.cityofnewyork.us/City-Government/Borough-Boundaries/tqmj-j8zm
- https://data.ny.gov/Transportation/MTA-Subway-Stations/39hk-dx4f/about_data
import geopandas as gpd
borough_boundaries = gpd.read_file('data/Borough Boundaries.geojson')
subway_stations = gpd.read_file('data/MTA Subway Stations.geojson')
Kullanacağımız verileri okuduğumuza göre şimdi de içeriklerine bakalım.
Yukarıdaki tablolara dikkatlice baktığınızda son sütunlarıdan yer alan ve format olarak diğerlerinden biraz daha farklı duran geometry sütununu umarım fark etmişsinizdir. İşte bu sütun bizim coğrafi bilgilerimizi saklayan alan!
Ancak başlarında yazan POINT, MULTIPOLYGON gibi ifadeler ne anlama geliyor? Şimdi de ona bakalım.
- POINT (Nokta): Coğrafi bir konumu belirtmek için kullanılan en basit geometrik şekildir. Bir nokta, yalnızca bir koordinat çifti (enlem ve boylam) ile tanımlanır. Örneğin, bir metro istasyonunun koordinatları bir nokta olarak temsil edilebilir.
- POLYGON (Çokgen): Kapalı bir alanı belirtmek için kullanılan bir geometrik şekildir. En az üç noktadan (daha yaygın olarak köşeler olarak adlandırılır) oluşur ve bu noktalar birbirine doğru çizgilerle bağlanarak bir sınır oluşturur. Örneğin, bir parkın sınırları bir polygon olarak temsil edilebilir.
- MULTIPOLYGON (Çoklu Çokgen): Birden fazla polygonun bir araya gelmesiyle oluşan bir geometrik şekildir. Genellikle karmaşık coğrafi alanları temsil etmek için kullanılır. Örneğin, bir ülkenin sınırları, içinde birden fazla boşluk veya adalar bulunan bir multipolygon olarak temsil edilebilir.
Elimizdeki verinin coğrafi bir veri olmasının bize sağladığı bir sürü avantaj vardır. Örneğin borough_boundaries veri setinde gösterilen her bir ilçenin alanı shape_area sütununda verilmiş durumda, ancak bu bilgi elimizde olmasaydı da biz bu bilgiyi kendimiz üretebilirdik. Bunun için yazmamız gereken tek kod borough_boundaries.area
!
Geopandas’ın .area
fonksiyonunu bizim için bu hesaplamayı yukarıdaki MULTIPOLYGON’nun koordinatlarını kullanarak yapacak. Ancak geometry sütununda yer alan bilgiler şu anda o noktaların enlem ve boylam bilgilerinden oluşuyor. Bu hesabın bize doğru sonucu verebilmesi için elimizde derece(°) cinsinden olan bu enlem, boylam bilgilerini metre cinsinde X ve Y koordinatlarına dönüştürmemiz gerekiyor! Biz bu hesaplamayı yapmak için EPSG:2263 koordinat sistemini kullanacağız.
NOT: Bu tarz hesaplamalar yaparken elinizdeki koordinatların projeksiyon koordinatları olduğundan emin olmalıyız. Eğer yanlış koordinatlarda çalışıyorsanız, muhtemelen Python size bir uyarı mesajı gösterecektir. Bu haritacılık alanıyla teknik bir bilgi, ancak neden bu işleme ihtiyaç duyduğumuzu merak ediyorsanız Esri sitesindeki yazıya göz atabilirsiniz.
# Koordinat Sistemi Dönüşümü
borough_boundaries.to_crs('EPSG:2263')
# X ve Y Koordinatlarını Kullanarak M² Cinsinden Alan Hesabı
borough_boundaries['area'] = borough_boundaries.to_crs('EPSG:2263').area
borough_boundaries
Şimdi bu ilçeleri bir de harita üzerinde görelim. Bu işlem için matplotlib
ve contextily
kütüphanelerinden yararlanacağız.
import matplotlib.pyplot as plt
# Elimizdeki Alan Bilgisinin Görsel Olarak Haritaya Eklenmesi
boroughs_area = borough_boundaries.plot('area', legend=True, cmap='inferno_r', alpha=0.7, figsize=[8,8])
plt.title('NYC Boroughs Area', size=15);
Gayet güzel! Ancak bu haritanın anlaşılırlığını arttırması için arka planına bir altlık harita ekleyelim. Bu örnekte OpenStreetMap.HOT altlık haritasını kullanalım.
# Görsellere altlık harita eklemek için kullanılan bir kütüphane
import contextily as ctx
# Elimizdeki alan bilgisinin görsel olarak haritaya eklenmesi
borough_boundaries.to_crs('EPSG:2263', inplace=True)
boroughs_area = borough_boundaries.plot('area', legend=True, cmap='inferno_r', alpha=0.7, figsize=[8,8])
# Görseli daha anlaşılır kılmak için altlık harita ekleme
ctx.add_basemap(boroughs_area, crs='EPSG:2263', source=ctx.providers.OpenStreetMap.HOT)
plt.title('NYC Boroughs Area', size=15);
Peki bu haritayı interaktif bir şekilde inceleyebilir miyiz? Cevabı kesinlikle evet! Bunun için de explore()
fonksiyonunu kullanacağız.
borough_boundaries.explore('area', legend=True, cmap='inferno_r', legend_kwds={'max_labels': 3}, style_kwds={'fillOpacity': 0.7})
Şimdi de New York’un ilçelerinden rastgele seçtiğimiz 10 istasyonu harita üzerinde gösterelim.
sample_stations = subway_stations.sample(10)
sample_stations = sample_stations.to_crs('EPSG:2263')
# Lejantta gtfs_stop_id değerlerinin gözükmesini istiyorum
subway_locations = sample_stations.plot('gtfs_stop_id', markersize=50, figsize=[7,7], legend=True)
ctx.add_basemap(subway_locations, crs='EPSG:2263', source=ctx.providers.OpenStreetMap.Mapnik, alpha=0.7)
plt.title('Subways Location in NYC', size=15);
Yukarıdaki örnekte olduğu gibi istasyon isimlerini lejantta görmek yerine haritanın üzerinde uygun gördüğümüz konuma da yerleştirebiliriz.
station_names = sample_stations.plot('gtfs_stop_id', markersize=50, figsize=[7,7])
# İstasyon isimlerini nokta konumun yanına eklemek istiyorum
for x, y, label in zip(sample_stations.geometry.x, sample_stations.geometry.y, sample_stations['gtfs_stop_id']):
station_names.annotate(label, xy=(x, y), xytext=(10, 0), textcoords="offset points")
ctx.add_basemap(station_names, crs='EPSG:2263', source=ctx.providers.OpenStreetMap.Mapnik, alpha=0.7)
plt.title('Subways Location in NYC', size=15);
Son olarak da aynı harita üzerinde hem ilçe sınırlarını hem de rastgele seçtiğimiz 10 istasyonu göstermeye çalışalım.
fig, ax = plt.subplots(figsize=[8,8])
borough_boundaries.plot('area', cmap='inferno_r', ax=ax, alpha=0.5, edgecolor='black')
sample_stations.plot('gtfs_stop_id', markersize=50, ax=ax, legend=True)
ctx.add_basemap(ax, crs='EPSG:2263', source=ctx.providers.OpenStreetMap.Mapnik, alpha=0.5)
plt.title('Subways Location in NYC Boroughs', size=15);