React ve Leaflet ile Haritalar Nasıl Oluşturulur

Yayınlanan: 2022-03-10
Kısa özet ↬ Broşür çok güçlü bir araçtır ve birçok farklı türde harita oluşturabiliriz. Bu eğitim, React ve Vanilla JS yardımıyla gelişmiş bir haritanın nasıl oluşturulacağını anlamanıza yardımcı olacaktır.

Bir CSV veya JSON dosyasından bilgi almak sadece karmaşık değil, aynı zamanda sıkıcıdır. Aynı verileri görsel yardım şeklinde temsil etmek daha basittir. Bu yazıda, SF İtfaiyesinin müdahale ettiği tıbbi olmayan yangın olaylarının yerlerini bir harita üzerinde sunacağız.

Bu eğitim için aşağıdaki araçları kullanacağız:

  • broşür
    Etkileşimli haritalar için bir JavaScript kitaplığı
  • Tepki
    Kullanıcı arayüzleri oluşturmak için bir JavaScript kitaplığı
  • React-Leaflet
    Broşür haritaları için tepki bileşenleri

Broşür Nedir?

Yaklaşık 27 bin yıldızla Leaflet.js, mobil uyumlu etkileşimli haritalar için önde gelen açık kaynaklı JavaScript kitaplıklarından biridir. Modern tarayıcılarda HTML5 ve CSS3'ten yararlanırken eski tarayıcılarda da erişilebilir. Sonuç olarak, tüm birincil masaüstü ve mobil platformları destekler.

Broşür yaklaşık 38 KB ağırlığındadır ve temel şeyler için mükemmel şekilde çalışır. Ek uzantılar için çok sayıda eklentiyle genişletilebilir.

NPR, Washington Post, Boston Globe ve diğerleri dahil olmak üzere birçok gazete ve diğer kuruluşlar, derinlemesine veri projeleri için Leaflet kullanıyor.

Örneğin San Francisco Chronicle, Leaflet kullanarak California'da yanan orman yangınları hakkında bilgi sağlayan etkileşimli bir harita olan California Fire tracker adlı bir proje yaptı. Sadece yangının kaynağını belirlemekle kalmadılar, aynı zamanda bize gidişatını da gösterdiler.

Bu bir giriş dersi olduğundan, sadece yangın olaylarının yerlerini işaretleyeceğiz ve bununla ilgili bazı detayları göstereceğiz.

React'e geçmeden önce, Leaflet'in temellerini anlayalım. Bunun için, bir Leaflet haritası kuracağımız, işaretçilerle ve açılır pencerelerle çalışacağımız basit bir örnek oluşturacağız.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Öncelikle /project klasörümüzde index.html ve app.js dosyalarını oluşturalım ve ikincisini index.html dosyamıza bağlayalım.

Leaflet'i kullanmaya başlamak için, head etiketlerimizde Leaflet CSS ve Leaflet JS'yi bağlamamız gerekiyor. Akılda tutulması gereken bir şey, Leaflet CSS'nin Leaflet JS'den önce geldiğidir. Leaflet için bu kadar.

index.html dosyamıza eklememiz gereken bir şey daha var – haritamızı tutacak bir kap.

 <div></div>

Unutmadan önce div'imize yükseklik verelim.

 #mapid { height: 1000px; }

Şimdi eğlenceli kısım geliyor. İster yeni bir JavaScript dosyası oluşturmaya ister komut dosyası etiketlerinde devam etmeye karar verin, L.map('mapid') çağırmadan önce dom <div id="mapid"> eklendiğinden emin olun.

Muhtemelen "Ama, neden?" diye soruyorsunuz. Eh, çünkü haritayı henüz var olmayan bir kapsayıcıya bağlarsanız size bir hata verecektir.

 Uncaught Error: Map container not found

Harita Oluşturma

