Skip to content

Commit 961aa2d

Browse files
authored
Merge branch 'develop' into feature/local_is_in
2 parents fa8f6b6 + ade36ab commit 961aa2d

File tree

10 files changed

+112
-161
lines changed

10 files changed

+112
-161
lines changed

core/src/main/scala/org/locationtech/rasterframes/expressions/aggregates/TileRasterizerAggregate.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ object TileRasterizerAggregate {
138138
}
139139
}
140140

141-
// Scan table and constuct what the TileLayerMetadata would be in the specified destination CRS.
141+
// Scan table and construct what the TileLayerMetadata would be in the specified destination CRS.
142142
val tlm: TileLayerMetadata[SpatialKey] = df
143143
.select(
144144
ProjectedLayerMetadataAggregate(

core/src/main/scala/org/locationtech/rasterframes/util/DataFrameRenderers.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ package org.locationtech.rasterframes.util
2424
import geotrellis.raster.render.ColorRamps
2525
import org.apache.spark.sql.Dataset
2626
import org.apache.spark.sql.functions.{base64, concat, concat_ws, length, lit, substring, when}
27+
import org.apache.spark.sql.jts.JTSTypes
2728
import org.apache.spark.sql.types.{StringType, StructField}
2829
import org.locationtech.rasterframes.expressions.DynamicExtractors
2930
import org.locationtech.rasterframes.{rfConfig, rf_render_png, rf_resample}
31+
import org.apache.spark.sql.rf.WithTypeConformity
3032

3133
/**
32-
* DataFrame extensiosn for rendering sample content in a number of ways
34+
* DataFrame extension for rendering sample content in a number of ways
3335
*/
3436
trait DataFrameRenderers {
3537
private val truncateWidth = rfConfig.getInt("max-truncate-row-element-length")
@@ -47,8 +49,9 @@ trait DataFrameRenderers {
4749
lit("\"></img>")
4850
)
4951
else {
52+
val isGeom = WithTypeConformity(c.dataType).conformsTo(JTSTypes.GeometryTypeInstance)
5053
val str = resolved.cast(StringType)
51-
if (truncate)
54+
if (truncate || isGeom)
5255
when(length(str) > lit(truncateWidth),
5356
concat(substring(str, 1, truncateWidth), lit("..."))
5457
)

core/src/test/resources/MCD43A4.A2019111.h30v06.006.2019120033434_01.mrf.aux.xml

Lines changed: 0 additions & 92 deletions
This file was deleted.

core/src/test/scala/org/locationtech/rasterframes/ExtensionMethodSpec.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import scala.xml.parsing.XhtmlParser
3939
class ExtensionMethodSpec extends TestEnvironment with TestData with SubdivideSupport {
4040
lazy val rf = sampleTileLayerRDD.toLayer
4141

42-
describe("DataFrame exention methods") {
42+
describe("DataFrame extension methods") {
4343
it("should maintain original type") {
4444
val df = rf.withPrefixedColumnNames("_foo_")
4545
"val rf2: RasterFrameLayer = df" should compile
@@ -49,7 +49,7 @@ class ExtensionMethodSpec extends TestEnvironment with TestData with SubdivideSu
4949
"val Some(col) = df.spatialKeyColumn" should compile
5050
}
5151
}
52-
describe("RasterFrameLayer exention methods") {
52+
describe("RasterFrameLayer extension methods") {
5353
it("should provide spatial key column") {
5454
noException should be thrownBy {
5555
rf.spatialKeyColumn
@@ -124,6 +124,10 @@ class ExtensionMethodSpec extends TestEnvironment with TestData with SubdivideSu
124124

125125
val md3 = rf.toMarkdown(truncate=true, renderTiles = false)
126126
md3 shouldNot include("<img")
127+
128+
// Should truncate JTS types even when we don't ask for it.
129+
val md4 = rf.withGeometry().select("geometry").toMarkdown(truncate = false)
130+
md4 should include ("...")
127131
}
128132

129133
it("should render HTML") {

datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSource.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class GeoTiffDataSource
4949

5050
def shortName() = GeoTiffDataSource.SHORT_NAME
5151

52+
/** Read single geotiff as a relation. */
5253
def createRelation(sqlContext: SQLContext, parameters: Map[String, String]) = {
5354
require(parameters.path.isDefined, "Valid URI 'path' parameter required.")
5455
sqlContext.withRasterFrames
@@ -57,6 +58,7 @@ class GeoTiffDataSource
5758
GeoTiffRelation(sqlContext, p)
5859
}
5960

61+
/** Write dataframe containing bands into a single geotiff. Note: performs a driver collect, and is not "big data" friendly. */
6062
override def createRelation(sqlContext: SQLContext, mode: SaveMode, parameters: Map[String, String], df: DataFrame): BaseRelation = {
6163
require(parameters.path.isDefined, "Valid URI 'path' parameter required.")
6264
val path = parameters.path.get
@@ -67,8 +69,6 @@ class GeoTiffDataSource
6769

6870
require(tileCols.nonEmpty, "Could not find any tile columns.")
6971

70-
71-
7272
val destCRS = parameters.crs.orElse(df.asLayerSafely.map(_.crs)).getOrElse(
7373
throw new IllegalArgumentException("A destination CRS must be provided")
7474
)

datasource/src/main/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceDataSource.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class RasterSourceDataSource extends DataSourceRegister with RelationProvider {
3737
override def shortName(): String = SHORT_NAME
3838
override def createRelation(sqlContext: SQLContext, parameters: Map[String, String]): BaseRelation = {
3939
val bands = parameters.bandIndexes
40-
val tiling = parameters.tileDims
40+
val tiling = parameters.tileDims.orElse(Some(NOMINAL_TILE_DIMS))
4141
val lazyTiles = parameters.lazyTiles
4242
val spec = parameters.pathSpec
4343
val catRef = spec.fold(_.registerAsTable(sqlContext), identity)

datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSourceSpec.scala

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -192,29 +192,36 @@ class GeoTiffDataSourceSpec
192192
}
193193

194194
it("should write GeoTIFF without layer") {
195-
196195
val pr = col("proj_raster_b0")
197-
val rf = spark.read.raster.withBandIndexes(0, 1, 2).load(rgbCogSamplePath.toASCIIString)
198196

199-
val out = Paths.get("target", "example2-geotiff.tif")
200-
logger.info(s"Writing to $out")
197+
val sample = rgbCogSample
198+
val expectedExtent = sample.extent
199+
val (expCols, expRows) = sample.tile.dimensions
201200

202-
withClue("explicit extent/crs") {
201+
val rf = spark.read.raster.withBandIndexes(0, 1, 2).load(rgbCogSamplePath.toASCIIString)
202+
203+
withClue("extent/crs columns provided") {
204+
val out = Paths.get("target", "example2a-geotiff.tif")
203205
noException shouldBe thrownBy {
204206
rf
205207
.withColumn("extent", rf_extent(pr))
206208
.withColumn("crs", rf_crs(pr))
207-
.write.geotiff.withCRS(LatLng).save(out.toString)
209+
.write.geotiff.withCRS(sample.crs).save(out.toString)
210+
checkTiff(out, expCols, expRows, expectedExtent, Some(sample.cellType))
208211
}
209212
}
210213

211-
withClue("without explicit extent/crs") {
214+
withClue("without extent/crs columns") {
215+
val out = Paths.get("target", "example2b-geotiff.tif")
212216
noException shouldBe thrownBy {
213217
rf
214-
.write.geotiff.withCRS(LatLng).save(out.toString)
218+
.write.geotiff.withCRS(sample.crs).save(out.toString)
219+
checkTiff(out, expCols, expRows, expectedExtent, Some(sample.cellType))
215220
}
216221
}
222+
217223
withClue("with downsampling") {
224+
val out = Paths.get("target", "example2c-geotiff.tif")
218225
noException shouldBe thrownBy {
219226
rf
220227
.write.geotiff
@@ -223,9 +230,6 @@ class GeoTiffDataSourceSpec
223230
.save(out.toString)
224231
}
225232
}
226-
227-
checkTiff(out, 128, 128,
228-
Extent(-76.52586750038186, 36.85907177863949, -76.17461216980891, 37.1303690755922))
229233
}
230234

231235
it("should produce the correct subregion from layer") {

docs/src/main/paradox/release-notes.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44

55
### 0.8.4
66

7-
* _Breaking_ (potentially): removed `GeoTiffCollectionRelation` due to usage limitation and overlap with `RasterSourceDataSource` functionality.
87
* Upgraded to Spark 2.4.4
9-
* Add `rf_mask_by_values` and `rf_local_is_in` raster functions; added optional `inverse` argument to `rf_mask` functions
8+
* Add `rf_mask_by_values` and `rf_local_is_in` raster functions; added optional `inverse` argument to `rf_mask` functions. ([#403](https://github.com/locationtech/rasterframes/pull/403), [#384](https://github.com/locationtech/rasterframes/issues/384))
9+
* Added forced truncation of WKT types in Markdown/HTML rendering. ([#408](https://github.com/locationtech/rasterframes/pull/408))
10+
* Add `rf_local_is_in` raster function. ([#400](https://github.com/locationtech/rasterframes/pull/400))
11+
* Added partitioning to catalogs before processing in RasterSourceDataSource ([#397](https://github.com/locationtech/rasterframes/pull/397))
12+
* Fixed bug where `rf_tile_dimensions` would cause unnecessary reading of tiles. ([#394](https://github.com/locationtech/rasterframes/pull/394))
13+
* _Breaking_ (potentially): removed `GeoTiffCollectionRelation` due to usage limitation and overlap with `RasterSourceDataSource` functionality.
1014

1115
### 0.8.3
1216

pyrasterframes/src/main/python/docs/index.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@
22

33
RasterFrames® brings together Earth-observation (EO) data access, cloud computing, and DataFrame-based data science. The recent explosion of EO data from public and private satellite operators presents both a huge opportunity and a huge challenge to the data analysis community. It is _Big Data_ in the truest sense, and its footprint is rapidly getting bigger.
44

5-
RasterFrames provides a DataFrame-centric view over arbitrary raster data, enabling spatiotemporal queries, map algebra raster operations, and compatibility with the ecosystem of Spark ML algorithms. By using DataFrames as the core cognitive and compute data model, it is able to deliver these features in a form that is both accessible to general analysts and scalable along with the rapidly growing data footprint.
5+
RasterFrames provides a DataFrame-centric view over arbitrary geospatial raster data, enabling spatiotemporal queries, map algebra raster operations, and interoperability with Spark ML. By using the DataFrame as the core cognitive and compute data model, RasterFrames is able to deliver an extensive set of functionality in a form that is both horizontally scalable as well as familiar to general analysts and data scientists. It provides APIs for Python, SQL, and Scala.
66

7-
To learn more, please see the @ref:[Getting Started](getting-started.md) section of this manual.
7+
![RasterFrames](static/rasterframes-pipeline-nologo.png)
88

9-
The source code can be found on GitHub at [locationtech/rasterframes](https://github.com/locationtech/rasterframes).
9+
Through its custom [Spark DataSource](https://rasterframes.io/raster-read.html), RasterFrames can read various raster formats -- including GeoTIFF, JP2000, MRF, and HDF -- and from an [array of services](https://rasterframes.io/raster-read.html#uri-formats), such as HTTP, FTP, HDFS, S3 and WASB. It also supports reading the vector formats GeoJSON and WKT/WKB. RasterFrame contents can be filtered, transformed, summarized, resampled, and rasterized through [200+ raster and vector functions](https://rasterframes.io/reference.html).
10+
11+
As part of the LocationTech family of projects, RasterFrames builds upon the strong foundations provided by GeoMesa (spatial operations) , GeoTrellis (raster operations), JTS (geometry modeling) and SFCurve (spatiotemporal indexing), integrating various aspects of these projects into a unified, DataFrame-centric analytics package.
12+
13+
![](static/rasterframes-locationtech-stack.png)
1014

11-
RasterFrames is released under the [Apache 2.0 License](https://github.com/locationtech/rasterframes/blob/develop/LICENSE).
15+
RasterFrames is released under the commercial-friendly [Apache 2.0](https://github.com/locationtech/rasterframes/blob/develop/LICENSE) open source license.
1216

13-
![RasterFrames](static/rasterframes-pipeline.png)
17+
To learn more, please see the @ref:[Getting Started](getting-started.md) section of this manual.
18+
19+
The source code can be found on GitHub at [locationtech/rasterframes](https://github.com/locationtech/rasterframes).
1420

1521
<hr/>
1622

0 commit comments

Comments
 (0)