
geotrellis.server.ogc.wcs.WcsView.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.12 Show documentation
Show all versions of geotrellis-server-stac-example_2.12 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 2019 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.wcs
import geotrellis.server.ogc.{OutputFormat, ToMediaType}
import geotrellis.server.ogc.params.ParamError
import geotrellis.server.ogc.ows.OwsDataRecord
import geotrellis.server.utils._
import org.backuity.ansi.AnsiFormatter.FormattedHelper
import org.http4s.scalaxml._
import org.http4s._
import org.http4s.dsl.Http4sDsl
import cats.effect._
import cats.{ApplicativeThrow, Parallel}
import cats.data.Validated
import cats.syntax.apply._
import cats.syntax.flatMap._
import cats.syntax.functor._
import cats.syntax.option._
import cats.syntax.applicativeError._
import org.typelevel.log4cats.Logger
import opengis.ows.{AllowedValues, AnyValue, DomainType, ValueType}
import opengis._
import org.http4s.headers.`Content-Type`
import scalaxb._
import java.net._
class WcsView[F[_]: Async: Parallel: ApplicativeThrow: Logger](
wcsModel: WcsModel[F],
serviceUrl: URL
) extends Http4sDsl[F] {
val logger = Logger[F]
val extendedRGBParameters: List[DomainType] = {
val channels = "Red" :: "Green" :: "Blue" :: Nil
def clamp(band: String): List[DomainType] =
DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord(s"clampMin$band")
)
) :: DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord(s"clampMax$band")
)
) :: Nil
def normalize(band: String): List[DomainType] =
DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord(s"normalizeOldMin$band")
)
) :: DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord(s"normalizeOldMax$band")
)
) :: DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord(s"normalizeNewMin$band")
)
) :: DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord(s"normalizeNewMax$band")
)
) :: Nil
def rescale(band: String): List[DomainType] =
DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord(s"rescaleNewMin$band")
)
) :: DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord(s"rescaleNewMax$band")
)
) :: Nil
channels.flatMap { b =>
clamp(b) ::: normalize(b) ::: rescale(b)
}
}
val extendedParameters: List[DomainType] = DomainType(
possibleValuesOption1 = OwsDataRecord(
AllowedValues(
OwsDataRecord(
ValueType("all")
) :: OwsDataRecord(
ValueType("data")
) :: OwsDataRecord(
ValueType("nodata")
) :: Nil
)
),
DefaultValue = ValueType("all").some,
attributes = Map(
"@name" -> DataRecord("target")
)
) :: DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord("zFactor")
)
) :: DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord("azimuth")
)
) :: DomainType(
possibleValuesOption1 = OwsDataRecord(AnyValue()),
attributes = Map(
"@name" -> DataRecord("altitude")
)
) :: Nil
private def handleError[Result: EntityEncoder[F, *]](result: Either[Throwable, Result], format: OutputFormat): F[Response[F]] =
result match {
case Right(res) =>
logger.info(s"response ${res.toString}")
Ok(res).map(_.putHeaders(`Content-Type`(ToMediaType(format))))
case Left(err) =>
logger.error(err.stackTraceString)
InternalServerError(err.stackTraceString)
}
private val getCoverage = new GetCoverage(wcsModel)
def responseFor(req: Request[F]): F[Response[F]] =
WcsParams(req.multiParams) match {
case Validated.Invalid(errors) =>
val msg = ParamError.generateErrorMessage(errors.toList)
logger.warn(msg) >> BadRequest(msg)
case Validated.Valid(wcsParams) =>
wcsParams match {
case _: GetCapabilitiesWcsParams =>
(logger.debug(ansi"%bold{GetCapabilities: $serviceUrl}") *>
new CapabilitiesView[F](
wcsModel,
serviceUrl,
extendedParameters ::: extendedRGBParameters
).toXML).flatMap { Ok(_) }
case p: DescribeCoverageWcsParams =>
logger.debug(ansi"%bold{DescribeCoverage: ${req.uri}}") *>
Ok(CoverageView(wcsModel, serviceUrl, p).toXML)
case p: GetCoverageWcsParams =>
for {
_ <- logger.debug(ansi"%bold{GetCoverage: ${req.uri}}")
getCoverage <- getCoverage.build(p).attempt
result <- handleError(getCoverage, p.format)
_ <- logger.debug(s"getcoverage result: $result")
} yield result
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy