お久しぶりです。地図とグラフが好きな溝畑です。
OpenLayers2は、JavaScript Mapping Libraryです。
地図を描画したり、画像を描画したり...。
主な用途は地図となると思います。
あとは、OpenLayers3なんかもリリースされて数年が経っていますが、
OpenLayers2 → 3は書き方がかなり変わっている模様。
まだあまり試せていないのが現状です。
OpenLayers2、OpenLayers3ともに公式のサンプルが豊富で、そこを見るだけでも、
大体のやりたいことはできてしまいます。
さて本題ですが、今回はOpenLayers2で地図に線を引いていきます。
地図を描画する
まずは地図を描画しないことには始まりません。OpenLayers2と一部jQuery使っていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
var Map = { init: function () { this.olmap = null; // 投影法 this.projMerc = new OpenLayers.Projection('EPSG:3857'); this.Proj4326 = new OpenLayers.Projection('EPSG:4326'); }, /** * 地図を表示 * @param {String} id_name 地図を表示する要素のID */ render: function (id_name) { // レイヤー var layers = [ // OpenStreetMap new OpenLayers.Layer.OSM('osm', null, { displayInLayerSwitcher: true }) // 他にも追加したい場合は追加していく ]; // コントロール var controls = [ new OpenLayers.Control.Navigation(), // 地図周回させたい場合は入れておく new OpenLayers.Control.PanZoomBar(), // ズームバー表示 new OpenLayers.Control.LayerSwitcher(), // レイヤーの切り替え new OpenLayers.Control.MousePosition() // マウスの位置を表示 ]; // 描画 this.olmap = new OpenLayers.Map(id_name, { projection: this.projMerc, displayProjection: this.proj4326, controls: controls, layers: layers, units: 'm' }); // 地図の中心を移動 var lonlat = new OpenLayers.LonLat(135.188, 34.685); this.olmap.setCenter(lonlat.transform(this.proj4326, this.projMerc), 14); } }; $(function () { Map.init(); }); $(window).load(function () { Map.render('olmap'); }); |
投影法はEPSG3857・EPSG4326で調べてみてください。
ここまでで、神戸〜三ノ宮中心の地図が表示されたはずです。
線と点を描画する
神戸付近の地図を出したので、神戸→元町→三ノ宮を結んでみたいと思います。位置情報はAjaxで取ってくるようなことが想定されますが、今回は直接用意しちゃいます。
1 2 3 4 5 |
var plot_data = [ { Longitude: 135.17830, Latitude: 34.67822 }, // 神戸 { Longitude: 135.18688, Latitude: 34.69029 }, // 元町 { Longitude: 135.19324, Latitude: 34.69227 } // 三ノ宮 ]; |
実際に描画してみます。
ボタンをクリックしたら、描画するみたいなのを想定。
さっきの地図を描画したものに追記していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
var Map = { init: function () { // ... // ボタン this.$plot_btn = $('#plot-btn'); // FeatureStyle 線とか、点のスタイル this.feature_style = { fillColor: '#98FB98', fillOpacity: 0.8, strokeColor: '#3CB371', strokeWidth: 2, pointRadius: 6 }; this.events(); }, events: function () { this.$plot_btn.on('click', this.plot.bind(this)); }, render: function (id_name) { // ... }, /** * 投影法の変換 * @param {Object} lonlat */ transformPoint: function (lonlat) { return lonlat.transform(this.proj4326, this.olmap.getProjectionObject()); }, /** * Point生成 * @param {Number} lon * @param {Number} lat */ createPoint: function (lon, lat) { return new OpenLayers.Geometry.Point(lon, lat); }, /** * 線を描画 */ plot: function () { var points = []; var line_data = []; $.each(plot_data, function (key, val) { var point = this.transformPoint(this.createPoint(val.Longitude, val.Latitude)); // 線を引くためのGeometry.Pointの配列を作る line_data.push(point); // 点を作る points.push(new OpenLayers.Feature.Vector(point, null, this.feature_style)); }.bind(this)); // 線を作る var line = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(line_data), null, this.feature_style); var point_layer = new OpenLayers.Layer.Vector('point_layer', null); var line_layer = new OpenLayers.Layer.Vector('line_layer', null); // レイヤーにFeatureを追加 point_layer.addFeatures(points) line_layer.addFeatures([line]); // 作成したVector Layersをolmapに追加 this.olmap.addLayers([line_layer, point_layer]); } }; |
これで各点と点を結んだ線が描画できたかと思います。
今回のサンプル
サンプルは線の削除も付けてみました。
線を作る場合は、OpenLayers.Geometry.Point
したものの配列をOpenLayers.Geometry.LineString
に渡すこと。
実際に表示するものにはnew OpenLayers.Layer.Vector
をかけてあげること。
あとは、普段は「緯度・経度」の順で言葉にすることが多いので、間違えやすいのですが、
new OpenLayers.Geometry.Point
の引数は「経度・緯度」の順番です。
(サンプルではcreatePointの中)
描画するものを作ったら、描画するためのレイヤーを作る必要があります。
そこがnew OpenLayers.Layer.Vector('layer_nam', null);
の部分です。
Vectorを描画していくので、これを使います。
addFeatures()
でレイヤーに描画するFeatureを追加。
今回はそれぞれ分けていますが、1つのレイヤーに入れてしまっても問題ありませんが、
点毎にツールチップを出したい!となると、分けておく方が無難だと思います。
最後に、↑のサンプルだとthis.olmap
にこのレイヤーを追加してやるとOKです。
線の描画には罠が...
今回は描画できることを確認するまでなので、これで良いのですが、例えば「世界を一周するような線を描きたい!」となったときに、このままでは少し問題が出てきます。
主に東経→西経・西経→東経・北緯→南緯・南緯→北緯を跨ぐときに絡む問題なのですが、長くなりそうなので、次回。
世界を一周する線を引く(何も考慮していない場合)
何も考慮せずに引くと、こうなっちゃいます。
180度の辺りで、超えたいのに線が戻っちゃってますね。点は問題なく描画されているのに...。

次回はこれを解決してみます。
キー・ポイントでは、ブラウザで地図やグラフを書いて、
自由にぐりぐりしたいエンジニアを募集しています。
・2017新卒の方はリクナビ2017へ(タイムリーに書類選考 受付中!)
・中途の方はコチラへ