添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
温柔的筷子  ·  JavaScript中Write和Write ...·  1 年前    · 
温暖的枕头  ·  android.os.deadobjecte ...·  1 年前    · 
活泼的香槟  ·  javascript文件读取 ...·  1 年前    · 

最近在做一个项目,涉及到求线与面的交点问题,查阅了API,没有发现符合需求的函数,于是就动手实现了求线与面交点的功能。
注意:这里的线与面的交点仅指二维平面的交点,而非三维的
参考链接: GeoTools官方文档

提示:以下是本篇文章正文内容,下面案例可供参考

一、maven引入GeoTools依赖

项目中用到的Geotools中的依赖都在这了,如果只是实现本文的线与面的交点功能,则不需要全部添加。

<repositories>
	<repository>
		<id>osgeo</id>
		<name>Open Source Geospatial Foundation Repository</name>
		<url>http://download.osgeo.org/webdav/geotools/</url>
	</repository>
</repositories>
<properties>
	<geotools.version>17.0</geotools.version>
</properties>
<dependencies>
	<dependency>
		<groupId>org.geotools</groupId>
		<artifactId>gt-shapefile</artifactId>
		<version>${geotools.version}</version>
	</dependency>
	<dependency>
		<groupId>org.geotools</groupId>
		<artifactId>gt-main</artifactId>
		<version>${geotools.version}</version>
	</dependency>
	<dependency>
		<groupId>org.geotools</groupId>
		<artifactId>gt-geojson</artifactId>
		<version>${geotools.version}</version>
	</dependency>
	<dependency>
		<groupId>org.geotools</groupId>
		<artifactId>gt-swing</artifactId>
		<version>${geotools.version}</version>
	</dependency>
</dependencies>

二、方法实现

这里考虑了面状数据为Polygon和MultiPolygon的情况,其中MultiPolygon中考虑每个Polygon中包含环的情况。

1.实现思路

将面状数据(Polygon/MultiPolygon)转换为线状数据(MultiLineString),然后使用GeoTools提供的intersection方法,计算两条线的交点坐标。

2.面转换为线

面转换为线代码如下:

