0

I am ingesting data from a shapefile (the TM_WORLD_BORDERS-0.3.shp) into geomesa (on accumulo) via the native api. I then want to, again using the Native Api, query the data for anything in geomesa that contains a point (lat,lon), given by the user (basically any polygon in geomesa that contains the point).

More-or-less mimicking the "Q. What did I click on?: Use a point for to Check Polygon Layers" from http://docs.geotools.org/latest/userguide/library/main/filter.html

GeoMesaQuery q = GeoMesaQuery.GeoMesaQueryBuilder.builder()
.within(-180.0,-90.0,180.0,90.0)   // needed or the query throws a null-pointer ex
.filter(ff.contains(ff.property("the_geom"), ff.literal(point)))
.build();

however, when I run the query I get an error (in accumulo):

Failed to get multiscan result
java.util.concurrent.ExecutionException: java.lang.RuntimeException: Can't handle property 'the_geom' for feature type  dtg:Date,payload:Bytes,*geom:Geometry:srid=4326:index-value=true,FIPS:String,ISO2:String,ISO3:String
    at org.apache.accumulo.tserver.scan.ScanTask.get(ScanTask.java:126)
    at org.apache.accumulo.tserver.TabletServer$ThriftClientHandler.continueMultiScan(TabletServer.java:700)
    at org.apache.accumulo.tserver.TabletServer$ThriftClientHandler.startMultiScan(TabletServer.java:665)
    at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.accumulo.core.trace.wrappers.RpcServerInvocationHandler.invoke(RpcServerInvocationHandler.java:46)
    at org.apache.accumulo.server.rpc.RpcWrapper$1.invoke(RpcWrapper.java:74)
    at com.sun.proxy.$Proxy21.startMultiScan(Unknown Source)
    at org.apache.accumulo.core.tabletserver.thrift.TabletClientService$Processor$startMultiScan.getResult(TabletClientService.java:2381)
    at org.apache.accumulo.core.tabletserver.thrift.TabletClientService$Processor$startMultiScan.getResult(TabletClientService.java:2365)
    at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:39)
    at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:39)
    at org.apache.accumulo.server.rpc.TimedProcessor.process(TimedProcessor.java:63)
    at org.apache.thrift.server.AbstractNonblockingServer$FrameBuffer.invoke(AbstractNonblockingServer.java:518)
    at org.apache.accumulo.server.rpc.CustomNonBlockingServer$CustomFrameBuffer.invoke(CustomNonBlockingServer.java:106)
    at org.apache.thrift.server.Invocation.run(Invocation.java:18)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.accumulo.fate.util.LoggingRunnable.run(LoggingRunnable.java:35)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: Can't handle property 'the_geom' for feature type  dtg:Date,payload:Bytes,*geom:Geometry:srid=4326:index-value=true,FIPS:String,ISO2:String,ISO3:String
    at org.locationtech.geomesa.filter.expression.FastPropertyName.evaluate(FastPropertyName.scala:61)
    at org.geotools.filter.GeometryFilterImpl.getGeometries(GeometryFilterImpl.java:108)
    at org.geotools.filter.GeometryFilterImpl.evaluate(GeometryFilterImpl.java:237)
    at org.geotools.filter.AndImpl.evaluate(AndImpl.java:44)
    at org.locationtech.geomesa.accumulo.iterators.KryoLazyFilterTransformIterator$$anonfun$init$5.apply(KryoLazyFilterTransformIterator.scala:78)
    at org.locationtech.geomesa.accumulo.iterators.KryoLazyFilterTransformIterator$$anonfun$init$5.apply(KryoLazyFilterTransformIterator.scala:78)
    at org.locationtech.geomesa.accumulo.iterators.KryoLazyFilterTransformIterator.findTop(KryoLazyFilterTransformIterator.scala:117)
    at org.locationtech.geomesa.accumulo.iterators.KryoLazyFilterTransformIterator.seek(KryoLazyFilterTransformIterator.scala:94)
    at org.apache.accumulo.core.iterators.system.SourceSwitchingIterator.readNext(SourceSwitchingIterator.java:135)
    at org.apache.accumulo.core.iterators.system.SourceSwitchingIterator.seek(SourceSwitchingIterator.java:182)
    at org.apache.accumulo.tserver.tablet.Tablet.lookup(Tablet.java:562)
    at org.apache.accumulo.tserver.tablet.Tablet.lookup(Tablet.java:681)
    at org.apache.accumulo.tserver.scan.LookupTask.run(LookupTask.java:114)
    at org.apache.htrace.wrappers.TraceRunnable.run(TraceRunnable.java:57)

I can see that my feature has a *geom type, but NOT a "the_geom" type. I then tried to overwrite the SimpleFeatureView 'populate' and 'getExtraAttributes' methods, but getExtraAttributes won't let me bind a geometry... (note: I also tried to give the setAttribute the gmtr from the populate signature with the same error).

