
geotrellis.server.ogc.conf.OgcSourceConf.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of geotrellis-server-stac-example_2.13 Show documentation
Show all versions of geotrellis-server-stac-example_2.13 Show documentation
GeoTrellis Server is a set of components designed to simplify viewing, processing, and serving raster data from arbitrary sources with an emphasis on doing so in a functional style.
The newest version!
/*
* Copyright 2020 Azavea
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package geotrellis.server.ogc.conf
import geotrellis.server.ogc.stac.{ByCollection, ByLayer, StacSearchCriteria}
import geotrellis.raster.{CellType, RasterSource}
import geotrellis.raster.io.geotiff.OverviewStrategy
import geotrellis.raster.resample._
import geotrellis.server.ogc._
import geotrellis.store.GeoTrellisPath
import geotrellis.proj4.{CRS, WebMercator}
import com.azavea.maml.ast._
import cats.syntax.option._
import eu.timepit.refined.types.numeric.NonNegInt
import geotrellis.stac.raster.StacCollectionSource
import pureconfig.ConfigReader
import scala.util.Try
import scala.util.matching.Regex
// This sumtype corresponds to the in-config representation of a source
sealed trait OgcSourceConf {
def name: String
def styles: List[StyleConf]
def resampleMethod: ResampleMethod
def overviewStrategy: OverviewStrategy
}
case class StacSourceConf(
name: String,
layer: Option[String],
collection: Option[String],
title: String,
source: String,
asset: Regex,
assetLimit: Option[NonNegInt],
pageLimit: Option[NonNegInt],
defaultStyle: Option[String],
styles: List[StyleConf],
commonCrs: CRS = WebMercator,
resampleMethod: ResampleMethod = ResampleMethod.DEFAULT,
overviewStrategy: OverviewStrategy = OverviewStrategy.DEFAULT,
ignoreTime: Boolean = false,
datetimeField: String = "datetime",
timeFormat: OgcTimeFormat = OgcTimeFormat.Default,
timeDefault: OgcTimeDefault = OgcTimeDefault.Oldest,
fetchTimePositions: Boolean = false,
withGDAL: Boolean = false,
withVSIAZ: Boolean = false,
parallelMosaic: Boolean = false
) extends OgcSourceConf {
/**
* flag used to convert https azure URI into wasbs:// URIs to smooth GDAL integration
*/
val toWASBS: Boolean = withGDAL && withVSIAZ
/**
* By default the search would happen across collections.
*/
def searchCriteria: StacSearchCriteria =
(collection, layer) match {
case (None, Some(_)) => ByLayer
case _ => ByCollection
}
def searchName: String =
(searchCriteria match {
case ByCollection => collection
case ByLayer => layer
}).getOrElse("")
def toLayer(rs: RasterSource): SimpleSource =
SimpleSource(name, title, rs, defaultStyle, styles.map(_.toStyle), resampleMethod, overviewStrategy, datetimeField.some, timeFormat)
def toLayer(rs: StacCollectionSource): StacOgcSource =
StacOgcSource(
name,
title,
rs,
defaultStyle,
styles.map(_.toStyle),
resampleMethod,
overviewStrategy,
datetimeField.some,
fetchTimePositions,
timeFormat,
timeDefault
)
}
object StacSourceConf {
implicit val crsReader: ConfigReader[CRS] =
ConfigReader[String].map { str =>
Try(CRS.fromName(str)).toOption.orElse(Try(CRS.fromString(str)).toOption) match {
case Some(crs) => crs
case None => throw new Exception(s"Invalid Proj4 String: $str")
}
}
}
case class RasterSourceConf(
name: String,
title: String,
source: String,
defaultStyle: Option[String],
styles: List[StyleConf],
resampleMethod: ResampleMethod = ResampleMethod.DEFAULT,
overviewStrategy: OverviewStrategy = OverviewStrategy.DEFAULT,
datetimeField: String = SimpleSource.TimeFieldDefault,
timeFormat: OgcTimeFormat = OgcTimeFormat.Default,
timeDefault: OgcTimeDefault = OgcTimeDefault.Oldest
) extends OgcSourceConf {
def toLayer: RasterOgcSource =
GeoTrellisPath
.parseOption(source)
.fold[RasterOgcSource](
SimpleSource(
name,
title,
RasterSource(source),
defaultStyle,
styles.map(_.toStyle),
resampleMethod,
overviewStrategy,
datetimeField.some,
timeFormat
)
)(_ =>
GeoTrellisOgcSource(
name,
title,
source,
defaultStyle,
styles.map(_.toStyle),
resampleMethod,
overviewStrategy,
datetimeField.some,
timeFormat,
timeDefault
)
)
}
case class MapAlgebraSourceConf(
name: String,
title: String,
algebra: Expression,
defaultStyle: Option[String],
styles: List[StyleConf],
resampleMethod: ResampleMethod = ResampleMethod.DEFAULT,
overviewStrategy: OverviewStrategy = OverviewStrategy.DEFAULT,
timeFormat: OgcTimeFormat = OgcTimeFormat.Default,
timeDefault: OgcTimeDefault = OgcTimeDefault.Oldest,
targetCellType: Option[CellType] = None
) extends OgcSourceConf {
def listParams(expr: Expression): List[String] = {
def eval(subExpr: Expression): List[String] =
subExpr match {
case v: Variable => List(v.name)
case _ => subExpr.children.flatMap(eval)
}
eval(expr)
}
/**
* Given a list of all available `SimpleSourceConf` instances in the global [[Conf]] object, attempt to produce the parameter bindings necessary for
* evaluating the MAML [[Expression]] in the algebra field
*/
def model(possibleSources: List[RasterOgcSource]): MapAlgebraSource = {
val layerNames = listParams(algebra)
val sourceList = layerNames.map { name =>
val layerSrc = possibleSources.find(_.name == name).getOrElse {
throw new Exception(
s"MAML Layer expected but was unable to find the simple layer '$name', make sure all required layers are in the server configuration and are correctly spelled there and in all provided MAML"
)
}
name -> layerSrc
}
MapAlgebraSource(
name,
title,
sourceList.toMap,
algebra,
defaultStyle,
styles.map(_.toStyle),
resampleMethod,
overviewStrategy,
timeFormat,
timeDefault,
targetCellType
)
}
def modelOpt(possibleSources: List[RasterOgcSource]): Option[MapAlgebraSource] = {
val layerNames = listParams(algebra)
val sourceList = layerNames.flatMap(name => possibleSources.find(_.name == name).map(layerSrc => name -> layerSrc))
if (sourceList.length == layerNames.length)
MapAlgebraSource(
name,
title,
sourceList.toMap,
algebra,
defaultStyle,
styles.map(_.toStyle),
resampleMethod,
overviewStrategy,
timeFormat,
timeDefault,
targetCellType
).some
else None
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy