您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)使用Openlayers實(shí)現(xiàn)測(cè)量功能,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <link rel="stylesheet" href="./ol.css" type="text/css"> <script src="./ol.js" type="text/javascript"></script> <link href="https://cdn.bootcss.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> <style type="text/css"> #map { width: 100%; height: 100%; position: absolute; } #menu { float: left; position: absolute; bottom: 50px; right: 30px; 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: #ffffff; color: black; border: 1px solid white; } .tooltip-measure:before, .tooltip-static:before { border-top: 6px solid rgba(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: #ffffff; } #scalebar { float: left; margin-bottom: 10px; } </style> </head> <body> <div id="map"> <div id="menu"> <label>測(cè)量類型選擇</label> <select id="type"> <option value="length">長(zhǎng)度</option> <option value="area">面積</option> </select> <label class="checkbox label"><input type="checkbox" id="geodesic" />使用大地測(cè)量</label> </div> </div> <div id="scalebar"></div> <script type="text/javascript"> $(function () { //格式 var format = 'image/png'; var bounds = [73.441277, 18.159829, 135.08693, 53.561771];//范圍 //中國(guó)各省底圖(面) var ImageMap = new ol.layer.Tile({ source: new ol.source.TileWMS({ ratio: 1, //自己的服務(wù)url url: 'http://localhost:8080/geoserver/China_Test/wms', //設(shè)置服務(wù)參數(shù) params: { 'FORMAT': format, 'VERSION': '1.1.0', STYLES: '', //圖層信息 LAYERS: 'China_Test:C_Test', } }) }); //設(shè)置地圖投影 var projection = new ol.proj.Projection({ code: 'EPSG:4326',//投影編碼 units: 'degrees', axisOrientation: 'neu' }); //設(shè)置地圖 實(shí)例化一個(gè)地圖 var map = new ol.Map({ //地圖中的比例尺等控制要素 controls: ol.control.defaults({ attribution: false }).extend([ new ol.control.FullScreen(),//全屏顯示 ]), //設(shè)置顯示的容器 target: 'map', //設(shè)置圖層 layers: [ //添加圖層 ImageMap ], //設(shè)置視圖 view: new ol.View({ //設(shè)置投影 projection: projection, center: [102.73333, 25.05], //初始在某一點(diǎn) minZoom: 3, zoom: 5, //縮放級(jí)別 }), }); //定義矢量數(shù)據(jù)源 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: '#e21e0a', width: 2 }), image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: '#ffcc33' }) }) }) }); //將矢量圖層添加到地圖中 map.addLayer(vector); //添加比例尺控件 var scaleLineControl = new ol.control.ScaleLine({ units: 'metric', target: 'scalebar', className: 'ol-scale-line' }); map.addControl(scaleLineControl); //實(shí)例化鼠標(biāo)位置控件 var mousePositionControl = new ol.control.MousePosition({ coodrdinateFormat: ol.coordinate.createStringXY(4),//坐標(biāo)格式 //地圖投影坐標(biāo)系 projection: new ol.proj.Projection({ code: 'EPSG:4326',//投影編碼 units: 'degrees', axisOrientation: 'neu' }), //className:'tip', target: document.getElementById('tip'),//顯示鼠標(biāo)位置信息的目標(biāo)容器 undefinedHTML: ' '//未定義坐標(biāo)標(biāo)記 }); //添加鼠標(biāo)位置控件 map.addControl(mousePositionControl); //實(shí)例化鷹眼控件 var overviewMapControl = new ol.control.OverviewMap({ //在鷹眼中相同坐標(biāo)系下不通數(shù)據(jù)源的圖層 layers: [ new ol.layer.Tile({ source: new ol.source.OSM({ 'url': 'http://{a-c}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png' }) }) ], collapseLabel: '\u00BB', lable: '\u00AB', collapsed: false, }); //添加鷹眼 map.addControl(overviewMapControl); //創(chuàng)建一個(gè)WGS84球體對(duì)象 var wgs84Sphere = new ol.Sphere(6378137); //創(chuàng)建一個(gè)當(dāng)前要繪制的對(duì)象 var sketch = new ol.Feature(); //創(chuàng)建一個(gè)幫助提示框?qū)ο? var helpTooltipElement; //創(chuàng)建一個(gè)幫助提示信息對(duì)象 var helpTooltip; //創(chuàng)建一個(gè)測(cè)量提示框?qū)ο? var measureTooltipElement; //創(chuàng)建一個(gè)測(cè)量提示信息對(duì)象 var measureTooltip; //繼續(xù)繪制多邊形的提示信息 var continuePolygonMsg = '單擊以繼續(xù)繪制多邊形'; //繼續(xù)繪制線段的提示信息 var continueLineMsg = '單擊以繼續(xù)繪制直線'; //鼠標(biāo)移動(dòng)觸發(fā)的函數(shù) var pointerMoveHandler = function (evt) { //Indicates if the map is currently being dragged. //Only set for POINTERDRAG and POINTERMOVE events. Default is false. //如果是平移地圖則直接結(jié)束 if (evt.dragging) { return; } //幫助提示信息 var helpMsg = '單擊開始'; if (sketch) { //獲取繪圖對(duì)象的幾何要素 var geom = sketch.getGeometry(); //如果當(dāng)前繪制的幾何要素是多線段,則將繪制提示信息設(shè)置為多線段繪制提示信息 if (geom instanceof ol.geom.Polygon) { helpMsg = continuePolygonMsg; } else if (geom instanceof ol.geom.LineString) { helpMsg = continueLineMsg; } } //設(shè)置幫助提示要素的內(nèi)標(biāo)簽為幫助提示信息 helpTooltipElement.innerHTML = helpMsg; //設(shè)置幫助提示信息的位置 helpTooltip.setPosition(evt.coordinate); //移除幫助提示要素的隱藏樣式 $(helpTooltipElement).removeClass('hidden'); }; //觸發(fā)pointermove事件 map.on('pointermove', pointerMoveHandler); //當(dāng)鼠標(biāo)移除地圖視圖的時(shí)為幫助提示要素添加隱藏樣式 $(map.getViewport()).on('mouseout', function () { $(helpTooltipElement).addClass('hidden'); }); //獲取大地測(cè)量復(fù)選框 var geodesicCheckbox = document.getElementById('geodesic'); //獲取類型 var typeSelect = document.getElementById('type'); //定義一個(gè)交互式繪圖對(duì)象 var draw; //添加交互式繪圖對(duì)象的函數(shù) function addInteraction() { // 獲取當(dāng)前選擇的繪制類型 var type = typeSelect.value == 'area' ? 'Polygon' : 'LineString'; //創(chuàng)建一個(gè)交互式繪圖對(duì)象 draw = new ol.interaction.Draw({ //繪制的數(shù)據(jù)源 source: source, //繪制類型 type: 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)' }) }) }) }); //將交互繪圖對(duì)象添加到地圖中 map.addInteraction(draw); //創(chuàng)建測(cè)量提示框 createMeasureTooltip(); //創(chuàng)建幫助提示框 createHelpTooltip(); //定義一個(gè)事件監(jiān)聽 var listener; //定義一個(gè)控制鼠標(biāo)點(diǎn)擊次數(shù)的變量 var count = 0; //繪制開始事件 draw.on('drawstart', function (evt) { //The feature being drawn. sketch = evt.feature; //提示框的坐標(biāo) var tooltipCoord = evt.coordinate; //監(jiān)聽?zhēng)缀我氐腸hange事件 //Increases the revision counter and dispatches a 'change' event. listener = sketch.getGeometry().on('change', function (evt) { //The event target. //獲取繪制的幾何對(duì)象 var geom = evt.target; //定義一個(gè)輸出對(duì)象,用于記錄面積和長(zhǎng)度 var output; if (geom instanceof ol.geom.Polygon) { map.removeEventListener('singleclick'); map.removeEventListener('dblclick'); //輸出多邊形的面積 output = formatArea(geom); //獲取多變形內(nèi)部點(diǎn)的坐標(biāo) tooltipCoord = geom.getInteriorPoint().getCoordinates(); } else if (geom instanceof ol.geom.LineString) { //輸出多線段的長(zhǎng)度 output = formatLength(geom); //獲取多線段的最后一個(gè)點(diǎn)的坐標(biāo) tooltipCoord = geom.getLastCoordinate(); } //設(shè)置測(cè)量提示框的內(nèi)標(biāo)簽為最終輸出結(jié)果 measureTooltipElement.innerHTML = output; //設(shè)置測(cè)量提示信息的位置坐標(biāo) measureTooltip.setPosition(tooltipCoord); }); //地圖單擊事件 map.on('singleclick', function (evt) { //設(shè)置測(cè)量提示信息的位置坐標(biāo),用來確定鼠標(biāo)點(diǎn)擊后測(cè)量提示框的位置 measureTooltip.setPosition(evt.coordinate); //如果是第一次點(diǎn)擊,則設(shè)置測(cè)量提示框的文本內(nèi)容為起點(diǎn) if (count == 0) { measureTooltipElement.innerHTML = "起點(diǎn)"; } //根據(jù)鼠標(biāo)點(diǎn)擊位置生成一個(gè)點(diǎn) var point = new ol.geom.Point(evt.coordinate); //將該點(diǎn)要素添加到矢量數(shù)據(jù)源中 source.addFeature(new ol.Feature(point)); //更改測(cè)量提示框的樣式,使測(cè)量提示框可見 measureTooltipElement.className = 'tooltip tooltip-static'; //創(chuàng)建測(cè)量提示框 createMeasureTooltip(); //點(diǎn)擊次數(shù)增加 count++; }); //地圖雙擊事件 map.on('dblclick', function (evt) { var point = new ol.geom.Point(evt.coordinate); source.addFeature(new ol.Feature(point)); }); }, this); //繪制結(jié)束事件 draw.on('drawend', function (evt) { count = 0; //設(shè)置測(cè)量提示框的樣式 measureTooltipElement.className = 'tooltip tooltip-static'; //設(shè)置偏移量 measureTooltip.setOffset([0, -7]); //清空繪制要素 sketch = null; //清空測(cè)量提示要素 measureTooltipElement = null; //創(chuàng)建測(cè)量提示框 createMeasureTooltip(); //移除事件監(jiān)聽 ol.Observable.unByKey(listener); //移除地圖單擊事件 map.removeEventListener('singleclick'); }, this); } //創(chuàng)建幫助提示框 function createHelpTooltip() { //如果已經(jīng)存在幫助提示框則移除 if (helpTooltipElement) { helpTooltipElement.parentNode.removeChild(helpTooltipElement); } //創(chuàng)建幫助提示要素的div helpTooltipElement = document.createElement('div'); //設(shè)置幫助提示要素的樣式 helpTooltipElement.className = 'tooltip hidden'; //創(chuàng)建一個(gè)幫助提示的覆蓋標(biāo)注 helpTooltip = new ol.Overlay({ element: helpTooltipElement, offset: [15, 0], positioning: 'center-left' }); //將幫助提示的覆蓋標(biāo)注添加到地圖中 map.addOverlay(helpTooltip); } //創(chuàng)建測(cè)量提示框 function createMeasureTooltip() { //創(chuàng)建測(cè)量提示框的div measureTooltipElement = document.createElement('div'); measureTooltipElement.setAttribute('id', 'lengthLabel'); //設(shè)置測(cè)量提示要素的樣式 measureTooltipElement.className = 'tooltip tooltip-measure'; //創(chuàng)建一個(gè)測(cè)量提示的覆蓋標(biāo)注 measureTooltip = new ol.Overlay({ element: measureTooltipElement, offset: [0, -15], positioning: 'bottom-center' }); //將測(cè)量提示的覆蓋標(biāo)注添加到地圖中 map.addOverlay(measureTooltip); } //測(cè)量類型發(fā)生改變時(shí)觸發(fā)事件 typeSelect.onchange = function () { //移除之前的繪制對(duì)象 map.removeInteraction(draw); //重新進(jìn)行繪制 addInteraction(); }; //格式化測(cè)量長(zhǎng)度 var formatLength = function (line) { //定義長(zhǎng)度變量 var length; //如果大地測(cè)量復(fù)選框被勾選,則計(jì)算球面距離 if (geodesicCheckbox.checked) { //獲取坐標(biāo)串 var coordinates = line.getCoordinates(); //初始長(zhǎng)度為0 length = 0; //獲取源數(shù)據(jù)的坐標(biāo)系 var sourceProj = map.getView().getProjection(); //進(jìn)行點(diǎn)的坐標(biāo)轉(zhuǎn)換 for (var i = 0; i < coordinates.length - 1; i++) { //第一個(gè)點(diǎn) var c1 = ol.proj.transform(coordinates[i], sourceProj, 'EPSG:4326'); //第二個(gè)點(diǎn) var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326'); //獲取轉(zhuǎn)換后的球面距離 //Returns the distance from c1 to c2 using the haversine formula. length += wgs84Sphere.haversineDistance(c1, c2); } } else { //計(jì)算平面距離 length = Math.round(line.getLength() * 100) / 100; } //定義輸出變量 var output; //如果長(zhǎng)度大于1000,則使用km單位,否則使用m單位 if (length > 1000) { output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km'; //換算成KM單位 } else { output = (Math.round(length * 100) / 100) + ' ' + 'm'; //m為單位 } return output; }; //格式化測(cè)量面積 var formatArea = function (polygon) { //定義面積變量 var area; //如果大地測(cè)量復(fù)選框被勾選,則計(jì)算球面面積 if (geodesicCheckbox.checked) { //獲取初始坐標(biāo)系 var sourceProj = map.getView().getProjection(); var geom = polygon.clone().transform(sourceProj, 'EPSG:4326'); //獲取多邊形的坐標(biāo)系 var coordinates = geom.getLinearRing(0).getCoordinates(); //獲取球面面積 area = Math.abs(wgs84Sphere.geodesicArea(coordinates)); } else { //獲取平面面積 area = polygon.getArea(); } //定義輸出變量 var output; //當(dāng)面積大于10000時(shí),轉(zhuǎn)換為平方千米,否則為平方米 if (area > 10000) { output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>'; } else { output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>'; } return output; }; //添加交互繪圖對(duì)象 addInteraction(); }); </script> </body> </html>
效果圖:
PS:這里調(diào)用的圖層是使用geoserver發(fā)布的一個(gè)組合圖層,可以自行定義。
以上就是使用Openlayers實(shí)現(xiàn)測(cè)量功能,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。