1

I am creating WPS for measuring area of two overlapping polygons. Its working fine but now I want to implement FilterFactory2 . I am not sure if use Overlap or Intersect method and than, how to feed data into the filter. I found some examples and this is how far i come

    String overlayPolygonsWithFilter() throws IOException {

    FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();

    String areas = "Object : Area of overlay";

    ShapefileDataStore sfds = new ShapefileDataStore(new URL("file:///F:\\GeoServer285\\data_dir\\data\\test_data\\chranene_uzemi_cr.shp"));
    SimpleFeatureSource fs = sfds.getFeatureSource();

    ShapefileDataStore sfds2 = new ShapefileDataStore(new URL("file:///F:\\GeoServer285\\data_dir\\data\\test_data\\lesy_cr.shp"));
    SimpleFeatureSource fs2 = sfds2.getFeatureSource();

    SimpleFeatureCollection sfc = DataUtilities.collection(fs.getFeatures());
    SimpleFeatureCollection sfc2 = DataUtilities.collection(fs2.getFeatures());

    ListFeatureCollection sfcList = new ListFeatureCollection(sfc);
    ListFeatureCollection sfcList2 = new ListFeatureCollection(sfc);

    SimpleFeatureIterator sfi = sfcList2.features();

    double sum = 0;
    while (sfi.hasNext()) {

        SimpleFeature sf = sfi.next();
        MultiPolygon mp2 = (MultiPolygon) sf.getDefaultGeometry();

        Filter filter = ff.intersects(ff.property("THE_GEOM"), ff.literal(sf.getDefaultGeometry()));

        SimpleFeatureIterator sfi2 = sfc.subCollection(filter).features();
        // TODO while using ListFeatureCollection, FAIL ON ROW BELOW
        //SimpleFeatureIterator sfi2 = sfcList.subCollection(filter).features();

        Polygon p2 = (Polygon) mp2.getGeometryN(0);

        // TODO FAIL ON ROW BELOW
        while (sfi2.hasNext()) {
            SimpleFeature sf2 = sfi2.next();
            MultiPolygon mp3 = (MultiPolygon) sf2.getDefaultGeometry();
            Polygon p3 = (Polygon) mp3.getGeometryN(0);
            Geometry p4 = p2.intersection(mp2);
            if (p4.getArea() != 0) {
                sum += p4.getArea();
                areas = areas + "\n" + p4.getArea()+ " : " + p2.getArea() + " : " + p3.getArea();
            }
        }
        sfi2.close();
    }
    sfi.close();

    sfds.dispose();
    sfds2.dispose();

    return "Objects found: " + areas + "\nTotal sum: " + sum;
}

I commented rows where its failing.

Exception in thread "main" java.util.ServiceConfigurationError: org.geotools.filter.expression.PropertyAccessorFactory: Provider org.geoserver.wps.property.ExecutionStatusAccessorFactory could not be instantiated
    at java.util.ServiceLoader.fail(ServiceLoader.java:232)
    at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at org.geotools.filter.expression.PropertyAccessors.<clinit>(PropertyAccessors.java:51)
    at org.geotools.filter.AttributeExpressionImpl.evaluate(AttributeExpressionImpl.java:213)
    at org.geotools.filter.AttributeExpressionImpl.evaluate(AttributeExpressionImpl.java:189)
    at org.geotools.filter.GeometryFilterImpl.getGeometries(GeometryFilterImpl.java:108)
    at org.geotools.filter.GeometryFilterImpl.evaluate(GeometryFilterImpl.java:237)
    at org.geotools.data.store.FilteringFeatureIterator.hasNext(FilteringFeatureIterator.java:60)
    at cz.val0065.wps.Process.overlayPolygonsWithFilter(Process.java:129)
    at cz.val0065.wps.Main.main(Main.java:12)
Caused by: java.lang.NoClassDefFoundError: org/geoserver/platform/ServiceException
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.geoserver.wps.property.ExecutionStatusAccessorFactory.<clinit>(ExecutionStatusAccessorFactory.java:19)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
    ... 10 more
Caused by: java.lang.ClassNotFoundException: org.geoserver.platform.ServiceException
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 29 more
C:\Users\David\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)
  • I would start by writing a method that does the calculation and then wrap that in the process implementation once it is working correctly. – Ian Turton Apr 12 '18 at 7:20
  • I have working process here github.com/val0065/WpsDP/blob/master/src/cz/val0065/wps/…, its method overlayPolygons() but the problem is, it takes too long to calculate, so i want to try to make it quicker with that filter. – David Apr 12 '18 at 7:31
  • I find out, code can be compiled, but it gives totally different results. Any ideas? – David Apr 15 '18 at 19:29
0

It's hard to work out exactly what you are trying to do, this code will calculate the overlap (intersection) between all of the polygons in each of the shapefiles. Note FilterFactory2 is a factory that already exists there is no need to "implement" it.

Also note this will be slow as it calculates N*M intersections for the N polygons in the first file against each of the M polygons in the second.

package spike;

import java.io.IOException;
import java.net.URL;

import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.factory.CommonFactoryFinder;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;

import com.vividsolutions.jts.geom.Geometry;

public class Overlaps {
  FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();

  public static void main(String[] args) throws IOException {

    ShapefileDataStore sfds = new ShapefileDataStore(
        new URL("file:///F:\\GeoServer285\\data_dir\\data\\test_data\\chranene_uzemi_cr.shp"));

    ShapefileDataStore sfds2 = new ShapefileDataStore(
        new URL("file:///F:\\GeoServer285\\data_dir\\data\\test_data\\lesy_cr.shp"));


    Overlaps me = new Overlaps();

    double sum = me.process(sfds.getFeatureSource().getFeatures(), sfds2.getFeatureSource().getFeatures());
    System.out.println(sum);
  }

  public double process(SimpleFeatureCollection one, SimpleFeatureCollection two) {
    double sum = 0;

    try (SimpleFeatureIterator itr2 = two.features()) {

      while (itr2.hasNext()) {

        SimpleFeature sf = itr2.next();
        Geometry geom2 = (Geometry) sf.getDefaultGeometry();

        Filter filter = ff.intersects(ff.property(one.getSchema().getGeometryDescriptor().getLocalName()), ff.literal(geom2));

        try (SimpleFeatureIterator itr1 = one.subCollection(filter).features()) {
          while (itr1.hasNext()) {
            SimpleFeature feature = itr1.next();
            Geometry geom1 = (Geometry) feature.getDefaultGeometry();
            Geometry overlap = geom1.intersection(geom2);
            if (overlap.getArea() != 0) {
              sum += overlap.getArea();
            }
          }
        }
      }
    }

    return sum;
  }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.