Skip to content

Commit da0d0f4

Browse files
authored
Merge pull request #235 from s22s/docs/gdal-install
GDAL related documentation
2 parents 562e962 + f6f6c73 commit da0d0f4

File tree

18 files changed

+207
-67
lines changed

18 files changed

+207
-67
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
<img src="docs/src/main/paradox/_template/images/RasterFramesLogo.png" width="300px"/><sup style="vertical-align: top;">&trade;</sup>
1+
<img src="docs/src/main/paradox/_template/images/RasterFramesLogo.png" width="300px"/><sup style="vertical-align: top;">&reg;</sup>
22

33
[![Join the chat at https://gitter.im/s22s/raster-frames](https://badges.gitter.im/s22s/raster-frames.svg)](https://gitter.im/s22s/raster-frames?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
44

55
_RasterFrames™_ brings the power of Spark DataFrames to geospatial raster data, empowered by the map algebra and tile layer operations of [GeoTrellis](https://geotrellis.io/).
66

7-
<img src="docs/src/main/paradox/RasterFramePipeline.svg" width="600px"/>
7+
<img src="docs/src/main/paradox/RasterFramePipeline.png" width="600px"/>
88

99
Please see the [Getting Started](http://rasterframes.io/getting-started.html) section of the Users' Manual to start using RasterFrames.
1010

@@ -54,6 +54,6 @@ The `pyrasterframes` build instructions are located at [pyrasterframes/src/main/
5454

5555
## Copyright and License
5656

57-
RasterFrames is released under the Apache 2.0 License, copyright Astraea, Inc. 2017-2018.
57+
RasterFrames is released under the Apache 2.0 License, copyright Astraea, Inc. 2017-2019.
5858

5959

core/src/it/scala/org/locationtech/rasterframes/ref/RasterSourceIT.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ class RasterSourceIT extends TestEnvironment with TestData {
6363
}
6464
}
6565

66-
if (RasterSource.IsGDAL.hasGDAL) {
67-
println("GDAL version: " + GDALWarp.get_version_info("--version"))
66+
if (GDALRasterSource.hasGDAL) {
67+
println("GDAL version: " + GDALRasterSource.gdalVersion())
6868

6969
describe("GDAL support") {
7070

core/src/main/scala/org/locationtech/rasterframes/ref/GDALRasterSource.scala

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ package org.locationtech.rasterframes.ref
2323

2424
import java.net.URI
2525

26+
import com.azavea.gdal.GDALWarp
27+
import com.typesafe.scalalogging.LazyLogging
28+
import geotrellis.contrib.vlm.gdal.{GDALRasterSource => VLMRasterSource}
2629
import geotrellis.proj4.CRS
27-
import geotrellis.raster.{CellType, GridBounds, MultibandTile, Raster}
2830
import geotrellis.raster.io.geotiff.Tags
31+
import geotrellis.raster.{CellType, GridBounds, MultibandTile, Raster}
2932
import geotrellis.vector.Extent
3033
import org.locationtech.rasterframes.ref.RasterSource.URIRasterSource
31-
import geotrellis.contrib.vlm.gdal.{GDALRasterSource => VLMRasterSource}
3234

3335
case class GDALRasterSource(source: URI) extends RasterSource with URIRasterSource {
3436

@@ -67,3 +69,17 @@ case class GDALRasterSource(source: URI) extends RasterSource with URIRasterSour
6769
override protected def readBounds(bounds: Traversable[GridBounds], bands: Seq[Int]): Iterator[Raster[MultibandTile]] =
6870
gdal.readBounds(bounds, bands)
6971
}
72+
73+
object GDALRasterSource extends LazyLogging {
74+
def gdalVersion(): String = if (hasGDAL) GDALWarp.get_version_info("--version").trim else "not available"
75+
76+
@transient
77+
lazy val hasGDAL: Boolean = try {
78+
val _ = new GDALWarp()
79+
true
80+
} catch {
81+
case _: UnsatisfiedLinkError =>
82+
logger.warn("GDAL native bindings are not available. Falling back to JVM-based reader for GeoTIFF format.")
83+
false
84+
}
85+
}

core/src/main/scala/org/locationtech/rasterframes/ref/RasterSource.scala

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ package org.locationtech.rasterframes.ref
2323

2424
import java.net.URI
2525

26-
import com.azavea.gdal.GDALWarp
2726
import com.github.blemale.scaffeine.Scaffeine
2827
import com.typesafe.scalalogging.LazyLogging
2928
import geotrellis.proj4.CRS
@@ -120,27 +119,18 @@ object RasterSource extends LazyLogging {
120119

121120
/** Determine if we should prefer GDAL for all types. */
122121
private val preferGdal: Boolean = org.locationtech.rasterframes.rfConfig.getBoolean("prefer-gdal")
123-
@transient
124-
lazy val hasGDAL: Boolean = try {
125-
val _ = new GDALWarp()
126-
true
127-
} catch {
128-
case _: UnsatisfiedLinkError =>
129-
logger.warn("GDAL native bindings are not available. Falling back to JVM-based reader.")
130-
false
131-
}
132122

133-
val gdalOnlyExtensions = Seq(".jp2", ".mrf", ".hdf")
123+
val gdalOnlyExtensions = Seq(".jp2", ".mrf", ".hdf", ".vrt")
134124

135125
def gdalOnly(source: URI): Boolean =
136126
if (gdalOnlyExtensions.exists(source.getPath.toLowerCase.endsWith)) {
137-
require(hasGDAL, s"Can only read $source if GDAL is available")
127+
require(GDALRasterSource.hasGDAL, s"Can only read $source if GDAL is available")
138128
true
139129
} else false
140130

141131
/** Extractor for determining if a scheme indicates GDAL preference. */
142132
def unapply(source: URI): Boolean =
143-
gdalOnly(source) || ((preferGdal || source.getScheme.startsWith("gdal")) && hasGDAL)
133+
gdalOnly(source) || ((preferGdal || source.getScheme.startsWith("gdal")) && GDALRasterSource.hasGDAL)
144134
}
145135

146136
object IsDefaultGeoTiff {

core/src/test/scala/org/locationtech/rasterframes/ref/RasterSourceSpec.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,7 @@ import org.apache.spark.sql.rf.RasterSourceUDT
2929
import org.locationtech.rasterframes.TestEnvironment
3030
import org.locationtech.rasterframes.model.TileDimensions
3131

32-
/**
33-
*
34-
*
35-
* @since 8/22/18
36-
*/
32+
3733
class RasterSourceSpec extends TestEnvironment with TestData {
3834
def sub(e: Extent) = {
3935
val c = e.center
@@ -112,7 +108,7 @@ class RasterSourceSpec extends TestEnvironment with TestData {
112108
}
113109
}
114110

115-
if(RasterSource.IsGDAL.hasGDAL) {
111+
if(GDALRasterSource.hasGDAL) {
116112
describe("GDAL Rastersource") {
117113
val gdal = GDALRasterSource(cogPath)
118114
val jvm = JVMGeoTiffRasterSource(cogPath)

docs/build.sbt

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// task to create documentation PDF
2+
lazy val makePDF = taskKey[File]("Build PDF version of documentation")
3+
lazy val pdfFileName = settingKey[String]("Name of the PDF file generated")
4+
pdfFileName := s"RasterFrames-Users-Manual-${version.value}.pdf"
5+
6+
makePDF := {
7+
import scala.sys.process._
8+
9+
// Get the python source directory configured in the root project.
10+
val base = (Compile / paradox / sourceDirectories).value.find(_.toString.contains("python")).head
11+
println(base)
12+
13+
// Hard coded lacking any simple way of determining order.
14+
val files = Seq(
15+
"index.md",
16+
"description.md",
17+
"concepts.md",
18+
"getting-started.md",
19+
"raster-io.md",
20+
"raster-catalogs.md",
21+
"raster-read.md",
22+
"raster-write.md",
23+
"vector-data.md",
24+
"raster-processing.md",
25+
"local-algebra.md",
26+
"nodata-handling.md",
27+
"aggregation.md",
28+
"time-series.md",
29+
"machine-learning.md",
30+
"unsupervised-learning.md",
31+
"supervised-learning.md",
32+
"numpy-pandas.md",
33+
"languages.md",
34+
"reference.md"
35+
).map(base ** _).flatMap(_.get)
36+
37+
val log = streams.value.log
38+
log.info("Section ordering:")
39+
files.foreach(f => log.info(" - " + f.getName))
40+
41+
val work = target.value / "makePDF"
42+
work.mkdirs()
43+
44+
val prepro = files.zipWithIndex.map { case (f, i)
45+
val dest = work / f"$i%02d.md"
46+
// Filter cross links and add a newline
47+
(Seq("sed", "-e", """s/@ref:\[\([^]]*\)\](.*)/_\1_/g;s/@@.*//g""", f.toString) #> dest).!
48+
// Add newline at the end of the file so as to make pandoc happy
49+
("echo" #>> dest).!
50+
("echo \\pagebreak" #>> dest).!
51+
dest
52+
}
53+
54+
val output = target.value / pdfFileName.value
55+
56+
val header = (Compile / sourceDirectory).value / "latex" / "header.latex"
57+
58+
val args = "pandoc" ::
59+
"--from=markdown" ::
60+
"--to=pdf" ::
61+
"-t" :: "latex" ::
62+
"-s" ::
63+
"--toc" ::
64+
"-V" :: "title:RasterFrames Users' Manual" ::
65+
"-V" :: "author:Astraea, Inc." ::
66+
"-V" :: "geometry:margin=0.75in" ::
67+
"-V" :: "papersize:letter" ::
68+
"-V" :: "links-as-notes" ::
69+
"--include-in-header" :: header.toString ::
70+
"-o" :: output.toString ::
71+
prepro.map(_.toString).toList
72+
73+
log.info(s"Running: ${args.mkString(" ")}")
74+
Process(args, base).!
75+
76+
log.info("Wrote: " + output)
77+
78+
output
79+
}
80+
81+
makePDF := makePDF.dependsOn(Compile / paradox).value

docs/src/main/latex/header.latex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
\DeclareUnicodeCharacter{2218}{$\circ$}
2+
\DeclareUnicodeCharacter{2714}{$\checkmark}
30.2 KB
Loading

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@
1111
* Added new tile functions `rf_round`, `rf_abs`, `rf_log`, `rf_log10`, `rf_log2`, `rf_log1p`, `rf_exp`, `rf_exp10`, `rf_exp2`, `rf_expm1`, `rf_resample`.
1212
* Support Python-side Tile User-Defined Type backed by [numpy](https://www.numpy.org/) `ndarray` or `ma.MaskedArray`.
1313
* Support Python-side [Shapely](https://pypi.org/project/Shapely/) geometry User-Defined Type.
14-
* SQL API support for: `rf_assemble_tile`, `rf_array_to_tile`.
14+
* SQL API support for `rf_assemble_tile` and `rf_array_to_tile`.
1515
* Introduced at the source level the concept of a `RasterSource` and `RasterRef`, enabling lazy/delayed read of sub-scene tiles.
1616
* Added `withKryoSerialization` extension methods on `SparkSession.Builder` and `SparkConf`.
1717
* Added `rf_render_matrix` debugging function.
18-
* Added `RasterFrame.withExtent` extension method.
18+
* Added `RasterFrameLayer.withExtent` extension method.
1919
* Added `SinglebandGeoTiff.toDF` extension method.
2020
* Added `DataFrame.rasterJoin` extension method for merging two dataframes with tiles in disparate CRSs.
2121
* Added `rf_crs` for `ProjectedRasterTile` columns.
2222
* Added `st_extent` (for `Geometry` types) and `rf_extent` (for `ProjectedRasterTile` and `RasterSource` columns).
2323
* Added `st_geometry` (for `Extent` types) and `rf_geometry` (for `ProjectedRasterTile` and `RasterSource` columns).
24-
* _Breaking_: The type `RasterFrame` renamed `RasterFrameLayer` to be reflect its purpose.
24+
* Reworked build scripts for RasterFrames Jupyter Notebook.
25+
* _Breaking_: The type `RasterFrame` renamed `RasterFrameLayer` to be reflect its intended purpose.
2526
* _Breaking_: All `asRF` methods renamed to `asLayer`.
2627
* _Breaking_: Root package changed from `org.locationtech.rasterframes` to `org.locationtech.rasterframes`.
2728
* _Breaking_: Removed `envelope`, in lieu of `st_extent`, `rf_extent` or `st_envelope`
@@ -37,8 +38,7 @@
3738
* _Breaking_: `CellHistogram` no longer carries along approximate statistics, due to confusing behavior. Use `rf_agg_stats` instead.
3839
* Introduced `LocalCellStatistics` class to wrap together results from `LocalStatsAggregate`.
3940
* _Breaking_: `TileDimensions` moved from `astraea.spark.rasterframes` to `org.locationtech.rasterframes.model`.
40-
* _Breaking_: Renamed `RasterFrame.withBounds` to `RasterFrame.withGeometry` for consistency with DataSource schemas.
41-
* Reworked build scripts for RasterFrames Jupyter Notebook.
41+
* _Breaking_: Renamed `RasterFrame.withBounds` to `RasterFrameLayer.withGeometry` for consistency with DataSource schemas.
4242

4343
## 0.7.x
4444

pyrasterframes/src/main/python/docs/getting-started.pymd

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,41 @@ spark.stop()
7878

7979
## Installing GDAL
8080

81-
GDAL provides a wide variety of drivers to read data from many different raster formats. If GDAL is installed in the environment, RasterFrames will be able to @ref:[read](raster-read.md) those formats. If you are using the @ref:[Jupyter Notebook image](getting-started.md#jupyter-notebook), GDAL is already installed for you. Otherwise follow the instructions below.
81+
GDAL provides a wide variety of drivers to read data from many different raster formats. If GDAL is installed in the environment, RasterFrames will be able to @ref:[read](raster-read.md) those formats. If you are using the @ref:[Jupyter Notebook image](getting-started.md#jupyter-notebook), GDAL is already installed for you. Otherwise follow the instructions below. Version 2.4.1 or greater is required.
8282

83-
__TODO__ Verify notebook env has GDAL?
83+
### Installing on MacOS
8484

85-
__TODO__ How to install it.
85+
Using [homebrew](https://brew.sh/):
86+
87+
```bash
88+
brew install gdal
89+
```
90+
91+
### Installing on Linux
92+
93+
Using [`apt-get`](https://wiki.debian.org/Apt):
94+
95+
```bash
96+
sudo apt-get update
97+
sudo apt-get install gdal-bin
98+
```
99+
100+
### Testing For GDAL
101+
102+
```bash
103+
gdalinfo --formats
104+
```
105+
106+
To support GeoTIFF and JPEG2000 formats, you should look for the following drivers from the output above:
107+
108+
* `GTiff -raster- (rw+vs): GeoTIFF`
109+
* `JPEG2000 -raster,vector- (rwv): JPEG-2000 part 1 (ISO/IEC 15444-1), based on Jasper library`
110+
111+
Do the following to see if RasterFrames was able to find GDAL:
112+
113+
```python
114+
from pyrasterframes.utils import gdal_version
115+
print(gdal_version())
116+
```
117+
118+
This will print out something like "GDAL x.y.z, released 20yy/mm/dd". If it reports `not available`, then GDAL isn't installed in a place where the RasterFrames runtime was able to find it. Please [file an issue](https://github.com/locationtech/rasterframes/issues) to get help resolving it.

0 commit comments

Comments
 (0)