You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sedona.apache.org by ji...@apache.org on 2023/09/30 01:06:07 UTC
[sedona] branch master updated: [DOCS] Add raster tutorial (#1034)
This is an automated email from the ASF dual-hosted git repository.
jiayu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sedona.git
The following commit(s) were added to refs/heads/master by this push:
new e23e98cfd [DOCS] Add raster tutorial (#1034)
e23e98cfd is described below
commit e23e98cfdaae6241adec975ca7c85e4dfddb789c
Author: Furqaanahmed Khan <46...@users.noreply.github.com>
AuthorDate: Fri Sep 29 21:05:59 2023 -0400
[DOCS] Add raster tutorial (#1034)
---
docs/api/sql/Raster-operators.md | 167 +++++------
docs/image/rasterized-image.png | Bin 0 -> 413 bytes
docs/tutorial/raster.md | 590 ++++++++++++++++++++++++++++++++++++++-
3 files changed, 665 insertions(+), 92 deletions(-)
diff --git a/docs/api/sql/Raster-operators.md b/docs/api/sql/Raster-operators.md
index cffe7fc0f..4bda00305 100644
--- a/docs/api/sql/Raster-operators.md
+++ b/docs/api/sql/Raster-operators.md
@@ -863,48 +863,7 @@ Output:
14.0, 204.0, 14.571428571428571, 11.509091348732502, 1.0, 25.0
```
-
-## Raster based operators
-
-### RS_AddBand
-
-Introduction: Adds a new band to a raster `toRaster` at a specified index `toRasterIndex`. The new band's values are copied from `fromRaster` at a specified band index `fromBand`.
-If no `toRasterIndex` is provided, the new band is appended to the end of `toRaster`. If no `fromBand` is specified, band `1` from `fromRaster` is copied by default.
-
-!!!Note
- IllegalArgumentException will be thrown in these cases:
-
- - The provided Rasters, `toRaster` & `fromRaster` don't have same shape.
- - The provided `fromBand` is not in `fromRaster`.
- - The provided `toRasterIndex` is not in or at end of `toRaster`.
-
-Format:
-
-```
-RS_AddBand(toRaster: Raster, fromRaster: Raster, fromBand: Integer = 1, toRasterIndex: Integer = at_end)
-```
-
-```
-RS_AddBand(toRaster: Raster, fromRaster: Raster, fromBand: Integer = 1)
-```
-
-```
-RS_AddBand(toRaster: Raster, fromRaster: Raster)
-```
-
-Since: `v1.5.0`
-
-Spark SQL Example:
-
-```sql
-SELECT RS_AddBand(raster1, raster2, 2, 1) FROM rasters
-```
-
-Output:
-
-```
-GridCoverage2D["g...
-```
+## Raster Predicates
### RS_Contains
@@ -913,7 +872,7 @@ The convex hull of the raster is considered in the test.
The rules for testing spatial relationship is the same as `RS_Intersects`.
-Format:
+Format:
`RS_Contains(raster: Raster, geom: Geometry)`
@@ -950,7 +909,7 @@ Rules for testing spatial relationship:
* If both sides are in the same CRS, then perform the relationship test directly.
* Otherwise, both sides will be transformed to WGS84 before the relationship test.
-Format:
+Format:
`RS_Intersects(raster: Raster, geom: Geometry)`
@@ -977,6 +936,79 @@ Output:
+---------+---------+
```
+### RS_Within
+
+Introduction: Returns true if the geometry or raster on the left side is within the geometry or raster on the right side.
+The convex hull of the raster is considered in the test.
+
+The rules for testing spatial relationship is the same as `RS_Intersects`.
+
+Format: `RS_Within(raster: Raster, geom: Geometry)`
+
+Format: `RS_Within(geom: Geometry, raster: Raster)`
+
+Format: `RS_Within(raster0: Raster, raster1: Raster)`
+
+Since: `v1.5.0`
+
+Spark SQL Example:
+
+```sql
+SELECT RS_Within(RS_MakeEmptyRaster(1, 20, 20, 2, 22, 1), ST_GeomFromWKT('POLYGON ((0 0, 0 50, 100 50, 100 0, 0 0))')) rast_geom,
+ RS_Within(RS_MakeEmptyRaster(1, 20, 20, 2, 22, 1), RS_MakeEmptyRaster(1, 30, 30, 2, 22, 1)) rast_rast
+```
+
+Output:
+```
++---------+---------+
+|rast_geom|rast_rast|
++---------+---------+
+| true| true|
++---------+---------+
+```
+
+## Raster Based Operators
+
+### RS_AddBand
+
+Introduction: Adds a new band to a raster `toRaster` at a specified index `toRasterIndex`. The new band's values are copied from `fromRaster` at a specified band index `fromBand`.
+If no `toRasterIndex` is provided, the new band is appended to the end of `toRaster`. If no `fromBand` is specified, band `1` from `fromRaster` is copied by default.
+
+!!!Note
+ IllegalArgumentException will be thrown in these cases:
+
+ - The provided Rasters, `toRaster` & `fromRaster` don't have same shape.
+ - The provided `fromBand` is not in `fromRaster`.
+ - The provided `toRasterIndex` is not in or at end of `toRaster`.
+
+Format:
+
+```
+RS_AddBand(toRaster: Raster, fromRaster: Raster, fromBand: Integer = 1, toRasterIndex: Integer = at_end)
+```
+
+```
+RS_AddBand(toRaster: Raster, fromRaster: Raster, fromBand: Integer = 1)
+```
+
+```
+RS_AddBand(toRaster: Raster, fromRaster: Raster)
+```
+
+Since: `v1.5.0`
+
+Spark SQL Example:
+
+```sql
+SELECT RS_AddBand(raster1, raster2, 2, 1) FROM rasters
+```
+
+Output:
+
+```
+GridCoverage2D["g...
+```
+
### RS_MetaData
Introduction: Returns the metadata of the raster as an array of double. The array contains the following values:
@@ -1081,7 +1113,8 @@ RESAMPLED_RASTER AS (
SELECT RS_AsMatrix(resample_rast) as rast_matrix, RS_Metadata(resample_rast) as rast_metadata from RESAMPLED_RASTER
```
-`Output`:
+Output:
+
```sql
| 1.0 1.0 2.0 3.0 3.0 5.0|
| 1.0 1.0 2.0 3.0 3.0 5.0|
@@ -1092,6 +1125,8 @@ SELECT RS_AsMatrix(resample_rast) as rast_matrix, RS_Metadata(resample_rast) as
(-0.33333333333333326,0.19999999999999996,6,5,1.388888888888889,-1.24,0,0,0,1)
```
+Spark SQL Example:
+
```sql
WITH INPUT_RASTER AS (
SELECT RS_AddBandFromArray(
@@ -1104,7 +1139,8 @@ SELECT RS_AsMatrix(resample_rast) as rast_matrix, RS_Metadata(resample_rast) as
SELECT RS_AsMatrix(resample_rast) as rast_matrix, RS_Metadata(resample_rast) as rast_metadata from RESAMPLED_RASTER
```
-`Output`:
+Output:
+
```sql
| NaN NaN NaN NaN NaN NaN NaN|
| NaN 3.050000 3.650000 4.250000 5.160000 6.690000 7.200000|
@@ -1115,6 +1151,7 @@ SELECT RS_AsMatrix(resample_rast) as rast_matrix, RS_Metadata(resample_rast) as
(0.0, 0.0, 7.0, 5.0, 1.2, -1.4, 0.0, 0.0, 0.0, 1.0)
```
+Spark SQL Example:
```sql
WITH INPUT_RASTER AS (
@@ -1129,7 +1166,8 @@ RESAMPLED_RASTER AS (
SELECT RS_AsMatrix(resample_rast) as rast_matrix, RS_Metadata(resample_rast) as rast_metadata from RESAMPLED_RASTER
```
-`Output`:
+Output:
+
```sql
| 1.0 1.0 2.0 3.0 3.0 5.0 5.0|
| 1.0 1.0 2.0 3.0 3.0 5.0 5.0|
@@ -1484,38 +1522,7 @@ Output:
+----+------------+-------+
```
-### RS_Within
-
-Introduction: Returns true if the geometry or raster on the left side is within the geometry or raster on the right side.
-The convex hull of the raster is considered in the test.
-
-The rules for testing spatial relationship is the same as `RS_Intersects`.
-
-Format: `RS_Within(raster: Raster, geom: Geometry)`
-
-Format: `RS_Within(geom: Geometry, raster: Raster)`
-
-Format: `RS_Within(raster0: Raster, raster1: Raster)`
-
-Since: `v1.5.0`
-
-Spark SQL Example:
-
-```sql
-SELECT RS_Within(RS_MakeEmptyRaster(1, 20, 20, 2, 22, 1), ST_GeomFromWKT('POLYGON ((0 0, 0 50, 100 50, 100 0, 0 0))')) rast_geom,
- RS_Within(RS_MakeEmptyRaster(1, 20, 20, 2, 22, 1), RS_MakeEmptyRaster(1, 30, 30, 2, 22, 1)) rast_rast
-```
-
-Output:
-```
-+---------+---------+
-|rast_geom|rast_rast|
-+---------+---------+
-| true| true|
-+---------+---------+
-```
-
-## Raster to Map Algebra operators
+## Raster to Map Algebra Operators
To bridge the gap between the raster and map algebra worlds, the following operators are provided. These operators convert a raster to a map algebra object. The map algebra object can then be used with the map algebra operators described in the next section.
@@ -1632,7 +1639,7 @@ Output:
For more details and examples about `RS_MapAlgebra`, please refer to the [Map Algebra documentation](../Raster-map-algebra/).
To learn how to write map algebra script, please refer to [Jiffle language summary](https://github.com/geosolutions-it/jai-ext/wiki/Jiffle---language-summary).
-## Map Algebra operators
+## Map Algebra Operators
Map algebra operators work on a single band of a raster. Each band is represented as an array of doubles. The operators return an array of doubles.
diff --git a/docs/image/rasterized-image.png b/docs/image/rasterized-image.png
new file mode 100644
index 000000000..c87b83859
Binary files /dev/null and b/docs/image/rasterized-image.png differ
diff --git a/docs/tutorial/raster.md b/docs/tutorial/raster.md
index 0b71149a8..c515453c0 100644
--- a/docs/tutorial/raster.md
+++ b/docs/tutorial/raster.md
@@ -1,23 +1,589 @@
+!!!note
+ Sedona uses 1-based indexing for all raster functions except [map algebra function](../../api/sql/Raster-map-algebra), which uses 0-based indexing.
+
+!!!note
+ Sedona by default enforces geographic coordinates to be in longitude/latitude order.
+
Starting from `v1.1.0`, Sedona SQL supports raster data sources and raster operators in DataFrame and SQL. Raster support is available in all Sedona language bindings including ==Scala, Java, Python and R==.
-## Initial setup
+This page outlines the steps to manage raster data using SedonaSQL.
+
+=== "Scala"
+
+ ```scala
+ var myDataFrame = sedona.sql("YOUR_SQL")
+ myDataFrame.createOrReplaceTempView("rasterDf")
+ ```
+
+=== "Java"
+
+ ```java
+ Dataset<Row> myDataFrame = sedona.sql("YOUR_SQL")
+ myDataFrame.createOrReplaceTempView("rasterDf")
+ ```
+
+=== "Python"
+
+ ```python
+ myDataFrame = sedona.sql("YOUR_SQL")
+ myDataFrame.createOrReplaceTempView("rasterDf")
+ ```
+
+Detailed SedonaSQL APIs are available here: [SedonaSQL API](../../api/sql/Overview). You can find example raster data in [Sedona GitHub repo](https://github.com/apache/sedona/blob/0eae42576c2588fe278f75cef3b17fee600eac90/spark/common/src/test/resources/raster/raster_with_no_data/test5.tiff).
+
+## Set up dependencies
+
+=== "Scala/Java"
+
+ 1. Read [Sedona Maven Central coordinates](../setup/maven-coordinates.md) and add Sedona dependencies in build.sbt or pom.xml.
+ 2. Add [Apache Spark core](https://mvnrepository.com/artifact/org.apache.spark/spark-core), [Apache SparkSQL](https://mvnrepository.com/artifact/org.apache.spark/spark-sql) in build.sbt or pom.xml.
+ 3. Please see [SQL example project](../demo/)
+
+=== "Python"
+
+ 1. Please read [Quick start](../../setup/install-python) to install Sedona Python.
+ 2. This tutorial is based on [Sedona SQL Jupyter Notebook example](../jupyter-notebook). You can interact with Sedona Python Jupyter notebook immediately on Binder. Click [](https://mybinder.org/v2/gh/apache/sedona/HEAD?filepath=binder) to interact with Sedona Python Jupyter notebook immediately on Binder.
+
+## Create Sedona config
+
+Use the following code to create your Sedona config at the beginning. If you already have a SparkSession (usually named `spark`) created by Wherobots/AWS EMR/Databricks, please skip this step and can use `spark` directly.
+
+
+==Sedona >= 1.4.1==
+
+You can add additional Spark runtime config to the config builder. For example, `SedonaContext.builder().config("spark.sql.autoBroadcastJoinThreshold", "10485760")`
+
+=== "Scala"
+
+ ```scala
+ import org.apache.sedona.spark.SedonaContext
+
+ val config = SedonaContext.builder()
+ .master("local[*]") // Delete this if run in cluster mode
+ .appName("readTestScala") // Change this to a proper name
+ .getOrCreate()
+ ```
+ If you use SedonaViz together with SedonaSQL, please add the following line after `SedonaContext.builder()` to enable Sedona Kryo serializer:
+ ```scala
+ .config("spark.kryo.registrator", classOf[SedonaVizKryoRegistrator].getName) // org.apache.sedona.viz.core.Serde.SedonaVizKryoRegistrator
+ ```
+
+=== "Java"
+
+ ```java
+ import org.apache.sedona.spark.SedonaContext;
+
+ SparkSession config = SedonaContext.builder()
+ .master("local[*]") // Delete this if run in cluster mode
+ .appName("readTestScala") // Change this to a proper name
+ .getOrCreate()
+ ```
+ If you use SedonaViz together with SedonaSQL, please add the following line after `SedonaContext.builder()` to enable Sedona Kryo serializer:
+ ```scala
+ .config("spark.kryo.registrator", SedonaVizKryoRegistrator.class.getName) // org.apache.sedona.viz.core.Serde.SedonaVizKryoRegistrator
+ ```
+
+=== "Python"
+
+ ```python
+ from sedona.spark import *
+
+ config = SedonaContext.builder() .\
+ config('spark.jars.packages',
+ 'org.apache.sedona:sedona-spark-shaded-3.0_2.12:{{ sedona.current_version }},'
+ 'org.datasyslab:geotools-wrapper:{{ sedona.current_geotools }}'). \
+ getOrCreate()
+ ```
+ If you are using Spark versions >= 3.4, please replace the `3.0` in package name of sedona-spark-shaded with the corresponding major.minor version of Spark, such as `sedona-spark-shaded-3.4_2.12:{{ sedona.current_version }}`.
+
+==Sedona < 1.4.1==
+
+The following method has been deprecated since Sedona 1.4.1. Please use the method above to create your Sedona config.
+
+=== "Scala"
+
+ ```scala
+ var sparkSession = SparkSession.builder()
+ .master("local[*]") // Delete this if run in cluster mode
+ .appName("readTestScala") // Change this to a proper name
+ // Enable Sedona custom Kryo serializer
+ .config("spark.serializer", classOf[KryoSerializer].getName) // org.apache.spark.serializer.KryoSerializer
+ .config("spark.kryo.registrator", classOf[SedonaKryoRegistrator].getName)
+ .getOrCreate() // org.apache.sedona.core.serde.SedonaKryoRegistrator
+ ```
+ If you use SedonaViz together with SedonaSQL, please use the following two lines to enable Sedona Kryo serializer instead:
+ ```scala
+ .config("spark.serializer", classOf[KryoSerializer].getName) // org.apache.spark.serializer.KryoSerializer
+ .config("spark.kryo.registrator", classOf[SedonaVizKryoRegistrator].getName) // org.apache.sedona.viz.core.Serde.SedonaVizKryoRegistrator
+ ```
+
+=== "Java"
+
+ ```java
+ SparkSession sparkSession = SparkSession.builder()
+ .master("local[*]") // Delete this if run in cluster mode
+ .appName("readTestScala") // Change this to a proper name
+ // Enable Sedona custom Kryo serializer
+ .config("spark.serializer", KryoSerializer.class.getName) // org.apache.spark.serializer.KryoSerializer
+ .config("spark.kryo.registrator", SedonaKryoRegistrator.class.getName)
+ .getOrCreate() // org.apache.sedona.core.serde.SedonaKryoRegistrator
+ ```
+ If you use SedonaViz together with SedonaSQL, please use the following two lines to enable Sedona Kryo serializer instead:
+ ```scala
+ .config("spark.serializer", KryoSerializer.class.getName) // org.apache.spark.serializer.KryoSerializer
+ .config("spark.kryo.registrator", SedonaVizKryoRegistrator.class.getName) // org.apache.sedona.viz.core.Serde.SedonaVizKryoRegistrator
+ ```
+
+=== "Python"
+
+ ```python
+ sparkSession = SparkSession. \
+ builder. \
+ appName('appName'). \
+ config("spark.serializer", KryoSerializer.getName). \
+ config("spark.kryo.registrator", SedonaKryoRegistrator.getName). \
+ config('spark.jars.packages',
+ 'org.apache.sedona:sedona-spark-shaded-3.0_2.12:{{ sedona.current_version }},'
+ 'org.datasyslab:geotools-wrapper:{{ sedona.current_geotools }}'). \
+ getOrCreate()
+ ```
+ If you are using Spark versions >= 3.4, please replace the `3.0` in package name of sedona-spark-shaded with the corresponding major.minor version of Spark, such as `sedona-spark-shaded-3.4_2.12:{{ sedona.current_version }}`.
+
+## Initiate SedonaContext
+
+Add the following line after creating Sedona config. If you already have a SparkSession (usually named `spark`) created by Wherobots/AWS EMR/Databricks, please call `SedonaContext.create(spark)` instead.
+
+==Sedona >= 1.4.1==
+
+=== "Scala"
+
+ ```scala
+ import org.apache.sedona.spark.SedonaContext
+
+ val sedona = SedonaContext.create(config)
+ ```
+
+=== "Java"
+
+ ```java
+ import org.apache.sedona.spark.SedonaContext;
+
+ SparkSession sedona = SedonaContext.create(config)
+ ```
+
+=== "Python"
+
+ ```python
+ from sedona.spark import *
+
+ sedona = SedonaContext.create(config)
+ ```
+
+==Sedona < 1.4.1==
+
+The following method has been deprecated since Sedona 1.4.1. Please use the method above to create your SedonaContext.
+
+=== "Scala"
+
+ ```scala
+ SedonaSQLRegistrator.registerAll(sparkSession)
+ ```
+
+=== "Java"
+
+ ```java
+ SedonaSQLRegistrator.registerAll(sparkSession)
+ ```
+
+=== "Python"
+
+ ```python
+ from sedona.register import SedonaRegistrator
+
+ SedonaRegistrator.registerAll(spark)
+ ```
+
+You can also register everything by passing `--conf spark.sql.extensions=org.apache.sedona.sql.SedonaSqlExtensions` to `spark-submit` or `spark-shell`.
+
+## Load data from files
+
+Assume we have a single raster data file called rasterData.tiff, [at Path](https://github.com/apache/sedona/blob/0eae42576c2588fe278f75cef3b17fee600eac90/spark/common/src/test/resources/raster/raster_with_no_data/test5.tiff).
+
+Use the following code to load the data and create a raw Dataframe.
+
+=== "Scala"
+ ```scala
+ var rawDf = sedona.read.format("binaryFile").load(path_to_raster_data)
+ rawDf.createOrReplaceTempView("rawdf")
+ rawDf.show()
+ ```
+
+=== "Java"
+ ```java
+ Dataset<Row> rawDf = sedona.read.format("binaryFile").load(path_to_raster_data)
+ rawDf.createOrReplaceTempView("rawdf")
+ rawDf.show()
+ ```
+
+=== "Python"
+ ```python
+ rawDf = sedona.read.format("binaryFile").load(path_to_raster_data)
+ rawDf.createOrReplaceTempView("rawdf")
+ rawDf.show()
+ ```
+
+The output will look like this:
+
+```
+| path| modificationTime|length| content|
++--------------------+--------------------+------+--------------------+
+|file:/Download/ra...|2023-09-06 16:24:...|174803|[49 49 2A 00 08 0...|
+```
+
+For multiple raster data files use the following code to load the data [from path](https://github.com/apache/sedona/blob/0eae42576c2588fe278f75cef3b17fee600eac90/spark/common/src/test/resources/raster/) and create raw DataFrame.
+
+!!!note
+ The above code works too for loading multiple raster data files. if the raster files are in separate directories and the option also makes sure that only `.tif` or `.tiff` files are being loaded.
+
+=== "Scala"
+ ```scala
+ var rawDf = sedona.read.format("binaryFile").option("recursiveFileLookup", "true").option("pathGlobFilter", "*.tif*").load(path_to_raster_data_folder)
+ rawDf.createOrReplaceTempView("rawdf")
+ rawDf.show()
+ ```
+
+=== "Java"
+ ```java
+ Dataset<Row> rawDf = sedona.read.format("binaryFile").option("recursiveFileLookup", "true").option("pathGlobFilter", "*.tif*").load(path_to_raster_data_folder);
+ rawDf.createOrReplaceTempView("rawdf");
+ rawDf.show();
+ ```
+
+=== "Python"
+ ```python
+ rawDf = sedona.read.format("binaryFile").option("recursiveFileLookup", "true").option("pathGlobFilter", "*.tif*").load(path_to_raster_data_folder)
+ rawDf.createOrReplaceTempView("rawdf")
+ rawDf.show()
+ ```
+
+The output will look like this:
+
+```
+| path| modificationTime|length| content|
++--------------------+--------------------+------+--------------------+
+|file:/Download/ra...|2023-09-06 16:24:...|209199|[4D 4D 00 2A 00 0...|
+|file:/Download/ra...|2023-09-06 16:24:...|174803|[49 49 2A 00 08 0...|
+|file:/Download/ra...|2023-09-06 16:24:...|174803|[49 49 2A 00 08 0...|
+|file:/Download/ra...|2023-09-06 16:24:...| 6619|[49 49 2A 00 08 0...|
+```
+
+The content column in the raster table is still in the raw form, binary form.
+
+## Create a Raster type column
+
+All raster operations in SedonaSQL require Raster type objects. Therefore, this should be the next step after loading the data.
+
+### From Geotiff
+
+```sql
+SELECT RS_FromGeoTiff(content) AS rast, modificationTime, length, path FROM rawdf
+```
+
+To verify this, use the following code to print the schema of the DataFrame:
+
+```sql
+rasterDf.printSchema()
+```
+
+The output will be like this:
+
+```
+root
+ |-- rast: raster (nullable = true)
+ |-- modificationTime: timestamp (nullable = true)
+ |-- length: long (nullable = true)
+ |-- path: string (nullable = true)
+```
+
+### From Arc Grid
+
+The raster data is loaded the same way as `tiff` file, but the raster data is stored with the extension `.asc`, ASCII format. The following code creates a Raster type objects from binary data:
+
+```sql
+SELECT RS_FromArcInfoAsciiGrid(content) AS rast, modificationTime, length, path FROM rawdf
+```
+
+## Raster's metadata
+
+Sedona has a function to get the metadata for the raster, and also a function to get the world file of the raster.
+
+### Metadata
+
+This function will return an array of metadata, it will have all the necessary information about the raster, Please refer to [RS_MetaData](../../api/sql/Raster-operators/#rs_metadata).
+
+```sql
+SELECT RS_MetaData(rast) FROM rasterDf
+```
+
+Output for the following function will be:
+
+```
+[-1.3095817809482181E7, 4021262.7487925636, 512.0, 517.0, 72.32861272132695, -72.32861272132695, 0.0, 0.0, 3857.0, 1.0]
+```
+
+The first two elements of the array represent the real world geographic coordinates (like longitude/latitude) of the raster image's top left pixel, while the next two elements represent the pixel dimensions of the raster.
+
+### World File
+
+There are two kinds of georeferences, GDAL and ESRI seen in [world files](https://en.wikipedia.org/wiki/World_file). For more information please refer to [RS_GeoReference](../../api/sql/Raster-operators/#rs_georeference).
+
+```sql
+SELECT RS_GeoReference(rast, "ESRI") FROM rasterDf
+```
+
+The Output will be as follows:
+
+```
+72.328613
+0.000000
+0.000000
+-72.328613
+-13095781.645176
+4021226.584486
+```
+
+World files are used to georeference and geo-locate images by establishing an image-to-world coordinate transformation that assigns real-world geographic coordinates to the pixels of the image.
+
+## Raster Manipulation
+
+Since `v1.5.0` there have been many additions to manipulate raster data, we will show you a few example queries.
+
+!!!note
+ Read [SedonaSQL Raster operators](../../api/sql/Raster-operators) to learn how you can use Sedona for raster manipulation.
+
+### Coordinate translation
+
+Sedona allows you to translate coordinates as per your needs. It can translate pixel locations to world coordinates and vice versa.
+
+#### PixelAsPoint
+
+Use [RS_PixelAsPoint](../../api/sql/Raster-operators#rs_pixelaspoint) to translate pixel coordinates to world location.
+
+```sql
+SELECT RS_PixelAsPoint(rast, 450, 400) FROM rasterDf
+```
+
+Output:
+
+```
+POINT (-13063342 3992403.75)
+```
+
+#### World to Raster Coordinate
+
+Use [RS_WorldToRasterCoord](../../api/sql/Raster-operators#rs_worldtorastercoord) to translate world location to pixel coordinates. To just get X coordinate use [RS_WorldToRasterCoordX](../../api/sql/Raster-operators#rs_worldtorastercoordx) and for just Y coordinate use [RS_WorldToRasterCoordY](../../api/sql/Raster-operators#rs_worldtorastercoordy).
+
+```sql
+SELECT RS_WorldToRasterCoord(rast, -1.3063342E7, 3992403.75)
+```
+
+Output:
+
+```
+POINT (450 400)
+```
+
+### Pixel Manipulation
+
+Use [RS_Values](../../api/sql/Raster-operators#rs_values) to fetch values for specified array of Point Geometries. The coordinates in the point geometry are indicative to real world location.
+
+```sql
+SELECT RS_Values(rast, Array(ST_Point(-13063342, 3992403.75), ST_Point(-13074192, 3996020)))
+```
+
+Output:
+
+```
+[132.0, 148.0]
+```
+
+To change values over a grid or area defined by a geometry, we will use [RS_SetValues](../../api/sql/Raster-operators#rs_setvalues).
+
+```sql
+SELECT RS_SetValues(
+ rast, 1, 250, 260, 3, 3,
+ Array(10, 12, 17, 26, 28, 37, 43, 64, 66)
+ )
+```
+
+Follow the links to get more information on how to use the functions appropriately.
+
+### Band Manipulation
+
+Sedona provides APIs to select specific bands from a raster image and create a new raster. For example, to select 2 bands from a raster, you can use the [RS_Band](../../api/sql/Raster-operators#rs_band) API to retrieve the desired multi-band raster.
+
+Let's use a [multi-band raster](https://github.com/apache/sedona/blob/2a0b36989aa895c0781f9a10c907dd726506d0b7/spark/common/src/test/resources/raster_geotiff_color/FAA_UTM18N_NAD83.tif) for this example. The process of loading and converting it to raster type is the same.
+
+```sql
+SELECT RS_Band(colorRaster, Array(1, 2))
+```
+
+Let's say you have many one band rasters and want to add a band to the raster to perform [map algebra operations](#execute-map-algebra-operations). You can do so using [RS_AddBand](../../api/sql/Raster-operators#rs_addband) Sedona function.
+
+```sql
+SELECT RS_AddBand(raster1, raster2, 1, 2)
+```
+
+This will result in `raster1` having `raster2`'s specified band.
+
+### Resample raster data
+
+Sedona allows you to resample raster data using different interpolation methods like nearest neighbor, bilinear, and bicubic to change the cell size or align raster grids, using [RS_Resample](../../api/sql/Raster-operators/#rs_resample).
+
+```sql
+SELECT RS_Resample(rast, 50, -50, -13063342, 3992403.75, true, "bicubic")
+```
+
+For more information please follow the link.
+
+## Execute map algebra operations
+
+Map algebra is a way to perform raster calculations using mathematical expressions. The expression can be a simple arithmetic operations or a complex combination of multiple operations.
+
+The Normalized Difference Vegetation Index (NDVI) is a simple graphical indicator that can be used to analyze remote sensing measurements from a space platform, and assess whether the target being observed contains live green vegetation or not.
+
+```
+NDVI = (NIR - Red) / (NIR + Red)
+```
+
+where NIR is the near-infrared band and Red is the red band.
+
+```sql
+SELECT RS_MapAlgebra(raster, 'D', 'out = (rast[3] - rast[0]) / (rast[3] + rast[0]);') as ndvi FROM raster_table
+```
+
+For more information please refer to [Map Algebra API](../../api/sql/Raster-map-algebra).
+
+## Interoperability between raster and vector data
+
+### Geometry As Raster
+
+Sedona allows you to rasterize a geometry by using [RS_AsRaster](../../api/sql/Raster-writer/#rs_asraster).
+
+```sql
+SELECT RS_AsRaster(
+ ST_GeomFromWKT('POLYGON((150 150, 220 260, 190 300, 300 220, 150 150))'),
+ RS_MakeEmptyRaster(1, 'b', 4, 6, 1, -1, 1),
+ 'b', 230
+ )
+```
+
+The image create is as below for the vector is:
+
+
+
+!!!note
+ The vector coordinates are buffed up to showcase the output, real use case, may or may not match the example.
+
+### Spatial range query
+
+Sedona provides raster predicates to do a range query using a geometry window, for example let's use [RS_Intersects](../../api/sql/Raster-operators#rs_intersects).
+
+```sql
+SELECT rast FROM rasterDf WHERE RS_Intersect(rast, ST_GeomFromWKT('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'))
+```
+
+### Spatial join query
+
+Sedona's raster predicates also have the capability to do a spatial join using the raster column and geometry column, using the same function as above.
+
+```sql
+SELECT r.rast, g.geom FROM rasterDf r, geomDf g WHERE RS_Interest(r.rast, g.geom)
+```
+
+!!!note
+ These range and join queries will filter rasters using the provided geometric boundary and the spatial boundary of the raster.
+
+ Sedona offers more raster predicates to do spatial range query and spatial join query. Please refer to [raster perdicates docs](../../api/sql/Raster-operators/#raster-predicates).
+
+## Visualize raster images
+
+Sedona provides APIs to visualize raster data in an image form.
+
+### Base64 String
+
+The [RS_AsBase64](../../api/sql/Raster-visualizer#rs_asbase64) encodes the raster data as a Base64 string and can be visualized using [online decoder](https://base64-viewer.onrender.com/).
+
+```sql
+SELECT RS_AsBase64(rast) FROM rasterDf
+```
+
+### HTML Image
+
+The [RS_AsImage](../../api/sql/Raster-visualizer#rs_asimage) returns an HTML img tag, that can be visualized using an HTML viewer or in Jupyter Notebook. For more information please click at the link.
+
+```sql
+SELECT RS_AsImage(rast, 500) FROM rasterDf
+```
+
+The output looks like:
+
+
+
+### 2-D Matrix
+
+Sedona offers an API to visualize raster data that is not sufficient for the other APIs mentioned above.
+
+```sql
+SELECT RS_AsMatrix(rast) FROM rasterDf
+```
+
+Output will as follows:
+
+```sql
+| 1 3 4 0|
+| 2 9 10 11|
+| 3 4 5 6|
+```
+
+Please refer to [Raster visualizer docs](../../api/sql/Raster-visualizer) to learn how to make most of the visualizing APIs.
+
+## Save to permanent storage
+
+Sedona has APIs that can save an entire raster column to files in a specified location. Before saving, the raster type column needs to be converted to a binary format. Sedona provides several functions to convert a raster column into a binary column suitable for file storage. Once in binary format, the raster data can then be written to files on disk using the Sedona file storage APIs.
+
+```sparksql
+rasterDf.write.format("raster").option("rasterField", "raster").option("fileExtension", ".tiff").mode(SaveMode.Overwrite).save(dirPath)
+```
+
+Sedona has a few writer functions that create the binary DataFrame necessary for saving the raster images.
+
+### As Arc Grid
+
+Use [RS_AsArcGrid](../../api/sql/Raster-writer#rs_asarcgrid) to get binary Dataframe of raster in Arc Grid format.
+
+```sql
+SELECT RS_AsArcGrid(raster)
+```
-1. [Set up dependencies](../sql/#set-up-dependencies)
-2. [Create Sedona config](../sql/#create-sedona-config)
-3. [Initiate SedonaContext](../sql/#initiate-sedonacontext)
+### As GeoTiff
-## API docs
+Use [RS_AsGeoTiff](../../api/sql/Raster-writer#rs_asgeotiff) to get binary Dataframe of raster in GeoTiff format.
-[Read raster data in DataFrame](../../api/sql/Raster-loader/)
+```sql
+SELECT RS_AsGeoTiff(raster)
+```
-[Write raster data in DataFrame](../../api/sql/Raster-writer/)
+### As PNG
-[Raster operators in DataFrame](../../api/sql/Raster-operators/)
+Use [RS_AsPNG](../../api/sql/Raster-writer#rs_aspng) to get binary Dataframe of raster in PNG format.
-## Tutorials
+```sql
+SELECT RS_AsPNG(raster)
+```
-[Python Jupyter Notebook](https://github.com/apache/sedona/blob/master/binder/ApacheSedonaRaster.ipynb)
+Please refer to [Raster writer docs](../../api/sql/Raster-writer) for more details.
-## Performance
+## Performance optimization
-[Storing large raster geometries in Parquet files](../storing-blobs-in-parquet)
\ No newline at end of file
+When working with large raster datasets, refer to the [documentation on storing raster geometries in Parquet format](../storing-blobs-in-parquet) for recommendations to optimize performance.
\ No newline at end of file