OpenLayers 3測定機能の実現

12309 ワード

本論文の例では、OpenLayers 3の測定機能を実現するための具体的なコードを共有します。
1.はじめに
測定機能は面積の測定と長さの測定を実現する。マウスで領域と長さを描画して測定します。OpenLayers 3フレームワークは測定コントロールを提供していませんが、対応するインターフェースが提供されています。幾何学的オブジェクトに基づく対応するインターフェースが必要です。グラフィック描画機能と結合して実装されます。
2.考え方を実現する
(1)新しいページを作成し、Onelayers 3開発ライブラリ、jQueryライブラリとbootstrapライブラリを参照して、前に地図を表示する文章を参照して、OSMM瓦レイヤーをロードします。
(2)地図容器に測定タイプ選択コントロールを作成し、選択距離測定と面積測定を行う。
(3)コードを作成し測定機能を実現する。
3.実現コード
)主要コード

<div id="map">
    <div id="menu">
      <label>    :</label>
      <select id="type">
      <option value="length">  </option>
      <option value="area">  </option>
    </select>
      <label class="checkbox"><input type="checkbox" id="geodesic">      </label>
    </div>
</div>
測定タイプコントロールのスタイル設定:

#menu {
      float: left;
      position: absolute;
      bottom: 10px;
      left: 10px;
      z-index: 2000;
    }

    .checkbox {
      left: 20px;
    }
    /*          */

    .tooltip {
      position: relative;
      background: rgba(0, 0, 0, 0.5);
      border-radius: 4px;
      color: white;
      padding: 4px 8px;
      opacity: 0.7;
      white-space: nowrap;
    }

    .tooltip-measure {
      opacity: 1;
      font-weight: bold;
    }

    .tooltip-static {
      background-color: #ffcc33;
      color: black;
      border: 1px solid white;
    }

    .tooltip-measure::before,
    .tooltip-static::before {
      border-top: 6px solid rgb(0, 0, 0, 0.5);
      border-right: 6px solid transparent;
      border-left: 6px solid transparent;
      content: "";
      position: absolute;
      bottom: -6px;
      margin-left: -7px;
      left: 50%;
    }

    .tooltip-static::before {
      border-top-color: #ffcc33;
}
コード解析
上のコードはbootstrapライブラリと結合して、泡を出して枠の形式を提示して現在の測定結果を表示します。上のスタイルはそれぞれ2種類のヒントボックスのスタイルを設定しています。
4.測定機能を実現するコアコード
(1)まず地図に測定機能の描画層をロードします。つまりベクトルレイヤーと同じです。絵を描くには紙が必要です。ここのベクトルレイヤーは私たちの紙に相当します。コードは以下の通りです

//          
var source = new ol.source.Vector(); //     
var vector = new ol.layer.Vector({
  source: source,
  style: new ol.style.Style({ //    
   fill: new ol.style.Fill({
    color: 'rgba(255, 255, 255, 0.2)' //    
   }),
   stroke: new ol.style.Stroke({
    color: '#ffcc33', //    
    width: 2 //     
   }),
   image: new ol.style.Circle({
    radius: 7,
    fill: new ol.style.Fill({
     color: '#ffcc33'
    })
   })
  })
 });
map.addLayer(vector);
(2)addInteraction法によって測定機能を実現し、まずインタラクティブ描画コントロール(ol.interactions.Draw)をロードし、つまり私たちが前に述べた絵を描くために必要なペンは、測定時に測定タイプによって線分や多角形を選択し、それぞれインタラクティブ描画コントロールにDRawstructとdrawendイベントを結びつける。図形描画の開始時に現在の描画線の長さまたは多角形の面積をリアルタイムで計算し、枠の形で表示します。図形描画の終了時に測定ヒントボックスを作成して測定結果を表示します。addInteraction関数による描画測定コード:
4.1 addInteraction関数による描画測定を実現するコード:

/**
  *         (     )
  * @param {Event} e Change event.
  */
 typeSelect.onchange = function(e) {
  map.removeInteraction(draw); //      
  addInteraction(); //        
 };
addInteraction(); //             ,        
addInteraction()関数コード:

