2015/06/13

OpenLayers 3 で Feature 毎にアイコン画像や文字を変更する

OpenLayers 3 のマーカーに文字を表示する方法 2種 では固定の Style を適用する方法を紹介しましたが、場合によってはこれでは不便なので、Feature 毎に Style を変更する方法も用意されています。


下記の例をみてもらうとわかると思いますが、Style として適用できるのは ol.style.Style オブジェクトだけではありません。関数を適用することも出来るのです。
そのため、ol.Featureオブジェクトに持たせておいたパラメータを使って、動的にマーカーの表示を切り替えることが可能になります。

注意点は ol.layer.Vector に適用する関数と ol.Feature に適用する関数では引数が異なるところです。ol.Feature に適用する関数は feature を引数にとりませんが、thisol.Featureオブジェクトになっています。
また、関数の返り値は ol.style.Style配列だという点にも注意が必要です。

サンプル

ソースコード
<!DOCTYPE html>
<html>
<head>
<title>Marker Expample</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.js"></script>
</head>
<body>
<div id="map" style="width:100%; height: 800px;"></div>

<script type="text/javascript">
function convertCoordinate(longitude, latitude) {
  return ol.proj.transform([longitude, latitude], "EPSG:4326","EPSG:900913");
}

// デフォルトのスタイル関数
var markerStyleDefault = function(feature, resolution) {
  var styles = [
    new ol.style.Style({
      image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ {
        anchor: [0.5, 1],
        anchorXUnits: 'fraction',
        anchorYUnits: 'fraction',
        opacity: 0.75,
        src: feature.get('markerSrc')
      }),
      text: new ol.style.Text({
        fill: new ol.style.Fill({color: feature.get("textColor")}),
        stroke: new ol.style.Stroke({color: "#ffffff", width: 2}),
        scale: 1.6,
        textAlign: "center",
        textBaseline: "top",
        offsetY: 0,
        text: feature.get("text"),
        font: "Courier New, monospace"
      })
    })
  ];
  return styles;
};

// FeatureA に適用するスタイル関数
var markerStyleA = function(resolution) {
  var styles = [
    new ol.style.Style({
      image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ {
        anchor: [0.5, 1],
        anchorXUnits: 'fraction',
        anchorYUnits: 'fraction',
        opacity: 0.75,
        src: this.get('markerSrc')
      }),
        text: new ol.style.Text({
            fill: new ol.style.Fill({color: this.get("textColor")}),
            stroke: new ol.style.Stroke({color: "#ffffff", width: 2}),
            scale: 1.6,
            textAlign: "center",
            textBaseline: "top",
            offsetY: 0,
            text: this.get("text"),
            font: "Courier New, monospace"
        })
    })
  ];
  return styles;
};

var markerFeatureA = new ol.Feature({
  geometry: new ol.geom.Point(convertCoordinate(139.745229, 35.658227)),
  markerSrc: "marker-blue.png",
  text: "FeatureA",
  textColor: "#0000ff"
});
markerFeatureA.setStyle(markerStyleA);

var markerFeatureB = new ol.Feature({
  geometry: new ol.geom.Point(convertCoordinate(139.744165, 35.658013)),
  markerSrc: "marker-red.png",
  text: "FeatureB",
  textColor: "#ff0000"
});

var markerFeatureC = new ol.Feature({
  geometry: new ol.geom.Point(convertCoordinate(139.744262, 35.659695)),
  markerSrc: "marker-green.png",
  text: "FeatureC",
  textColor: "#00ff00"
});

// Feature 一覧 を Source にセット
var markerSource = new ol.source.Vector({
  features: [markerFeatureA, markerFeatureB, markerFeatureC]
});

// Source を Layer にセット
var markerLayer = new ol.layer.Vector({
  source: markerSource,
  style: markerStyleDefault
});

// Open Street Map Layer
var osmLayer = new ol.layer.Tile({
  source: new ol.source.OSM()
});

var map = new ol.Map({
  layers: [ osmLayer, markerLayer ],
  target: document.getElementById('map'),
  view: new ol.View({
    center: convertCoordinate(139.745433, 35.658579),
    zoom: 18
  })
});

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

0 件のコメント: