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