public static Geometry polygon2LineString(Geometry geoms) {
		GeometryFactory gf = JTSFactoryFinder.getGeometryFactory();
		String type = geoms.getGeometryType().toUpperCase();
		Geometry res;
		if ("MULTIPOLYGON".equals(type)) {
			int geomNum = geoms.getNumGeometries();
			List<LineString> lineList = new ArrayList<>();
			if (geomNum > 1) {
				// 包含多个面,面中包含环
				for (int i = 0; i < geomNum; i++) {
					Polygon geo = (Polygon) geoms.getGeometryN(i);
					lineList.add(gf.createLineString(geo.getExteriorRing().getCoordinates()));
					for (int j = 0; j < geo.getNumInteriorRing(); j++) {
						lineList.add(gf.createLineString(geo.getInteriorRingN(i).getCoordinates()));
				LineString[] lines = new LineString[lineList.size()];
				lineList.toArray(lines);
				res = gf.createMultiLineString(lines);
			} else {
				// 包含一个面,面中包含环
				Polygon poly = (Polygon) geoms.getGeometryN(0);
				lineList.add(gf.createLineString(poly.getExteriorRing().getCoordinates()));
				for (int i = 0; i < poly.getNumInteriorRing(); i++) {
					lineList.add(gf.createLineString(poly.getInteriorRingN(i).getCoordinates()));
				LineString[] lines = new LineString[lineList.size()];
				lineList.toArray(lines);
				res = gf.createMultiLineString(lines);
		} else if ("POLYGON".equals(type)) {
			// 只包含一个面
			res = gf.createLineString(geoms.getCoordinates());
		} else {
			res = null;
		return res;

3.计算交点坐标

public static Geometry getPointOfIntersection(Geometry geom, Geometry line) {
	//面转换为线
	Geometry lines = polygon2LineString(geom);
	return lines.intersection(line);

4.wkt转Geometry

此部分代码在代码测试中用到。

public static Geometry wkt2Geometry(String wktString) {
	GeometryFactory gc = JTSFactoryFinder.getGeometryFactory();
    WKTReader reader = new WKTReader(gc);
    Geometry geom = null;
    try {
        geom = reader.read(wktString);
    } catch (ParseException e) {
        e.printStackTrace();
    return geom;

5.完整代码

import java.util.ArrayList;
import java.util.List;
import org.geotools.geometry.jts.JTSFactoryFinder;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
public class PointOfIntersectionTest {
	 * Polygon转换为LineString
	 * @param geoms
	 * @return
	public static Geometry polygon2LineString(Geometry geoms) {
		GeometryFactory gf = JTSFactoryFinder.getGeometryFactory();
		String type = geoms.getGeometryType().toUpperCase();
		Geometry res;
		if ("MULTIPOLYGON".equals(type)) {
			int geomNum = geoms.getNumGeometries();
			List<LineString> lineList = new ArrayList<>();
			if (geomNum > 1) {
				// 包含多个面,面中包含环
				for (int i = 0; i < geomNum; i++) {
					Polygon geo = (Polygon) geoms.getGeometryN(i);
					lineList.add(gf.createLineString(geo.getExteriorRing().getCoordinates()));
					for (int j = 0; j < geo.getNumInteriorRing(); j++) {
						lineList.add(gf.createLineString(geo.getInteriorRingN(i).getCoordinates()));
				LineString[] lines = new LineString[lineList.size()];
				lineList.toArray(lines);
				res = gf.createMultiLineString(lines);
			} else {
				// 包含一个面,面中包含环
				Polygon poly = (Polygon) geoms.getGeometryN(0);
				lineList.add(gf.createLineString(poly.getExteriorRing().getCoordinates()));
				for (int i = 0; i < poly.getNumInteriorRing(); i++) {
					lineList.add(gf.createLineString(poly.getInteriorRingN(i).getCoordinates()));
				LineString[] lines = new LineString[lineList.size()];
				lineList.toArray(lines);
				res = gf.createMultiLineString(lines);
		} else if ("POLYGON".equals(type)) {
			// 只包含一个面
			res = gf.createLineString(geoms.getCoordinates());
		} else {
			res = null;
		return res;
	 * wkt转Geometry
	 * @param wktString
	 * @return
	public static Geometry wkt2Geometry(String wktString) {
		GeometryFactory gc = new GeometryFactory();
        WKTReader reader = new WKTReader(gc);
        Geometry geom = null;
        try {
            geom = reader.read(wktString);
        } catch (ParseException e) {
            e.printStackTrace();
        return geom;
	public static void main(String[] args) {
		String poly = "Polygon((1.0 1.0, 2.0 1.0, 2.0 2.0, 1.0 2.0, 1.0 1.0))";
		//String poly = "MultiPolygon(((1.0 1.0, 2.0 1.0, 2.0 2.0, 1.0 2.0, 1.0 1.0),(1.2 1.2, 1.8 1.2, 1.8 1.8, 1.2 1.8, 1.2 1.2)))";
		Geometry geoms = wkt2Geometry(poly);
		Geometry polyGeo = polygon2LineString(geoms);
		// 面转线结果
		System.out.println(polyGeo.toText());
		String line1 = "LineString(1.5 0.0, 1.5 1.5)";
		Geometry lineGeo = wkt2Geometry(line1);
		Geometry points = polyGeo.intersection(lineGeo);
		System.out.println(points.toText());

6.测试结果

上述代码运行完的结果为:

LINESTRING (1 1, 2 1, 2 2, 1 2, 1 1)
POINT (1.5 1)

使用QGIS对上述结果可视化:
图1结果可视化1
使用main函数中注释的MultiPolygon数据做测试,运行结果为:

MULTILINESTRING ((1 1, 2 1, 2 2, 1 2, 1 1), (1.2 1.2, 1.8 1.2, 1.8 1.8, 1.2 1.8, 1.2 1.2))
MULTIPOINT ((1.5 1), (1.5 1.2))

使用QGIS对上述结果可视化:
图2 结果可视化2

本文仅简单介绍了一种计算平面内线与面交点的方法,在此记录下,方便以后查阅。函数只做了简单的测试,只能满足当前项目的小需求,如果您遇到类似的问题,希望能给予您一点点的提示。

文章目录前言一、maven引入GeoTools依赖二、方法实现1.实现思路2.面转换为线3.计算交点坐标4.wkt转Geometry5.完整代码6.测试结果总结前言最近在做一个项目,涉及到求线与面的交点问题,查阅了API,没有发现符合需求的函数,于是就动手实现了求线与面交点的功能。注意:这里的线与面的交点仅指二维平面的交点,而非三维的参考链接:GeoTools官方文档提示:以下是本篇文章正文内容,下面案例可供参考一、maven引入GeoTools依赖项目中用到的Geotools中的依赖都在
一:代数方式 我们假设它们的交点为P,既然我们有一个平,那么平的一个点P0和平的normal(垂直于平的向量)我们是肯定知道的。 根据3D数学知识,(P-P0) · normal = 0(公式一);(既然垂直,那么它们点乘肯定为0)。 对于这条直线,我们肯定知道直线的某一点L0和直线的方向L,那么 P = L0 + dL(公式二),d是距离。 把公式二代入公式一,我们可以得
空间数据模型 (1)、JTS Geometry model (2)、ISO Geometry model (Geometry Plugin and JTS Wrapper Plugin) GeoTools has two implementations of these interfaces: Geometry Plugin a port of JTS 1.7 to the ISO Geometry interfaces JTS Wrapper Plugin an implementation that.
这两天在做一个系统的后台,需要用到GeoTools做后端空间分析,记录一下自己遇到的问题。 项目通过Maven进行构建,参照文档Maven Quickstart添加GeoTools依赖和远程仓库地址。 <dependencies> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-shapefile</