构建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工具包


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.appleyk</groupId>
	<artifactId>spring-boot-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Java-Web</name>
	<!-- 继承官网最新父POM【假设当前项目不再继承其他POM】 -->
	<!-- http://projects.spring.io/spring-boot/#quick-start -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
	</parent>
	<!-- 使用Java8,嘗試使用新特新【stream和lambda】 -->
	<properties>
		<java.version>1.8</java.version>
		<geotools.version>17.0</geotools.version>
		<postgresql.version>42.1.4</postgresql.version>
	</properties>
	<repositories>
		<repository>
			<id>osgeo</id>
			<name>Open Source Geospatial Foundation Repository</name>
			<url>http://download.osgeo.org/webdav/geotools/</url>
		</repository>
	</repositories>
	<!-- Starter POMs是可以包含到应用中的一个方便的依赖关系描述符集合 -->
	<!-- 该Starters包含很多你搭建项目, 快速运行所需的依赖, 并提供一致的, 管理的传递依赖集。 -->
	<!-- 大多数的web应用都使用spring-boot-starter-web模块进行快速搭建和运行。 -->
	<!-- spring-boot-starter-web -->
	<!-- 对全栈web开发的支持, 包括Tomcat和 spring-webmvc -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- Spring 单元测试 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- 添加thymeleaf 支持页面跳转 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<!-- 添加热部署 devtools:监听文件变动 -->
		<!-- 当Java文件改动时,Spring-boo会快速重新启动 -->
		<!-- 最简单的测试,就是随便找一个文件Ctrl+S一下,就可以看到效果 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<!-- optional=true,依赖不会传递 -->
			<!-- 本项目依赖devtools;若依赖本项目的其他项目想要使用devtools,需要重新引入 -->
			<optional>true</optional>
		</dependency>
		<!-- JUnit单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<!-- 添加GeoTools依赖 -->
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-shapefile</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-swing</artifactId>
			<version>${geotools.version}</version>
		</dependency>
	</dependencies>
	<!-- Spring Boot包含一个Maven插件, 它可以将项目打包成一个可执行jar -->
	<build>
		<!-- 解决配置资源文件被漏掉问题 -->
		<resources>
			<!--  如果出现thymeleaf无法渲染html模板,请加上这个 -->
			<resource>
				<directory>src/main/resources</directory>
			</resource>
			<resource>
				<directory>src/main/resources</directory>
				<includes>
					<include>**/*.properties</include>
					<include>**/*.xml</include>
				</includes>
				<filtering>false</filtering>
			</resource>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.properties</include>
					<include>**/*.xml</include>
				</includes>
				<filtering>false</filtering>
			</resource>
		</resources>
		<plugins>
			<!-- boot-maven插件 -->
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<configuration>
					<includes>
						<include>**/*Documentation.java</include>
					</includes>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<packaging>war</packaging>
</project>




二、单元测试构建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);






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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值