JSON Formatındaki Veriye Ulaşmak: İBB WiFi Yeni Kullanıcı Verisi

Web Map

İBB Açık Veri Portalı’ndaki JSON formatındaki bir veri setinin çekilmesi ve haritalandırılması.

A. Uraz Akgül
2022-06-11

2020 yılının Ocak ayında İBB, Açık Veri Portalı’nı hizmete sundu. Geçen sürede 253 veri seti paylaşmışlar. Bu veri setlerinin çoğu xlsx, csv gibi formatlardan oluşuyor. Her ne kadar bu formatlar yaygın olarak kullanılsa da direkt web üzerinden verilere ulaşabileceğimiz yollar da var. Daha çok kullanılması dileğiyle demek isterim.

Bu uygulamada hem JSON formatını tanıyacağız hem de çektiğimiz veriler üzerinden bir haritalandırma yapacağız.

Uygulamaya konu İBB WiFi Yeni Kullanıcı Verisi, İstanbul Büyük Şehir Belediyesi tarafından sağlanan kablosuz internet hizmetini kullanan kullanıcı verilerini içermektedir. İşbu veri kaynağının içerisinde, Abonelik tarihi, Abone olunan ilçe, Abonenin Yerli/Yabancı, Abone olunan lokasyon bilgisi ve kullanıcı sayısı bilgilerini içerir. -İBB

Bu veri setinin 6 tane değişkeni bulunmaktadır.

Veri API butonuna tıklarsak eğer karşımıza aşağıdaki ekran çıkacaktır.

API, iki yazılım ve bir sunucunun olduğu yerde bağlantı kurma görevi üstlenen bir protokoldür. Biz bu API’ı kullanarak talebimizi sunucuya aktarıyoruz. Talebi alan sunucu kaynağa başvuruyor. Başvurduğu kaynak sunucuya geri dönüş sağlıyor. Sunucu gelen bu geri dönüşü API ile kullanıcıya iletiyor.

https://www.altexsoft.com/blog/engineering/what-is-api-definition-types-specifications-documentation/

Endpointler, API üzerinde belli bir amaca yönelik oluşturulmuş metotlardır.

İlk görselde Sorgulama başlığını görüyoruz. Buraya tıklarsak eğer OData örneği (ilk 5 sonuç, OData JSON’ı olarak dön) alt başlığını göreceğiz. Open Data Protocol anlamına gelen OData, veri kaynaklarına HTTP (sunucu ve istemci arasındaki haberleşme protokolü) üzerinden sorgu atılmasını sağlar. Yani HTTP tabanlı olması, tüm sorguların url (web sitesi erişiminde kullanılan adres) üzerinden gerçekleştirilmesidir.

Son olarak, JavaScript Object Notation’ın kısaltması olan JSON, verileri depolamak ve veri alışverişi yapmak için kullanılan kolay ve hafif bir yapıdır. JSON, veriyi okuyabilmemizi sağlar. Nasıl?

Gelin R’da örnek bir JSON yapısı oluşturalım. Bunun için jsonlite paketini kullanacağız. rjson da kullandığım paketler arasındadır.

library(jsonlite) # JSON

id <- c(100,101,102)
title <- c("X","Y","Z")

df <- data.frame(id, title)
somedata <- data.frame(Category_A = c("1","0","0"),
                       Category_B = c("0","0","1"),
                       Category_C = c("1","1","1"))
df$somedata <- somedata

toJSON(df, pretty = TRUE)
[
  {
    "id": 100,
    "title": "X",
    "somedata": {
      "Category_A": "1",
      "Category_B": "0",
      "Category_C": "1"
    }
  },
  {
    "id": 101,
    "title": "Y",
    "somedata": {
      "Category_A": "0",
      "Category_B": "0",
      "Category_C": "1"
    }
  },
  {
    "id": 102,
    "title": "Z",
    "somedata": {
      "Category_A": "0",
      "Category_B": "1",
      "Category_C": "1"
    }
  }
] 

API ile çalışırken httr paketini kullanacağız.

İlk fonksiyon GET(), veri çekmek için kullanılır.

res <- GET(
  url = "https://data.ibb.gov.tr/en/datastore/odata3.0/12f5bc23-224a-43cb-b60d-3f36f83ffd33?$format=json"
)

Yukarıda oluşturduğumuz res değişkeni (response), API sunucusunun isteğimize verdiği yanıtı içerir.

