基于udig(开源GIS软件)二次开发(4)
本次主要基于udig做一个简单的二次开发实例,假如我们手里有一批经纬度的信息,想直接在地图上查看。当然这时候方法非常多,譬如我通过postgis+geoserver+openlayers很容易实现,或者在udig里有create point也可以直接绘制,还有通过openlayers的marker只需要一个简单的txt文件也行,完全用不到二次开发,但这里只是说做一个简单的范例看看udig是怎么样加载地图数据和怎么样我们可以生成一份地图数据。
本次我们生成比较通用的shp文件(postgis等以后再说),生成shp我们这里需要用到geotools,不过udig里已经集成进去了geotools的jar包,我们只需要在我们自己的插件里引用net.refractions.udig.libs这个插件即可。闲话不多说,我们开始先创建一个插件项目(因为是DEMO,所以就一个插件,记得勾选RCP)。
1、 创建项目,如图:
1、 2、创建几个包,如图:
其中command下我们生成一个类ImportDataCommand extends AbstractHandler ,pojo下我们生成一个基础的点实体类 DemoPoint {
private double lon ;
private double lat ;
private String site_name ;
public double getLon() {
return lon;
}
public void setLon(double lon) {
this.lon = lon;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public String getSite_name() {
return site_name;
}
public void setSite_name(String site_name) {
this.site_name = site_name;
}
}
3、1、 Command中实现 public Object execute(ExecutionEvent event) throws ExecutionException {} 这个方法。里面需要的操作有
a、 a 弹出选择文件对话框,要求使用者导入需要导入的经纬度文件(文件格式预先定义好)。
b、 b 读取文件转换为实体数据
c、 c 根据实体数据生成shp 图层数据文件
d、 d 将shp图层数据文件加载显示到udig的地图中
1、 4、多话不说,我贴代码
a、 a 弹出对话框要求用户选择需要导入的文件。
//弹出选择文件对话框 要求选择文件,要求格式csv 字段要求为LON,LAT,SITE_NAME
FileDialog dialog = new FileDialog(Display.getDefault().getActiveShell(), SWT.OPEN);
dialog.setText("请选择要导入的文件");
String path = dialog.open();
if(path != null) {
//选择的文件不为空 开始读取文件信息 转换为实体数据
}
b、 b 解析文件,转换为我们需要的实体数据
/**
* 解析文件,转换为我们需要的实体数据
* @param path 文件路径
* @return 演示用的点信息集合 文件不存在时返回空
*/
private Collection<DemoPoint> parseFile(String path) {
List<DemoPoint> points = new LinkedList<DemoPoint>();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(path));
String line = br.readLine() ;//跳过表头
while((line = br.readLine()) != null) {
String[] _ss = line.split(",");
//由于是演示 所以这里不做数据检查
DemoPoint point = new DemoPoint();
point.setLon(Double.valueOf(_ss[0]));
point.setLat(Double.valueOf(_ss[1]));
point.setSite_name(_ss[2]);
points.add(point);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(br != null) {
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return points ;
}
c、c 生成shp图层文件
/**
* 根据数据生成图层文件
* @param data
* @return 返回生成好的图层文件地图 SHP图层 数据保存在当前workspace下
*/
protected String createShpData(Collection<DemoPoint> data){
//拿到当前的workspace路径
String ws = Platform.getInstanceLocation().getURL().getPath();
//文件名用当前系统时间
String layerName = String.valueOf(System.currentTimeMillis()) ;
File shpFile = new File(ws , layerName + ".shp");
//图层的属性配置 坐标系采用4326
String layerFeatures = "GEOM:Point:srid=4326,LON:Double,LAT:Double,SITE_NAME:String" ;
FeatureWriter<SimpleFeatureType, SimpleFeature> fw = null;
try {
ShapefileDataStore myData = new ShapefileDataStore(shpFile
.toURI().toURL());
myData.setStringCharset(Charset.forName("GBK"));
SimpleFeatureType ft = DataUtilities.createType(layerName,
layerFeatures);
myData.createSchema( ft);
//手动事物 发现有时候给自动回出些问题
Transaction tran = new DefaultTransaction();
fw = myData.getFeatureWriter(layerName,
tran);
GeometryFactory gf = new GeometryFactory();
for(DemoPoint point : data) {
Geometry geo = gf.createPoint(new Coordinate(point.getLon(), point.getLat()));
SimpleFeature sf = (SimpleFeature) fw.next();
sf.setDefaultGeometry(geo);
//添加属性
sf.setAttribute("SITE_NAME",point.getSite_name());
fw.write();
}
fw.close();
tran.commit();
tran.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SchemaException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(fw != null)
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return shpFile.getAbsolutePath();
}
d、 d 创建一个新的地图,加载我们刚才生成的shp图层文件
/**
* 创建一个新地图并打开shp图层文件
* @param path 文件路径
*/
protected void createMapAndOpenShp(String path) {
IRepository local = CatalogPlugin.getDefault().getLocal();
IService service = null;
List<IGeoResource> resources = null;
try {
service = local.acquire(
URLUtils.fileToURL(new File(path)),
new NullProgressMonitor());
resources = (List<IGeoResource>) service.resources(new NullProgressMonitor());
//发布
ApplicationGIS.createAndOpenMap(resources);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
5、注意事项
插件中引用要因为udig的applicationgis类,并且需要生成图层,所以在当前插件里我们要引入5个插件(本次的开发环境udig为1.2的版本):
创建product文件后,最好引入udig的所有包(新手必须).
6、1、 好了 打开看看效果
代码和演示数据在附件中可以下载,有问题请留言或者加我们的 群 251615521
251615521251615521251615521