Şimdi, eğlenceli kısma. Haritayı başlatmak için bazı seçeneklerle L.map() 'e geçiyoruz.

 const myMap = L.map('mapid', { center: [37.7749, -122.4194], zoom: 13 })

Az önce ne olduğunu anlamak için adım adım gidelim. Sayfada bir harita oluşturmak için Leaflet API'nin Map sınıfını kullanıyoruz. Bu sınıfa iki parametre iletiyoruz:

  1. DOM kimliğini temsil eden bir dize değişkeni ilettik
  2. Harita seçenekleriyle isteğe bağlı bir nesne değişmezi

Sınıfımıza geçebileceğimiz pek çok seçenek var ama ana iki seçenek merkez ve yakınlaştırma. Merkez, haritanın ilk coğrafi merkezini tanımlarken, yakınlaştırma bir başlangıç ​​harita yakınlaştırma seviyesini belirtir. Her ikisi de varsayılan olarak tanımsızdır.

Merkez için San Francisco'nun koordinatlarını geçtik. İleri ve geri coğrafi kodlama yapabileceğimiz pek çok yer var ama bunun gibi temel aramalar için google'da aratabiliriz.

Genellikle, yakınlaştırma değeri görüntülemek istediğiniz şeye bağlı olacaktır. Bir şehri mi yoksa bir eyaleti mi göstermek istiyorsunuz? Ülke mi, kıta mı? Devam edin ve daha iyi bir fikir edinmek için yakınlaştırma değeriyle oynayın. Bu örnek için 13'ü seçtik çünkü tüm şehri gösteriyor.

Haritayı başlatmanın başka bir yolu da setView() kullanmaktır. Yakınlaştırma düzeyi için bir dizi koordinat ve bir tamsayı alır.

 const myMap = L.map('map').setView([37.7749, -122.4194], 13);

Varsayılan olarak, haritadaki tüm fare ve dokunma etkileşimleri etkindir ve yakınlaştırma ve ilişkilendirme kontrollerine sahiptir.

Katman Oluşturma

Ardından haritamıza bir döşeme katmanı ekleyeceğiz; bizim durumumuzda, bu bir Mapbox Streets döşeme katmanıdır. TileLayer sınıfını somutlaştırarak çeşitli karo katmanları ekleyebiliriz.

Bir döşeme katmanı oluşturmak için, döşeme görüntüsü için URL şablonunu, ilişkilendirme metnini ve katmanın maksimum yakınlaştırma düzeyini ayarlamamız gerekir. URL şablonu, servis sağlayıcıdan istenen döşeme katmanına erişmemizi sağlayan şeydir. Mapbox'ın Static Tiles API'sini kullandığımız için bir erişim belirteci istememiz gerekecek.

 L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', { attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery (c) <a href="https://www.mapbox.com/">Mapbox</a>', maxZoom: 18, id: 'mapbox/streets-v11', accessToken: 'your.mapbox.access.token' }).addTo(mymap);

Bu noktada index.html dosyamızı bir tarayıcıda açarsak San Francisco haritasını görebiliriz. Haritaya bir raptiye bırakalım.

İşaretleyiciler ve Daireler

Haritaya ve katmana sahibiz, ancak bu bizi belirli bir şeye işaret etmiyor. Haritada belirli bir yeri işaret etmek için Leaflet bize işaretçiler sağlar.

Bir konumu sabitlemek için, Marker sınıfını kullanarak işaretçiyi somutlaştırır, koordinatları iletir ve onu haritaya ekleriz. Burada şehirdeki Twin Peaks koordinatlarını kullanıyoruz.

 const marker = L.marker([37.7544, -122.4477]).addTo(mymap);

Benzer şekilde, Circle sınıfını kullanarak bir çemberi haritaya bağlayabiliriz. Yarıçap, renk vb. gibi birkaç isteğe bağlı seçeneği geçiyoruz. circle işareti için Point Bonita Deniz Feneri koordinatlarında geçiyoruz.

 const circle = L.circle([37.8157, -122.5295], { color: 'gold', fillColor: '#f03', fillOpacity: 0.5, radius: 200 }).addTo(mymap);

