2009年5月26日星期二

不稳定的Blogger

如果2009.6.1之前不恢复的话,我就换个地方吧

作坊暂定搬到:http://hi.baidu.com/wuyf0330

2009年5月14日星期四

ArcGIS Server Java ADF 案例教程 27

四 QueryResult

上面几个小节让我们知道了不同的查询功能应该怎么去实现,每个查询中都返回了QueryResult对象的集合。这个小节我们就来详细说说QueryResult对象。

QueryResult对象是一个查询结果,当然,这是一个服务器端对象,然而在服务器上QueryResult并不仅仅是一个记录,而是一个可以和Map互动,可以高亮显示、移除、缩放到的一个对象。

比如当我们做完查询以后,想在地图上显示所有的结果要素,那么,调用QueryResult的highlight方法就可以做到:
webContext.getWebGraphics().clearGraphics();
for (int i = 0; i <>
{
QueryResult queryResult = listQueryResult.get(i);
queryResult.highlight();

}
webContext.refresh();


面的代码遍历了查询结果中所有的QueryResult对象,调用每个对象的highlight方法使其在地图上高亮显示,让我们看一下执行的结果:
图 18 高亮查询结果

高亮的这些元素事实上是将这些查询结果以Graphic的形式添加到Map中的。ADF的Graphic通常用于表现临时的、动态生成的业务数据,下面一章我们会马上去看Graphic的来龙去脉。

ArcGIS Server Java ADF 案例教程 26

三 Where条件查询

三个实现了QueryCriteria接口的类我们还剩PredefinedQueryCriteria没有介绍,这个类是用于进行where查询的。在进行查询的时候,通常需要设置一个比较复杂的过滤条件,这里就需要PredefinedQueryCriteria。

下面我们尝试把前面使用TextCriteria查询的方法用PredefinedQueryCriteria来实现:
WebQuery webQuery = (WebQuery) webContext.getAttribute("query");

PredefinedQueryCriteria criteria = new PredefinedQueryCriteria();
criteria.setWhereClause("CITY_NAME like '%"+this.keyWord+"%'");

List
listQueryResult = webQuery.query(criteria, webQuery.getQueryLayers());

PredefinedQueryCriteria的用法非常简单,无非是把你想要设置的where条件放到它的whereClause属性中去,这里就不赘述了。

ArcGIS Server Java ADF 案例教程 25

二 几何对象查询

在上一章的QueryTask中也有对几何对象的查询,你可以回忆一下那个Task面板中“选择”那个Tool。这个Tool会在Map中绘制一个多边形,然后ADF根据这个多边形查询位于多边形内的所有要素。

几何对象的查询主要使用IdentifyCriteria对象,下面的代码实现了这样一个根据多边形查询要素的功能:
WebContext webContext = event.getWebContext();
WebGeometry webGeometry = (WebPolygon) event.getWebGeometry().toMapGeometry(webContext.getWebMap());

WebQuery webQuery = (WebQuery) webContext.getAttribute("query");
List
layers = webQuery.getQueryLayers();
List
queryLayers = new ArrayList();
for (WebLayerInfo layer : layers)
{
if (layer.getName().equals("World Cities"))
{
queryLayers.add(layer);
break;
}
}

IdentifyCriteria identifyCriteria = new IdentifyCriteria();
identifyCriteria.setWebGeometry(webGeometry);

List
listQueryResult = webQuery.query(identifyCriteria, queryLayers);

在这个查询过程中,首先从MapEvent事件中获得从客户端传来的WebGeometry对象(这里是用户在客户端的Map中画的多边形),这个对象是基于客户端坐标的,因此需要转化成地图坐标。由于我们只想查“World Cities”这个图层上的要素,因此下面又构造了一个queryLayers,将我们想要查询的图层挑选了出来。在此之后,我们就可以使用IdentifyCriteria对象,将ADF转化成地图坐标的WebGeometry对象作为它的参数,进行查询得到结果。

2009年5月13日星期三

Flex中实现行军箭头的效果

2009年5月8日星期五

ArcGIS Server Java ADF 案例教程 24

第六章 查询及结果

对空间信息进行查询是GIS中很基本且很常用的功能,在这一章中,我们主要看在ADF中如何进行查询、查询出结果以后怎样返回客户端。另外,在这里也先预告下,在下一章我们还会讲查询到的这些结果怎样在Map中表现出来。

一 文本查询

在上一章QueryTask的query方法中我们已经用到了文本查询的功能,你可以回忆一下,在这个方法中我们根据Task面板中文本框的内容,对图层进行了查询,用到的就是keyWord这个字符串变量。下面我们来详细说一下文本查询的过程。

在ADF中负责进行文本查询的是WebQuery对象,需要用到查询功能的ADF应用都需要在配置文件中加上了这个对象:

当我们需要使用查询功能的时候,首先第一步就是获得这个WebQuery对象,当然,通常都是先获得WebContext对象,再查找它的attribute来获得WebQuery对象:
WebQuery webQuery = (WebQuery) webContext.getAttribute("query");

通过这个WebQuery对象我们就可以开始进行查询了,WebQuery最重要的方法就是query方法,让我们先看一下query方法的原型:

这个query方法主要有两个参数:criteria参数表示查询条件,这是一个实现了QueryCriteria 接口的对象,实现这个接口的类有三种:IdentifyCriteria, PredefinedQueryCriteria, TextCriteria,分别对应不同的查询类型,在这里我们将要用到TextCriteria这个类;query方法的另外一个参数queryLayers表示需要进行查询的图层,一个服务中可能有多个图层,这个参数可以限制查询的范围。

上面说到进行查询需要一个实现了QueryCriteria接口的对象作为查询条件,这里我们需要查询文本,所以需要使用TextCriteria,这是一个专为文本查询设计的类。下面的代码定义了一个TextCriteria对象,通过这个对象定义了一些查询条件和限制,最后通过WebQuery对象的query方法来得到查询结果:

这是一个很简单的查询,事实上TextCriteria还可以设置很多限制和条件,比如限制查询字段、是否模糊查询、设置返回字段、设置LayerDefinition (包括字段别名、符号渲染方式)等等。最后,查询后会得到一个QueryResult的集合,关于这个QueryResult的特点和用法,我们在后面会有一个小节专门说明。

2009年5月7日星期四

刚做的H1N1猪流感分布图Demo

主要是HeatMap的实现,原来网上有人发了一个,不过我去看的时候已经因为没有得奖的原因把源码给撤了……还是自力更生吧。

点击这里查看在线演示

这是大概的效果图:

2009年5月4日星期一

使用pgRouting进行路径分析

pgRouting是一个基于PostgreSQL/PostGIS的项目,目的是提供路径分析的功能,它是PostLBS的一个子项目,这个项目使用GPL许可发布。

pgRouting的安装很简单,以Windows为例,下载编译包以后解压缩,将lib目录下文件复制到PostgreSQL的lib目录下,再在PostgreSQL数据库中执行share/contrib目录下的sql脚本,这些脚本分别对应不同的功能:“core”对应Dijkstra算法计算最短路径,使用函数为“shortest_path_*”;“dd”对应Driving Distance行驶距离计算,使用函数为“driving_distance”;“tps”对应采用遗传算法的Travelling Sales Person方法,使用函数为“tsp_*”。

下面用日本神奈川的城市道路数据进行测试。

计算最短路径我们使用shortest_path这个函数,这个函数需要提供5个参数,下面是shortest_path的函数原型:
shortest_path(sql text, source_id integer, target_id integer, directed boolean, has_reverse_cost boolean)

这里的sql是一个sql语句,通过这个sql语句可以获得需要计算的数据集合;source和target分别是起始节点的id;directed表明是否限制方向。需要说明的是这个sql语句,在这个sql中需要查询到一些特殊的字段:id、source、target、cost等,而且这些字段的类型必须和pgRouting的要求相符。下面是我构造的一个查询:
SELECT * FROM shortest_path(' SELECT objectid as id, source::integer, target::integer, length::double precision as cost FROM kanagawa', 84808, 13234, false, false);

在本机上测试,上述查询在19万行数据中执行了2秒得到结果318行(路径分为318段):

以下是服务器端的主要代码:
public ArrayList> getNodes(int source, int target)
{
ArrayList> result = new ArrayList>();

if ( this.getConn()==null )
return result;

try
{
String sql = "SELECT * FROM shortest_path('SELECT objectid as id,source::integer,target::integer,length::double precision as cost FROM kanagawa', "+source+", "+target+", false, false) as a left join kanagawa as b on a.edge_id=b.objectid;";

Statement st = this.getConn().createStatement();
st.setFetchSize(0);
ResultSet rs = st.executeQuery(sql);
while (rs.next())
{
HashMap map = new HashMap();
map.put("x1", rs.getDouble("x1"));
map.put("y1", rs.getDouble("y1"));
map.put("x2", rs.getDouble("x2"));
map.put("y2", rs.getDouble("y2"));
result.add(map);
}
rs.close();
st.close();
}
catch(Exception e)
{
System.err.print(e);
}

return result;
}