Kartograph.js: 2. Bölüm Etkileşimli Haritalar

Merhabalar,

Geçtiğimiz hafta temel anlamda Kartograph kütüphanesi nasıl kurulur, kullanılır konusuna değinmiştim. Bu hafta başladığımız çalışmaya devam ederek haritalar üzerinde bilgi balonları çıkarma ve bar grafikler çizme konusuna değineceğim.

Etkileşimli Haritalar

İlk örneğimiz bölgelerin üzerine gelindiğinde ufak bir bilgi balonu çıkarmak olacak. Bunun için Jquery QTip2 eklentisine ihtiyaç duyuyoruz. Geçtiğimiz hafta içi QTip2 projesinin stabil sürümü jquery’nin son sürümü ile sorunlu çalıştı bu yüzden nightly build indirmenizi tavsiye ediyorum.

Qtip2’yi indirdikten sonra aşağıdaki satırları html kodunuza eklemeniz gerekmektedir.

<link href="/s/css/jquery.qtip.min.css" rel="stylesheet" media="screen">
<script type="text/javascript" src="jquery.qtip.min.js"></script>


Şimdi sıra geçtiğimiz hafta katman eklemek için kullandığımız addLayer fonksiyonunu değiştirmeye geldi.

map.addLayer('countries', {
    styles: {
        fill: '#abc',
        stroke: '#fff'
    },
    chunks: 50,
    tooltips: function(data) {
        return "Merhaba Dünya";
    }
});


addLayer fonksiyonun da kullandığımız tooltip ifadesi fare ile svg path elemanın üzerine gelindiğinde görüntülenmesi istenen değeri döndüren bir fonksiyondur. İlk aşamada sadece “Merhaba Dünya” ifadesini döndürecektir, data parametresinden birazdan bahsedeceğim.

İlk bilgi balonumuz şöyledir.

popupHelloWorld

Eğer bu görüntü hoşunuza gitmediyse, bootstrap desteğini de kullanmamız mümkün. Bunu yapmak için aşağıda ki kodları loadMap fonksiyonundan önce ekleyiniz.

$.fn.qtip.defaults.style.classes = 'qtip-bootstrap';
$.fn.qtip.defaults.style.def = false;


popupHelloWorld2

Ufak bir not, balonlar içinde html taglerini kullanmanızın mümkün olduğunu belirteyim.

Evet ilk aşamayı böylece tamamlamış bulunuyoruz. Peki bilgi balonlarında gösterilecek bu verileri SVG içersinden nasıl çekeceğiz, daha da önemlisi bu bilgileri SVG içersine nasıl ekleyeceğiz?

Öncelikle daha kısa olduğu için SVG içersinden nasıl veri çekebileceğimizden bahsetmek istiyorum. Yapmamız gereken tek şey tooltips için tanımladığımız fonksiyonun data parametresini kullanmak olacaktır. Bu data parametresin ile SVG içersinde bulunan path elemanına ait attributelere erişmemiz mümkün. Örnek olarak üzerine gelindiğinde ülke isimlerini listelemek istersek yapmamız gereken kodu aşağıda ki gibi değiştirmek olacaktır.

tooltips: function(data) {
    return data.name;
}


popupHelloWorld3

Şimdi sırada istediğimiz bilgileri içersinde barındıran SVG’ler üretmeye geldi. Bu işi yapmak için bir önceki yazıda kullandığımız kartograph.py kütüphanesini kullanacağız. Geçen yazıda kullandığımız json dosyasının içeriğinde ufak bir değişiklik yapıyoruz ve iki anahtar ifade daha ekliyoruz, “charset” ve “attributes”. World.json dosyamızın içeri şu şekildedir.

{
    "layers": [{
        "id"         : "countries",
        "src"        : "ne_50m_admin_0_countries.shp",
        "charset"    : "utf-8",
        "attributes" : "all"
    }],
    "export": {
        "width" : 1000
    },
    "styles": {
        "fill"  : "#dfdcdc",
        "stroke": "#fff"
    }
}


İlk aşamada kaynak dosyasının içeriğini bilmediğimizi varsayarak tüm bilgileri SVG’ye ekleyelim. Bunun için attribute anahtar kelimesine “all” değerini vermemiz yeterli. “charset” ile SVG içersine yazılacak bilgilerin hangi encoding kullanılarak yazılacağını belirtiyoruz. Json dosyamızda gerekli değişiklikleri yaptıktan sonra kartograph.py’i çalıştırıyoruz.

kartograph world.json -o world-detailed.svg


Elde edilen yeni SVG dosyası yaklaşık 300kb daha büyük oldu. Bu SVG içerinde hangi attributelar olduğunu öğrenmek için aşağıdaki basit python betiği kullanabiliriz.

from xml.dom import minidom
svgFile = 'world-detailed.svg'
xmldoc = minidom.parse(svgFile)
paths=xmldoc.getElementsByTagName('path')
p=paths[0] # sadece ilk elemana bakalım.
attr=p.attributes
for k in attr.keys():
    if k <> 'd':
        print k, '=',attr.get(k).value


Bu betik ilk path elemanı üzerinde tanımlanmış attribute ve değerlerini listeliyor.  Betik sadece fikir vermesi için hazırlanmıştır. d attributeu bu aşamada işimize yaramayacağı için atlanmıştır. Betiğin ekran çıktısı şu şekildedir.

data-adm0-a3-is = ABW
data-mapcolor13 = 9.0
data-su-dif = 0.0
data-sovereignt = Netherlands
data-wb-a3 = ABW
data-fips-10 =
data-admin = Aruba
data-pop-year = -99.0
data-geou-dif = 0.0
data-lastcensus = 2010.0
data-economy = 6. Developing region
data-gdp-year = -99.0
data-tiny = 4.0
data-sov-a3 = NL1
data-adm0-a3-us = ABW
data-iso-n3 = 533
data-mapcolor8 = 2.0
data-mapcolor9 = 2.0
data-subregion = Caribbean
data-un-a3 = 533
data-abbrev = Aruba
data-formal-fr =
data-abbrev-len = 5.0
data-adm0-a3-wb = -99.0
data-homepart = -99.0
data-name-sort = Aruba
data-adm0-a3-un = -99.0
data-featurecla = Admin-0 country
data-subunit = Aruba
data-long-len = 5.0
data-income-grp = 2. High income: nonOECD
data-region-un = Americas
data-brk-name = Aruba
data-adm0-dif = 1.0
data-name-alt =
data-adm0-a3 = ABW
data-postal = AW
data-brk-diff = 0.0
data-brk-a3 = ABW
data-name = Aruba
data-name-long = Aruba
data-gdp-md-est = 2258.0
data-scalerank = 3
data-iso-a3 = ABW
data-iso-a2 = AW
data-su-a3 = ABW
data-labelrank = 5.0
data-geounit = Aruba
data-brk-group =
data-gu-a3 = ABW
data-woe-id = -99.0
data-pop-est = 103065.0
data-mapcolor7 = 4.0
data-note-brk =
data-wb-a2 = AW
data-continent = North America
data-type = Country
data-note-adm0 = Neth.
data-formal-en = Aruba
data-region-wb = Latin America & Caribbean
data-wikipedia = -99.0
data-name-len = 5.0
data-level = 2.0


Bu bilgilere tooltips için tanımladığımız fonksiyonunun data parametresi üzerinden erişmemiz mümkün.

Harita Üzerinde Bar Grafiği Göstermek

Bilgi balonları konusunu tamamladıktan sonra şimdi sıra haritalar üzerinde çeşitli olay yoğunluklarını özetlemek için yaygın olarak kullanılan bar grafiklerine geldi. Bu tip grafikleri çizmeden önce haritalar üzerinde basit işaretleri nasıl koyacağımızdan bahsedelim. Örnek olarak Türkiye sınırları içersinde bir nokta ve bu noktaya bir bilgi balonu ekleyelim.

function drawPoint(map, x, y) {
    x = -1 * x;
    var c = new Array(x, y);
    var bar = map.addGeoPath([c, c]);
    bar.attr({
        stroke: '#FF0000',
        opacity:.75,
        'stroke-width': 5,
        fill: '#FF0000',
        'stroke-linecap': 'round'
    }); /* stroke-linecap için tanımlı değerler: butt, round, square, inherit */

    if (Raphael.svg) {
        /* Bilgi Balonu için kullanılan kod bölümü */
        setTimeout(function() {
            $(bar.node).qtip({
                content: {
                    title: 'Baslik',
                    text: 'x: ' + x + ' y: ' + y
                },
                position: {
                    target: 'mouse',
                    viewport: $(window),
                    adjust: { x:7, y:7}
                }
            }, 0);
        });
    } else {
        bar.attr('path', map.getGeoPathStr(pts));
    }
}

Bu fonksiyonu addLayer fonksiyonundan sonra drawPoint(map, 40, 40); şeklinde çağırdığımızda aşağıda ki ekran görüntüsünü elde ediyoruz.
pointWithPopup
parametre olarak x için 40 vermemize rağmen -40 olmasının sebebi kullanılan koordinat sistemlerinin farklı olmasıdır. Ayrıntılara sonraki yazılarda değinmeye çalışacağım.
Kodu kısaca açıklayalım.
  • var c = new Array(x, y); ile bir koordinat ikilisi olusturuyoruz. Daha sonra bu duzlemde gosterilecek noktamızı var bar = map.addGeoPath([c, c]); komutu ile sisteme ekliyoruz. Bu fonksiyon parametre olarak çizilecek şekil koordinatlarını alıyor. En az iki nokta tanımlamamız gerekmekte, nokta olduğu için tanımlanan iki noktada birbirinin aynısı oluyor. Öteyandan bu fonksiyona birden fazla koordinat vermenizde mümkün.
  • noktamızı olusturduktan sonra görsel özelliklerini belirlemek için bar.attr() fonksiyonunu kullanıyoruz. Bu fonksiyonun özelliklerinden vurgulamam gereken sadece “stroke-linecap” olduğunu düşünüyorum. Bu değer konulacak olan noktanın şeklini belirlemeye yarıyor ve alabileceği değerler ise “butt, round, square, inherit” olarak tanımlıdır.
  • Devamında ki bölümde ise qtip kullanarak konulan nokta için bilgi balonu tanımlanıyor.

Noktanın nasıl ekleneceğini gördükten sonra bunu bir bar haline getirmek için yapmamız gereken tek şey, noktayı tanımlamak için kullandığımız koordinatlardan ikincisini istenilen büyüklüğe uygun olacak koordinatı hesaplamak ve çizdirmek olacaktır. Örnek kodu aşağıda ki gibi güncellemediğimizde  bu ekran görüntüsünü elde edeceğiz.

drawPoint(map, 42, 38.42);

// drawPoint fonksiyonun içini aşağıdaki gibi güncelleyiniz.

var c = new Array(x, y);
var d = new Array(x+0.6, y+4);
var bar = map.addGeoPath([c, d]);

barWithPopup

Burada örnek olması için verdiğimiz değerlerin oluşturduğunuz haritalara göre otomatik hesaplanabiliyor olması gerekmektedir. Bu konuya ilerleyen yazılarda değineceğim.
Umarım faydalı bir yazı olmuştur.
İyi haftalar,
Gürcan
Tagged with: , ,
Posted in yakindanegitim

Kartograph.js: 1. Bölüm Nedir ve Nasıl Kullanılır

Merhabalar, bu hafta kartograph kutuphanesinin kullanımından bahsedeceğim.

Kartograph Nedir? 

Bu kütüphane etkileşimli haritalar yaratmak için kullanılan basit ve hafif bir sistemdir. Temelde 2 kütüphaneden oluşmaktadır. Bunlar kartograph.py ve kartograph.js‘dir. Birincisi istediğiniz özelliklerde SVG haritaları hazırlamanıza imkan sağlarken, diğeri ise hemen hemen bilindik tüm internet tarayıcılarında çalışan etkileşimli haritalar hazırlamanızı sağlar.

Merhaba Dünya

Bu link üzerinden aşağıdaki örneğe erişebilirsiniz. Github üzerinden tüm projeyi bilgisayarınıza çekmenizi tavsiye ederim. Şimdi aşağıda ki kodu inceleyelim.

<!DOCTYPE html>
<html>
<head>
<script src="../lib/jquery.min.js"></script>
<script src="../lib/raphael-min.js"></script>
<script src="../kartograph.min.js"></script>
<script type="text/javascript">
    $(function() {
        var svgLayer='countries';
        var map = Kartograph.map('#map');
        map.loadMap('svg/world.svg', function() {
            map.addLayer(svgLayer, {
                styles: {
                    fill: '#abc',
                    stroke: '#fff'
                },
                chunks: 50,
                done: function() {
                    map.getLayer(svgLayer).style('fill', '#789');
                }
            });
        });
    });
    </script>