var geodesicCheckbox = document.getElementById('geodesic'); //       
var typeSelect = document.getElementById('type'); //      
var draw; // global so we can remove it later
/**
 *            
 */
function addInteraction() {
 var type = (typeSelect.value == 'area' ? 'Polygon' : 'LineString');
 draw = new ol.interaction.Draw({
  source: source, //        
  type: /** @type {ol.geom.GeometryType} */ (type), //      
  style: new ol.style.Style({ //         
   fill: new ol.style.Fill({
    color: 'rgba(255, 255, 255, 0.2)'
   }),
   stroke: new ol.style.Stroke({
    color: 'rgba(0, 0, 0, 0.5)',
    lineDash: [10, 10],
    width: 2
   }),
   image: new ol.style.Circle({
    radius: 5,
    stroke: new ol.style.Stroke({
     color: 'rgba(0, 0, 0, 0.7)'
    }),
    fill: new ol.style.Fill({
     color: 'rgba(255, 255, 255, 0.2)'
    })
   })
  })
 });
 map.addInteraction(draw);

 createMeasureTooltip(); //         
 createHelpTooltip(); //       

 var listener;
 //               
 draw.on('drawstart',
  function(evt) {
   // set sketch
   sketch = evt.feature; //     

   /** @type {ol.Coordinate|undefined} */
   var tooltipCoord = evt.coordinate; //      
   //  change  ,                   ,                
   listener = sketch.getGeometry().on('change', function(evt) {
    var geom = evt.target; //      
    var output;
    if (geom instanceof ol.geom.Polygon) {
     output = formatArea( /** @type {ol.geom.Polygon} */ (geom)); //   
     tooltipCoord = geom.getInteriorPoint().getCoordinates(); //  
    } else if (geom instanceof ol.geom.LineString) {
     output = formatLength( /** @type {ol.geom.LineString} */ (geom)); //   
     tooltipCoord = geom.getLastCoordinate(); //  
    }
    measureTooltipElement.innerHTML = output; //                 
    measureTooltip.setPosition(tooltipCoord); //              
   });
  }, this);
 //               
 draw.on('drawend',
  function(evt) {
   measureTooltipElement.className = 'tooltip tooltip-static'; //          
   measureTooltip.setOffset([0, -7]);
   // unset sketch
   sketch = null; //           
   // unset tooltip so that a new one can be created
   measureTooltipElement = null; //           
   createMeasureTooltip(); //                 
   ol.Observable.unByKey(listener);
  }, this);
}
コード解析
まず図形描画コントロール(ol.interactions.Draw)をロードします。つまり、私たちのペンは、コントロールを実行する時に現在の図形描画要素のスタイルを設定して、それぞれcreateHelpTooltop()とcreateMease Tooltip()を呼び出して、ヘルプ情報提示ボックスと測定ツールの提示フレームオブジェクトを作成します。図形描画コントロールオブジェクトを最後に結びつけるdrawStartとdrawendイベントは、図形描画測定機能を実現する。ここで、drawstructイベントハンドラ関数では、イベントオブジェクトから現在描画されている要素を取得し、要素の幾何学的オブジェクトバインディングchangeイベントを描画することにより、イベントによって傍受される幾何学的オブジェクトタイプは、ラインまたはポリゴン(ol.geom.Polygonまたはol.geom.LineStering)であり、formatire()とformatingth()を呼び出して出力測定した面積値または長さ値を計算します。
4.2ヒントボックスを作成するコード: 

/**
  *           (tooltip)
  */
 function createHelpTooltip() {
  if (helpTooltipElement) {
   helpTooltipElement.parentNode.removeChild(helpTooltipElement);
  }
  helpTooltipElement = document.createElement('div');
  helpTooltipElement.className = 'tooltip hidden';
  helpTooltip = new ol.Overlay({
   element: helpTooltipElement,
   offset: [15, 0],
   positioning: 'center-left'
  });
  map.addOverlay(helpTooltip);
 }
 /**
  *             (tooltip)
  */
 function createMeasureTooltip() {
  if (measureTooltipElement) {
   measureTooltipElement.parentNode.removeChild(measureTooltipElement);
  }
  measureTooltipElement = document.createElement('div');
  measureTooltipElement.className = 'tooltip tooltip-measure';
  measureTooltip = new ol.Overlay({
   element: measureTooltipElement,
   offset: [0, -15],
   positioning: 'bottom-center'
  });
  map.addOverlay(measureTooltip);
}
コード解析
Openlayers 3のol.Overlayに基づいてヘルプ情報提示枠と測定ツール提示枠を作成し、それぞれcreateHelpTooltip()とcreateMeass reTooltip()を通じてヘルプ情報提示枠と測定ツール提示枠を作成し、ol.Overlay jは動的に重畳層オブジェクトとその目標容器(div層)を作成し、重畳層を地図容器に追加します。
4.3長さと面積を計算するコード:

