現在、弊社でもSlackを試験的に利用しているのですが、RTM APIを使えばローカルでもbotが作成できることを知ったのでPythonで作ってみようという記事です。
今回はついに最終回です。
Tag / Python
PythonでSlackbotを作る(3)
現在、弊社でもSlackを試験的に利用しているのですが、RTM APIを使えばローカルでもbotが作成できることを知ったのでPythonで作ってみようという記事です。
今回は第3回目です。
PythonでSlackbotを作る(2)
現在、弊社でもSlackを試験的に利用しているのですが、RTM APIを使えばローカルでもbotが作成できることを知ったのでPythonで作ってみようという記事です。
今回は第2回目です。
PythonでSlackbotを作る(1)
現在、弊社でもSlackを試験的に利用しているのですが、RTM APIを使えばローカルでもbotが作成できることを知ったのでPythonで作ってみようという記事です。
今回は第1回目です。
PostGISとGeoDjangoを使ってLeafletでGeoJSON Tile Layerを表示してみる(5) – GeoDjangoでTiled GeoJSONを出力する –
前回でようやく、PostGISに登録されているデータをGeoDjango経由でGeoJSONに出力してブラウザ上でLeafletを使って地図上に表示されるところまでできました。ところがどっこいデータ量が多いとモッサリしすぎて使いものにならないときたもんだ。ああ困ってしまった。ということで「それ、Tiled GeoJSONにすればいいじゃん?」という最終回です。
GeoDjangoでTiledなGeoJSONを出力する
実はですね、django-geojsonにはTiledGeoJSONLayerViewがいるんですよ。え? 知ってた? そんなキミの都合は知らんがな、これ使うようにするのにどんだけ苦労したと思ってんだ。いや、あんまりしてないけどね。
URLマッピングの定義変更
Tile用のURLマッピングを追加します。ちなみにこのワイルドカードでの指定、公式のサンプルの形式だと動きません。
vi api/urls.py
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from djgeojson.views import GeoJSONLayerView
from demo.models import Border
from api import views
urlpatterns = patterns('',
url(r'^v1/borders.geojson$',GeoJSONLayerView.as_view(model=Border), name='borders'),
url(r'^v2/borders/(\d+)/(\d+)/(\d+).geojson$',
views.BorderTiledLayer.as_view(model=Border), name='tiledborders'),
)
続いてTiledGeoJSONLayerViewを継承したBorderTiledLayerクラスを定義します。
vi api/view.py
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from demo.models import Border
from djgeojson.views import TiledGeoJSONLayerView
class BorderTiledLayer(TiledGeoJSONLayerView):
# Options
srid=4612
trim_to_boundary=False
properties=('n03_001','n03_003','n03_004','n03_007')
直接呼んでもいいのですがオプションが多いので継承した方がシンプルです。因みにオプションの「trim_to_boundary」をFalseにしないと動かなかったのです、これも罠です。
さて、今度は、クライアント側のTile対応です。
Leaflet GeoJSON Tile Layerのダウンロード
Djangoだけでなく、Leafletもプラグインが存在しています。そして今回は「Leaflet GeoJSON Tile Layer」というその名の通りのプラグインを使います。
上記サイトから「TileLayer.GeoJSON.js」を取得して以下のように配置します(何度も言いますがお好みでよいのですが)。
$ tree -c leaflet-demo/
leaflet-demo/
├── js
│ ├── jquery-2.1.1.min.js
│ ├── TileLayer.GeoJSON.js
│ ├── leaflet.js
│ └── leaflet-src.js
├── index.html
├── css
│ └── leaflet.css
└── images
├── layers-2x.png
├── layers.png
├── marker-icon-2x.png
├── marker-icon.png
└── marker-shadow.png
index.htmlをこんな内容で改造(「TileLayer.GeoJSON.js」のREADME.mdのまま)
<!DOCTYPE html>
<html>
<head lang="ja">
<meta charset="UTF-8">
<title>Leafletテスト</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/leaflet.css" />
</head>
<body>
<div id="map" style="width: 960px; height: 600px"></div>
<script src="js/leaflet.js"></script>
<script src="js/jquery-2.1.1.min.js"></script>
<script src="js/TileLayer.GeoJSON.js"></script>
<script>
var map = L.map('map');
L.tileLayer('https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png', {
maxZoom: 30,
attribution: 'Map data © ' +
'<a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'examples.map-i875mjb7'
}).addTo(map);
map.setView([35.85556, 139.65117], 15);
var style = {
"clickable": true,
"color": "#00D",
"fillColor": "#00D",
"weight": 1.0,
"opacity": 0.3,
"fillOpacity": 0.2
};
var hoverStyle = {
"fillOpacity": 0.5
};
var geojsonURL = 'http://192.168.1.15:8000/api/v2/borders/{z}/{x}/{y}.geojson';
var geojsonTileLayer = new L.TileLayer.GeoJSON(geojsonURL, {
clipTiles: true,
unique: function (feature) {
return feature.id;
}
}, {
style: style,
onEachFeature: function (feature, layer) {
if (feature.properties) {
var popupString = '<div class="popup">';
for (var k in feature.properties) {
var v = feature.properties[k];
popupString += k + ': ' + v + '<br />';
}
popupString += '</div>';
layer.bindPopup(popupString);
}
if (!(layer instanceof L.Point)) {
layer.on('mouseover', function () {
layer.setStyle(hoverStyle);
});
layer.on('mouseout', function () {
layer.setStyle(style);
});
}
}
}
);
map.addLayer(geojsonTileLayer);
</script>
</body>
</html>
</body>
</html>
それではブラウザで開いてみましょう。
はいキタ━(゚∀゚)━! もうサックサクじゃないですかー。ついでにマウスオーバースタイルとかポップアップまでできちゃってますよー。すごい。もう感動しますわ。マジで。
とはいえ、流石にズームを引いていくと取得するTile数が増えるのでサーバ側が悲鳴を上げると思いますし、クライアント側の描画も辛くなっていくと思います。その辺りはまだまだ改善の余地があります。また、GeoDjangoは当然空間検索ができるのでそういうった機能と組み合わせていくと楽しいかなと思います。それではみなさんよいクリスマスをお過ごしください。

