OpenLayers中基于Filter的WFS查询

打算实现的功能:基于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-11-05 06:25:30

OpenLayers中基于Filter的WFS查询的相关文章

云计算-hbase中filter只能用于查询吗?

问题描述 hbase中filter只能用于查询吗? 1.fiter还能用于put和delete吗? 2.hbase又能判断表是否存在的方法,有能判断表中是否有列族?有能判断类族中有列?的方法吗?(我看api好像没有啊)如果没有怎么实现这样的方法? 3.hbase的时间戳不指定是默认,可是有什么属性之类的能设定让他连系统默认都不使用吗?(个人感觉hbase没有时间戳了就没有版本了,不用时间戳好像没意义.) 4.hbase当操作表的结构时候,传值设定表的属性,那么参数太多,使用哪个传值方式更合适(m

openlayers3 在地图上叠加WFS查询矢量图层

随着终端设备计算能力的加强,用户在使用地图的时候也需要越来越多的交互效果.比如现在很火的室内导航,为了获得好的用户体验,就需要当用户单击某一商店的时候该商店的颜色能相应的变化,这就需要叠加矢量图层.如何能在瓦片地图之上叠加矢量图层呢,这个就需要用到WFS查询. 我的思路是:基于WFS查询把得到需要矢量显示的图层中数据,然后再显示.具体思路为: 1.通过geoserver的WFS服务查询所需要矢量显示的数据信息 2.设置矢量数据的显示样式 3.openlayers添加矢量图层 4.设置鼠标移上去的

利用JQuery方便实现基于Ajax的数据查询、排序和分页功能

ajax|分页|排序|数据        之前很少会用javascript去实现页功能主要怕麻烦,但了解JQuery后这种想法发生了变化:有了这样的脚本组件就可以在编写脚本时方便和HTML隔离出来,这样编写高重用性的脚本就更方便.下面就是介绍在学习JQuery过程中编写的基于Ajax的数据查询.排序和分页功能的复用脚本,只要遵循脚本的某些规则描述HTML把脚本文件引入就可以方便实现以上描述的功能.        先看下实现功能的脚代码: /**应用脚本规则:           引用脚本: JQ

基于设计选择媒体查询不是基于移动设备

文章简介:基于设计的媒体查询. 在刚一开始的时候,我们已经把特定移动设备的媒体查询运用到我们的网站上,并且服务于我们(网站),因为当时我们只是需要一种应急式的响应式设计解决方案来适应iPhone和屏幕相似的智能手机. 但是随着大量移动设备不断地被推向市场,现在是时候重新考虑使用在我们设计中的公用响应式设计断点了.为什么呢?因为原来方法重用性不高.我们也必须去改变下面讲到需要改变原来方法的理由和为什么我们要在这些特殊点上设置我们的响应式设计断点的背后积极因素. 我将会围绕"基于设计的媒体查询&qu

Visual Studio .NET Enterprise Architect 中基于 Visio 的数据库建模:第二部分

enterprise|visual|数据|数据库  Terry HalpinMicrosoft Corporation 2001年11月 摘要:本文是介绍 Microsoft Visual Studio Enterprise Architect 中基于 Visio 的数据库建模组件系列文章中的第二篇.第一部分讨论了如何创建新的对象角色建模 (ORM) 源模型,如何在 fact editor(事实编辑器)中添加句子类型.基本内部约束及示例,如何将事实类型从 business rules edito

Oracle 9i中的一个闪回查询操作实例

在利用闪回功能前需要确认: 1.用户有对dbms_flashback包有执行权限! 2.进行闪回查询必须设置自动回滚段管理,在init.ora设置参数UNDO_MANAGEMENT=AUTO,参数UNDO_RETENTION=n,决定了能往前闪回的最大时间,值越大就需要越多Undo空间. Oracle 9i中闪回查询操作实例 查看Oracle中Delete和Commit操作的流程分析 例:Oracle 9i的Flashback Query操作. (1)创建闪回查询用户 SQL> create u

代码-如何在VS中使用C#设计程序实现查询点、线、面要素的空间查询

问题描述 如何在VS中使用C#设计程序实现查询点.线.面要素的空间查询 各位大婶 本人GIS专业大三学生一枚 实习中遇到任务 要基于MO的开发环境实现点.线.面要素的空间查询?因为以前学的比较渣 然后现在对于VS操作步骤基本不会 然后对于代码也是一脸茫然 跪求会的大神在百忙之中能知道一二 代表组内成员不胜感激! 解决方案 大婶们来帮个忙呗 真的很着急啊 唉 解决方案二: 这么急,直接上淘宝找人做吧

[译] 理解 NodeJS 中基于事件驱动的架构

本文讲的是[译] 理解 NodeJS 中基于事件驱动的架构, 原文地址:Understanding Node.js Event-Driven Architecture 原文作者:Samer Buna 译文出自:掘金翻译计划 译者:刘德元 薛定谔的猫 校对者:bambooom zaraguo 理解 NodeJS 中基于事件驱动的架构 绝大部分 Node.js 对象,比如 HTTP 请求.响应以及"流",都使用了 eventEmitter 模块来支持监听和触发事件. 事件驱动最简单的形式是

VC中基于 Windows 的精确定时

在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位 机定时向下位机发送命令和传送数据等.特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要精确定时操作. 众所周知,Windows 是基于消息机制的系统,任何事件的执行都是通过发送和接收消息来完成的. 这样就带来了一些问题,如一旦计算机的CPU被某个进程占用,或系统资源紧张时,发送到消息队列 中的消息就暂时被挂起,得不到实时处理.因此,不能简单地通过Windows消息引发一个对定时要求