【OpenLayers 6】複数のテキストを配置する

はじめに

 マップ上にテキストを配置したいと思うシチュエーションは度々あります。今回はまず、マップ上にテキストを配置する方法について説明した後、複数のテキストを配置する方法について説明したいと思います。

テキストをマップに配置する方法

 テキストをマップに配置するには、マーカー同様に、座標情報を持つ Feature と、見た目の情報を持つ Style を定義して、レイヤーに追加することで、地図上に表示させます。ここで、Style には ol.style.Text を使用します。

 まず、テキストの座標情報を持つ ol.Feature を定義します。

//ol.Feature: テキストの持つ座標情報等を保存するオブジェクト
var textFeature = new ol.Feature({
  geometry: new ol.geom.Point(ol.proj.fromLonLat([142.14, 43.65])) //[経度, 緯度]
});

 次に、テキストの見た目を管理する ol.style.Style を定義します。

//ol.style.Style: テキストの見た目に関する情報を管理するオブジェクト
textStyle = new ol.style.Style({
  text: new ol.style.Text({
    fill: new ol.style.Fill({color: "#000000"}),
    stroke: new ol.style.Stroke({color: "#ffffff", width: 3}),
    scale: 2,
    textAlign: "center",
    text: "北海道", //表示したいテキスト
    font: "Courier New, monospace"
  })
});

 これらをレイヤーに追加します。ここで、 ol.source.Vector は Feature 一覧をまとめて管理するオブジェクトになっています。

  //ol.layer.Vector: テキストを保持するレイヤー
  var textLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: [textFeature]
    }),
    style: textStyle
  });

 最後に addLayer() でマップにレイヤーを追加すれば完成です。

//マップにテキストレイヤーを追加
map.addLayer(textLayer);

 全体のソースコードと実装例は以下のようになります。

<!DOCTYPE html>
<html>
<head>
<title>htmlMap</title>
<meta http-equiv='content-type' charset='utf-8'>
<meta name='viewport' content='width=device-width'>
</head>
<body>
<!-- 埋め込みマップのdivタグ。マップサイズはwidth(幅)とheight(高さ)で決まる -->
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>

<!-- 以下OpenLayersのJavaScriptとCSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/css/ol.css" type="text/css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/build/ol.js"></script>

<script>
function init_map() {

  // マップを表示
  var map = new ol.Map({
    target: 'mapcontainer',
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      })
    ],
    view: new ol.View({
      center: ol.proj.fromLonLat([142.14, 43.65]),
      zoom: 6
    })
  });

  //ol.Feature: テキストの持つ座標情報等を保存するオブジェクト
  var textFeature = new ol.Feature({
    geometry: new ol.geom.Point(ol.proj.fromLonLat([142.14, 43.65]))
  });

  //ol.style.Style: テキストの見た目に関する情報を管理するオブジェクト
  textStyle = new ol.style.Style({
    text: new ol.style.Text({
      fill: new ol.style.Fill({color: "#000000"}),
      stroke: new ol.style.Stroke({color: "#ffffff", width: 3}),
      scale: 2,
      textAlign: "center",
      text: "北海道",
      font: "Courier New, monospace"
    })
  });
 
  //ol.layer.Vector: テキストを保持するレイヤー
  var textLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: [textFeature]
    }),
    style: textStyle
  });

  //マップにテキストレイヤーを追加
  map.addLayer(textLayer);
}

//ダウンロード時に初期化する
window.addEventListener('DOMContentLoaded', init_map());

</script>
</body>
</html>

 実装例

複数のテキストを配置する

 複数のテキストをマップ上に配置するには、個別に Feature (座標情報を保持するオブジェクト) と Style (見た目の情報を保持するオブジェクト) を作成した後に、addFeature() で Source (Feature を一括管理するオブジェクト) に追加していくのが良いかと思います。

 まず、二次元配列でテキストとテキストの位置情報を保持する配列を定義します。

