要创建一个Geometry对象,我们利用GeometryFactoryJTS提供的。GeometryFactory有很多创建方法,这些方法采用Coordinate实例(和数组)并将它们包装在相应的Geometry实例中。

JTS实现的OGC SQL规范简单功能可与PointLineStringPolygon一起使用

每个几何都可以包含在一个信封中(充当包含所有几何坐标的边界框)。

用于SQL规范的OGC简单功能还提供了对的支持GeometryCollectionsGeometryCollections本身就是几何。

您可以GeometryFactory使用特定的PrecisionModel和创建自己的CoordinateSequenceFactory

笔记

如果您需要负责坐标的存储方式(也许是浮点数而不是双精度数),则可以使用这些“高级”配置选项。这两个概念可以一起使用:如果将坐标存储在浮点数数组中,则仅使用JTS在计算过程中需要考虑浮点精度。

默认情况下创建的GeometryFactory可以正常工作。

GeoTools extends these core Geometry classes to allow support for curves. These implementations generate coordinates allowing them to act as normal JTS Geometries (as required for JTS Operations).

The linearization process used to generate coordinates makes use of the control points defining the curve and a tolerance provided by a CurvedGeometryFactory.

Creating a Point

This time we are using a JTS GeometryFactory, although you can create one yourself (if you want to fiddle with Precision}} there is a global one available using the FactoryFinder.:

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();Coordinate coord = new Coordinate(1, 1);Point point = geometryFactory.createPoint(coord);

“Well Known Text” is a simple text format defined by the Simple Feature for SQL specification:

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();WKTReader reader = new WKTReader(geometryFactory);Point point = (Point) reader.read("POINT (1 1)");

If you need to represent many points (perhaps fence posts forming a fence) you can use use a MultiPoint.

Creating a LineString

The following makes a line string in the shape of a check mark:

GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();Coordinate[] coords  =new Coordinate[] {new Coordinate(0, 2), new Coordinate(2, 0), new Coordinate(8, 6) };LineString line = geometryFactory.createLineString(coordinates);

Alternative - Reading a LineString from WKT:

GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();WKTReader reader = new WKTReader( geometryFactory );
LineString line = (LineString) reader.read("LINESTRING(0 2, 2 0, 8 6)");

If you need to represent a line with gaps in it you can use a MultiLineString.

Creating a Polygon

The following makes a Polygon in the shape of a square:

GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();Coordinate[] coords  =new Coordinate[] {new Coordinate(4, 0), new Coordinate(2, 2),new Coordinate(4, 4), new Coordinate(6, 2), new Coordinate(4, 0) };LinearRing ring = geometryFactory.createLinearRing( coords );
LinearRing holes[] = null; // use LinearRing[] to represent holes
Polygon polygon = geometryFactory.createPolygon(ring, holes );

Alternative - Reading a Polygon from WKT:

GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );WKTReader reader = new WKTReader( geometryFactory );
Polygon polygon = (Polygon) reader.read("POLYGON((20 10, 30 0, 40 10, 30 20, 20 10))");

You can also create a Polygon will holes in it. And once again use a MultiPolygon to represent a single geometry made up of distinct shapes.

Creating CircularString

To create a CircularString (or a CircularRing) use the GeoTools CurvedGeometryFactory. When setting up a CurvedGeometryFactory the provided tolerance will be used during linearization:

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();CurvedGeometryFactory curvedFactory =new CurvedGeometryFactory(geometryFactory, Double.MAX_VALUE);CoordinateSequence coords =PackedCoordinateSequenceFactory.DOUBLE_FACTORY.create(new double[] {10, 14, 6, 10, 14, 10}, 2);CircularString arc = (CircularString) curvedFactory.createCurvedGeometry(coords);

The circle arc is defined between coordinates 10,14 and 14, 10 passing through point 6,10. The example uses a PackedCoordinateSequence allowing an array of doubles to be used directly. Curve support is limited to 2D coordinates. A CircularLineString is returned in this case, a CircularRing would be produced if two or more curves were provided form a closed ring.

Reading a circular arc from WKT:

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();CurvedGeometryFactory curvedfactory = new CurvedGeometryFactory(Double.MAX_VALUE);WKTReader2 reader = new WKTReader2(curvedfactory);CircularString arc = (CircularString) reader.read("CIRCULARSTRING(10 14,6 10,14 10)");

CompoundCurve (or closed CompoundRing) consists mix of CircularString and/or plain LineString components.

Custom Curves

The JTS Topology Suite does not have any constructs to represent a “curve” or “circle” - GeoTools added that as an extension. The mathematics used by JTS is strictly limited to geometry made up of straight (i.e. linear) lines.

