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-10-03 14:03:12

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

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

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

OpenLayers自定义投影,转换OpenLayers中加载的OSM的默认投影坐标

giser都会遇到一个问题就是数据与底图坐标系不符合导致偏移的产生. Openlayers中应该只包含EPSG:3857和EPSG:4326,其中EPSG:3857更是作为默认的OSM底图的坐标.(这是根据官方文档以及查到资料,猜的..此处放出官网文档截图) 可是手上的数据是EPSG:4549的呀,,,于是只能辛苦自定义并转换.根据官网所说,如果用proj4.js,那么要加proj4.defs();...算了     不解释了   直接上代码(小声bb,因为作者英语不好,实在是装不了这个X,另外

GoldenGate中使用FILTER,COMPUTE 和SQLEXEC命令

本文主要介绍OGG中一些过滤或计算函数的用法,以及sqlexec的基本用法 SQLPREDICATE 在使用OGG初始化时,可以添加此参数到extract中,用于选择符合条件的记录,下面是OGG官方文档中的描述 : "在用OGG初始化数据时,使用SQLPredicate是比where或filter更好的一个选项.使用此语句比其它参数初始化更快,因为它直接作用于SQL语句,告诉OGG不应该取所有数据之后再过滤(这正是其它参数的运行方式),而是应该只取需要的部分." 如下 TABLE gg

Exchange的PowerShell中关于Filter的写法

这篇文章简单说一下Exchange的PowerShell中,Filter的用法,不过相信看完的同学以后可能不会用这个东西------虽然这么说,但是毕竟是一个新的选择,大家可以学习一下. 首先我们看一个输出,我们看看在Exchange2010中,get-user有哪些属性可以做筛选 [PS] E:\>Get-User zhangpengliang|select * 正在创建新会话来隐式远程处理"Get-User"命令... RunspaceId               : 2

OpenLayers中的图层

OpenLayers有多个不同的图层类,每一个都可以连接到不同的地图服务器.例如通过Layer.WMS类可以连接到WMS地图服务器,通过Layer.Google类可以连接到谷歌地图服务器.OpenLayers中的每个图层都是独立的,对一个的操作不会影响到另外一个. 不管地图应用的目的是什么,一个有用的地图至少需要有一个图层,至少一个基底图层.其他基底图层之上的图层称之为叠加图层.基底图层和叠加图层是OpenLayers中的两种图层类型. 基底图层 基底图层在图层列表的最下方,其他图层都在其之上.

WebGIS中基于控制点库进行SHP数据坐标转换的一种查询优化策略

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 目前项目中基于控制点库进行SHP数据的坐标转换,流程大致为:遍历图层要素,获取每个要素的坐标串,查询控制点库,分别进行坐标转换,构建新的要素,最后构建新的图层.此方法效率如下: a.控制点库有100W个控制点对. b.待转换SHP数据有5K个面要素. 转换完毕大概需要120分钟. 此效率是相对较低的,如果想对更多包含大量要素的图层组数据进行批量转换,耗时会成倍

基于R-Tree的最近邻查询

转自基于R-Tree的最近邻查询 BAB(Branch.and.Band)算法是由Nick Roussopoulousnl等人于1995年提出的,是最早的基于R.树的静态最近邻查询算法.该算法使用MINDIST和MINMAXDIST两个距离作为查询过程中的判断条件,对R树进行深度优先 搜索以查找最近邻,适用于基于静态对象的最近邻搜索.BAB思想已经被广泛的应用于人工智能以及运筹学等领域.如果搜索顺序和剪枝的规则选取适当,可以有效的减少系统在大规模空间搜索过程中的结点访问数目. 一.The MBR

python中基于descriptor的一些概念(上)

@python中基于descriptor的一些概念(上) python中基于descriptor的一些概念(上) 1. 前言 2. 新式类与经典类 2.1 内置的object对象 2.2 类的方法 2.2.1 静态方法 2.2.2 类方法 2.3 新式类(new-style class) 2.3.1 __init__方法 2.3.2 __new__静态方法 2.4. 新式类的实例 2.4.1 Property 2.4.2 __slots__属性 2.4.3 __getattribute__方法

初解,Scala语言中基于Actor的并发编程的机制,并展示了在Spark中基于Scala语言的Actor而产生的消息驱动框架Akka的使用,

Scala深入浅出实战中级--进阶经典(第66讲:Scala并发编程实战初体验及其在Spark源码中应用解析)内容介绍和视频链接 2015-07-24 DT大数据梦工厂 从明天起,做一个勤奋的人 看视频.下视频,分享视频 DT大数据梦工厂-Scala深入浅出实战中级--进阶经典:第66讲:Scala并发编程实战初体验及其在Spark源码中的应用解析 本期视频通过代码实战详解了Java语言基于加锁的并发编程模型的弊端以及Scala语言中基于Actor的并发编程的机制,并展示了在Spark中基于Sc