//テキスト情報を保持している二次元配列
var text_Database = [
  ["東京",   139.753, 35.685],
  ["神奈川", 139.622, 35.466],
  ["千葉",   140.113, 35.613]];

 次に、定義した配列のデータを元に、Feature と Style を作成します。

//ol.Feature: テキストの持つ座標情報等を保存するオブジェクト
textFeature = new ol.Feature({
  geometry: new ol.geom.Point(ol.proj.fromLonLat([text_Database[i][1], text_Database[i][2]]))
});

//ol.style.Style: テキストの見た目に関する情報を管理するオブジェクト
textStyle = new ol.style.Style({
  text: new ol.style.Text({
    fill: new ol.style.Fill({color: "#000000"}),
    stroke: new ol.style.Stroke({color: "#ffffff", width: 3}),
    scale: 2,
    textAlign: "center",
    text: text_Database[i][0],
    font: "Courier New, monospace"
  })
});

 Style を Feature に紐づけ、Feature を Source に追加します。

// Style を Feature に紐づける
textFeature.setStyle(textStyle);
// Feature を Source に追加する
textSource.addFeature(textFeature);

 最後に作成した Source を持つレイヤーを定義して、マップに追加したら完成です。

//ol.layer.Vector: テキストを保持するレイヤー
var textLayer = new ol.layer.Vector({
  source: textSource 
});

//マップにテキストレイヤーを追加
map.addLayer(textLayer);

 全体のソースコードと実装例は以下のようになります。

<!DOCTYPE html>
<html>
<head>
<title>htmlMap</title>
<meta http-equiv='content-type' charset='utf-8'>
<meta name='viewport' content='width=device-width'>
</head>
<body>
<!-- 埋め込みマップのdivタグ。マップサイズはwidth(幅)とheight(高さ)で決まる -->
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>

<!-- 以下OpenLayersのJavaScriptとCSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/css/ol.css" type="text/css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/build/ol.js"></script>

<script>
function init_map() {

  // マップを表示
  var map = new ol.Map({
    target: 'mapcontainer',
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      })
    ],
    view: new ol.View({
      center: ol.proj.fromLonLat([139.935, 35.562]),
      zoom: 9
    })
  });

  //テキスト情報を保持している二次元配列
  var text_Database = [
    ["東京",   139.753, 35.685],
    ["神奈川", 139.622, 35.466],
    ["千葉",   140.113, 35.613]];

  //空のSource, Feature, Style を定義
  var textSource = new ol.source.Vector({});
  var textFeature = new ol.Feature({});
  var textStyle = new ol.style.Style({});

  for (var i = 0; i < text_Database.length; i++) {

    //ol.Feature: テキストの持つ座標情報等を保存するオブジェクト
    textFeature = new ol.Feature({
      geometry: new ol.geom.Point(ol.proj.fromLonLat([text_Database[i][1], text_Database[i][2]]))
    });

    //ol.style.Style: テキストの見た目に関する情報を管理するオブジェクト
    textStyle = new ol.style.Style({
      text: new ol.style.Text({
        fill: new ol.style.Fill({color: "#000000"}),
        stroke: new ol.style.Stroke({color: "#ffffff", width: 3}),
        scale: 2,
        textAlign: "center",
        text: text_Database[i][0],
        font: "Courier New, monospace"
      })
    });

    // Style を Feature に紐づける
    textFeature.setStyle(textStyle);
    // Feature を Source に追加する
    textSource.addFeature(textFeature);
  }


  //ol.layer.Vector: テキストを保持するレイヤー
  var textLayer = new ol.layer.Vector({
    source: textSource 
  });

  //マップにテキストレイヤーを追加
  map.addLayer(textLayer);
}

//ダウンロード時に初期化する
window.addEventListener('DOMContentLoaded', init_map());

</script>
</body>
</html>

実装例

コメントを残す

メールアドレスが公開されることはありません。