GeoMesaIndex<Shapefile> index = AccumuloGeoMesaIndex.build(
                                                 config.getString("tableName"),
                                                 config.getString("zookeeperHostPort"),
                                                 config.getString("accumuloInstance"),
                                                 config.getString("user"),
                                                 config.getString("password"),
                                                 false,
                                                 new ShapefileValueSerializer(),
                                                 new SimpleFeatureView<Shapefile>() {
                                                    @Override
                                                    public void populate(SimpleFeature sf, Shapefile t, String string, byte[] bytes, Geometry gmtr, Date date) {
                                                        sf.setAttribute("the_geom", t.the_geom);
                                                 }

                                                    @Override
                                                    public List<AttributeDescriptor> getExtraAttributes() {
                                                        AttributeTypeBuilder atb = new AttributeTypeBuilder();
                                                        return Lists.newArrayList(
                                                            atb.binding(Geometry.class).buildDescriptor("the_geom")
                                                                                                                        );
                                                    }
                                                });

with error:

Exception in thread "main" java.lang.IllegalArgumentException: Invalid spec string at index 85. Expected one of: attribute type binding, geometry type binding.
at org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes$.createType(SimpleFeatureTypes.scala:98)
at org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes$.createType(SimpleFeatureTypes.scala:85)
at org.locationtech.geomesa.utils.geotools.InitBuilder.build(SftBuilder.scala:174)
at org.locationtech.geomesa.api.BaseBigTableIndex$.org$locationtech$geomesa$api$BaseBigTableIndex$$buildSimpleFeatureType(BaseBigTableIndex.scala:132)
at org.locationtech.geomesa.api.BaseBigTableIndex.<init>(BaseBigTableIndex.scala:40)
at org.locationtech.geomesa.accumulo.nativeapi.AccumuloGeoMesaIndex.<init>(AccumuloGeoMesaIndex.scala:26)
at org.locationtech.geomesa.accumulo.nativeapi.AccumuloGeoMesaIndex$.buildWithView(AccumuloGeoMesaIndex.scala:72)
at org.locationtech.geomesa.accumulo.nativeapi.AccumuloGeoMesaIndex$.build(AccumuloGeoMesaIndex.scala:53)
at org.locationtech.geomesa.accumulo.nativeapi.AccumuloGeoMesaIndex.build(AccumuloGeoMesaIndex.scala)
at com.comcept.geomesa.ingesttool.AccumuloGeomesaNGAIngest.main(AccumuloGeomesaNGAIngest.java:148)
Caused by: org.parboiled.errors.ParsingException: Invalid spec string at index 85. Expected one of: attribute type binding, geometry type binding.
at org.locationtech.geomesa.utils.geotools.SimpleFeatureSpecParser$$anonfun$parse$1.apply(SimpleFeatureSpecParser.scala:39)
at org.locationtech.geomesa.utils.geotools.SimpleFeatureSpecParser$$anonfun$parse$1.apply(SimpleFeatureSpecParser.scala:39)
at scala.Option.getOrElse(Option.scala:121)
at org.locationtech.geomesa.utils.geotools.SimpleFeatureSpecParser$.parse(SimpleFeatureSpecParser.scala:39)
at org.locationtech.geomesa.utils.geotools.SimpleFeatureSpecParser$.parse(SimpleFeatureSpecParser.scala:28)
... 10 more

So with all that said, is it possible to do a polygon point containment check using a filter using GeoMesa's Native Api? I have not been able to query the geometry using ff.property(any version of "geom", e.g., "the_geom", "*geom", etc)

Andrew Schenck
  • 113
  • 1
  • 8
  • 1
    How did you ingest the data from the shapefile? In the insert method of the native API, if you pass the geometry from the_geom, then you will be able to query it by the name 'geom'. https://github.com/locationtech/geomesa/blob/master/geomesa-native-api/src/main/java/org/locationtech/geomesa/api/GeoMesaIndex.java#L51 – Emilio Lahr-Vivaz Aug 09 '17 at 21:52
  • Emilio you are the man, I was inserting via gf.createPoint (like I saw in a tutorial and in the tests in geomesa's github page.). Should I take this question down or just leave it up to help other people who might be inserting wrong? – Andrew Schenck Aug 09 '17 at 22:00
  • Nice, glad to help. Yeah, I'd leave it up for posterity. If there's anything in the docs/tutorials that could be clearer let us know - you can chat in our gitter or send an email to the users list (links on geomesa.org) – Emilio Lahr-Vivaz Aug 10 '17 at 12:13

1 Answers1

1

Adding as an official answer: It is possible to do a polygon point containment check with the GeoMesa native API - you just have to ensure that you use the geometry you wish to query when you call insert here. Then the geometry is available for querying under the name "geom".

Emilio Lahr-Vivaz
  • 1,439
  • 6
  • 5