Açılır pencereler

Bunların hepsi harika, ama ya konum hakkında biraz daha bilgi vermek istersek. Bunu pop-up kullanarak yapıyoruz.

 circle.bindPopup("I am pointing to Point Bonita Lighthouse"); marker.bindPopup("I am pointing to Twin Peaks");

bindPopup yöntemi, belirtilen bir HTML içeriğini alır ve işaretçiye ekler, böylece işaretçiye tıkladığınızda açılır pencere görünür.

React-Leaflet

Artık bir haritanın nasıl oluşturulacağını ve Leaflet ve Vanilla JavaScript kullanarak işaretçilerin nasıl ekleneceğini biliyoruz. Şimdi aynı sonuçları React ile nasıl elde edebileceğimizi görelim. Aynı uygulamayı yapmayacağız, bunun yerine gelişmiş bir uygulama yapacağız.

Bizim için ilk görev, San Francisco Açık Veri portalından bir erişim belirteci almaktır. San Francisco Şehri ve İlçesinden yüzlerce veri seti bulabileceğimiz çevrimiçi bir portal. Bu kaynağı kullanmaya karar verdim, ancak bunun yerine kullanabileceğimiz birçok başka kaynak var.

API Anahtarına Erişim

  1. Bir hesap oluşturun ve portalda oturum açın.
  2. Sağ alttaki yönet bağlantısını tıklayın.
  3. Yeni API Anahtarı Oluştur'a tıklayın ve ona bir ad verin.
  4. Anahtar Kimliğinizi ve Anahtar Sırrınızı kopyalayın. Verilere erişmek için buna ihtiyacınız olacak.

Bunun için, Leaflet haritaları için React-Leaflet – reaksiyon bileşenlerini kullanacağız. Bir tepki uygulaması oluşturalım.

 npx create-react-app react-fire-incidents cd react-fire-incidents

Ardından terminalimizde aşağıdaki komutu çalıştırarak react-leaflet ve Leaflet'i yükleyelim:

 npm install react-leaflet leaflet

App.js

src içinde bir klasör /components oluşturalım. Bileşenlerin içinde Map.js adında bir dosya oluşturalım. Haritamızın yaşayacağı yer burasıdır. Şimdi gereksiz kodu kaldırarak ve react-leaflet axios ve yeni oluşturulan Map.js'den modülleri içe aktararak App.js'yi düzenleyelim.

 import React, { Component, Fragment } from 'react'; import axios from 'axios'; import Map from './components/Map'

App sınıfımızda, durumumuzda olaylar adı verilen bir dizi tanımlayacağız - sayfa yüklendiğinde verilerimizi bu diziye göndereceğiz.

 class App extends Component { state = { incidents: [], } render() { return ( <div> </div> ); } } export default App;

Ardından, bileşen bağlandığında bir GET isteğinde bulunacağız. Uygulama belirtecimiz var, ancak yine de bir uç noktaya ihtiyacımız var. Son noktayı nerede bulacağız?

Portala gidelim ve Verilere Gözat'a tıklayalım. Arama çubuğunda yangın olaylarını arayalım. Ortaya çıkan ilk sonuç, aradığımız şeydir. Bağlantıya tıkladığımızda, sağ üstteki API butonuna tıklayarak URL'yi alabiliriz.

Son noktayı GET isteğimize ileteceğiz ve parametre olarak bir limit ve uygulama belirtecimizi ileteceğiz. Orijinal verilerin binlerce kaydı var, ancak işleri basit tutmak adına 500 ile sınırladık. Olay dizimizi sonuçlarla güncelliyoruz.