res
Response [https://data.ibb.gov.tr/en/datastore/odata3.0/12f5bc23-224a-43cb-b60d-3f36f83ffd33?$format=json]
  Date: 2022-06-11 11:54
  Status: 200
  Content-Type: text/html; charset=utf-8
  Size: 92.3 kB

Status’ın 200 olması yanıtın başarılı olduğunu gösterir. Yani, istemci ile sunucu arasındaki iletişim herhangi bir hata olmadan gerçekleşmiştir.

https://dev.to/bisrategebriel/http-status-codes-101-6jh

İçeriği aşağıdaki gibi JSON formatına çevirmemiz gerekiyor.

# rawToChar(res$content)

Her ne kadar dağınık görünse de aslında JSON formatına çevirmiş olduk ancak bu format character yapısında oldu. Bu formatı list yapısına çevirebiliriz.

dt <- fromJSON(rawToChar(res$content))
names(dt)
[1] "odata.metadata" "value"         

İhtiyacımız olan veriler value’nun içindedir. Koordinat bazlı haritalandırma yapacağımız için kullanacağımız değişkenler SUBSCRIBER_DOMESTIC_FOREIGN, LONGITUDE, LATITUDE ve NUMBER_OF_SUBSCRIBER olacaktır.

master <- dt$value
SUBSCRIBER_DOMESTIC_FOREIGN LONGITUDE LATITUDE NUMBER_OF_SUBSCRIBER
Yabancı 29.02325 40.99270 1
Yerli 29.10552 41.01701 2
Yerli 29.08863 40.95404 2
Yerli 29.09082 41.24324 2
Yerli 29.14665 40.90128 1
Yerli 28.65662 41.00984 1
Yerli 29.11825 41.04074 32
Yerli 28.94929 41.01124 3
Yerli 28.72508 40.98418 2
Yabancı 28.97837 41.00851 2

Boom!

Küçük bir düzeltme yapmamız gerekiyor. SUBSCRIBER_DOMESTIC_FOREIGN değişkenine ait değerlerde Yabancı yerine Yabancı yazılmış. Bunu gsub() fonksiyonu ile aşağıdaki gibi düzeltebiliriz.

master <- master %>% 
  mutate(
    SUBSCRIBER_DOMESTIC_FOREIGN = gsub("Yabancı","Yabancı",SUBSCRIBER_DOMESTIC_FOREIGN)
  )
SUBSCRIBER_DOMESTIC_FOREIGN LONGITUDE LATITUDE NUMBER_OF_SUBSCRIBER
Yabancı 29.02325 40.99270 1
Yerli 29.10552 41.01701 2
Yerli 29.08863 40.95404 2
Yerli 29.09082 41.24324 2
Yerli 29.14665 40.90128 1
Yerli 28.65662 41.00984 1
Yerli 29.11825 41.04074 32
Yerli 28.94929 41.01124 3
Yerli 28.72508 40.98418 2
Yabancı 28.97837 41.00851 2

Haritaya geçebiliriz.

Bu bölümde JavaScript’in bir kütüphanesi olan ve web tabanlı interaktif haritalamada tercih edilebilecek leaflet’i kullanacağız. En basit haliyle aşağıdaki gibi bir örnek verebiliriz.

leaflet() %>% 
  addTiles() %>% 
  addMarkers(lng = 32.836944, lat = 39.925, popup = "Anıtkabir")

Çektiğimiz verileri artık haritaya aktarabiliriz.

palet <- colorFactor(palette = c("gray","orange","red"),
                     domain = master$SUBSCRIBER_DOMESTIC_FOREIGN) # renklendirme

master %>% 
  leaflet() %>% 
  addTiles() %>% 
  addProviderTiles(provider = providers$CartoDB.DarkMatterNoLabels) %>% # harita tipi
  addCircles(lng = ~LONGITUDE,
             lat = ~LATITUDE,
             weight = 3,
             color = ~palet(SUBSCRIBER_DOMESTIC_FOREIGN),
             popup=paste("Abonelik Tarihi:", master$SUBSCRIPTION_DATE, "<br>",
                         "Abone Tipi:", master$SUBSCRIBER_DOMESTIC_FOREIGN, "<br>", 
                         "Abone Sayısı:", master$NUMBER_OF_SUBSCRIBER, "<br>")) %>% # nokta
  addLegend(position = "bottomright",
            pal = palet,
            values = master$SUBSCRIBER_DOMESTIC_FOREIGN,
            title = "",
            opacity = 1) # lejant

Yukarıdaki harita zoomlanabilir; haritadan noktaların üzerine tıklanarak bilgi alınabilir.