Geoserver+Openlayers拉框查询
1.代码
1 <!doctype html> 2 <html> 3 <head> 4 <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 5 <title>openlayers</title> 6 <link rel="stylesheet" href="geoserver/ol.css" type="text/css"> 7 <script src="geoserver/ol.js"></script> 8 <script src="bower_components/jquery/dist/jquery.min.js"></script> 9 <link rel="stylesheet" href="plugins/layui-v2.4.3/layui/css/layui.css"> 10 <script src="plugins/layui-v2.4.3/layui/layui.js" charset="utf-8"></script> 11 <link rel="stylesheet" href="https://openlayers.org/en/v3.20.1/css/ol.css" type="text/css"> 12 <#--注意openlayer的版本号,高版本存在es6中新语法不兼容的情况--> 13 <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestanimationframe,element.prototype.classlist,url"></script> 14 <script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script> 15 </head> 16 <style> 17 #map { 18 height: 600px; 19 /*width: 1024px;*/ 20 /* float: left;*/ 21 } 22 </style> 23 <body> 24 <div id="map"> 25 <form class="form-inline"> 26 <label>查询类型</label> 27 <select id="type"> 28 <option value="none">none</option> 29 <option value="point">点击</option> 30 <option value="polygon">多边形</option> 31 <option value="circle">拉框</option> 32 </select> 33 </form> 34 </div> 35 <script> 36 var map = new ol.map({ 37 target: 'map', 38 view: new ol.view({ 39 projection: 'epsg:4326', 40 center: [104.07, 30.72], 41 zoom: 7 42 }) 43 }); 44 var wfsparams = { 45 service: 'wfs', 46 version: '1.1.1', 47 request: 'getfeature', 48 typename: 'map_dz:tl_lx_g', //图层名称,可以是单个或多个 49 outputformat: 'text/javascript', //重点,不要改变 50 format_options: 'callback:loadfeatures' //回调函数声明 51 }; 52 53 var vectorsource = new ol.source.vector({ 54 format: new ol.format.geojson(), 55 loader: function (extent, resolution, projection) { //加载函数 56 var url = 'http://192.168.1.113:8080/geoserver/map_dz/wms'; 57 $.ajax({ 58 url: url, 59 data: $.param(wfsparams), //传参 60 type: 'get', 61 datatype: 'jsonp', //解决跨域的关键 62 jsonpcallback: 'loadfeatures' //回调 63 64 }); 65 }, 66 strategy: ol.loadingstrategy.tile(new ol.tilegrid.createxyz({ 67 maxzoom: 20 68 })), 69 projection: 'epsg:4326' 70 }); 71 //回调函数使用 72 window.loadfeatures = function (response) { 73 vectorsource.addfeatures((new ol.format.geojson()).readfeatures(response)); //载入要素 74 }; 75 var vectorlayer = new ol.layer.vector({ 76 source: vectorsource, 77 style: new ol.style.style({ 78 stroke: new ol.style.stroke({ 79 color: 'rgba(0, 0, 255, 1.0)', 80 width: 2 81 }) 82 }) 83 }); 84 map.addlayer(vectorlayer); 85 var draw; 86 var typeselect = document.getelementbyid('type'); 87 var value; 88 var num=10;//用于删除之前的框,表示号,随便取一个 89 function addinteraction() { 90 if (value !== 'none') { 91 if (value === 'polygon') { 92 draw = new ol.interaction.draw({ 93 source: vectorlayer.getsource(), 94 style: new ol.style.style({ 95 stroke: new ol.style.stroke({ 96 color: '#ffcc33', 97 width: 2 98 }), 99 image: new ol.style.circle({ 100 radius: 7, 101 fill: new ol.style.fill({ 102 color: '#ffcc33' 103 }) 104 }) 105 }), 106 type: value 107 }); 108 } else if (value === 'circle') { 109 draw = new ol.interaction.draw({ 110 source: vectorlayer.getsource(), 111 style: new ol.style.style({ 112 stroke: new ol.style.stroke({ 113 color: '#ffcc33', 114 width: 2 115 }), 116 image: new ol.style.circle({ 117 radius: 7, 118 fill: new ol.style.fill({ 119 color: '#ffcc33' 120 }) 121 }) 122 }), 123 type: value, 124 geometryfunction: ol.interaction.draw.createbox() 125 }); 126 } else if (value === 'point') { 127 draw = new ol.interaction.draw({ 128 source: vectorlayer.getsource(), 129 style: new ol.style.style({ 130 stroke: new ol.style.stroke({ 131 color: '#ffcc33', 132 width: 2 133 }), 134 image: new ol.style.circle({ 135 radius: 7, 136 fill: new ol.style.fill({ 137 color: '#ffcc33' 138 }) 139 }) 140 }), 141 type: value 142 }); 143 } 144 145 map.addinteraction(draw); 146 //删除之前draw的部分 147 draw.on('drawstart',function(evt) { 148 var featureadd=vectorlayer.getsource().getfeaturebyid(num); 149 if(featureadd!=null){ 150 vectorlayer.getsource().removefeature(featureadd); 151 } 152 }); 153 //绘图结束,处理选中部分 154 draw.on('drawend',function(e){ 155 e.feature.setid(num); 156 var geom=e.feature.getgeometry(); 157 var coor = geom.v; 158 mapselect(coor); 159 }); 160 } 161 } 162 //选择事件 163 typeselect.onchange = function() { 164 value = typeselect.value; 165 map.removeinteraction(draw); 166 addinteraction(); 167 }; 168 169 //draw图像与原始数据相交 170 function mapselect(coor) { 171 if(value=='point') { 172 coor = [coor[0]-0.0001,coor[1]-0.0001,coor[0]+0.0001,coor[1]+0.0001]; 173 } 174 var filter = '<filter xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><bbox><propertyname>geom</propertyname><gml:envelope srsname="epsg:4326"><gml:lowercorner>' + coor[0] + ' ' + coor[1] + '</gml:lowercorner><gml:uppercorner>' + coor[2] + ' ' + coor[3] + '</gml:uppercorner></gml:envelope></bbox></filter>'; 175 getfeature({ 176 typename: 'map_dz:tl_lx_g',//查询的服务图层名称 177 filter: filter,//查询条件 178 callback: 'getidentifyroadgrid'//查询的回调函数 179 }); 180 } 181 var selectnum=[]; 182 var geojsonformat = new ol.format.geojson({defaultdataprojection: "epsg:4326"}); 183 function getidentifyroadgrid(res) { 184 var querydata = []; 185 var features = geojsonformat.readfeatures(res); 186 187 for (var nu = 0; nu<selectnum.length;nu++) { 188 var featureselect=vectorlayer.getsource().getfeaturebyid(selectnum[nu]); 189 if(featureselect!=null) { 190 featureselect.setstyle( 191 new ol.style.style({ 192 stroke: new ol.style.stroke({ 193 color: 'rgba(0, 0, 255, 1.0)', 194 width: 2 195 }) 196 })); 197 } 198 } 199 selectnum=[]; 200 for (var i = 0; i < features.length; i++) { 201 var feature = features[i]; 202 console.log(feature); 203 selectnum.push(feature.f); 204 var featureselectcurrent=vectorlayer.getsource().getfeaturebyid(feature.f); 205 featureselectcurrent.setstyle( 206 new ol.style.style({ 207 stroke: new ol.style.stroke({ 208 color: '#ff4118', 209 width: 2 210 }) 211 })); 212 var lxmc = feature.h["lxmc"]; 213 var ldbm = feature.h["ldbm"]; 214 var lxbh = feature.h["lxbh"]; 215 var result = { 216 "lxmc": lxmc, 217 "ldbm": ldbm, 218 "lxbh": lxbh, 219 "setindex": i 220 }; 221 querydata.push(result) 222 } 223 console.log(selectnum); 224 var tableins=null; 225 var datatable = "<table class=\"layui-table\" lay-filter=\"demo\" id=\"jointab\"></table>"; 226 layui.use(['table', 'layer'], function () { 227 var table = layui.table; 228 var layer = layui.layer; 229 var index = layer.open({ 230 type: 1 //page层类型 231 , title: '要素属性' 232 , shade: 0 //遮罩透明度 233 , anim: 0 //0-6的动画形式,-1不开启 234 , content: datatable 235 , offset: ['250px', '290px'] 236 , zindex: 1 237 , scrollbar: false 238 , resize: false 239 , skin: 'layui-layer-molv' 240 , closebtn: 2 241 , btn: ["关闭"] 242 , yes: function (index) { 243 layer.close(index); 244 } 245 , cancel: function () { 246 } 247 }); 248 tableins = table.render({ 249 elem: "#jointab", 250 width: "auto", 251 height: "auto", 252 data: querydata, 253 initsort: {field: 'lxbh', type: 'desc'}, 254 cols: [[ 255 {field: 'lxmc', title: '路线名称', width: 150, align: 'center', sort: true}, 256 {field: 'ldbm', title: '路线编号', width: 150, align: 'center', sort: true}, 257 {field: 'lxbh', title: '路段编码', width: 150, align: 'center', sort: true} 258 ]] 259 }); 260 layer.style(index, { 261 opacity: 0.8 262 }); 263 }); 264 265 if (tableins) { 266 tableins.reload({ 267 data: querydata 268 }); 269 } else { 270 // console.log("do nothing!"); 271 } 272 } 273 274 //请求wfs数据 275 function getfeature(options) { 276 $.ajax(/*'http://192.168.1.113:8080/geoserver/map_dz/wms', */{ 277 type: 'get', 278 url: 'http://192.168.1.113:8080/geoserver/map_dz/wms', 279 data: { 280 service: 'wfs', 281 version: '1.1.1', 282 request: 'getfeature', 283 typename: options.typename, 284 srsname: options.srid, 285 outputformat: 'text/javascript', 286 viewparams: options.viewparams, 287 bbox: (options.extent === undefined) ? undefined : options.extent.join(',') + ',' + options.srid, 288 filter: options.filter 289 }, 290 datatype: 'jsonp', 291 jsonp: 'format_options', 292 jsonpcallback: 'callback:' + options.callback 293 }); 294 295 } 296 297 </script> 298 </body> 299 </html>
2.代码解释
这一部分是主要针对用户做此功能的时候,遇到的问题进行总结:
在引入 openlayers 的 js 文件的时候,注意版本号,5.0+ 的版本中大量应用了es6 的最新特性,如果直接引入 5.0+ ,可能与前期的项目有所冲突,所以这里建议使用低版本,同样能完成拉框查询
这里主要通过 draw 对象进行框选的,draw 的本质是在图层上兴建 shape ,那么在下一次框选的时候,需要把上次 draw 的框去掉:(回答了网上用户的提问:openlayers 在重新画图(圆或矩形)如何清除之前的图,openlayer删除上一次绘制的图)
首先记录框选时,增加的框框的id
然后在下次框选之前,通过 id 找到上次那个 feature,并删掉
对选中的对象进行重新设置颜色,这里主要通过 style 属性进行处理:
在下次选中对象的时候,删除上次选中对象的样式 将选中对象的 id 压到数组汇总
在下次设置选中对象的样式之前,遍历数组,对上次选中的feature进行样式设置(设置为原来的样式)
3.结果
参考
https://www.cnblogs.com/kkyyhh96/p/6379515.html
https://blog.csdn.net/songjian1314/article/details/17263865
https://blog.csdn.net/shaxiaozilove/article/details/60780175
https://blog.csdn.net/m0_37659871/article/details/80598589
https://openlayers.org/en/latest/examples/draw-features.html
https://openlayers.org/en/latest/examples/draw-shapes.html