构建Polygon多边形的时候提示 -- Invalid number of points in LinearRing (found 3 - must be 0 or >= 4)

      最近在项目中由于导入的OSM(OpenStreetMap)数据量太大,暴露了一个先前就藏匿着的bug,只不过,随着数据量的增加,实例越来越多,测试就更加逼近实战,于是,这个bug终于爆炸了,只见控制台输出():



Invalid number of points in LinearRing (found 3 - must be 0 or >= 4)
异常捕获消息:java.lang.RuntimeException: 导入异常XXXXXX



只要是来路明确的bug,都别怕好吧,怕就怕那种异常我们也没有捕获,程序就戛然而止,留下一脸懵逼的我们无从下手


那为什么会出现这种异常呢?我们看异常提示就知道:


首先构建LinearRing的时候,点数(Points)不够,提示我们只发现了3个,而我们的LinearRing是一个闭合的线性环,由它我们再来构建多边形Polygon,

其次后面还有一句“must be 0 or >=4”,这个就厉害了,直接把错误的解决方案告诉我们了


“你要构建LinearRing行,请保证你的点数要么是0个,要么超过3个!” -- 硬性指标,有没有


好了,自己挖的坑,自己填 --"肯定是在导数据的时候,在构建Geometry的时候出现了这种低级错误"


至于,为什么是“must be 0 or >= 4”,我下面会讲到


一、Pom文件


pom只贴出和Geometry相关的依赖,比如我们用到了GeoTools工具包



	4.0.0
	com.appleyk
	spring-boot-web
	0.0.1-SNAPSHOT
	Java-Web
	
	
	
		org.springframework.boot
		spring-boot-starter-parent
		1.5.9.RELEASE
	
	
	
		1.8
		17.0
		42.1.4
	
	
		
			osgeo
			Open Source Geospatial Foundation Repository
			http://download.osgeo.org/webdav/geotools/
		
	
	
	
	
	
	
	
		
			org.springframework.boot
			spring-boot-starter-web
		
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
		
			org.springframework.boot
			spring-boot-starter-thymeleaf
		
		
		
		
		
			org.springframework.boot
			spring-boot-devtools
			
			
			true
		
		
		
			junit
			junit
		
		
		
			org.geotools
			gt-shapefile
			${geotools.version}
		
		
			org.geotools
			gt-swing
			${geotools.version}
		
	
	
	
		
		
			
			
				src/main/resources
			
			
				src/main/resources
				
					**/*.properties
					**/*.xml
				
				false
			
			
				src/main/java
				
					**/*.properties
					**/*.xml
				
				false
			
		
		
			
			
				org.springframework.boot
				spring-boot-maven-plugin
			
			
				org.apache.maven.plugins
				maven-surefire-plugin
				
					
						**/*Documentation.java
					
				
			
		
	
	war




二、单元测试构建Geometry的几种方式



(1)项目所在的测试单元文件的目录图






(2)GeometryTest.java


package com.appleyk.geotools.learn;

import org.junit.Test;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;

public class GeometryTest {

	private GeometryFactory geometryFactory = new GeometryFactory();
	
	@Test
	public void Test() {
		
		Coordinate coords[] = new Coordinate[4];
		coords[0] = new Coordinate(113.6248492, 34.7384023);
		coords[1] = new Coordinate(113.6248465, 34.7381533);
		coords[2] = new Coordinate(113.6248492, 34.7384024);
		coords[3] = new Coordinate(113.6248492, 34.7384023);
		
		
		Geometry geometry = null;
		
		if(isClosed(coords)){
			//如果是闭合的多边形
			geometry = geometryFactory.createPolygon(coords);
		}else{
			if(coords.length==1){
				//如果坐标数组就一个元素的话,除了Point,我想不到其他Geometry
				geometry = geometryFactory.createPoint(coords[0]);
			}else{
				//否则的话,不闭合也不是点,那么它只能是线了--- LineString
				geometry =geometryFactory.createLineString(coords);
			}
		}
		
		System.err.println("类型:"+geometry.getGeometryType()+"\n形态:"+geometry);
	}
	
	/**
	 * 判斷 -- 是否是闭合的(Polygon)
	 * @param coords
	 * @return
	 */
	public boolean isClosed(Coordinate coords[]){
		/**
		 * 闭合条件
		 * 1.点(坐标)数组不等于空
		 * 2.点(坐标)数组至少含4个元素(>=4 or >3 --  最基本的闭合多边形是---> 三角形)
		 * 3.点(坐标)数组首尾元素相当(关键条件,所谓的闭合,也就是首尾点是同一个点,绕了一圈又绕回来了才称之为闭合)
		 */
		return coords!=null && coords.length>3 && coords[0].equals(coords[coords.length-1]);		
	}
}


(3)测试一番


A.  构建Point (点)






Test





B.  构建LineString (线)






Test





C.  构建LinearRing(闭合线环)


正确的做法:





Test





根据LinearRing可以构建我们的Polygon(不再演示)





错误的做法





Test






最后,我们看一下,刚才正确创建的LinearRing长什么样,


Coordinate coords[] = new Coordinate[4];
coords[0] = new Coordinate(113.6248492, 34.7384023);
coords[1] = new Coordinate(113.6248465, 34.7381533);
coords[2] = new Coordinate(113.6245214, 34.7332024);
coords[3] = new Coordinate(113.6248492, 34.7384023);






看似是两条线,其实它是一个闭合的多边形,只不过坐标我们给的太紧奏了



你可能感兴趣的:(GeoToolsGIS领域)