打算实现的功能:基于OpenLayers实现对地图中城市POI模糊查询,并且能提供基于位置的查询(GIS中就是基于圆的查询,通俗的说就是当确定用户位置后,可以查询用户周边一定范围内的POI)和基于多边形的查询(用户自己画出多边形,实现在多边形范围内的POI查询),设定的界面如下图所示
1. 界面实现
页面的body主体实现如下:
<body onload="init()"> <div id="searchDiv" style="position:absolute;top:50px;left:80px;width:300px;height:100px;z-index:99999;border: 1px solid #ccc; padding: 1em;"> <ul id="controls"> <li> <label for="pointToggle">关键字:</label> <input name="searchkey" id="searchkey" type="text"> <input name="type" value="搜索" id="polygonToggle" onclick="search()" type="button"> </li> <li> <input name="type" value="point" id="free" checked="checked" type="radio" onclick="setfree();"> <label for="pointToggle">不限</label> </li> <li> <input name="type" value="point" id="nearbySearch" onclick="drawCircle();" type="radio"> <label for="nearbySearch">周边搜索</label> <select id="radius" onchange="setSize(parseFloat(this.value))" style="width:100px" > <option value="0.01000">1000</option> <option value="0.02000">2000</option> <option value="0.03000">3000</option> </select> <label for="pointToggle">以内</label> </li> <li> <input name="type" value="polygon" id="polygonSearch" onclick="drawPolyon();" type="radio"> <label for="polygonSearch">多边形搜索</label> </li> </ul> </div> <div id="directionDiv" style="position:absolute;top:200px;left:80px;width:300px;z-index:99999;border: 1px solid #ccc; padding: 1em;"> <table> <tr><td> 起点:</td><td ><input id="start" type="text" ></input><input id="starthidden" type="text" style="display:none"></input></td><td rowspan="2" > <input id="direction" style="width:80px;height:40px" type="button" value="搜索路径" onclick="direction()" ></input></tr> <tr><td> 终点:</td><td><input id="end" type="text" ></input><input id="endhidden" type="text" style="display:none"></input></td></tr> </table> </div> <div id="map" class="smallmap"> </div> </body>
2. 周边检索时画圆和画多边形方法方法的实现
/** * 画圆和画多边形方法实现 */ var drawPolygnControl; var polyOptions; function drawCircle() { //drawPolygnControl.deactivate(); //删除之前画的圆或多边形 setfree(); //if(markslayer!=null) //markslayer.removeAllFeatures(); if (document.getElementById("nearbySearch").checked) { //polyOptions = {sides: 4}; drawPolygnControl = new OpenLayers.Control.DrawFeature(polygonLayer, OpenLayers.Handler.RegularPolygon, { handlerOptions : polyOptions }); setOptions({ sides : parseInt("40") }); setSize(parseFloat("0.01000")); map.addControl(drawPolygnControl); drawPolygnControl.activate(); } else { //drawControls.deactivate(); // marks.clearMarkers(); // polygonLayer.removeAllFeatures(); //drawPolygnControl.deactivate(); //ap.removeControl(drawPolygnControl); //alert("操你妹的"); setfree(); } } function drawPolyon() { //click.deactivate(); //polygonLayer.removeAllFeatures(); setfree(); //if(markslayer!=null) //markslayer.removeAllFeatures(); if (document.getElementById("polygonSearch").checked) { drawPolygnControl = new OpenLayers.Control.DrawFeature(polygonLayer, OpenLayers.Handler.Polygon); map.addControl(drawPolygnControl); drawPolygnControl.activate(); } else { //drawControls.deactivate(); // marks.clearMarkers(); // polygonLayer.removeAllFeatures(); //drawPolygnControl.deactivate(); //ap.removeControl(drawPolygnControl); setfree(); } } function setfree() { if (drawPolygnControl instanceof OpenLayers.Control.DrawFeature && drawPolygnControl != null) { drawPolygnControl.deactivate(); map.removeControl(drawPolygnControl); } click.deactivate(); if (polygonLayer != null) { polygonLayer.removeAllFeatures(); } if (markslayer != null) markslayer.removeAllFeatures(); } function setOptions(options) { drawPolygnControl.handler.setOptions(options); } function setSize(fraction) { var radius = fraction * map.getExtent().getHeight(); drawPolygnControl.handler.setOptions({ radius : radius, angle : 0 }); }
在上述代码中drawCircle函数中有一个polyOptions,需要在init()函数中对其进行如下设置:
polyOptions = {sides: 4};
3. 检索功能的实现,这里把周边位置检索和多边形检索统称为基于范围的查找,把界面中直接基于关键字的查找称为普通查找。这里普通查找用一种方法实现,基于范围的查找用一种方法实现。基于范围的查找中无论是基于圆的查找还是基于多边形的查找其实现原理都是先基于关键字查找,然后再查找的结果再跟圆或者多边形进行叠加,如果相交则该POI点符合条件。
实现代码为:
/** * POI检索服务 * 支持普通检索,周边检索和多边形检索 * */ var geometry; var markslayer;//存放选择出的POI function search() { if (drawPolygnControl instanceof OpenLayers.Control.DrawFeature && drawPolygnControl != null) { drawPolygnControl.deactivate(); map.removeControl(drawPolygnControl); } if (markslayer != null) { markslayer.removeAllFeatures(); map.removeLayer(markslayer); } var searchstr = document.getElementById("searchkey").value; if (searchstr == null || searchstr == "") { alert("请输入搜索关键字!"); return; } if (marks != null) marks.clearMarkers(); if (routeLayer != null) routeLayer.removeAllFeatures(); if (stopLayer != null) stopLayer.removeAllFeatures(); //基于位置查找和基于多边形查找功能实现 if (document.getElementById("nearbySearch").checked || document.getElementById("polygonSearch").checked) { geometry = polygonLayer.features[0].geometry; markslayer = new OpenLayers.Layer.Vector("WFS", { strategies : [ new OpenLayers.Strategy.BBOX() ], protocol : new OpenLayers.Protocol.WFS({ url : "http://192.168.1.50:8080/geoserver/wfs?", featureType : "res2_4m", featureNS : "http://www.cxzx.com" }), styleMap : new OpenLayers.StyleMap({ externalGraphic : 'img/marker-target.png', graphicWidth : 20, graphicHeight : 24, graphicYOffset : -24, }), filter : new OpenLayers.Filter.Logical({ type : OpenLayers.Filter.Logical.AND, filters : [ new OpenLayers.Filter.Comparison({ type : OpenLayers.Filter.Comparison.LIKE, property : "NAME", value : "*" + searchstr + "*" }), new OpenLayers.Filter.Spatial({ type : OpenLayers.Filter.Spatial.INTERSECTS, value : geometry,// projection : 'EPSG:4326' }) ] }) }); map.addLayer(markslayer); addPop(); } //普通检索功能实现 else { markslayer = new OpenLayers.Layer.Vector("WFS", { strategies : [ new OpenLayers.Strategy.BBOX() ], protocol : new OpenLayers.Protocol.WFS({ url : "http://192.168.1.50:8080/geoserver/wfs?", featureType : "res2_4m", featureNS : "http://www.cxzx.com" }), styleMap : new OpenLayers.StyleMap({ externalGraphic : 'img/marker-target.png', graphicWidth : 20, graphicHeight : 24, graphicYOffset : -24, }),// filter : new OpenLayers.Filter.Comparison({ type : OpenLayers.Filter.Comparison.LIKE, property : "NAME", value : "*" + searchstr + "*" }) }); map.addLayer(markslayer); addPop(); } }//end function search
上述代码中,featureType :
"res2_4m",为城市POI所在图层,featureNS :
"http://www.cxzx.com"为地图数据所在工作区的URI,如下图所示:
4. 实现的功能
普通查询中,输入“州”检索结果如下:
周边检索中,设定要用户所在位置和圆半径后,检索结果如下:
多边形检索中,画好多边形,设置好关键字后,检索结果如下:
时间: 2024-10-03 14:03:12