geotools中泰森多边形的生成
概述
本文讲述如何在geotools中生成泰森多边形,并shp输出。
泰森多边形
1、定义
泰森多边形又叫冯洛诺伊图(Voronoi diagram),得名于Georgy Voronoi,是由一组由连接两邻点直线的垂直平分线组成的连续多边形组成。
2、建立步骤
建立泰森多边形算法的关键是对离散数据点合理地连成三角网,即构建Delaunay三角网。建立泰森多边形的步骤为:
1)离散点自动构建三角网,即构建Delaunay三角网。对离散点和形成的三角形编号,记录每个三角形是由哪三个离散点构成的。
2)找出与每个离散点相邻的所有三角形的编号,并记录下来。这只要在已构建的三角网中找出具有一个相同顶点的所有三角形即可。
3)对与每个离散点相邻的三角形按顺时针或逆时针方向排序,以便下一步连接生成泰森多边形。设离散点为o。找出以o为顶点的一个三角形,设为A;取三角形A除o以外的另一顶点,设为a,则另一个顶点也可找出,即为f;则下一个三角形必然是以of为边的,即为三角形F;三角形F的另一顶点为e,则下一三角形是以oe为边的;如此重复进行,直到回到oa边。
4)计算每个三角形的外接圆圆心,并记录之。
5)根据每个离散点的相邻三角形,连接这些相邻三角形的外接圆圆心,即得到泰森多边形。对于三角网边缘的泰森多边形,可作垂直平分线与图廓相交,与图廓一起构成泰森多边形。
3、特征
1)每个泰森多边形内仅含有一个离散点数据;
2)泰森多边形内的点到相应离散点的距离最近;
3)位于泰森多边形边上的点到其两边的离散点的距离相等。
geotools中的生成
1、创建测试点
int xmin = 0, xmax=180;
int ymin = 0, ymax=90;
Random random = new Random();
List<Geometry> geomsPoints = new ArrayList<Geometry>();
for(int i=0;i<100;i++){
int x = random.nextInt(xmax)%(xmax-xmin+1) + xmin,
y = random.nextInt(ymax)%(ymax-ymin+1) + ymin;
Coordinate coord = new Coordinate(x,y,i);
coords.add(coord);
clipEnvelpoe.expandToInclude(coord);
geomsPoints.add(new GeometryFactory().createPoint(coord));
}
2、生成泰森多边形
voronoiDiagramBuilder.setSites(coords);
voronoiDiagramBuilder.setClipEnvelope(clipEnvelpoe);
Geometry geom = voronoiDiagramBuilder.getDiagram(JTSFactoryFinder.getGeometryFactory());
List<Geometry> geoms = new ArrayList<Geometry>();
for(int i=0;i<geom.getNumGeometries();i++){
geoms.add(geom.getGeometryN(i));
}
完整代码如下:
package com.lzugis.geotools;
import java.io.File;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.triangulate.VoronoiDiagramBuilder;
public class TsdbxTest {
static TsdbxTest tsdbx = new TsdbxTest();
public void voronoiTest(){
VoronoiDiagramBuilder voronoiDiagramBuilder = new VoronoiDiagramBuilder();
List<Coordinate> coords = new ArrayList<Coordinate>();
Envelope clipEnvelpoe = new Envelope();
int xmin = 0, xmax=180;
int ymin = 0, ymax=90;
Random random = new Random();
List<Geometry> geomsPoints = new ArrayList<Geometry>();
for(int i=0;i<100;i++){
int x = random.nextInt(xmax)%(xmax-xmin+1) + xmin,
y = random.nextInt(ymax)%(ymax-ymin+1) + ymin;
Coordinate coord = new Coordinate(x,y,i);
coords.add(coord);
clipEnvelpoe.expandToInclude(coord);
geomsPoints.add(new GeometryFactory().createPoint(coord));
}
String pointpath = "d:/data/tsdbxpt.shp";
tsdbx.writeShape(pointpath,"Point", geomsPoints);
voronoiDiagramBuilder.setSites(coords);
voronoiDiagramBuilder.setClipEnvelope(clipEnvelpoe);
Geometry geom = voronoiDiagramBuilder.getDiagram(JTSFactoryFinder.getGeometryFactory());
List<Geometry> geoms = new ArrayList<Geometry>();
for(int i=0;i<geom.getNumGeometries();i++){
geoms.add(geom.getGeometryN(i));
}
String polygonpath = "d:/data/tsdbx.shp";
tsdbx.writeShape(polygonpath,"Polygon", geoms);
}
/**
*
* @param filepath
* @param geoType
* @param geoms
*/
public void writeShape(String filepath, String geoType, List<Geometry> geoms) {
try {
//创建shape文件对象
File file = new File(filepath);
Map<String, Serializable> params = new HashMap<String, Serializable>();
params.put( ShapefileDataStoreFactory.URLP.key, file.toURI().toURL() );
ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
//定义图形信息和属性信息
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.setCRS(DefaultGeographicCRS.WGS84);
tb.setName("shapefile");
if(geoType=="Point"){
tb.add("the_geom", Point.class);
}
else{
tb.add("the_geom", Polygon.class);
}
ds.createSchema(tb.buildFeatureType());
//设置编码
Charset charset = Charset.forName("GBK");
ds.setCharset(charset);
//设置Writer
FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);
for(int i=0,len=geoms.size();i<len;i++){
//写下一条
SimpleFeature feature = writer.next();
Geometry geom = geoms.get(i);
feature.setAttribute("the_geom", geom);
}
writer.write();
writer.close();
ds.dispose();
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args){
long start = System.currentTimeMillis();
tsdbx.voronoiTest();
System.out.println("共耗时"+(System.currentTimeMillis() - start)+"ms");
}
}
参考文献:
1、百度百科
---------------------------------------------------------------------------------------------------------------
技术博客
CSDN:http://blog.csdn.NET/gisshixisheng
博客园:http://www.cnblogs.com/lzugis/
在线教程
http://edu.csdn.Net/course/detail/799
Github
https://github.com/lzugis/
联系方式
q q:1004740957
e-mail:niujp08@qq.com
公众号:lzugis15
Q Q 群:452117357(webgis)
337469080(Android)
geotools中泰森多边形的生成的更多相关文章
- GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换
GeoJson的生成与解析 一.wkt格式的geometry转成json格式 二.json格式转wkt格式 三.json格式的数据进行解析 四.Java读写geojson 五.geotools读取sh ...
- Git中如何利用生成SSH个人公钥访问git仓库
Git中如何利用生成SSH个人公钥访问git仓库方法(这里以coding平台为例): 1. 获取 SSH 协议地址 在项目的代码页面点击 SSH 切换到 SSH 协议, 获得访问地址, 请使用这个地址 ...
- visual 2008中error PRJ0003 : 生成 cmd.exe 时出错
visual 2008中error PRJ0003 : 生成 cmd.exe 时出错”, 和vs2008 sp1没关系 解决方案:工具—>选项—>项目和解决方案—>VC++目录, ...
- MVC中验证码的生成
在项目中验证码的生成通常是需要页面无刷新的,所以验证码图片实际是跟在某个input后面的img,通过控制该img来控制验证码显示的位置,例如: <div> <input id=&qu ...
- (DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device
Linux kernel 是怎么将 devicetree中的内容生成plateform_device 1,实现场景(以Versatile Express V2M为例说明其过程)以arch/arm/ma ...
- VS中的预先生成事件和后期生成事件
原文:VS中的预先生成事件和后期生成事件 在C#开发中,有时候需要在程序编译之前或之后做一些操作. 要达到这个目的,可以使用Visual Studio中的预先生成事件和后期生成事件. 下图是一个简单例 ...
- 【转】(DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device
原文网址:http://www.cnblogs.com/biglucky/p/4057495.html Linux kernel 是怎么将 devicetree中的内容生成plateform_devi ...
- (原)caffe中通过图像生成lmdb格式的数据
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5909121.html 参考网址: http://www.cnblogs.com/wangxiaocvp ...
- sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别
原文:sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别 IDENT_CURRENT 返回为任何会话和任何作用域中的指定表 ...
随机推荐
- 20145331 《Java程序设计》第10周学习总结
20145331 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置 ...
- 20135320赵瀚青LINUX内核分析第一周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.概述 第一周的学习内容主 ...
- platform_device和platform_driver的注册过程,及probe函数何时调用的分析 ⭐⭐⭐
add platform_device之后,需要注意的一个地方是这里,add是通过系统初始化里边调用platform_add_devices把所有放置在板级platform_device数组中的所有 ...
- 4.9版本linux内核的ina220电流检测芯片源码在哪里
答:在drivers/hwmon/ina2xx.c中,内核配置项为CONFIG_SENSORS_INA2XX Location: -> Device Drivers -> Hardware ...
- 【ROI Pooling】ROI Pooling层详解(转)
原文链接:https://blog.deepsense.ai/region-of-interest-pooling-explained/ 目标检测typical architecture 通常可以分为 ...
- Nagios安装完后status map,trends等页面访问出错之解决
首先,可以进入/usr/local/nagios/sbin, [root@localhost sbin]# ldd statusmap.cgi linux-vdso.so. => (0x0000 ...
- kubernetes dashboard 二次开发
Kubernetes Dashboard 二次开发 官方源码:https://github.com/kubernetes/dashboard 开发文档:https://github.com/kuber ...
- Jquery移动html到另一个标签下
需求再现 <div id="div1"> <p>这是一段测试文本001</p> </div> <div id="di ...
- iOS 可变字符串NSMutableString的使用
.创建一个可变字符串 NSMutableString * ms1 = [[NSMutableString alloc]init]; .可以通过类方法来创建 NSMutableString * ms2 ...
- 阿里云centOS7.4 ftp连接不上的问题
首先查看是开启21端口 选择ECS-->安全组-->配置规则 增加21端口配置 配置如下