Pages

Showing posts with label jts. Show all posts
Showing posts with label jts. Show all posts

Thursday, 2 August 2018

JTS 1.15.1 and XYZM development

One of the things I have been working on with the LocationTech crew is the JTS Topology Suite project with a recent release of JTS 1.15.1 and looking into XYZM coordinate support.

JTS logo

Tuesday, 15 October 2013

JTS Downloaded

Introducing the concept of geometry is a fundamental stepping stone to entering our GIS profession. The trick is where to do the introducing?

Java developers are a tough lot, or at least their lot is tough with code examples and theory for an introduction. You can have a bit of fun with curl and a good web API, take the time to set up Open Layers and WPS, try your hand at SFSQL, or break out an desktop application.

In each case you get distracted by the application or technology stack used and lose sight of the point we are trying to make: POINT (160 280)

JTS Topology Suite

So what would it take to download and run the original JTS Topology Suite?
  1. The first step is finding JTS Topology Suite. The project exists on source forge and has a big fat download button.

    Martin does provide an actual home page for JTS, but often as not google will take you to the orphaned Vivid Solutions page from 2006.
  2. The home page comes with nice screenshots, alluding to an easy to use playground somewhere in that bundle.
    Lets see what comes out of the box:
    > unzip jts-1.13.zip -d jts
    > ls jts
    bin doc jtsio lib src testxml
  3. This looks promising:
    >cd jts/bin
    > ls
    test.bat test_stmlf.bat testbuilder.command testrunner.bat testrunner.sh test_robust.bat testbuilder.bat testbuilder.sh testrunner.properties
  4. Time to fix permissions and give that a go:
    >chmod 777 *.sh
    >./testbuilder.sh
  5. A few short clicks later and you can bend it like Martin.

    This is the same application Martin uses in every other lin.ear th.inking blog post so it must be good for something.

Launching JTSTestBuilder

Lets see what that testbuilder.sh script actually does on the inside:

#!/bin/sh
#to change L&F if desired.  Blank is default
JAVA_LOOKANDFEEL="-Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel"
#JAVA_LOOKANDFEEL=""
JAVA_OPTS="-Xms256M -Xmx1024M"
APP_OPTS=""
if test "x$JTS_LIB_DIR" = "x"; then
        JTS_LIB_DIR=`dirname $0`/../lib/
fi
#---------------------------------#
# dynamically build the classpath #
#---------------------------------#
CP=
for i in `ls ${JTS_LIB_DIR}/*.jar`
do
  CP=${CP}:${i}
done
#---------------------------#
# run the program           #
#---------------------------#
MAIN=com.vividsolutions.jtstest.testbuilder.JTSTestBuilder
java -cp ".:${CP}" $JAVA_OPTS  $JAVA_LOOKANDFEEL $MAIN $APP_OPTS

So the usual amount of bash-ing about and then running the JTSTestBuilder class.

JTSTestBuilder Executable

Still all of that is not quite easy enough for use in a training course. Time to get to work:
  1. Since this is JTS (and Martin still does not believe in Maven) we will bust out a ANT script to create an executable jar:
    <project name="jts_runner" default="jar" basedir=".">
      <property name="lib" location="lib"/>
      <property name="build" location="build"/>
      <target name="init">
        <tstamp/>
        <mkdir dir="${build}"/>
      </target>
      <target name="jar" depends="init"
              description="package as executable jar" >
        <jar destfile="${build}/jts-runner.jar" basedir="${build}">
           <zipgroupfileset dir="${lib}"
             includes="*.jar"
             excludes="jtsio*.jar,junit.jar"/>
           <manifest>
              <attribute name="Main-Class"
              value="com.vividsolutions.jtstest.testbuilder.JTSTestBuilder"/>
           </manifest>
        </jar>
      </target>
      <target name="clean" >
        <delete dir="${build}"/>
      </target>
    </project>
  2. Giving that a go:
    >ant
    Buildfile: /Users/jody/Downloads/jts/build.xml
    init:
        [mkdir] Created dir: /Users/jody/Downloads/jts/build
    jar:
          [jar] Building jar: /Users/jody/Downloads/jts/build/jts-runner.jar
    BUILD SUCCESSFUL
    Total time: 1 second
  3. And the result something we can double click and run:


Wednesday, 24 September 2008

Applying the Secrets of JTS

FOSS4G is next week - let me share a little gem from last years FOSS4G conference - Martin's Secrets of JTS presentation.

Talks like this cover material you can revisit, and revisit and revisit. Although Martin does his best to make JTS numercially stable; his presentations can sometimes induce a little recursion.

I revisited this set of slides today as I went over how to "snap" points onto a line - as fast you possibly can. The general set up is some laxidasical source of data that you wish to "auto correct" with the wild assumption that cars stay on roads (or the even better assumption that you have data for all the roads).

The general approach here is to take a peek at behind the API; in this case we can explore the technology that makes a method call like geometry.getDistance( point ) possible.

Here is the heart of the code example - for details see the GeoTools user guide:

Envelope search = new Envelope(pt);
search.expandBy(distance);

List hits = index.query( search );
double d = Double.MAX_VALUE;
Coordinate best = null;
for( LocationIndexedLine line : hits ){
LinearLocation here = line.project( pt );
Coordinate point = line.extractPoint( here );
double currentD = point.distance( pt );
if( currentD <k d ){
best = point;
}
}
if( best == null ){
// we did not manage to snap to a line?
// with real data sets this happens all the time...
System.out.println( pt + "-X");
}
else {
System.out.println( pt + "->" + best );
}



Documentation harmed in the making of this example: Using SpatialIndex and LocationIndexLine to Snap points.

Tuesday, 20 May 2008

Which class is used to repsent a bounding box?

Today we have a great question:
I noticed in the GeoTools Javadoc (2.5 branch) the following 5 classes that could be used to represent an envelope: Envelope, Envelope2D, EnvelopeExample , org.geotools.geometry.iso.coordinate.EnvelopeImpl , org.geometry.jts.spatialschema.geometry.EnvelopeImpl

Is it possible these different envelope classes are represented by a
single interface that I could reference in my code, or do I need to
pick one? Could we refactor these 5 different classes into a single
Envelope2D class/interface?
The answer is a bit of a pain; but it does go a long way toward explaining what we are about with a spatial library, and why GeoTools may be considered difficult to learn.

Is it possible to have a single interface?

In short there is one interface that represents an "Rectangle" well:
- Envelope - this is a GeoAPI interface defined according to the the ISO 19107 Geometry specification

The Envelope interface stores a CRS and a range of valid values for each axis mentioned by the CRS. If you are really sure you are working with a 2D CRS you can make use of a BoundingBox subclass.

But in actual fact you will need to consider a couple other interfaces:
- When working with Java you will need to use a Rectangle, specifically Rectangle2D.Double
- When working with the JTS Topology Suite you will need to use an Envelope class (defined according to the Simple Features for SQL Specification)
- If you are working with Java3D you will find it has its own Bounds and BoundingBox (and BoundingSphere) classes
- And so on ....

Do I need to pick one?

So yes you need to pick one for your application; the GeoTools library will do its best to work with your needs.

Could we refactor these into a single Envelope2D class/interface?

Internally GeoTools often makes use of a single implementation:
- ReferencedEnvelope

The ReferencedEnvelope is one of the first GeoTools specific classes documented in our user guide, and is an example of something that makes the library unique.

Literally RefernecedEnvelope is a compromise:
- ReferencedEnvelope extends JTS Envelope
- RefernecedEnvelope implements GeoAPI BoundingBox

This gives you the best of both worlds; access bounds in a form acceptable to the JTS Geometry classes (which only wory about the numbers), that also address the need of the GeoTools library to track the Coordinate Refernece System (so we know what the number mean).

Documentation Link

Here is the user guide page that talks about this stuff.