Friday, January 2, 2009

JTS Version 1.10 released

I'm happy to announce that after a long gestation JTS 1.10 has been released. (This is my contribution to help fulfill James Fee's prediction 8^)

The package is available on SourceForge here.

There are numerous enhancements in this version. The highlights are:
  • Dramatic improvements to buffer performance, robustness and quality
  • Moving the GML I/O classes into the core library, and provided more control over the emitted GML
  • numerous bug fixes and performance improvements.
The full list of changes is:

Functionality Improvements

  • Added Geometry.reverse() method for all geometry types
  • Added setSrsName, setNamespace, setCustomRootElements methods to GMLWriter
  • Added Envelope.getArea method
  • Added copy, copyCoord methods to CoordinateSequences
  • Added area method to Envelope
  • Added extractPoint(pt, offset) methods to LengthIndexedLine and LocationIndexedLine
  • Added CoordinatePrecisionReducerFilter
  • Added UnaryUnionOp(Collection, GeometryFactory) constructor to handle empty inputs more automatically
  • Added DiscreteHausdorffDistance class
  • Made LineMerger able to be called incrementally
  • Added GeometricShapeFactory.createArcPolygon to create a polygonal arc
  • Enhanced Geometry.buffer() to preserve SRID

Performance Improvements

  • Improved performance for EdgeList (by using a more efficient technique for detecting duplicate edges)
  • Improved performance for ByteArrayInStream (by avoiding use of java.io.ByteArrayInputStream)
  • Unrolled intersection computation in HCoordinate to avoid object allocation
  • Improved performance for buffering via better offset curve generation and simplification.
  • Improved performance for IsValipOp by switching to use STRtree for nested hole checking

Bug Fixes

  • Fixed Geometry.getClassSortIndex() to lazily initialize the sorted class list. This fixes a threading bug.
  • Fixed RectangleContains to return correct result for points on the boundary of the rectangle
  • Fixed error in com.vividsolutions.jts.simplify.LineSegmentIndex which caused polygons simplified using TopologyPreservingSimplifier to be invalid in certain situations
  • Fixed error in DouglasPeuckerSimplifier which caused empty polygons to be returned when they contained a very small hole
  • Fixed PackedCoordinateSequence to return NaN for null ordinate values
  • Fixed Geometry.centroid() (CentroidArea) so that it handles degenerate (zero-area) polygons
  • Fixed Geometry.buffer() (OffsetCurveBuilder) so that it handles JOIN_MITRE cases with nearly collinear lines correctly
  • Fixed GeometryFactory.toGeometry(Envelope) to return a CW polygon
  • Fixed UnaryUnionOp to correctly handle heterogeneous inputs with P/L/A components
  • Fixed UnaryUnionOp to accept LINEARRINGs
  • Fixed CentroidArea to handle zero-area polygons correctly
  • Fixed WKBWriter to always output 3D when requested, and to handle 2D PackedCoordinateSequences correctly in this case
  • Fixed NodedSegmentString to handle zero-length line segments correctly (via safeOctant)
  • Cleaned up code to remove unneeded CGAlgorithms objects
  • Fixed GeometricShapeFactory.createArc to ensure arc has requested number of vertices

API Changes

  • Moved GML I/O classes into core JTS codebase
  • Changed GMLWriter to not write the srsName attribute by default
  • In DistanceOp switched to using nearestPoints method names
  • Exposed STRtree.getRoot() method

JTS TestBuilder

UI Improvements

  • Added ability to read GML from input panel
  • Added GML output to View dialog
  • Added file drag'n'drop to Geometry Input text areas
  • Add display of computation time
  • Added Stats panel
  • Added Scalar functions panel, with extensible function list
  • Added Save as PNG...

JTS TestRunner

Functionality Improvements

  • Added -testCaseIndex command-line option

1 comment:

Michael said...

Hi Martin, and happy new year,

Thanks for this new release.
Nice to see that JTS is not only the best choice to do geoprocessing, but that it's also getting more robust and faster version after version.

Is it a good place and a good time for a wish list ? As I have no idea about your plans, I'll risk to write a few ideas (just a way to know more about yours)

1 - Spatial indexing : I followed recent discussions on jts list, some older ones on h2 database list. I saw also an interesting post about sqlite spatial capabilities on gvsig list (see also http://www.gaia-gis.it/spatialite/) and you probably know this interesting paper about spatial indexing : http://anandmu.googlepages.com/comparison3finalreport.pdf.
JTS has an excellent RTree index, but it is probably not well suited for database indexing because it is not updatable. On the other hand, quadtree has poor performances compared to STRtree. I think that a good Gist competitor for java databases would help java database authors including spatial capabilities, which would be great.

2 - Z ordinate : when an intersection is computed between two segments, there is no interpolated z on the new coordinate.
I do not have a precise idea of how to deal with this complex problem, but what I can imagine is :
keep an interpolated z on each intersecting segment as long as possible,
and if only one z is needed for the final geometry (ex. get linestring1.intersection(linestring2)), follow a user-defined rule like
z null or
z of first geometry or
z max, z min, z mean or ...

4 - geometry cleaning. I know you already wrote much code in this area (JCS, road matcher). I also recently saw some code written by rgould for uDig (http://svn.refractions.net/udig/udig/community/rgould/ - don't know if it has been released). Having some automatic processes to adress common issues like node mismatches, undershoots, overshoots, small gaps, small overlaps... would be great. These problems generally need an automatic cleaning (to solve cases with very very small distances) then an interactive tool to deal with cases which may be or may not be a problem... JTS could help to solve first cases (automatic process). Second cases may be solved by plugin developpers.

Michaƫl Michaud