The GeoTools curve implementations rely on using control points to define a curve, and converting it to a straight lines at the last possible moment.

Curves can also be produced by hand using a little bit of math.

Creating a Circle:

private static Geometry createCircle(double x, double y, final double RADIUS) {GeometricShapeFactory shapeFactory = new GeometricShapeFactory();shapeFactory.setNumPoints(32);shapeFactory.setCentre(new Coordinate(x, y));shapeFactory.setSize(RADIUS * 2);return shapeFactory.createCircle();
}

Even though GeometricShapeFactory is provided out of the box from JTS; there is nothing fancy about the code. It creates a series of coordinates in a circle.

Another approach is to create a curve or shape object with one of Java’s handy Shape classes and then extract the coordinates from that object to create your geometry.

Arcs without the math:

private static Geometry createBezierCurve(Coordinate start,Coordinate end,Coordinate ctrlPoint1,Coordinate ctrlPoint2double smooth) {Shape curve = new CubicCurve2D.Double(start.x, start.y,ctrlPoint1.x, ctrlPoint1.y,ctrlPoint2.x, ctrlPoint2.y,end.x, end.y);// the value of the smooth arg determines how closely the line// segments between points approximate the smooth curve// (see javadocs for Shape.getPathIterator method)PathIterator iter = curve.getPathIterator(null, smooth);// a length 6 array is required for the iteratordouble[] iterBuf = new double[6];List<Coordinate> coords = new ArrayList<Coordinate>();while (!iter.isDone()) {iter.currentSegment(iterBuf);coords.add(new Coordinate(buf[0], buf[1]);iter.next();}GeometryFactory gf = new GeometryFactory();return gf.createLineString(coords.toArray(new Coordinate[coords.size()]));
}

Here’s an example of some randomly orientated and shaped curves generated in this way…

Sometimes you need to generate a smooth curve that is guaranteed to pass through a specified set of points. The tried and true approach here is to use a spline function. This generates a set of polynomial (cubic) curves, each of which fits a part of the data and joins smoothly to its neighboring curves.

Splines:

public Geometry splineInterpolatePoints(double[] xPoints, double[] yPoints) {/** First we create a LineString of segments with the* input points as vertices.*/final int N = xPoints.length;Coordinate[] coords = new Coordinate[N];for (int i = 0; i < N; i++) {coords[i] = new Coordinate(xPoints[i], yPoints[i]);}GeometryFactory gf = new GeometryFactory();LineString line = gf.createLineString(coords);/** Now we use the GeoTools JTS utility class to smooth the* line. The returned Geometry will have all of the vertices* of the input line plus extra vertices tracing a spline* curve. The second argument is the 'fit' parameter which* can be in the range 0 (loose fit) to 1 (tightest fit).*/return JTS.smooth(line, 0.0);
}

Here is an example of this in use:

Example smoothing a polygon:

WKTReader reader = new WKTReader();
Geometry tShape = reader.read(
"POLYGON((10 0, 10 20, 0 20, 0 30, 30 30, 30 20, 20 20, 20 0, 10 0))");Geometry tLoose = JTS.smooth(tShape, 0.0);
Geometry tTighter = JTS.smooth(tShape, 0.75);

Here is the resulting image:

Geometry

Using Geometry is pretty straight forward, although a little intimidating when starting out due to the number of methods.

Some summary information is available:

  • getArea() - area returned in the same units as the coordinates (be careful of latitude/longitude data!)

  • getCentroid() - the center of the geometry

  • getEnvelope() - returns a geometry which is probably not what you wanted

  • getEnvelopeInternal() - this returns a useful Envelope

  • getInteriorPoint() - the center of the geometry (that is actually on the geometry)

  • getDimension()

Geometry relationships are represented by the following functions returning true or false:

  • disjoint(Geometry) - same as “not” intersects

  • touches(Geometry) - geometry have to just touch, crossing or overlap will not work

  • intersects(Geometry)

  • crosses(Geometry)

  • within(Geometry) - geometry has to be full inside

  • contains(Geometry)

  • overlaps(Geometry) - has to actually overlap the edge, being within or touching will not work

  • covers(Geometry)

  • coveredBy(Geometry)

  • relate(Geometry, String) - allows general check of relationship see dim9 page

  • relate(Geometry)

To actually determine a shape based on two geometry:

  • intersection(Geometry)

  • union(Geometry)

  • difference(Geometry)

  • symDifference(Geometry)

