Added by jgarnett, last edited by aaime on Aug 08, 2007  (view change) show comment

Labels

 
(None)
Upgrade to 2.3 Upgrade to 2.4 Upgrade to 2.5

The following is needed when upgrading to 2.4:

For more information:

Rename FactoryFinder to ReferencingFactoryFinder

BEFORE (GeoTools 2.2 Code)

CRSFactory factory = FactoryFinder.getCSFactory( null );

AFTER (GeoTools 2.4 Code)

CRSFactory factory = ReferencingFactoryFinder.getCSFactory( null );

Update FeatureStore addFeatures

The use of FeatureReader has been revmoved from the FeatureStore API.

Before (GeoTools 2.2 Code)

featureStore.addFeatures( DataUtilities.reader( collection )); // add FeatureCollection
featureStore.addFeatures( DataUtilities.reader(array)); // add Feature[]
featureStore.addFeatures( DataUtilities.reader(feature )); // add Feature
featureStore.addFeatures( reader );

After (GeoTools 2.4 Code)

featureStore.addFeatures( collection ); // add FeatureCollection
featureStore.addFeatures( DataUtilities.collection( array ) ); // add Feature[]
featureStore.addFeatures( DataUtilities.collection( feature )); // add Feature
featureStore.addFeatures( DataUtilities.collection( reader )); // add FeatureReader

DataUtilities.collection( reader ) will currently load the contents into memory, if you have any volunteer time a "lazy" implementation would be helpful.

Add FeatureSource getSupportedHints

We added a getSupportedHints() method that can be used to check which Query hints are supported by a certain FeatureSource.
If your FeatureSource does not intend to leverage query hints, just return an empty set.

After (GeoTools 2.4 Code)

/**
     * By default, no Hints are supported
     */
    public Set getSupportedHints() {
        return Collections.EMPTY_SET;
    }

Add Query getHints

If you have a Query implementation other than DefaultQuery you'll need to add the getHints() method. The default implementation, if you don't plan to leverage hints, can just return an empty Hints object.

After (GeoTools 2.4 Code)

/**
     * Returns an empty Hints set
     */
    public Hints getHints() {
        return new Hints(Collections.EMPTY_MAP);
    }

Transition to GeoAPI Filter

Special case of GeoAPI filter upgrades:

Before (GeoTools 2.2 Code)

package org.geotools.filter;

import junit.framework.TestCase;

import org.geotools.filter.LogicFilter;
import org.geotools.filter.FilterFactory;
import org.geotools.filter.Filter;

public class FilterFactoryBeforeTest extends TestCase {

    public void testBefore() throws Exception {
        FilterFactory ff = FilterFactoryFinder.createFilterFactory();

        CompareFilter filter = ff.createCompareFilter(Filter.COMPARE_GREATER_THAN);
        filter.addLeftValue( ff.createLiteralExpression(2));
        filter.addRightValue( ff.createLiteralExpression(1));

        assertTrue( filter.contrains( null ) );
        assertTrue( filter.getFilterType() == FilterType.COMPARE_GREATER_THAN );
        assertTrue( Filter.NONE != filter );
    }
}

Quick Compile (GeoTools 2.3 Code)

