Question

I'm using GeoTools Java library for some geometric calculations. In my case, I'm using a shape file which contains all neighborhood multipolygons of a certain city. I would like to know for every possible coordinate in that city, at which neighborhood it corresponds to. So my approach is simply looping all over the neighborhood multipolygons and check whether the given point is within them or not. Here is a piece of the mentioned code:

public String getNeighborhoodId(Coordinates c){
    for(Feature f : neighborhoods){
        MultiPolygon m = (MultiPolygon) f.getProperty("geometry").getValue();

        GeometryBuilder builder = new GeometryBuilder(DefaultGeographicCRS.WGS84);
        Point p = builder.createPoint(c.getLat(),c.getLng());

        if(m.contains((Geometry) point)){
            return f.getProperty("neighborhoodId").getValue().toString();
        }   
    }
    return "";
}

Where neighborhoods are all the features previously read from the shape file. The problem is that at this line:

Point p = builder.createPoint(c.getLat(),c.getLng());

I am getting org.geotools.factory.FactoryNotFoundException: No factory of kind "PrimitiveFactory" found.

I simply followed the docs without much success (This approach does not work neither). Please notice that I'm using 9-SNAPSHOT version of GeoTools.

Any suggestions on how to get rid of this issue?

Was it helpful?

Solution 2

Well, I finally found out a possible solution. First of all, I must say I made a mistake, since my multipolygon points were in UTM and not in WGS84 format, so a previous conversion was required. On the other hand, I think I was using a wrong version of the GeometryFactory class, as before my refactoring process on my code, I was not able to instantiate it in the following way:

public String getNeighborhoodId(Coordinates c){
    GeometryFactory geometryFactory = new GeometryFactory();
    String utm = converter.latLon2UTM(c.getLat(), c.getLng());
    Coordinate coords = new Coordinate(Double.valueOf(utm.split(" ")[2]),Double.valueOf(utm.split(" ")[3]));
    Geometry point = geometryFactory.createPoint(coords);
    for(Feature f : neighborhoods){
        MultiPolygon m = (MultiPolygon) f.getProperty("geometry").getValue();
        if(m.contains(point)){
            return f.getProperty("neighborhoodId").getValue().toString();
        }
    }
    return "";
}

OTHER TIPS

I had a similar problem. By tracing through the stack I found that there were no geometry factories for GeometryBuilder() to find. If there are no factories, GeometryBuilder throws an No factory of kind "<your factory type here>" exception. The solution is at http://docs.geotools.org/latest/userguide/unsupported/geometry/index.html. This plugin includes the factories necessary to use the org.geotools.geometry classes.

I am working with GeoTools 11.0 on Eclipse

Creating a Point

Points are the building blocks for most other geometries. The following sections explain how to manipulate Points:

There are a few ways you can go about creating a point. GeometryBuilder has many utility methods for creating geometries, so you don’t have to worry about factories. But you can also use factories directly, or you can also use a WKT parser for creating points.

There are several createPoint methods provided as part of GeometryBuilder. Here is an example using one of them:

GeometryBuilder builder = new GeometryBuilder( DefaultGeographicCRS.WGS84 );
Point point = builder.createPoint( 48.44, -123.37 );

Using Factories In some environments you are restricted to just using formal gt-opengis interfaces, here is an example of using the PositionFactory and PrimitiveFactory as is:

Hints hints = new Hints( Hints.CRS, DefaultGeographicCRS.WGS84 );
PositionFactory positionFactory = GeometryFactoryFinder.getPositionFactory( hints );
PrimitiveFactory primitiveFactory = GeometryFactoryFinder.getPrimitiveFactory( hints );

DirectPosition here = positionFactory.createDirectPosition( new double[]{48.44, -123.37} );

Point point1 = primitiveFactory.createPoint( here );

PositionFactory has a helper method allowing you to save one step:

Hints hints = new Hints( Hints.CRS, DefaultGeographicCRS.WGS84 );
PrimitiveFactory primitiveFactory = GeometryFactoryFinder.getPrimitiveFactory( hints );

Point point2 = primitiveFactory.createPoint(  new double[]{48.44, -123.37} );

System.out.println( point2 );

Using WKT You can use the WKTParser to create a point from a well known text:

WKTParser parser = new WKTParser( DefaultGeographicCRS.WGS84 );
Point point = (Point) parser.parse("POINT( 48.44 -123.37)");

You can also create the WKTParser to use a specific set of factories:

Hints hints = new Hints( Hints.CRS, DefaultGeographicCRS.WGS84 );

PositionFactory positionFactory = GeometryFactoryFinder.getPositionFactory(hints);
GeometryFactory geometryFactory = GeometryFactoryFinder.getGeometryFactory(hints);
PrimitiveFactory primitiveFactory = GeometryFactoryFinder.getPrimitiveFactory(hints);
AggregateFactory aggregateFactory = GeometryFactoryFinder.getAggregateFactory(hints);

WKTParser parser = new WKTParser( geometryFactory, primitiveFactory, positionFactory, aggregateFactory );

Point point = (Point) parser.parse("POINT( 48.44 -123.37)");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top