1. 程式人生 > >openlayers3 實現測距 面積

openlayers3 實現測距 面積

.get int mov zoom 根據 stroke 一個 lan attribute

  1 <!DOCTYPE html> 
  2 <html xmlns="http://www.w3.org/1999/xhtml"> 
  3 <head> 
  4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
  5 <title></title> 
  6 <link href="~/Scripts/OpenLayers-demo/css/ol.css" rel="stylesheet" />
  7 <script src="~/Scripts/OpenLayers-demo/build/ol.js"></script>
  8
<script src="~/Scripts/jquery-1.10.2.min.js"></script> 9 <script src="~/Scripts/map/mapzoomtool.js" charset="gb2312"></script> 10 <link href="~/Content/mapCtrlsstyles.css" rel="stylesheet" /> 11 <link href="~/Content/resources/KitchenSink-all.css" rel="stylesheet" /> 12 <script src="~/Scripts/ext-all.js"></script> 13
<style type="text/css"> 14 #map { 15 width: 100%; 16 height: 100%; 17 position: absolute; 18 } 19 20 #menu { 21 float: left; 22 position: absolute; 23 bottom: 10px; 24 left: 10px; 25 z-index: 2000; 26 } 27 28 .checkbox { 29 left: 20px; 30 } 31 /** 32 * 提示框的樣式信息 33 */ 34
.tooltip { 35 position: relative; 36 background: rgba(0, 0, 0, 0.5); 37 border-radius: 4px; 38 color: white; 39 padding: 4px 8px; 40 opacity: 0.7; 41 white-space: nowrap; 42 } 43 44 .tooltip-measure { 45 opacity: 1; 46 font-weight: bold; 47 } 48 49 .tooltip-static { 50 background-color: #ffffff; 51 color: black; 52 border: 1px solid white; 53 } 54 55 .tooltip-measure:before, 56 .tooltip-static:before { 57 border-top: 6px solid rgba(0, 0, 0, 0.5); 58 border-right: 6px solid transparent; 59 border-left: 6px solid transparent; 60 content: ""; 61 position: absolute; 62 bottom: -6px; 63 margin-left: -7px; 64 left: 50%; 65 } 66 67 .tooltip-static:before { 68 border-top-color: #ffffff; 69 } 70 71 #scalebar { 72 float: left; 73 margin-bottom: 10px; 74 } 75 </style> 76 <script type="text/javascript"> 77 $(function () { 78 //初始化地圖 79 var map = new ol.Map({ 80 target: ‘map‘, 81 layers: [ 82 new ol.layer.Tile({ 83 source:new ol.source.OSM() 84 }) 85 ], 86 view: new ol.View({ 87 center: new ol.proj.fromLonLat([114.4250, 23.0890]), 88 zoom: 18, 89 maxZoom: 20 90 }) 91 }); 92 93 //定義矢量數據源 94 var source = new ol.source.Vector(); 95 //定義矢量圖層 96 var vector = new ol.layer.Vector({ 97 source: source, 98 style: new ol.style.Style({ 99 fill: new ol.style.Fill({ 100 color:‘rgba(255,255,255,0.2)‘ 101 }), 102 stroke: new ol.style.Stroke({ 103 color: ‘#e21e0a‘, 104 width:2 105 }), 106 image: new ol.style.Circle({ 107 radius: 5, 108 fill: new ol.style.Fill({ 109 color:‘#ffcc33‘ 110 }) 111 }) 112 }) 113 }); 114 //將矢量圖層添加到地圖中 115 map.addLayer(vector); 116 117 //添加比例尺控件 118 var scaleLineControl = new ol.control.ScaleLine({ 119 units: ‘metric‘, 120 target: ‘scalebar‘, 121 className: ‘ol-scale-line‘ 122 }); 123 map.addControl(scaleLineControl); 124 125 126 //創建一個WGS84球體對象 127 var wgs84Sphere = new ol.Sphere(6378137); 128 //創建一個當前要繪制的對象 129 var sketch = new ol.Feature(); 130 //創建一個幫助提示框對象 131 var helpTooltipElement; 132 //創建一個幫助提示信息對象 133 var helpTooltip; 134 //創建一個測量提示框對象 135 var measureTooltipElement; 136 //創建一個測量提示信息對象 137 var measureTooltip; 138 //繼續繪制多邊形的提示信息 139 var continuePolygonMsg = ‘Click to continue drawing the polygon‘; 140 //繼續繪制線段的提示信息 141 var continueLineMsg = ‘Click to continue drawing the line‘; 142 143 //鼠標移動觸發的函數 144 var pointerMoveHandler = function (evt) { 145 //Indicates if the map is currently being dragged. 146 //Only set for POINTERDRAG and POINTERMOVE events. Default is false. 147 //如果是平移地圖則直接結束 148 if (evt.dragging) { 149 return; 150 } 151 //幫助提示信息 152 var helpMsg = ‘Click to start drawing‘; 153 154 if (sketch) { 155 //Get the feature‘s default geometry. 156 //A feature may have any number of named geometries. 157 //獲取繪圖對象的幾何要素 158 var geom = sketch.getGeometry(); 159 //如果當前繪制的幾何要素是多邊形,則將繪制提示信息設置為多邊形繪制提示信息 160 //如果當前繪制的幾何要素是多線段,則將繪制提示信息設置為多線段繪制提示信息 161 if (geom instanceof ol.geom.Polygon) { 162 helpMsg = continuePolygonMsg; 163 } else if (geom instanceof ol.geom.LineString) { 164 helpMsg = continueLineMsg; 165 } 166 } 167 //設置幫助提示要素的內標簽為幫助提示信息 168 helpTooltipElement.innerHTML = helpMsg; 169 //設置幫助提示信息的位置 170 //The coordinate in view projection corresponding to the original browser event. 171 helpTooltip.setPosition(evt.coordinate); 172 //移除幫助提示要素的隱藏樣式 173 $(helpTooltipElement).removeClass(‘hidden‘); 174 }; 175 176 //觸發pointermove事件 177 map.on(‘pointermove‘, pointerMoveHandler); 178 179 //當鼠標移除地圖視圖的時為幫助提示要素添加隱藏樣式 180 $(map.getViewport()).on(‘mouseout‘, function () { 181 $(helpTooltipElement).addClass(‘hidden‘); 182 }); 183 184 //獲取大地測量復選框 185 var geodesicCheckbox = document.getElementById(‘geodesic‘); 186 //獲取類型 187 var typeSelect = document.getElementById(‘type‘); 188 //定義一個交互式繪圖對象 189 var draw; 190 191 //添加交互式繪圖對象的函數 192 function addInteraction() { 193 // 獲取當前選擇的繪制類型 194 var type = typeSelect.value == ‘area‘ ? ‘Polygon‘ : ‘LineString‘; 195 //創建一個交互式繪圖對象 196 draw = new ol.interaction.Draw({ 197 //繪制的數據源 198 source: source, 199 //繪制類型 200 type: type, 201 //樣式 202 style: new ol.style.Style({ 203 fill: new ol.style.Fill({ 204 color:‘rgba(255,255,255,0.2)‘ 205 }), 206 stroke: new ol.style.Stroke({ 207 color: ‘rgba(0,0,0,0.5)‘, 208 lineDash: [10, 10], 209 width:2 210 }), 211 image: new ol.style.Circle({ 212 radius: 5, 213 stroke: new ol.style.Stroke({ 214 color:‘rgba(0,0,0,0.7)‘ 215 }), 216 fill: new ol.style.Fill({ 217 color: ‘rgba(255,255,255,0.2)‘ 218 }) 219 }) 220 }) 221 }); 222 //將交互繪圖對象添加到地圖中 223 map.addInteraction(draw); 224 225 //創建測量提示框 226 createMeasureTooltip(); 227 //創建幫助提示框 228 createHelpTooltip(); 229 230 //定義一個事件監聽 231 var listener; 232 //定義一個控制鼠標點擊次數的變量 233 var count = 0; 234 //繪制開始事件 235 draw.on(‘drawstart‘, function (evt) { 236 //The feature being drawn. 237 sketch = evt.feature; 238 //提示框的坐標 239 var tooltipCoord = evt.coordinate; 240 //監聽幾何要素的change事件 241 //Increases the revision counter and dispatches a ‘change‘ event. 242 243 listener = sketch.getGeometry().on(‘change‘, function (evt) { 244 //The event target. 245 //獲取繪制的幾何對象 246 var geom = evt.target; 247 //定義一個輸出對象,用於記錄面積和長度 248 var output; 249 if (geom instanceof ol.geom.Polygon) { 250 map.removeEventListener(‘singleclick‘); 251 map.removeEventListener(‘dblclick‘); 252 //輸出多邊形的面積 253 output = formatArea(geom); 254 //Return an interior point of the polygon. 255 //獲取多變形內部點的坐標 256 tooltipCoord = geom.getInteriorPoint().getCoordinates(); 257 } else if (geom instanceof ol.geom.LineString) { 258 //輸出多線段的長度 259 output = formatLength(geom); 260 //Return the last coordinate of the geometry. 261 //獲取多線段的最後一個點的坐標 262 tooltipCoord = geom.getLastCoordinate(); 263 } 264 265 //設置測量提示框的內標簽為最終輸出結果 266 measureTooltipElement.innerHTML = output; 267 //設置測量提示信息的位置坐標 268 measureTooltip.setPosition(tooltipCoord); 269 }); 270 271 //地圖單擊事件 272 map.on(‘singleclick‘, function (evt) { 273 //設置測量提示信息的位置坐標,用來確定鼠標點擊後測量提示框的位置 274 measureTooltip.setPosition(evt.coordinate); 275 //如果是第一次點擊,則設置測量提示框的文本內容為起點 276 if (count == 0) { 277 measureTooltipElement.innerHTML = "起點"; 278 } 279 //根據鼠標點擊位置生成一個點 280 var point = new ol.geom.Point(evt.coordinate); 281 //將該點要素添加到矢量數據源中 282 source.addFeature(new ol.Feature(point)); 283 //更改測量提示框的樣式,使測量提示框可見 284 measureTooltipElement.className = ‘tooltip tooltip-static‘; 285 //創建測量提示框 286 createMeasureTooltip(); 287 //點擊次數增加 288 count++; 289 }); 290 291 //地圖雙擊事件 292 map.on(‘dblclick‘, function (evt) { 293 //根據 294 var point = new ol.geom.Point(evt.coordinate); 295 source.addFeature(new ol.Feature(point)); 296 }); 297 }, this); 298 //繪制結束事件 299 draw.on(‘drawend‘, function (evt) { 300 count = 0; 301 //設置測量提示框的樣式 302 measureTooltipElement.className = ‘tooltip tooltip-static‘; 303 //Set the offset for this overlay. 304 //設置偏移量 305 measureTooltip.setOffset([0, -7]); 306 //清空繪制要素 307 sketch = null; 308 //清空測量提示要素 309 measureTooltipElement = null; 310 //創建測量提示框 311 createMeasureTooltip(); 312 //Removes an event listener using the key returned by on() or once(). 313 //移除事件監聽 314 ol.Observable.unByKey(listener); 315 //移除地圖單擊事件 316 map.removeEventListener(‘singleclick‘); 317 }, this); 318 } 319 //創建幫助提示框 320 function createHelpTooltip() { 321 //如果已經存在幫助提示框則移除 322 if (helpTooltipElement) { 323 helpTooltipElement.parentNode.removeChild(helpTooltipElement); 324 } 325 //創建幫助提示要素的div 326 helpTooltipElement = document.createElement(‘div‘); 327 //設置幫助提示要素的樣式 328 helpTooltipElement.className = ‘tooltip hidden‘; 329 //創建一個幫助提示的覆蓋標註 330 helpTooltip = new ol.Overlay({ 331 element: helpTooltipElement, 332 offset: [15, 0], 333 positioning:‘center-left‘ 334 }); 335 //將幫助提示的覆蓋標註添加到地圖中 336 map.addOverlay(helpTooltip); 337 } 338 //創建測量提示框 339 function createMeasureTooltip() { 340 //創建測量提示框的div 341 measureTooltipElement = document.createElement(‘div‘); 342 measureTooltipElement.setAttribute(‘id‘,‘lengthLabel‘); 343 //設置測量提示要素的樣式 344 measureTooltipElement.className = ‘tooltip tooltip-measure‘; 345 //創建一個測量提示的覆蓋標註 346 measureTooltip = new ol.Overlay({ 347 element: measureTooltipElement, 348 offset: [0, -15], 349 positioning:‘bottom-center‘ 350 }); 351 //將測量提示的覆蓋標註添加到地圖中 352 map.addOverlay(measureTooltip); 353 } 354 //測量類型發生改變時觸發事件 355 typeSelect.onchange = function () { 356 //移除之前的繪制對象 357 map.removeInteraction(draw); 358 //重新進行繪制 359 addInteraction(); 360 }; 361 362 //格式化測量長度 363 var formatLength = function (line) { 364 //定義長度變量 365 var length; 366 //如果大地測量復選框被勾選,則計算球面距離 367 if (geodesicCheckbox.checked) { 368 //Return the coordinates of the linestring. 369 //獲取坐標串 370 var coordinates = line.getCoordinates(); 371 //初始長度為0 372 length = 0; 373 //獲取源數據的坐標系 374 var sourceProj = map.getView().getProjection(); 375 //進行點的坐標轉換 376 for (var i = 0; i < coordinates.length - 1; i++) { 377 //第一個點 378 var c1 = ol.proj.transform(coordinates[i], sourceProj, ‘EPSG:4326‘); 379 //第二個點 380 var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, ‘EPSG:4326‘); 381 //獲取轉換後的球面距離 382 //Returns the distance from c1 to c2 using the haversine formula. 383 length += wgs84Sphere.haversineDistance(c1,c2); 384 } 385 } else { 386 //Return the length of the linestring on projected plane. 387 //計算平面距離 388 length = Math.round(line.getLength() * 100) / 100; 389 } 390 //定義輸出變量 391 var output; 392 //如果長度大於1000,則使用km單位,否則使用m單位 393 if (length > 1000) { 394 output = (Math.round(length / 1000 * 100) / 100) + ‘ ‘ + ‘km‘; //換算成KM單位 395 } else { 396 output = (Math.round(length * 100) / 100) + ‘ ‘ + ‘m‘; //m為單位 397 } 398 return output; 399 }; 400 401 //格式化測量面積 402 var formatArea = function (polygon) { 403 //定義面積變量 404 var area; 405 //如果大地測量復選框被勾選,則計算球面面積 406 if (geodesicCheckbox.checked) { 407 //獲取初始坐標系 408 var sourceProj = map.getView().getProjection(); 409 //Make a complete copy of the geometry. 410 //Transform each coordinate of the geometry from one coordinate reference system to another. 411 //The geometry is modified in place. For example, a line will be transformed to a line and a circle to a circle. 412 //If you do not want the geometry modified in place, first clone() it and then use this function on the clone. 413 //克隆該幾何對象然後轉換坐標系 414 var geom = polygon.clone().transform(sourceProj, ‘EPSG:4326‘); 415 //Return the Nth linear ring of the polygon geometry. 416 //Return null if the given index is out of range. 417 //The exterior linear ring is available at index 0 and the interior rings at index 1 and beyond. 418 //獲取多邊形的坐標系 419 var coordinates = geom.getLinearRing(0).getCoordinates(); 420 //Returns the geodesic area for a list of coordinates. 421 //獲取球面面積 422 area = Math.abs(wgs84Sphere.geodesicArea(coordinates)); 423 } else { 424 //獲取平面面積 425 area = polygon.getArea(); 426 } 427 //定義輸出變量 428 var output; 429 //當面積大於10000時,轉換為平方千米,否則為平方米 430 if (area > 10000) { 431 output = (Math.round(area/1000000*100)/100) + ‘ ‘ + ‘km<sup>2</sup>‘; 432 } else { 433 output = (Math.round(area*100)/100) + ‘ ‘ + ‘m<sup>2</sup>‘; 434 } 435 return output; 436 }; 437 //添加交互繪圖對象 438 addInteraction(); 439 }); 440 </script> 441 </head> 442 <body> 443 <div id="map"> 444 <div id="menu"> 445 <label>測量類型選擇</label> 446 <select id="type"> 447 <option value="length">長度</option> 448 <option value="area">面積</option> 449 </select> 450 <label class="checkbox"><input type="checkbox" id="geodesic" />使用大地測量</label> 451 </div> 452 </div> 453 <div id="scalebar"></div> 454 </body> 455 </html>

openlayers3 實現測距 面積