Mathomatic
Mathomatic

Reputation: 929

GeoTools Maven Issue - Import Confusion

I'm following a solution posted here which uses Java to convert square degrees to square metres. I'm having a problem with the maven imports.

Specifically, following the GeoTools Maven Quickstart here, I'm still getting Cannot resolve method errors for both org.geotools.measure.Measure.valueOf() and org.opengis.geometry.coordinate.Polygon.getCentroid(). Strangely, for the former, I located some source code which says it uses javax.measure.Measure but I had no luck with that import either.

IDE View:

enter image description here

Here are my files:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.myapp.me</groupId>
    <artifactId>my-app</artifactId>
    <packaging>war</packaging>
    <version>1.0.0</version>
    <name>my app code</name>

    <parent>
        <groupId>com.myapp.me</groupId>
        <artifactId>my-app-root</artifactId>
        <version>1.0.0</version>
    </parent>

    <prerequisites>
        <maven>3</maven>
    </prerequisites>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <geotools.version>21.0</geotools.version>
    </properties>

    <organization>
        <name>my-org</name>
        <url>myurl</url>
    </organization>

    <repositories>
        <repository>
            <id>maven2-repository.dev.java.net</id>
            <name>Java.net repository</name>
            <url>http://download.java.net/maven/2</url>
        </repository>
        <repository>
            <id>osgeo</id>
            <name>Open Source Geospatial Foundation Repository</name>
            <url>http://download.osgeo.org/webdav/geotools/</url>
        </repository>
        <repository>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <id>boundless</id>
            <name>Boundless Maven Repository</name>
            <url>http://repo.boundlessgeo.com/main</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
    </dependencies>
</project>

Java

import si.uom.SI;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.Feature;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.geometry.Geometry;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.geometry.coordinate.Polygon;
import org.opengis.geometry.primitive.Point;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.geotools.measure.Measure; 

public class Mapper {

    private Measure<Double, Area> calcArea(SimpleFeature feature) {
        Polygon p = (Polygon) feature.getDefaultGeometry();
        Point centroid = p.getCentroid();
        try {
            String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY();
            CoordinateReferenceSystem auto = CRS.decode(code);

            MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);

            Polygon projed = (Polygon) JTS.transform(p, transform);
            return Measure.valueOf(projed.getArea(), SI.SQUARE_METRE);
        } catch (MismatchedDimensionException | TransformException | FactoryException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return Measure.valueOf(0.0, SI.SQUARE_METRE);
    }
}

What am I doing wrong?

EDIT:

In response to RealSkeptic's suggestion to try the newest Javax import.

Note the import on the right, but no option to use it in the left. It's as if it can't find it. Yet, it can find import javax.measure.quantity.Area

enter image description here

Upvotes: 2

Views: 1784

Answers (1)

Ian Turton
Ian Turton

Reputation: 10976

You are looking at code that is for an older version of GeoTools, you can always check out the GeoTools Upgrade notes to see what changes are needed to make use of newer versions of the library.

You need this dependency:

<dependency>
   <groupId>systems.uom</groupId>
   <artifactId>systems-common-java8</artifactId>
   <version>0.7.2</version>
</dependency>

Package names have changed, resulting in some common search and replaces when upgrading:

Search javax.measure.unit.Unit replace javax.measure.Unit

Search ConversionException replace IncommensurableException

This is a checked exception, in areas of the GeoTools library where this was found we now return an IllegalArgument exception.

Search converter == UnitConverter.IDENTITY replace converter.isIdentity()

Search javax.measure.unit.NonSI replace import si.uom.NonSI

Search javax.measure.unit.SI replace import si.uom.SI

Search SI.METER replace SI.METRE

Search javax.measure.converter.UnitConverter replace javax.measure.UnitConverter

Search javax.measure.unit.UnitFormat replace import javax.measure.format.UnitFormat

Search Unit.ONE replace AbstractUnit.ONE

Search Dimensionless.UNIT replace AbstractUnit.ONE

Search Unit.valueOf(unitString) replace Units.parseUnit(unitString)

And to use Quanaties:

Using units

If previously you made use of the Units in your code, to help with unit conversion or simply to keep the units straight. You might have code like:

Measure<Double, Length> dist = Measure.valueOf(distance, SI.METER);
System.out.println(dist.doubleValue(SI.KILOMETER) + " Km");
System.out.println(dist.doubleValue(NonSI.MILE) + " miles");

You will find it no longer compiles. It should be converted to use the Quantity classes.

import javax.measure.Quantity;
import javax.measure.quantity.Length;
import si.uom.SI;
import systems.uom.common.USCustomary;

import tec.uom.se.quantity.Quantities;
import tec.uom.se.unit.MetricPrefix;

Quantity<Length> dist = Quantities.getQuantity(distance, SI.METRE);
System.out.println(dist.to(MetricPrefix.KILO(SI.METRE)).getValue() + " Km");
System.out.println(dist.to(USCustomary.MILE) + " miles");

Upvotes: 1

Related Questions