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>
时间: 2024-11-05 00:18:16