作者:xinxin
在使用SuperMap iMobile for Android的项目开发中,经常实现对数据的查询和对象拓扑关系判定功能,小编在此就这功能的实现做一分享。
####一、数据查询
1、按数据类型来分:本地数据查询和在线数据查询
(1)本地数据查询
适用于本地的矢量数据,影像、栅格数据集和地图缓存无法查询。对于矢量数据集,项目中常用条件和范围来做查询,查询方法是datasetvector.query(),返回的结果是Recordset。根据项目需求(按条件、范围和条件+范围)来设置query()方法中的参数,如:
- 按条件查可用:
query(QueryParameter queryParameter) ;
或 query(java.lang.String attributeFilter, CursorType cursorType) ;
或 queryByKeyword(java.lang.String fieldName, java.lang.String keywords, Geometry geoRegion, int count) ; - 按范围查可用:
query(Geometry geometry, double bufferDistance, CursorType cursorType) ;
或 query(Rectangle2D bounds, CursorType cursorType) ;
或 queryByFilter(java.lang.String attributeFilter, Geometry geoRegion, int count) ; - 按条件+范围查可用:
query(Geometry geometry, double bufferDistance, java.lang.String attributeFilter, CursorType cursorType) ;
或 query(Rectangle2D bounds, java.lang.String attributeFilter, CursorType cursorType) ;
备注:
① 上面方法中的参数如果不是很清楚,可以对照SuperMap iMobile for Android中的该方法参数解释来设置;
② 另外在用缓冲区做查询的时候经常会查询出所有的对象,主要是设置的缓冲半径过大,半径的单位与数据集的单位一致,所以如果查询的数据集是地理坐标系,半径的单位是度,往往出现设置过大,解决方案可以设置较小值或将数据集转成平面投影坐标系以米为单位;
③ 条件查询时的查询过滤条件使用SQL语句。
④ 查询返回的结果是记录集Recordset;
⑤ 查询方法中的CursorType是游标常量,动态游标(DYNAMIC)和静态游标(STATIC),如果查询得到的记录集后面要编辑更改记录则用动态,否则用静态。
(2)在线数据查询
这类数据查询主要针对Web数据中Rest地图服务,主要是通过查询服务类QueryService来实现的。该功能的实现方法是query(ServiceQueryParameter param, QueryMode mode) ,其中QueryMode参数是一个枚举类,可将服务查询分为SQL查询(SqlQuery)、空间查询(SpatialQuery)、范围查询 (BoundsQuery)、距离查询(DistanceQuery)和最近地物查询(FindNearest)。下面以举例SQL查询的实现关键代码:
private void Query() {
final ProgressDialog progress = new ProgressDialog(MainFrame.this);
//定义一个查询服务对象,m_strServer是指定的服务的URL
QueryService service = new QueryService(m_strServer);
//定义一个服务查询参数对象
ServiceQueryParameter parameter = new ServiceQueryParameter();
//设置查询图层的地图名称
parameter.setQueryMapName(m_edtMapName.getText().toString());
//设置当前查询的服务的实例的服务名称
parameter.setQueryServiceName(m_edtServerName.getText().toString());
//设置当前查询的图层的名称
parameter.setQueryLayerName(m_edtLayerName.getText().toString());
//设置期望返回的查询记录个数
parameter.setExpectRecordCount(100);
//设置查询记录的起始位置
parameter.setQueryRecordStart(0);
//设置查询结果内容类型
parameter.setQueryOption(QueryOption.GEOMETRY);
parameter.setAttributeFilter(m_edtSql.getText().toString());
//设置响应回调
service.setResponseCallback(new ResponseCallback() {
//查询成功回调
@Override
public void requestSuccess() {
//销毁进度条显示框
progress.dismiss();
Toast.makeText(MainFrame.this, "查询成功", Toast.LENGTH_LONG).show();
}
//查询失败回调
@Override
public void requestFailed(String arg0) {
//销毁进度条显示框
progress.dismiss();
Toast.makeText(MainFrame.this, "查询失败", Toast.LENGTH_LONG).show();
System.out.println("错误信息 " + arg0);
}
//收到服务器响应结果时回调
@Override
public void receiveResponse(FeatureSet arg0) {
if (arg0 instanceof FeatureSet) {
FeatureSet featureSet = (FeatureSet)arg0;
int nCount = 0;
featureSet.moveFirst();
while (!featureSet.isEOF()) {
Geometry geo = featureSet.getGeometry();
if (geo == null) {
featureSet.moveNext();
continue;
}
nCount++;
featureSet.moveNext();
}
System.out.println("count is " + nCount);
System.out.println("featureSet count is " + featureSet.getFeatureCount());
}
}
// 数据服务结束时调用,如下载、更新、提交数据集等结束后调用该方法,在这些服务执行过程中出现异常将调用requestFaild()
@Override
public void dataServiceFinished(String arg0) {
// TODO Auto-generated method stub
}
});
//显示服务查询进度条,回调里面销毁
progress.setMessage("服务查询中...");
progress.show();
// 查询
service.query(parameter, QueryMode.SqlQuery);
}
备注:服务查询中的SQL查询中的源码在Supermap iMobile for Android解压包下的Samplecode文件中的Service工程。
2、按查询类型来分:属性查询和空间查询
在本地数据和在线数据中都有属性查询和空间查询,具体接口和方法和1中的一样,这里就不在赘述了。
####二、拓扑关系判定
拓扑关系的判定也是GIS项目中的常用功能,实现这类功能一般使用Geometrist类中的方法。常用的拓扑关系判定如下:
- 是否包含:isWithin(Geometry geometrySearch, Geometry geometryTarget) ->参数1是搜索几何对象,参数2是被搜索;点不能包含线、面;线不能包含面;
- 是否部分重叠:hasOverlap(Geometry geometrySearch, Geometry geometryTarget) ->是判定部分重叠所以点没有这个拓扑关系,且只能是线查线、面查面;
- 是否穿越:hasCross(Geometry geometrySearch, Geometry geometryTarget) ->参数1只能为线,参数可以为线或面;
- 是否分离:isDisjointed(Geometry geometrySearch, Geometry geometryTarget);
- 是否有公共线段:hasCommonLine(Geometry geometrySearch, Geometry geometryTarget) ->判定对象为线和面,点不存在公共线段;
- 是否完全相等:isIdentical(Geometry geometrySearch, Geometry geometryTarget) ->判定点与点、线与线、面与面是否完全重叠;
- 是否有自相交:isSelfIntersect(Geometry geometry) ->主要判断线或面本身是否有线相交;
备注:拓扑关系的判定返回的是一个布尔值,true存在拓扑关系,false不存在拓扑关系。