openlayers 3 OSM layers (OSM, Humanitarian, Stamen (Terrain/Toner/Watercolor))

すまぬ、タイトルどうつけていいもんか珍しく悩んでそのまま。

まぁこういうことだ:

METAR Search (with simple parsing)ってさ、地図は主役ではないとはいえ…、地図そのものに情報量が多過ぎるとマーカが識別しにくいのな。なのでなんか白地図的なものとかそういった、「見やすい」(ゴテゴテしてない)もので、API キーやらアカウント登録やらがいらないもんてないのかしらね、と思って。

OpenLayers 2 だった頃は「出来合いのレイヤー」的な結構な量のものと LayerSwitcher が用意されてて苦労しなかったんだけど、OpenLayers 3 のほうって、なんか情報がとっ散らかってんのかしら、出来るんだか出来ないんだかすぐにはわからない。あと「LayerSwitcher が消えてなくなってるー」と皆大騒ぎしてる。ので多分出来ないんでしょう。アタシは動画でみての通り、普通にプルダウン作って切り替えてるだけ。(removeLayer、addLayer で。)

先に OpenStreetMap 本家公式トップページの解析からやってた。うぅ、構造が難しくてよくわからない。辛うじて「Humanitarian」が API キー的なものなしで使えて、普通に XYZ タイルであることが理解出来た。attribution も猿真似れば、Humanitarian レイヤーの構築はこんな:

 1     var layerHumanitarian = new ol.layer.Tile({
 2       source: new ol.source.XYZ({
 3         attributions: [
 4           new ol.Attribution({
 5             html: '&copy; <a href="https://www.openstreetmap.org/copyright">' +
 6                 'OpenStreetMap contributors</a>. <br/>' +
 7                 'Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">' +
 8                 'Humanitarian OpenStreetMap Team</a>'
 9           })
10         ],
11         url: 'https://tile-{a-c}.openstreetmap.fr/hot/{z}/{x}/{y}.png'
12       }),
13       name: 'Humanitarian'
14     });

「XYZ で出来る」とわかったからこうしてるだけで、実は predefined なものがあったりするのかも、と思ったりはする。

でほかにもないかなぁと色々探ってるうちに、ベストなサイト発見。

なんか若干重たいサイトな気がすんだけど、ともあれサンプルは非常にわかりやすい。でこのなかで「Stamen」を使ってた。あー、これは見やすいなぁ、と。そしてこれらも API キーとかいらない。あと attributions も ol.source.Stamen が勝手に補ってくれる:

 1     //
 2     var layerTerrain = new ol.layer.Tile({
 3       source: new ol.source.Stamen({
 4         layer: 'terrain'
 5       }),
 6       name: 'Terrain'
 7     });
 8     //
 9     var layerToner = new ol.layer.Tile({
10       source: new ol.source.Stamen({
11         layer: 'toner'
12       }),
13       name: 'Toner'
14     });
15     //
16     var layerWatercolor = new ol.layer.Tile({
17       source: new ol.source.Stamen({
18         layer: 'watercolor'
19       }),
20       name: 'Watercolor'
21     });

Watercolor はなんかネタにも思えるけど見やすいことは見やすい。Terrain が好きだが、Toner も悪くない。

あとはこれらを「切り替える」コードを自分でまかなわないといけないので(たぶん)、使いやすいように辞書に名前とレイヤーのインスタンスをぶっこんでおく:

1     var layersByName = {
2       OSM: layerOSM,
3       Watercolor: layerWatercolor,
4       Humanitarian: layerHumanitarian,
5       Toner: layerToner,
6       Terrain: layerTerrain
7     };

こっから先は普通どおりに:

 1     var map = new ol.Map({
 2       target: 'map',
 3       layers: [
 4         layersByName["Terrain"]
 5       ],
 6       view: new ol.View({
 7         center: ol.proj.fromLonLat([initial_center_lon, initial_center_lat]),
 8         zoom: 7
 9       })
10     });

で、プルダウンを作っておいて、そのイベントリスナで:

 1     $(document).ready(function() {
 2 
 3         // osmlayers という id の <select> がいるとして。
 4         $("#osmlayers").on("change", function(e) {
 5             map.getLayers().forEach(function(layer, i) {
 6               map.removeLayer(layer);
 7             });
 8             map.addLayer(layersByName[this.value]);
 9           });
10     // ...

ちなみに「削除して追加する」はいっけん非合理にみえるけれど、スタック的に全部積んでおいて、表示非表示を(z-order制御で)切り替えるアプローチはやってみればわかるけれど結構不愉快な振る舞いをする。つまり初期表示で「いったん一瞬全部みえちゃう」とか色々。



Related Posts