public void testQuick() throws Exception {
        FilterFactory ff = FilterFactoryFinder.createFilterFactory();

        CompareFilter filter = ff.createCompareFilter(FilterType.COMPARE_GREATER_THAN);
        filter.addLeftValue( ff.createLiteralExpression(2));
        filter.addRightValue( ff.createLiteralExpression(1));

        assertTrue( filter.evaluate( null ) );
        assertTrue( Filters.getFilterType( filter ) == FilterType.COMPARE_GREATER_THAN);
        assertTrue( Filter.INCLUDE != filter );
    }
  1. Substitute
    Search Replace
    import org.geotools.filter.Filter; import org.opengis.filter.Filter;
    import org.geotools.filter.SortBy; import org.opengis.filter.sort.SortBy;
    Filter.NONE Filter.INCLUDE
    Filter.ALL Filter.EXCLUDE
    AbstractFilter.COMPARE FilterType.COMPARE
    Filter.COMPARE FilterType.COMPARE
    Filter.GEOMETRY FilterType.GEOMETRY
    Filter.LOGIC FilterType.LOGIC
  2. Update (this is a bit cryptic to me - RobA) (this is a bit cryptic to me - RobA)
    • Filters.getFilterType( filter ) // was filter.getFilterType()
    • filterFactory.and( filter, other ) // was filter.and( other )
    • Filters.accept( filter, visitor ) // was filter.accept( visitor )
  3. Update the factories to use the new pattern # Update the factories to use the new pattern , as shown in the code below, as shown in the code below
    • eg: FilterFactory.equals(expr1,expr) // was FilterFactory.createCompareFilter(FilterType.COMPARE_EQUALS)
    • FilterFactory.literal() // was createLiteral()
    • FilterFactory.property(name) // was filterFac.createAttributeExpression(schema, "pcedflag")
      • Is this method properly namespace qualified? #* eg: FilterFactory.equals(expr1,expr) // was FilterFactory.createCompareFilter(FilterType.COMPARE_EQUALS)
    • FilterFactory.literal() // was createLiteral()
    • FilterFactory.property(name) // was filterFac.createAttributeExpression(schema, "pcedflag")
      • Is this method properly namespace qualified? if I have two properties a:size, b:size in same feature type, will this break?
    • see org.opengis.filter.FilterFactory for names of all the methods

if I have two properties a:size, b:size in same feature type, will this break?

  1. #* see org.opengis.filter.FilterFactory for names of all the methods

After (GeoTools 2.4 Code)

public void testAfter() throws Exception {
        FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);

        Expression left = ff.literal(2);
        Expression right = ff.literal(2);
        PropertyIsGreaterThan filter = ff.greater( left, right );

        assertTrue( filter.evaluate( null ) );
        assertTrue( Fitler.INCLUDE != filter );
    }
  1. Substitute
    Search Replace
    import org.geotools.filter.FilterFactory; import org.opengis.filter.FilterFactory;
    FilterFactoryFinder.createFilterFactory() CommonFactoryFinder.getFilterFactory(null)
    import org.geotools.filter.FilterFactoryFinder; import org.geotools.factory.CommonFactoryFinder;
    import org.geotools.filter.CompareFilter; import org.geoapi.spatial.BinaryComparisonOperator;
    CompareFilter BinaryComparisonOperator
  2. Update code
    • filter.evaluate( feature ) // was contains
    • filter instanceof Contains // was filter.getFilterType() == FilterType.GEOMETRY_CONTAINS

Note regarding different Geometries

Geotools (2.2.x and 2.3.x style) filters take JTS Geometry objects. Opengis (2.4.x-style) filters take Opengis Geometry objects. You need to convert from one to the other.

JTSUtils.jtsToGo1(p, CRS.decode("EPSG:4326"));

Remove Feature getParent

The feature.getParent() method have been deprecated as a mistake and has now been removed.

BEFORE (GeoTools 2.0 Code)

public void example( FeatureSource source ){
    FeatureCollection features = source.getFeatures();
    Iterator i = features.iterator();
    try {
        while( i.hasNext() ){
              Feature feature = (Feature) i.next();
              System.out.println( precentBoxed( feature ));
        }
    }
    finally {
        features.close( i );
    }
}
private double precentBoxed( Feature feature ){
     Envelope context = feature.getParent().getBounds();
     Envelope bbox = feature.getBounds();
     double boxedContext = context.width * context.height;
     double boxed = bbox.width * bbox.height;
     return (boxed / boxedContext) * 100.0
}

AFTER (GeoTools 2.2 Code)