Some of the most helpful functions are:

  • distance(Geometry)

  • buffer(double) - used to buffer the edge of a geometry to produce a polygon

  • union() - used on a geometry collection to produce a single geometry

The three most difficult methods are here (they will be discussed in detail):

  • equals(Object) - normal Java equals which checks that the two objects are the same instance

  • equals(Geometry) - checks if the geometry is the same shape

  • equalsExact(Geometry) - check if the data structure is the same

有一些簿记方法可以帮助您发现如何构造几何体:

  • getGeometryFactory()

  • getPreceisionModel()

  • toText() -几何的WKT表示

  • getGeoemtryType()-称为工厂方法(即pointlinestring等。)

有两种方法可以存储您的开发人员信息:

  • getSRID() -存储“空间参考ID”,在使用数据库时用作外部键

  • getUserData()-旨在供开发人员使用,最佳做法是存储java.util.Map。GeoTools有时会使用此字段来存储asrsName或full CoordinateReferenceSystem

几何枚举

使用Geometry的代码最终需要进行大量instanceof测试,以确定Geometry所使用的类型(采取适当的措施)。

在这种情况下,我们定义了一个枚举来帮助您:

    public boolean hit(Point point, Geometry geometry) {final double MAX_DISTANCE = 0.001;switch (Geometries.get(geometry)) {case POINT:case MULTIPOINT:case LINESTRING:case MULTILINESTRING:// Test if p is within a threshold distancereturn geometry.isWithinDistance(point, MAX_DISTANCE);case POLYGON:case MULTIPOLYGON:// Test if the polygonal geometry contains preturn geometry.contains(point);            default:// For simplicity we just assume distance check will work for other// types (e.g. GeometryCollection) in this examplereturn geometry.isWithinDistance(point, MAX_DISTANCE);}}

精密模型

开箱即用的JTS使用默认的双精度模型。使用配置您GeometryFactoryPrecisionModel可以使您以与默认值不同的分辨率工作。

PrecisionModel在使用几何图形时,形成了“数值稳定性”的核心。当使用大值时,Java内置的数学不是很准确。通过在PrecisionModelJTS中明确捕获“舍入”过程,可以管理这些类型的错误,并在工作速度与准确性之间做出适当的权衡。

  • 即使以双精度工作时,也会经常发生舍入。

    特别是如果您正在使用具有大量数字的坐标系,并且距原点还有很长的路要走。

  • 要查看的另一个原因PrecisionModel是确保它与您的数据最终用途相匹配。如果您知道只在屏幕上显示答案,则可能会降低精度。

    通过PrecisionModel与您的预期用途匹配,某些长时间运行的操作(需要收敛于一个答案)可以在达到您期望的详细程度时停止。如果结果要在一天结束时四舍五入,就没有必要为更高的位数做额外的工作。

以下代码示例考虑到传递的位置仅作为浮点值x / y提供。我们创建了这个测试点处理此GeometryFactory,需要一个PrecisionModel说法。测试点将被标记为具有一定的有限精度,并且所有JTS操作都将考虑这一点。

有多种指定a的方法,PrecisionModel但在此我们将其基于用于坐标比较的小数位数。

private boolean polyContains(Polygon poly, float x, float y, int numDecPlaces) {double scale = Math.pow(10, numDecPlaces);PrecisionModel pm = new PrecisionModel(scale);GeometryFactory gf = new GeometryFactory(pm);Geometry testPoint = gf.createPoint(new Coordinate(x, y));return poly.contains(testPoint);
}

您还可以PrecisionModel使用几个常量定义:

pm = new PrecisionModel( PrecisionModel.Type.FIXED ); // fixed decimal point
pm = new PrecisionModel( PrecisionModel.Type.FLOATING ); // for Java double
pm = new PrecisionModel( PrecisionModel.Type.FLOATING_SINGLE ); // for Java float

这是一个不经常使用的高级功能。

CoordinateSequence

您可能CoordinateSequenceFactory出于效率和/或减少内存使用的原因而希望提供一个自定义。

内部几何通常与Coordinate []一起使用。但是,为提高效率,许多用于JTS的空间格式会将值存储为flat double []或float []。通过实现CoordinateSequenceFactoryGeoTools,可以教导JTS如何例如直接从shapefile中处理值。

这是一个不经常使用的高级功能。

捷讯

上面使用的一些代码示例引用了JTS实用程序类。此类由gt-main模块提供;并包含许多用于处理几何的有用方法。

GEOTOOLS-几何学相关推荐

  1. java使用geotools读取shp文件

    java使用geotools读取shp文件 测试shp文件 引入geotools包 压缩包文件处理 shp文件相关信息的读取 运行结果 GeoTools是一个开源的Java GIS工具包,可利用它来开 ...

  2. JAVA IDEA集成geotools gt-mif gdal读取.MIF

    JAVA IDEA集成geotools gt-mif gdal读取.MIF 1. 结论 2. 问题1:gdal maven下载不下来 3. geotools,gt-mif maven配置 4. 源码 ...

  3. 2018-4-5 丘成桐---现代几何学与计算机科学---自我总结

    CNCC 2017  特邀报告 视频以及PDF课件来源: 音视频详情页 http://dl.ccf.org.cn/audioVideo/detail.html?id=3712087377283072 ...

  4. 扛鼎之作!Twitter 图机器学习大牛发表160页论文:以几何学视角统一深度学习

    编译 | Mr Bear.青暮 转自 | AI科技评论 导语:近日,帝国理工学院教授.Twitter 首席科学家 Michael Bronstein 发表了一篇长达160页的论文(或者说书籍),试图从 ...

  5. 素数问题是物质的几何学问题

    来源:知乎 大家知道,黎曼猜想.孪生素数猜想.哥德巴赫猜想中皆涉及素数(质数).关于黎曼猜想,黄逸文说"这是1900年希尔伯特提出的23个唯一未被解决的问题,也是数学中最重大的未解决的难题. ...

  6. geotools的dotnet版本

    今天成功用ikvm将开源java gis中间件geotools转换到.net上.详细操作见我的blog文章: 将java库转换为.net库

  7. [iOS Animation]-CALayer 图层几何学

    2019独角兽企业重金招聘Python工程师标准>>> 图层几何学 不熟悉几何学的人就不要来这里了 --柏拉图学院入口的签名 在第二章里面,我们介绍了图层背后的图片,和一些控制图层坐 ...

  8. 简析服务端通过geotools导入SHP至PG的方法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 项目中需要在浏览器端直接上传SHP后服务端进行数据的自动入PG ...

  9. 算法导论之计算几何学

    计算几何学是计算机科学的一个分支,专门研究集合问题的解决的算法.计算几何学的问题一般输入关于一组集合对象的描述,如一组点.一组线段:输出是对问题的回答,如直线是否相交.三维空间和高维空间很难视觉化,这 ...

  10. 解决GeoTools中CQL解析中文字段名的问题

    GeoTools中CQL无法解析中文字段名的过滤条件,会报异常错误,经过一个下午的努力,终于通过简单有效的方式解决啦 String filterCondition = "temp='&quo ...

最新文章

  1. zabbix之rpm简单快速安装详解
  2. 会计的思考(3):通过公司例会制度加强财务管理职能
  3. 新闻发布项目——接口类(BaseDao)
  4. An invalid form control with name='timeone[]' is not focusable.
  5. 【Kafka】Kafka SCRAM认证 ERROR [ZooKeeperClient] Auth failed
  6. 电子计算机工作的特征是什么,电子计算机的基本特征是什么?
  7. 分析JQ作者的类实现过程
  8. 系统学习深度学习(三十八)--深度确定性策略梯度(DDPG)
  9. 从备用类型总盗用steal page
  10. itextpdf使用
  11. java对接金蝶webapi
  12. 微信直播监控服务器,HTML5微信网页调用监控直播代码接口文档v3.02
  13. 测试连接--ping (IP地址,网址,主机名)
  14. 顺口溜:国足欢迎你(贬)
  15. Metaverse 元宇宙入门-02-Hardware 硬件与元宇宙
  16. 【渝粤教育】广东开放大学 公共经济学 形成性考核 (33)
  17. AD之PCB各层说明
  18. Python科研绘图第一期——线型图(Line)、条型图(Bar)、散点图(Scatter)、子图(subplot)
  19. 精品微信小程序springboot居家养老服务+后台管理前后分离
  20. 列表推导式与字典推导式,滚雪球学 Python

热门文章

  1. mysql修改表结构 删除字段_mysql更改表结构:添加、删除、修改字段、调整字段顺序...
  2. 蓝桥杯 基础练习 高精度加法
  3. 自动驾驶公司 | 纽劢科技与黑芝麻智能战略合作,共推自动驾驶量产落地
  4. el表达式 多条件判断
  5. LeetCode刷题(9)
  6. html5音乐播放时间监测,【HTML5】HTML5中video元素事件详解(实时监测当前播放时间)...
  7. 若依前后端分离如何修改title标题呢?
  8. 若依前端如何生成序号?
  9. [Ext JS 4]性能优化
  10. .net mysql 参数,在MySQL .NET Provider中使用命名参数