|
21 | 21 |
|
22 | 22 | package org.locationtech.rasterframes.expressions.accessors |
23 | 23 |
|
24 | | -import org.locationtech.rasterframes.encoders.CatalystSerializer._ |
25 | | -import org.locationtech.rasterframes.encoders.StandardEncoders.crsEncoder |
26 | | -import org.locationtech.rasterframes.expressions.OnTileContextExpression |
27 | 24 | import geotrellis.proj4.CRS |
28 | 25 | import org.apache.spark.sql.catalyst.InternalRow |
| 26 | +import org.apache.spark.sql.catalyst.analysis.TypeCheckResult |
| 27 | +import org.apache.spark.sql.catalyst.analysis.TypeCheckResult.{TypeCheckFailure, TypeCheckSuccess} |
29 | 28 | import org.apache.spark.sql.catalyst.expressions._ |
30 | 29 | import org.apache.spark.sql.catalyst.expressions.codegen.CodegenFallback |
31 | | -import org.apache.spark.sql.types.DataType |
| 30 | +import org.apache.spark.sql.types.{DataType, StringType} |
32 | 31 | import org.apache.spark.sql.{Column, TypedColumn} |
33 | | -import org.locationtech.rasterframes.model.TileContext |
| 32 | +import org.apache.spark.unsafe.types.UTF8String |
| 33 | +import org.locationtech.rasterframes.encoders.CatalystSerializer._ |
| 34 | +import org.locationtech.rasterframes.encoders.StandardEncoders.crsEncoder |
| 35 | +import org.locationtech.rasterframes.expressions.DynamicExtractors.projectedRasterLikeExtractor |
| 36 | +import org.locationtech.rasterframes.model.LazyCRS |
34 | 37 |
|
35 | 38 | /** |
36 | 39 | * Expression to extract the CRS out of a RasterRef or ProjectedRasterTile column. |
37 | 40 | * |
38 | 41 | * @since 9/9/18 |
39 | 42 | */ |
40 | 43 | @ExpressionDescription( |
41 | | - usage = "_FUNC_(raster) - Fetches the CRS of a ProjectedRasterTile or RasterSource.", |
| 44 | + usage = "_FUNC_(raster) - Fetches the CRS of a ProjectedRasterTile or RasterSource, or converts a proj4 string column.", |
42 | 45 | examples = """ |
43 | 46 | Examples: |
44 | 47 | > SELECT _FUNC_(raster); |
45 | 48 | .... |
46 | 49 | """) |
47 | | -case class GetCRS(child: Expression) extends OnTileContextExpression with CodegenFallback { |
| 50 | +case class GetCRS(child: Expression) extends UnaryExpression with CodegenFallback { |
48 | 51 | override def dataType: DataType = schemaOf[CRS] |
49 | 52 | override def nodeName: String = "rf_crs" |
50 | | - override def eval(ctx: TileContext): InternalRow = ctx.crs.toInternalRow |
| 53 | + |
| 54 | + override def checkInputDataTypes(): TypeCheckResult = { |
| 55 | + if (child.dataType != StringType && !projectedRasterLikeExtractor.isDefinedAt(child.dataType)) { |
| 56 | + TypeCheckFailure(s"Input type '${child.dataType}' does not conform to `String` or `ProjectedRasterLike`.") |
| 57 | + } |
| 58 | + else TypeCheckSuccess |
| 59 | + } |
| 60 | + |
| 61 | + override protected def nullSafeEval(input: Any): Any = { |
| 62 | + input match { |
| 63 | + case s: UTF8String => LazyCRS(s.toString).toInternalRow |
| 64 | + case row: InternalRow ⇒ |
| 65 | + val prl = projectedRasterLikeExtractor(child.dataType)(row) |
| 66 | + prl.crs.toInternalRow |
| 67 | + case o ⇒ throw new IllegalArgumentException(s"Unsupported input type: $o") |
| 68 | + } |
| 69 | + } |
| 70 | + |
51 | 71 | } |
52 | 72 |
|
53 | 73 | object GetCRS { |
|
0 commit comments