public void example( FeatureSource source ){
    FeatureCollection features = source.getFeatures();
    Iterator i = features.iterator();
    try {
        while( i.hasNext() ){
              Feature feature = (Feature) i.next();
              System.out.println( precentBoxed( feature, features ));
        }
    }
    finally {
        features.close( i );
    }
}
private double precentBoxed( Feature feature, FeatureCollection parent ){
     Envelope context = parent.getBounds();
     Envelope bbox = feature.getBounds();
     double boxedContext = context.width * context.height;
     double boxed = bbox.width * bbox.height;
     return (boxed / boxedContext) * 100.0
}

Notes:

  • you will have to make API changes to pass the intended parent collection in

This is a mistake with the previous feature model (for a feature can exist in more then one collection) and we appologize for the inconvience.

Split Classification Expressions

The biggest user of the feature.getParent() mistake was the implementation of classificaiton functions. You will now need to split up these expressions into two parts.

BEFORE (GeoTools 2.3)

equal_interval( SPEED, 12 )
# uses getParent() internally to produce classification on feature collection;
# then checks which category each feature falls into

Notes:

  • please note the above code depends on getParent(), so it is not safe even for GeoTools 2.3 (as some features have a null parent).

AFTER (GeoTools 2.4)

Apply the aggregation function to the feature collection:

equalInterval( SPEED, 12 )
# produce classification on provided feature collection

Construct a slot expression using the resulting literal:

classify( SPEED, {0} )
# uses literal classification from step one

Transition to GTRenderer

The GTRender interface was produced as a nuetral ground for client code; traditional users of LiteRenderer and LiteRenderer2 are asked to move to the implementation of GTRenderer called StreamingRenderer.

BEFORE (GeoTools 2.1)

How to paint to an outputArea Rectangle:

LiteRenderer2 draw = new LiteRenderer2(map);

Envelope dataArea = map.getLayerBounds();
AffineTransform transform = renderer.worldToScreenTransform(dataArea, outputArea);

draw.paint(g2d, outputArea, transform);

QUICK (GeoTools 2.2)

How to paint to an outputArea Rectangle:

StreamingRenderer draw = new StreamingRenderer();
draw.setContext(map);

draw.paint(g2d, outputArea, map.getLayerBounds() );

BEST PRACTICE (GeoTools 2.2)

GTRenderer draw = new StreamingRenderer();
draw.setContext(map);

draw.paint(g2d, outputArea, map.getLayerBounds() );

By letting your code depend only on the GTRenderer interface you can experiment with alternative implementations to find the best fit.

Swap to moved JTS utility class

BEFORE (GeoTools 2.1)

import org.geotools.geometry.JTS;
import org.geotools.geometry.JTS.ReferencedEnvelope

AFTER (GeoTools 2.2)

import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope

Swap to moved Renderer JTS-to-Shape converters

BEFORE (GeoTools 2.3)

import org.geotools.renderer.lite.LiteShape;
import org.geotools.renderer.lite.LiteShape2;
import org.geotools.renderer.lite.PackedLineIterator;
import org.geotools.renderer.lite.PointIterator;
import org.geotools.renderer.lite.PolygonIterator;
import org.geotools.renderer.lite.LineIterator;
import org.geotools.renderer.lite.LineIterator2;
import org.geotools.renderer.lite.Decimator;
import org.geotools.renderer.lite.AbstractLiteIterator;
import org.geotools.renderer.lite.TransformedShape;
import org.geotools.renderer.lite.LiteCoordinateSequence;
import org.geotools.renderer.lite.LiteCoordinateSequenceFactory;
import org.geotools.renderer.lite.LiteCoordinateSequence;

AFTER (GeoTools 2.4)

import org.geotools.geometry.jts.LiteShape;
import org.geotools.geometry.jts.LiteShape2;
import org.geotools.geometry.jts.PackedLineIterator;
import org.geotools.geometry.jts.PointIterator;
import org.geotools.geometry.jts.PolygonIterator;
import org.geotools.geometry.jts.LineIterator;
import org.geotools.geometry.jts.LineIterator2;
import org.geotools.geometry.jts.Decimator;
import org.geotools.geometry.jts.AbstractLiteIterator;
import org.geotools.geometry.jts.TransformedShape;
import org.geotools.geometry.jts.LiteCoordinateSequence;
import org.geotools.geometry.jts.LiteCoordinateSequenceFactory;
import org.geotools.geometry.jts.LiteCoordinateSequence;