Verileri aldıktan sonra durumumuzu güncelliyoruz.

 async componentDidMount() { const res = await axios.get('https://data.sfgov.org/resource/wr8u-xric.json', { params: { "$limit": 500, "$$app_token": YOUR_APP_TOKEN } }) const incidents = res.data; this.setState({incidents: incidents }); };

App.js'miz böyle görünmelidir.

 class App extends Component { state = { incidents: [], } async componentDidMount() { const res = await axios.get('https://data.sfgov.org/resource/wr8u-xric.json', { params: { "$limit": 500, "$$app_token": YOUR_APP_TOKEN } }) const incidents = res.data; this.setState({incidents: incidents }); }; render() { return ( <Map incidents={this.state.incidents}/> ); } } export default App;

Map.js

Bir Broşür haritasının nasıl oluşturulacağını zaten bildiğimiz için bu kısım nispeten kolay olacaktır. Map , TileLayer , Marker , Popup bileşenlerini react-leaflet içe aktaracağız.

 import React, { Component } from 'react' import { Map, TileLayer, Marker, Popup } from 'react-leaflet'

Bir önceki örnekten hatırlarsak, haritayı başlatmak için koordinatlara ve bir yakınlaştırma seviyesine ihtiyacımız var. Map sınıfımızda onları durumumuzda lat , lng ve zoom değişkenlerini kullanarak tanımlarız.

 export default class Map extends Component { state = { lat: 37.7749, lng: -122.4194, zoom: 13, } render() { return ( <div></div> ) } }

Ardından olay dizimizin boş olup olmadığını kontrol edeceğiz. Eğer boşsa “Veri Yükleniyor” diye bir mesaj göndereceğiz; aksi takdirde bir harita döndürürüz.

react-leaflet Map bileşeninde, bazı stiller ile birlikte merkez koordinatlarını ve yakınlaştırma seviyesini geçeceğiz. TileLayer bileşenimizde, önceki örneğimize benzer şekilde atıf ve URL ileteceğiz.

 render() { return ( this.props.incidents ? <Map center={[this.state.lat, this.state.lng]} zoom={this.state.zoom} style={{ width: '100%', height: '900px'}} > <TileLayer attribution='&copy <a href="https://osm.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> </Map> : 'Data is loading...' ) } }

Ardından, props.incident üzerinde döngü yaparız ve her olayın koordinatlarını Marker bileşenine iletiriz. React, bir dizideki her öğeye bir anahtar iletmemiz için bizi uyardığı için, Marker'a da bir anahtar ileteceğiz.

Marker bileşeninin içinde bir Popup bileşenini geçiyoruz. Açılır pencerenin içine olayla ilgili bazı bilgiler ekledim.

 <Map center={[this.state.lat, this.state.lng]} zoom={this.state.zoom} style={{ width: '100%', height: '900px'}}> <TileLayer attribution='&copy <a href="https://osm.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> { this.props.incidents.map(incident => { const point = [incident['point']['coordinates'][1], incident['point']['coordinates'][0]] return ( <Marker position={point} key={incident['incident_number']} > <Popup> <span>ADDRESS: {incident['address']}, {incident['city']} - {incident['zip_code']}</span> <br/> <span>BATTALION: {incident['battalion']}</span><br/> </Popup> </Marker> ) }) } </Map>

Ve işte bu. Uygulamamızı çalıştırırsak ve her şey yolunda giderse, yangın olaylarının yerlerini bize gösteren 500 işaretli bir San Francisco haritasını görebiliriz. Bu işaretçilerden birine tıklarsak, olay hakkında daha fazla bilgi içeren bir açılır pencere belirecektir.

Toplama

Çok şey anlatmış olsak da, bu sadece temel bilgilerdi. Broşür çok güçlü bir araçtır ve birçok farklı türde harita oluşturabiliriz. Oynamak istiyorsanız, başka bir katman veya özel bir simge eklemeyi deneyin. Veya etkileşimli bir Choropleth Haritası oluşturmak isteyebilirsiniz.