概述

本文讲述如何在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、百度百科

2、geotools user guide

---------------------------------------------------------------------------------------------------------------

技术博客

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中泰森多边形的生成的更多相关文章

  1. GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换

    GeoJson的生成与解析 一.wkt格式的geometry转成json格式 二.json格式转wkt格式 三.json格式的数据进行解析 四.Java读写geojson 五.geotools读取sh ...

  2. Git中如何利用生成SSH个人公钥访问git仓库

    Git中如何利用生成SSH个人公钥访问git仓库方法(这里以coding平台为例): 1. 获取 SSH 协议地址 在项目的代码页面点击 SSH 切换到 SSH 协议, 获得访问地址, 请使用这个地址 ...

  3. visual 2008中error PRJ0003 : 生成 cmd.exe 时出错

    visual 2008中error PRJ0003 : 生成 cmd.exe 时出错”,   和vs2008 sp1没关系 解决方案:工具—>选项—>项目和解决方案—>VC++目录, ...

  4. MVC中验证码的生成

    在项目中验证码的生成通常是需要页面无刷新的,所以验证码图片实际是跟在某个input后面的img,通过控制该img来控制验证码显示的位置,例如: <div> <input id=&qu ...

  5. (DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device

    Linux kernel 是怎么将 devicetree中的内容生成plateform_device 1,实现场景(以Versatile Express V2M为例说明其过程)以arch/arm/ma ...

  6. VS中的预先生成事件和后期生成事件

    原文:VS中的预先生成事件和后期生成事件 在C#开发中,有时候需要在程序编译之前或之后做一些操作. 要达到这个目的,可以使用Visual Studio中的预先生成事件和后期生成事件. 下图是一个简单例 ...

  7. 【转】(DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device

    原文网址:http://www.cnblogs.com/biglucky/p/4057495.html Linux kernel 是怎么将 devicetree中的内容生成plateform_devi ...

  8. (原)caffe中通过图像生成lmdb格式的数据

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5909121.html 参考网址: http://www.cnblogs.com/wangxiaocvp ...

  9. sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别

    原文:sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别 IDENT_CURRENT 返回为任何会话和任何作用域中的指定表 ...

随机推荐

  1. 20145231熊梓宏 《网络对抗》 实验9 Web安全基础实践

    20145231熊梓宏 <网络对抗> 实验9 Web安全基础实践 基础问题回答 1.SQL注入攻击原理,如何防御? •SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面 ...

  2. Elasticsearch Server,2nd Edition pdf 翻译 中文

    很偶然的机会,就需要接触到搜索,入门就是google trend已然超过solr的ES.在入门的时候找书的时候发现没有中文版的.于是自己开始翻译Elasticsearch Server,2nd Edi ...

  3. 分词工具比较及使用(ansj、hanlp、jieba)

    一.分词工具 ansj.hanlp.jieba 二.优缺点 1.ansj 优点: 提供多种分词方式 可直接根据内部词库分出人名.机构等信息 可构造多个词库,在分词时可动态选择所要使用的词库缺点: 自定 ...

  4. layui和bootstrap 对比

    layui和bootstrap 对比 这两个都属于UI渲染框架. layui是国人开发的一套框架,2016年出来的,现在已更新到2.X版本了.比较新,轻量级,样式简单好看. bootstrap 相对来 ...

  5. jqGrid入门简单使用

    jqGrid中文API:https://blog.mn886.net/jqGrid/ 这里没有请求后台,是直接读取本地.json文件 就两个文件,一个html.一个json文件,jquery是jqgr ...

  6. jdk官网历史版本下载&Oracle账号密码

    jdk官网下载地址: https://www.oracle.com/technetwork/java/javase/archive-139210.html 账号密码: 1772885836@qq.co ...

  7. 读书笔记: Microsot .NET企业级应用架构设计

    Microsot .NET企业级应用架构设计 Dino Esposito   Andrea Saltarello 编    陈黎夫 译   人民邮电出版社 第一部分 设计原则 第1章 当代架构师和架构 ...

  8. java 获取今天,昨天,上个月的日期

    获取今天,昨天,上个月的日期 的方法: Calendar cal = Calendar.getInstance(); //获取今天的日期 cal.setTime(new Date()); int ye ...

  9. python脚本7_打印九九乘法表

    #打印九九乘法表 for i in range(1,10): s = "" for j in range(1,i+1): s += str(j) + '*' + str(i) + ...

  10. 2017 年你应该尝试的 25 个 Android 库

    1.Lottie 由 Airbnb 推出,支持将 Adobe After Effects 动画通过 Bodymovin 导出成 JSON,并在手机上渲染它们.目前已经有超过 8600 颗 star,相 ...