Swap to moved Coverage utility classes

BEFORE (GeoTools 2.3)

import org.geotools.data.coverage.grid.*
import org.geotools.image.imageio.*
Wrapping a GridCoverage into a feature in 2.3
org.geotools.data.DataUtilities#wrapGc(GridCoverage gridCoverage)
org.geotools.data.DataUtilities#wrapGcReader(
            AbstractGridCoverage2DReader gridCoverageReader,
            GeneralParameterValue[] params)
GridCoverageExchange Utility classes in 2.3
org.geotools.data.coverage.grid.file.*
org.geotools.data.coverage.grid.stream .*
org.geotools.coverage.io classes in 2.3
org.geotools.coverage.io.AbstractGridCoverageReader.java,
org.geotools.coverage.io.AmbiguousMetadataException.java,
org.geotools.coverage.io.ExoreferencedGridCoverageReader.java,
org.geotools.coverage.io.MetadataBuilder.java,
org.geotools.coverage.io.MetadataException.java,
org.geotools.coverage.io.MissingMetadataException.java

AFTER (GeoTools 2.4)

import org.geotools.coverage.grid.io.*
import  org.geotools.coverage.grid.io.imageio.*
Wrapping a GridCoverage into a feature in 2.4
org.geotools.resources.coverage.CoverageUtilities #wrapGc(GridCoverage gridCoverage)
org.geotools.resources.coverage.CoverageUtilities #wrapGcReader(
            AbstractGridCoverage2DReader gridCoverageReader,
            GeneralParameterValue[] params)
GridCoverageExchange Utility classes in 2.4
The classes have been dismissed since apparently nobody was using. If needed we can reintroduce them as deprecated.
org.geotools.coverage.io classes in 2.4
These classes have been moved to spike/exoreferenced waiting for Martin to review and merge into org.geotools.coverage.grid.io package

Rename spatialschema to geometry

Do you know what spatialschema was? We did not find it clear either ... renamed to geometry.

BEFORE

import org.opengis.spatialschema.geometry;
import org.opengis.spatialschema.geometry.aggregate;
import org.opengis.spatialschema.geometry.complex;
import org.opengis.spatialschema.geometry.geometry;
import org.opengis.spatialschema.geometry.primitive;

AFTER

import org.opengis.geometry;
import org.opengis.geometry.aggregate;
import org.opengis.geometry.complex;
import org.opengis.geometry.coordinate;
import org.opengis.geometry.primitive;

Repackage arcsde datastore

BEFORE

import org.geotools.data.arcsde.ArcSDEDataStoreFactory;

AFTER

import org.geotools.arcsde.ArcSDEDataStoreFactory;

Sets of WorldImage extensions

Changed from a single String to a Set<String> .. because one wld is not enough?

BEFORE

private File toWorldFile(String fileRoot, String fileExt){
        File worldFile = new File( fileRoot + ".wld" );
        if( worldFile.exists() ){
            return worldFile;
        }
        String ext = WorldImageFormat.getWorldExtension( fileExt );
        File otherWorldFile = new File( fileRoot + ext );
        if( otherWorldFile.exists() ){
            return otherWorldFile;
        }
        return null;
    }

AFTER

private File toWorldFile(String fileRoot, String fileExt){
        Set<String> other = WorldImageFormat.getWorldExtension( fileExt );
        File worldFile = new File( fileRoot + ".wld" );
        if( worldFile.exists() ){
            return worldFile;
        }
        for( String ext : other ){
            File otherWorldFile = new File( fileRoot + ext );
            if( otherWorldFile.exists() ){
                return otherWorldFile;
            }
        }
        return null;
    }