ArcServer 的 MapServer 查询与 GeoServer 的 WFS 查询实现

1,279 阅读4分钟

       最近在做一个点的聚类处理,就是根据点的属性,进行点的聚合展示,提升在同一个页面展示点的效率。最开始进行的是点与行政区域的聚合,即根据点的行政划分进行聚合。但是由于点的数据量较多,且没有行政区域这一属性(只有经纬度坐标),所以需要我们对点的行政区域进行自动计算。我们采用的是将我们的数据点与行政区域进行空间叠加,获取坐标点所在的行政区域,并入库,使这些坐标点具有行政区域划分。这篇文章讨论的就是这个点与行政区域的计算过程。

       1、  基于ArcServer的MapServer查询实现

       ArcGIS for Server是用户创建企业级GIS应用的平台,通过ArcGIS for Server创建集中管理的、支持多用户的、提供丰富的GIS功能、并且满足工业标准的GIS应用。基于ArcServer的MapServer方式进行处理,简单易行,由于ArcServer提供图形化管理界面进行操作,测试方便,但是安装较为麻烦,软件较大。

      我们只需要创建相应行政边界的图层服务(面图层),然后进行Query操作,将坐标点当作参数传进去,就可以获取到该点所在的行政区域。

       下面是图形化查询界面

      

         

        下面是查询结果

        

        我们所要做的就是在里实现这个过程即可,所以我们要做的就是用java实现一次http请求,传递参数,然后对数据解析即可,下面是java代码

         

public class GetArea {	
	  public void query(){
	        HttpClient client=new DefaultHttpClient();
	        //创建一个POST请求,地址是发布的GIS服务,此地址是市查询地址
	        HttpPost requestPro=new HttpPost("http://localhost:6080/arcgis/rest/services/city/MapServer/0/query");
	        //设置查询条件
	        List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
	        params.add(new BasicNameValuePair("f", "json"));	   
	        //传入要素是点状要素
	        params.add(new BasicNameValuePair("geometryType","esriGeometryPoint"));
	        params.add(new BasicNameValuePair("outFields","*"));
		  //测试一千个点
		  for(int i=0;i<100;i++){
	        try {
	            //经纬度随机生成
		        //String pos=getPosition();
	        	String pos="114.81,33.6218";
		        if(params.size()>=4){
		        	 params.remove(3);
		        }		       
		        params.add(new BasicNameValuePair("geometry",pos));
	            //设置http Post请求参数
	            HttpEntity entity = new UrlEncodedFormEntity(params);
	            requestPro.setEntity(entity);
	            HttpResponse responsePro=client.execute(requestPro);
	          //如果状态码为200,就是正常返回
	            if(responsePro.getStatusLine().getStatusCode()==200){
	                String resultPro= EntityUtils.toString(responsePro.getEntity());
	                JSONObject jsonObjectPro =JSONObject.fromObject(resultPro);
	                //解析json结构,具体结构文档中有说明
	                if(jsonObjectPro.getJSONArray("features").size()>0){
	                	   String result="第"+i+"个坐标点:"+pos+":"+jsonObjectPro.getJSONArray("features").getJSONObject(0).getJSONObject("attributes").get("NAME");	                	
	                	   System.out.println(result);  
	                }	             	               
	                //如果一个点查询到多个多边形,即此点是边界点,可以再进行其他处理
	            }
	        } catch (ClientProtocolException e) {
	            e.printStackTrace();
	        } catch (IOException e) {
	        }
	    }
	  }	  
	  //生成随机坐标,范围是经度98-117,维度27-40
	  public static String getPosition(){
		  double longitude=Math.random()*19+98;
		  double latitude=Math.random()*13+27;
		  String pos=longitude+","+latitude;
		  return pos;
	  }
}

 

     

       2、  基于GeoServer的WFS查询实现

     由于ArcServer安装较为麻烦,而且ArcServer是商用软件,涉及到版权问题,所以我们可以基于GeoServer的WFS查询实现上述功能,其原理是一样的。

      查看GeoServer服务

      

      

      查看WFS服务参数结果(未加筛选条件)

http://localhost:28080/geoserver/topp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=topp:tasmania_water_bodies&maxFeatures=50&outputFormat=application%2Fjson

     传递点的参数

http://localhost:28080/geoserver/topp/ows?service=WFS%20&version=1.0.0%20&request=GetFeature%20&typeName=topp:tasmania_water_bodies%20&maxFeatures=50&outputFormat=json%20&filter=%20%3CFilter%20xmlns=%22http://www.opengis.net/ogc%22%20xmlns:gml=%22http://www.opengis.net/gml%22%3E%20%3CIntersects%3E%20%3CPropertyName%3Ebj:the_geom%3C/PropertyName%3E%20%3Cgml:Point%3E%20%3Cgml:coordinates%3E146.122,-42.682%3C/gml:coordinates%3E%20%3C/gml:Point%3E%20%3C/Intersects%3E%20%3C/Filter%3E

     下面是java实现过程

public class GetAreaByGeoServer {
	public void query() {
		HttpClient client = new DefaultHttpClient();
		// 创建一个POST请求,地址是发布的GIS服务,此地址是市查询地址
		String longitude = "146.746";
		String latitude = "-41.858";
		String url = "http://localhost:28080/geoserver/topp/ows?service=WFS%20&version=1.0.0%20&request=GetFeature%20&typeName=topp:tasmania_water_bodies%20&maxFeatures=50&outputFormat=json%20&filter=%20%3CFilter%20xmlns=%22http://www.opengis.net/ogc%22%20xmlns:gml=%22http://www.opengis.net/gml%22%3E%20%3CIntersects%3E%20%3CPropertyName%3Ebj:the_geom%3C/PropertyName%3E%20%3Cgml:Point%3E%20%3Cgml:coordinates%3E"
				+ longitude + "," + latitude
				+ "%3C/gml:coordinates%3E%20%3C/gml:Point%3E%20%3C/Intersects%3E%20%3C/Filter%3E";
		HttpPost requestPro = new HttpPost(url);
		try {
			for (int i = 0; i < 100; i++) {
				HttpResponse responsePro = client.execute(requestPro);
				if (responsePro.getStatusLine().getStatusCode() == 200) {
					String resultPro = EntityUtils.toString(responsePro.getEntity());
					// System.out.println(resultPro);
					JSONObject jsonObjectPro = JSONObject.fromObject(resultPro);
					// 解析json结构
					if (jsonObjectPro.getJSONArray("features").size() > 0) {
						String result = i + "个点:" + jsonObjectPro.getJSONArray("features").getJSONObject(0)
								.getJSONObject("properties").get("PERIMETER");
						System.out.println(result);
					}
					// 如果一个点查询到多个多边形,即此点是边界点,可以再进行其他处理
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}