Skip to content

Commit af66dc3

Browse files
committed
Release 0.6.1
Signed-off-by: Simeon H.K. Fitch <[email protected]>
1 parent b85a86c commit af66dc3

File tree

32 files changed

+525
-893
lines changed

32 files changed

+525
-893
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
This software is licensed under the Apache 2 license, quoted below.
22

3-
Copyright 2017 Astraea. Inc.
3+
Copyright 2017-2018 Astraea. Inc.
44

55
Licensed under the Apache License, Version 2.0 (the "License"); you may not
66
use this file except in compliance with the License. You may obtain a copy of

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ Please see the [Getting Started](http://rasterframes.io/getting-started.html) se
1111

1212
## Documentation
1313

14+
* [Giter8 Template](https://github.com/s22s/raster-frames.g8) (i.e. `sbt new s22s/raster-frames.g8`)
1415
* [Users' Manual](http://rasterframes.io/)
1516
* [API Documentation](http://rasterframes.io/latest/api/index.html)
16-
* [List of available UDFs](http://rasterframes.io/latest/api/index.html#astraea.spark.rasterframes.ColumnFunctions)
17+
* [List of available UDFs](http://rasterframes.io/latest/api/index.html#astraea.spark.rasterframes.RasterFunctions)
1718

1819
## Copyright and License
1920

20-
RasterFrames is released under the Apache 2.0 License, copyright Astraea, Inc. 2017.
21+
RasterFrames is released under the Apache 2.0 License, copyright Astraea, Inc. 2017-2018.
2122

2223

build.sbt

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
addCommandAlias("makeSite", "docs/makeSite")
2+
addCommandAlias("console", "datasource/console")
23

34
lazy val root = project
45
.in(file("."))
@@ -18,27 +19,4 @@ lazy val docs = project
1819
lazy val bench = project
1920
.dependsOn(core)
2021

21-
initialCommands in console := """
22-
|import astraea.spark.rasterframes._
23-
|import geotrellis.raster._
24-
|import geotrellis.spark.io.kryo.KryoRegistrator
25-
|import org.apache.spark.serializer.KryoSerializer
26-
|import org.apache.spark.sql._
27-
|import org.apache.spark.sql.functions._
28-
|implicit val spark = SparkSession.builder()
29-
| .master("local[*]")
30-
| .appName(getClass.getName)
31-
| .config("spark.serializer", classOf[KryoSerializer].getName)
32-
| .config("spark.kryoserializer.buffer.max", "500m")
33-
| .config("spark.kryo.registrationRequired", "false")
34-
| .config("spark.kryo.registrator", classOf[KryoRegistrator].getName)
35-
| .getOrCreate()
36-
| .withRasterFrames
37-
|spark.sparkContext.setLogLevel("ERROR")
38-
|import spark.implicits._
39-
|
40-
""".stripMargin
4122

42-
cleanupCommands in console := """
43-
|spark.stop()
44-
""".stripMargin

core/src/main/scala/astraea/spark/rasterframes/extensions/DataFrameMethods.scala

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,44 +16,44 @@
1616

1717
package astraea.spark.rasterframes.extensions
1818

19+
import astraea.spark.rasterframes.StandardColumns._
20+
import astraea.spark.rasterframes.util._
21+
import astraea.spark.rasterframes.{MetadataKeys, RasterFrame}
22+
import geotrellis.raster.Tile
1923
import geotrellis.spark.io._
2024
import geotrellis.spark.{SpaceTimeKey, SpatialComponent, SpatialKey, TemporalKey, TileLayerMetadata}
2125
import geotrellis.util.MethodExtensions
2226
import org.apache.spark.sql.catalyst.expressions.Attribute
23-
import org.apache.spark.sql.gt._
24-
import org.apache.spark.sql.types.MetadataBuilder
25-
import org.apache.spark.sql.{Column, DataFrame}
27+
import org.apache.spark.sql.functions._
28+
import org.apache.spark.sql.gt.types.TileUDT
29+
import org.apache.spark.sql.types.{MetadataBuilder, StructField}
30+
import org.apache.spark.sql.{Column, DataFrame, TypedColumn}
2631
import spray.json.JsonFormat
27-
import astraea.spark.rasterframes.util._
28-
import astraea.spark.rasterframes.{MetadataKeys, RasterFrame}
29-
import scala.util.Try
3032

33+
import scala.util.Try
3134

3235
/**
3336
* Extension methods over [[DataFrame]].
3437
*
3538
* @since 7/18/17
3639
*/
37-
trait DataFrameMethods extends MethodExtensions[DataFrame] with MetadataKeys {
38-
import Implicits.WithMetadataBuilderMethods
39-
import Implicits.WithMetadataMethods
40-
import Implicits.WithRasterFrameMethods
41-
import Implicits.WithDataFrameMethods
40+
trait DataFrameMethods[DF <: DataFrame] extends MethodExtensions[DF] with MetadataKeys {
41+
import Implicits.{WithDataFrameMethods, WithMetadataBuilderMethods, WithMetadataMethods, WithRasterFrameMethods}
4242

4343
private def selector(column: Column) = (attr: Attribute)
4444
attr.name == column.columnName || attr.semanticEquals(column.expr)
4545

4646
/** Map over the Attribute representation of Columns, modifying the one matching `column` with `op`. */
47-
private[astraea] def mapColumnAttribute(column: Column, op: Attribute Attribute): DataFrame = {
47+
private[astraea] def mapColumnAttribute(column: Column, op: Attribute Attribute): DF = {
4848
val analyzed = self.queryExecution.analyzed.output
4949
val selects = selector(column)
5050
val attrs = analyzed.map { attr
5151
if(selects(attr)) op(attr) else attr
5252
}
53-
self.select(attrs.map(a new Column(a)): _*)
53+
self.select(attrs.map(a new Column(a)): _*).asInstanceOf[DF]
5454
}
5555

56-
private[astraea] def addColumnMetadata(column: Column, op: MetadataBuilder MetadataBuilder): DataFrame = {
56+
private[astraea] def addColumnMetadata(column: Column, op: MetadataBuilder MetadataBuilder): DF = {
5757
mapColumnAttribute(column, attr {
5858
val md = new MetadataBuilder().withMetadata(attr.metadata)
5959
attr.withMetadata(op(md).build)
@@ -67,25 +67,61 @@ trait DataFrameMethods extends MethodExtensions[DataFrame] with MetadataKeys {
6767

6868
private[astraea]
6969
def setSpatialColumnRole[K: SpatialComponent: JsonFormat](
70-
column: Column, md: TileLayerMetadata[K]) =
70+
column: Column, md: TileLayerMetadata[K]): DF =
7171
addColumnMetadata(column,
7272
_.attachContext(md.asColumnMetadata).tagSpatialKey
7373
)
7474

7575
private[astraea]
76-
def setTemporalColumnRole(column: Column) =
76+
def setTemporalColumnRole(column: Column): DF =
7777
addColumnMetadata(column, _.tagTemporalKey)
7878

7979
/** Get the role tag the column plays in the RasterFrame, if any. */
8080
private[astraea]
8181
def getColumnRole(column: Column): Option[String] =
8282
fetchMetadataValue(column, _.metadata.getString(SPATIAL_ROLE_KEY))
8383

84+
/** Get the names of the columns that are of type `Tile` */
85+
def tileColumns: Seq[TypedColumn[Any, Tile]] =
86+
self.schema.fields
87+
.filter(_.dataType.typeName.equalsIgnoreCase(TileUDT.typeName))
88+
.map(f col(f.name).as[Tile])
89+
90+
/** Get the spatial column. */
91+
def spatialKeyColumn: Option[TypedColumn[Any, SpatialKey]] = {
92+
val key = findSpatialKeyField
93+
key
94+
.map(_.name)
95+
.map(col(_).as[SpatialKey])
96+
}
97+
98+
/** Get the temporal column, if any. */
99+
def temporalKeyColumn: Option[TypedColumn[Any, TemporalKey]] = {
100+
val key = findTemporalKeyField
101+
key.map(_.name).map(col(_).as[TemporalKey])
102+
}
103+
104+
/** Find the field tagged with the requested `role` */
105+
private[rasterframes] def findRoleField(role: String): Option[StructField] =
106+
self.schema.fields.find(
107+
f
108+
f.metadata.contains(SPATIAL_ROLE_KEY) &&
109+
f.metadata.getString(SPATIAL_ROLE_KEY) == role
110+
)
111+
112+
/** The spatial key is the first one found with context metadata attached to it. */
113+
private[rasterframes] def findSpatialKeyField: Option[StructField] =
114+
findRoleField(SPATIAL_KEY_COLUMN.columnName)
115+
116+
/** The temporal key is the first one found with the temporal tag. */
117+
private[rasterframes] def findTemporalKeyField: Option[StructField] =
118+
findRoleField(TEMPORAL_KEY_COLUMN.columnName)
119+
84120
/** Renames all columns such that they start with the given prefix string.
85121
* Useful for preparing dataframes for joins where duplicate names may arise.
86122
*/
87-
def withPrefixedColumnNames(prefix: String): DataFrame =
88-
self.columns.foldLeft(self)((df, c) df.withColumnRenamed(c, s"$prefix$c"))
123+
def withPrefixedColumnNames(prefix: String): DF =
124+
self.columns.foldLeft(self)((df, c) df.withColumnRenamed(c, s"$prefix$c").asInstanceOf[DF])
89125

90126
/** Converts this DataFrame to a RasterFrame after ensuring it has:
91127
*

core/src/main/scala/astraea/spark/rasterframes/extensions/Implicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ trait Implicits {
4444
implicit class WithProjectedRasterMethods(val self: ProjectedRaster[Tile])
4545
extends ProjectedRasterMethods
4646

47-
implicit class WithDataFrameMethods(val self: DataFrame) extends DataFrameMethods
47+
implicit class WithDataFrameMethods[D <: DataFrame](val self: D) extends DataFrameMethods[D]
4848

4949
implicit class WithRasterFrameMethods(val self: RasterFrame) extends RasterFrameMethods
5050

core/src/main/scala/astraea/spark/rasterframes/extensions/RFSpatialColumnMethods.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ trait RFSpatialColumnMethods extends MethodExtensions[RasterFrame] with Standard
103103
case rf rf.certify
104104
}
105105
}
106-
107106
}
108107

109108
object RFSpatialColumnMethods {

0 commit comments

Comments
 (0)