/**
  *       
  * @param {ol.geom.LineString} line
  * @return {string}
  */
 var formatLength = function(line) {
  var length;
  if (geodesicCheckbox.checked) { //          
   var coordinates = line.getCoordinates(); //      
   length = 0;
   var sourceProj = map.getView().getProjection(); //          
   //              ,          
   for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {
    var c1 = ol.proj.transform(coordinates[i], sourceProj, 'EPSG:4326');
    var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326');
    length += wgs84Sphere.haversineDistance(c1, c2);
   }
  } else {
   length = Math.round(line.getLength() * 100) / 100; //        
  }
  var output;
  if (length > 100) {
   output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km'; //   KM  
  } else {
   output = (Math.round(length * 100) / 100) + ' ' + 'm'; //m   
  }
  return output; //      
 };
 /**
  *       
  * @param {ol.geom.Polygon} polygon
  * @return {string}
  */
 var formatArea = function(polygon) {
  var area;
  if (geodesicCheckbox.checked) { //          
   var sourceProj = map.getView().getProjection(); //          
   var geom = /** @type {ol.geom.Polygon} */ (polygon.clone().transform(sourceProj, 'EPSG:4326')); //            EPSG:4326
   var coordinates = geom.getLinearRing(0).getCoordinates(); //         
   area = Math.abs(wgs84Sphere.geodesicArea(coordinates)); //    
  } else {
   area = polygon.getArea(); //          
  }
  var output;
  if (area > 10000) {
   output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>'; //   KM  
  } else {
   output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>'; //m   
  }
  return output; //        
 };

addInteraction(); //            ,        
コード解析
上のコードは、出力の長さ値と面積値をformating()とformatire()でそれぞれ計算します。長さ値または面積値を計算する場合は、測定法を用いてデータに基づく射影座標系を計算し、もう一つは幾何学的オブジェクトまたは多角形オブジェクトを呼び出す方法で直接に値を取得する2つの方法で計算することができます。
(3)絵を描き始めました。それぞれmapオブジェクトを使ってマウス移動イベント(pointermove)とマウス除去イベント(mouseout)をバインドします。
4.4地図マウス移動イベントのコードを追加します。

 /**
  *                   
  * @type {string}
  */
 var continuePolygonMsg = '         ';
 /**
  *                 
  * @type {string}
  */
 var continueLineMsg = '       ';

 /**
  *           
  * @param {ol.MapBrowserEvent} evt
  */
 var pointerMoveHandler = function(evt) {
  if (evt.dragging) {
   return;
  }
  /** @type {string} */
  var helpMsg = '    '; //        
  //                   
  if (sketch) {
   var geom = (sketch.getGeometry());
   if (geom instanceof ol.geom.Polygon) {
    helpMsg = continuePolygonMsg; //            
   } else if (geom instanceof ol.geom.LineString) {
    helpMsg = continueLineMsg; //          
   }
  }
  helpTooltipElement.innerHTML = helpMsg; //              
  helpTooltip.setPosition(evt.coordinate); //          
  $(helpTooltipElement).removeClass('hidden'); //                
 };
 map.on('pointermove', pointerMoveHandler); //            ,           
 //          ,                 
 $(map.getViewport()).on('mouseout', function() {
  $(helpTooltipElement).addClass('hidden');
});
コード解析
マウス移動イベント(pointermove)は、コールバック関数において、ユーザーが測定のタイプを選択することによって、地図コンテナバインディングマウス除去イベント(mouseout)をポップアップ画面に表示し、このイベントが発生したときに、バックライトプロンプトボックスを隠します。
5.効果を実現する

以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。