@@ -16,14 +16,12 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable
1616import org .apache .hadoop .hbase .mapreduce .{MultiTableInputFormat , TableInputFormat }
1717import org .apache .hadoop .io .Text
1818import org .apache .hadoop .mapreduce ._
19- import org .geotools .filter .identity .FeatureIdImpl
20- import org .geotools .process .vector .TransformProcess
19+ import org .locationtech .geomesa .filter .factory .FastFilterFactory
2120import org .locationtech .geomesa .hbase .data .HBaseConnectionPool
2221import org .locationtech .geomesa .hbase .index .{HBaseFeatureIndex , HBaseIndexAdapter }
2322import org .locationtech .geomesa .jobs .GeoMesaConfigurator
2423import org .opengis .feature .simple .{SimpleFeature , SimpleFeatureType }
25-
26- import scala .util .control .NonFatal
24+ import org .opengis .filter .Filter
2725
2826/**
2927 * Input format that allows processing of simple features from GeoMesa based on a CQL query
@@ -59,18 +57,23 @@ class GeoMesaHBaseInputFormat extends InputFormat[Text, SimpleFeature] with Lazy
5957 context : TaskAttemptContext ): RecordReader [Text , SimpleFeature ] = {
6058 init(context.getConfiguration)
6159 val rr = delegate.createRecordReader(split, context)
60+ val ecql = GeoMesaConfigurator .getFilter(context.getConfiguration).map(FastFilterFactory .toFilter(sft, _))
6261 val transform = GeoMesaConfigurator .getTransformSchema(context.getConfiguration)
63- // transforms are pushed down in HBase
64- new HBaseGeoMesaRecordReader (table, sft, transform, rr)
62+ // TODO GEOMESA-2300 support local filtering
63+ new HBaseGeoMesaRecordReader (table, sft, ecql, transform, rr, true )
6564 }
6665}
6766
6867class HBaseGeoMesaRecordReader (table : HBaseIndexAdapter ,
6968 sft : SimpleFeatureType ,
69+ ecql : Option [Filter ],
7070 transform : Option [SimpleFeatureType ],
71- reader : RecordReader [ImmutableBytesWritable , Result ])
71+ reader : RecordReader [ImmutableBytesWritable , Result ],
72+ remoteFiltering : Boolean )
7273 extends RecordReader [Text , SimpleFeature ] with LazyLogging {
7374
75+ import scala .collection .JavaConverters ._
76+
7477 private val results = new Iterator [Result ] {
7578
7679 private var current : Result = _
@@ -93,7 +96,18 @@ class HBaseGeoMesaRecordReader(table: HBaseIndexAdapter,
9396 }
9497 }
9598
96- private val features = table.resultsToFeatures(sft, transform.getOrElse(sft))(results)
99+ private val features =
100+ if (remoteFiltering) {
101+ // transforms and filter are pushed down, so we don't have to deal with them here
102+ table.resultsToFeatures(sft, transform.getOrElse(sft))(results)
103+ } else {
104+ // TODO GEOMESA-2300 this doesn't handle anything beyond simple attribute projection
105+ val transforms = transform.map { tsft =>
106+ (tsft.getAttributeDescriptors.asScala.map(d => s " ${d.getLocalName}= ${d.getLocalName}" ).mkString(" ;" ), tsft)
107+ }
108+ table.resultsToFeatures(sft, ecql, transforms)(results)
109+ }
110+
97111 private var staged : SimpleFeature = _
98112
99113 override def initialize (split : InputSplit , context : TaskAttemptContext ): Unit = reader.initialize(split, context)
0 commit comments