</head>
<body>
    <div id="map"></div>
</body>
</html>

  • Öncelikli olarak gerekli kütüphaneleri ekliyoruz. Bunlar JQuery, Raphael ve Kartograph.js.
  • Daha sonra ilk işimiz haritanın gösterileceği div elemanı ile ilişkilendirilmiş map nesnesini yaratmak.
    var map = Kartograph.map(‘#map’); ifadesi ile bu işlemi yapıyoruz.
  • Şimdi sırada ilgili svg’nin seçilmesi var. Bu işlemi loadMap fonksiyonu ile yapıyoruz. Buradaki önemli ayrıntı görüntülemek istediğiniz katmanların(layer) map nesnesine eklenmesidir. Aksi halde tarayıcınızda herhangi bir şey göremeyeceksiniz.
    Esas problem elimizde bulunan svglerde hangi katmanların mevcut oldugunu bilmektir. Bunu belirlemenin en ilkel yöntemi herhangi bir text editor yada more komutu ile svg dosyasını açıp svg group elemanlarını aramak olacaktır. Bir başka deyişle g tag’i bulunan <g class=”” id=”countries”> gibi ifadelere bakmaktır.Bir başka yöntem olarak aşağıdaki gibi ufak bir python betiği ile grupların id’lerini listeleyebiliriz.

    from xml.dom import minidom<
    svgFile = 'world.svg'
    xmldoc = minidom.parse(svgFile)
    svgGroups = xmldoc.getElementsByTagName('g')
    for g in svgGroups:
        print g.getAttribute('id')
    


    Eminim daha kolay yöntemleri mevcuttur fakat Gimp yada Inkscape tarzı araçlarla pek haşır neşir olmadığım için bu yöntemler daha kolay geliyor. 🙂

  • Katmanlarımızı belirlediğimize göre addLayer fonksiyonuna geçebiliriz. Bu fonksiyon ile hangi katmanların yükleneceğinin yanısıra bu katmanların nasıl ve hangi özelliklerle yükleneceğini de belirleyebiliyoruz. Bunun için kullanacağımız bazı parametreler mevcut. Bu aşamada bizim için önemli olan ifade chunks:50’dir. Bu ifade sayesinde haritalar bütün olarak değilde küçük parçalar halinde yüklenir. Bu da tarayıcının büyük haritalarla çalışırken donmasını engeller.
  • Son olarak done ifadesi gelir. Bu da yükleme işlemi tamamlandığında verilen fonksiyonu çağırır.

Daha ayrıntılı bilgi için projenin dökümantasyonuna buradan ulaşabilirsiniz.

İlk ekran görüntümüz:
world-1
Bu ayrıntılar benim için yeterli değil diyenler için bir sonraki adıma geçiyoruz. Kartograph.py kullanarak daha ayrıntılı bir harita olusturacağız ve kodu güncelleyip tekrar çalıştıracağız. Eğer ayrıntılı bir haritaya ihtiyacınız yoksa yazıyı burada bitirebilirsiniz.

Kartograph.py

Bu yazıda sadece Ubuntu üzerine nasıl kurulum yapılacağından bahsedeceğim. Ubuntu kullanmıyorsanız bu linkleri okuyunuz. Windows, Mac OS X

  • Önce gerekli paketleri kuralım:

    sudo apt-get install libxslt1-dev python-dev python-shapely python-gdal python-pyproj python-pip

  • Şimdi Github üzerinden kartograph.py’i kuralım:

    sudo pip install https://github.com/kartograph/kartograph.py/zipball/master -r https://raw.github.com/kartograph/kartograph.py/master/requirements.txt

  • Kurulum işlemi tamamlandıktan sonra svg’yi oluşturmak için kullanacağımız harita detaylarını indirmemiz gerekmektedir:

    mkdir ~/kartograph-test cd ~/kartograph-test
    wget http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/cultural/ne_50m_admin_0_countries.zip
    unzip ne_50m_admin_0_countries.zip

  • Bu işlemden sonra svg ve indirdiğimiz shape dosyası arasında bağ kuracak olan json dosyasını oluşturuyoruz:

    {
        "layers": [{
            "id" : "mylayer",
            "src": "ne_50m_admin_0_countries.shp"
        }],
        "export" : { "width" : 1000 },
        "styles" : { "fill": "#dfdcdc", "stroke": "#fff" }
    }

  • addLayers içersinde kullandığımız styles ifadesini burada da tanımlayabiliyoruz. Ayrıca oluşturulacak svg dosyasının genişlik yükseklik gibi ifadelerini de tanımlamamız mümkün. Örnekte olduğu gibi sadece genişlik yada sadece yükseklik verildiğinde diğer özellik otomatik olarak hesaplanmaktadır. Ayrıca bir başka ayrıntı ise katmanların id değerlerinin belirlenmesi. Bu örnekte “mylayer” değerini verdik. Eğer burada id tanımı yapılmasaydı, id değeri “layer_0” olarak atanacaktı.
    Ayrıntılı bilgi için bu linki kullanabilirsiniz.
  • Json dosyamızda hazır olduğuna göre artık svg dosyamızı oluşturabiliriz. Bunu yapmak için:
    kartograph world.json -o world.svg
  • Bu işlemde tamamlandıktan sonra yukarıda açıkladığımız ilk örnekte bulunan var svgLayer değişkeninin değerini mylayer olarak değiştirip sayfayı tekrar açtığımızda aşağıda ki ekran görüntüsünü elde etmiş oluruz.

world-2

Özellikle bu konuya benim gibi yeni başlayanlar için faydalı olacağını umuyorum.
Not: Sitesinde bulunan örneklere bu linkten ulaşabilirsiniz.
İyi haftalar,
Gurcan
Tagged with: , ,
Posted in yakindanegitim

Yakından Eğitim – Malwarez

1. dönem Yakından Eğitim projelerinden “Kötü Amaçlı Yazılım Görsellemesi: Malwarez” projesinde çalışmaya hak kazandım.

Yakından Eğitim projesinin temel hedefi Özgür Yazılım dünyasına geliştiriciler kazandırırken, alanında uzman kişilerle tanışma ve çalışma imkanı sunmaktır. Bu yüzden yerel GSoC olarak tanımlayanlar da mevcut. Usta Çırak ilişkisini temel alan bu çalışmada katılımcılar özgür yazılım geliştirme süreçlerini daha yakından tecrübe etme imkanı yakalıyorlar. Bu açıdan bu projeyi düzenleyen ve projede emeği geçen herkese teşekkür etmek istiyorum. Umarım bundan sonraki dönemlerde de proje büyüyerek daha fazla kişiye ulaşabilir.

Projenin amacı ve yöntemi hoşuma gittiği için yakından eğitime katılmak ve katkı vermek istedim. Bu çalışma sayesinde hem özgür yazılım geliştirme süreçlerini daha iyi anlayabileceğime hem de danışmanlık süreçlerini yakından takip edebileceğime inanıyorum.

Malwarez projesine gelecek olursak. Bu projeyi seçmemde iki temel sebep vardı, Honeypot ve Görselleştirme. Son zamanlarda vakit ayırmak istediğim bu konuları bir projede görmek karar vermemi oldukça kolaylaştırdı. Proje kapsamında başlıca hedefimiz zararlı yazılım aktivitelerinin kolay kullanıma sahip bir arayüz yardımıyla Dünya haritası üzerinde görselleştirilmesidir.

Bu aktivitelerin görselleştirilmesi için kullanacağımız yöntemler kısaca şöyledir. Lokasyona bağlı olarak zararlı yazılımların tespit haritası, zararlı yazılımların yoğunluğuna bağlı sıcaklık haritası ve saldırı/hedef merkezlerinin görsel tespitini kolaylaştıracak ilişki haritası olarak bahsedilebilir. Ayrıca görsellenen bu veriler ile ilgili zamana bağlı grafikler, istenilen zararlı yazılımlar hakkında tespit edilme oranları ve ne tür zararlı yazılım gruplarına girdiği gibi daha detaylı bilgileri de kullanıcıya sunmayı hedefliyor olacağız.

Temel olarak proje için kullanılacak teknolojileri Javascript (kartograph, socket.io, jquery) ve Django olarak özetleyebiliriz.

Bundan sonraki süreçte projeyle ilgili gelişmeleri burada yazıyor olacağım.

Bu 2 ayın projedeki herkes için eğlenceli geçmesi dileğiyle 🙂

İyi haftalar,
Gürcan

Tagged with: ,
Posted in yakindanegitim
Archives