您的位置:首页 > 移动开发 > Android开发

[ArcGIS for Android] arcgis runtime for android 中加载矢量数据的实现

2014-02-12 10:21 471 查看
Android设备中加载矢量数据的方法,对于在Android中存储矢量数据可以通过Sqlite数据库或以Sqlite数据库扩展的Spatialite空间数据库实现。

1.基于Sqlite数据库

矢量数据存储实际上将Geomentry转成json字符串后存储到数据库中,从数据库读取数据则是将json字符串转成Geomentry。这两个转换的实现借助GeometryEngine类的geometryToJson()和jsonToGeometry()方法。这种方法的不足就是不能直接将Shapefile数据存储到数据库中,也只能对数据库中的数据属性查询,不能对数据库进行空间查询。

2.基于Spatialite空间数据库

Spatialite空间数据库实际上是对salite数据库的扩展,使其能够支持空间数据。可以通过Spalite-gui工具将shapefile数据导入到spatialite数据库中。那如何将数据库中的Geometry读取出来并显示大地图中呢?数据库查询语句可以将Geometry转成OGC标准的wkt(一种文本标记语言)字符串形式,wkt格式如:POINT(0 0),LINESTRING(0 0,1 1,1 2),POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1 ,2 1, 2 2,
1 2, 1 1))通过查询语句“SELECT AsText(Geometry) from table"将Geometry读出来,然后就是讲Wkt字符串转成Geometry了。方法如下:

public static Geometry WKTToGeometry(String wkt){

Geometry geo = null;

if(wkt ==null || wkt ==""){

return null;

}

String headStr = wkt.substring(0, wkt.indexOf("("));

String temp = wkt.substring(wkt.indexOf("(")+1, wkt.lastIndexOf(")"));

if(headStr.equals("POINT")){

String[] values = temp.split(" ");

geo = new Point(Double.valueOf(values[0]),Double.valueOf(values[1]));

}else if(headStr.equals("LINESTRING") || headStr.equals("POLYGON")){

geo = parseWKT(temp,headStr);

}else if(headStr.equals("Envelope")){

String[] extents = temp.split(",");

geo = new Envelope(Double.valueOf(extents[0]),Double.valueOf(extents[1]),Double.valueOf(extents[2]),Double.valueOf(extents[3]));

}else if(headStr.equals("MultiPoint")){

}else{

return null;

}

return geo;

}

private static Geometry parseWKT(String multipath,String type){

String subMultipath = multipath.substring(1, multipath.length()-1);

String[] paths;

if(subMultipath.indexOf("), (") >=0 ){

paths = subMultipath.split("\\),
\\(");//多个几何对象的字符串

}else{

paths = new String[]{subMultipath};

}

Point startPoint = null;

MultiPath path = null ;

if(type.equals("LINESTRING")){

path = new Polyline();

}else{

path = new Polygon();

}

for(int i=0;i<paths.length;i++){

String[] points = paths[i].split(",");

startPoint = null;

for(int j=0;j<points.length;j++){

String[] pointStr = points[j].trim().split(" ");

if(startPoint ==null){

startPoint = new Point(Double.valueOf(pointStr[0]),Double.valueOf(pointStr[1]));

path.startPath(startPoint);

}else{

path.lineTo(new Point(Double.valueOf(pointStr[0]),Double.valueOf(pointStr[1])));

}

}

}

return path;

}

转成Geometry后在GraphicsLayer中以Graphic的形式显示即可。

那么将Geometry存储到数据库中则是相反的过程,实际上存储的是wkt字符串形式,在数据库中以Blob格式存储,通过:"insert into table fiels(Geometry) VALUES(AsText(Geometry))) "插入语句存到数据库中。这个数据库支持sql语句的空间操作,通过Contains,Intersect,等方法操作,如:

"SELECT * where Contains(GeomFromText(wkt'),Geometry)",查询语句获得是位于GeomFromText(wkt')内的记录。如果建立了空间索引,数据库的存取速度会提升很多。

最后你可能问数据直接存储在数据库中是否安全,其实通过修改数据库源码是可以设置用户名和密码访问的,然后再编译成功。这样数据库就通过用户名和密码才能访问。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: