Skip to content

Commit

Permalink
Support configurable CRS in WCS services (#314)
Browse files Browse the repository at this point in the history
* add supported-projects to wcs in ogc-example and stac-example
* add supported projections to wcs in stac-example
* include supported projections in describe coverage response

Co-authored-by: Grigory Pomadchin <gr.pomadchin@gmail.com>
  • Loading branch information
jisantuc and pomadchin authored Feb 21, 2021
1 parent 1672c35 commit f4bd4f6
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 17 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

## Fixed

- Service endpoints reject requests with unsupported version parameters [#313](https://github.com/geotrellis/geotrellis-server/pull/313)

## Added
- WCS services support configuration of `supported-projections` [#314](https://github.com/geotrellis/geotrellis-server/pull/314)

## [4.3.0] - 2021-02-12

## Added
Expand Down
21 changes: 15 additions & 6 deletions ogc-example/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ wms = {
${layers.us-ned-slope},
${layers.us-ned-hillshade},
${layers.us-census-median-household-income},
${layers.markham},
${layers.lc8-rgb}
${layers.lc8-rgb},
${layers.markham}
]
}

Expand All @@ -68,8 +68,17 @@ wcs = {
${layers.us-ned-slope},
${layers.us-ned-hillshade},
${layers.us-census-median-household-income},
${layers.markham},
${layers.lc8-rgb}
${layers.lc8-rgb},
${layers.markham}
]
supported-projections = [
4326,
3410,
3978,
4617,
3979,
3413,
26916
]
}

Expand All @@ -93,8 +102,8 @@ wmts = {
${layers.us-ned-slope},
${layers.us-ned-hillshade},
${layers.us-census-median-household-income},
${layers.markham},
${layers.lc8-rgb}
${layers.lc8-rgb},
${layers.markham}
]
tile-matrix-sets = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ object Main
WcsModel[IO](
svc.serviceMetadata,
svc.layerSources(simpleSources),
svc.supportedProjections,
ExtendedParameters.extendedParametersBinding
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import geotrellis.server.ogc.{ows, MapAlgebraSource, OgcSource, RasterOgcSource}
import geotrellis.server.ogc.wms.WmsParentLayerMeta
import geotrellis.server.ogc.wmts.GeotrellisTileMatrixSet
import geotrellis.store.query.Repository
import geotrellis.proj4.CRS

/**
* Each service has its own unique configuration requirements (see the below instances)
Expand Down Expand Up @@ -55,5 +56,6 @@ case class WmtsConf(
/** WCS Service configuration */
case class WcsConf(
serviceMetadata: ows.ServiceMetadata,
layerDefinitions: List[OgcSourceConf]
layerDefinitions: List[OgcSourceConf],
supportedProjections: List[CRS]
) extends OgcServiceConf
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import scalaxb._

import scala.xml.Elem
import java.net.{URI, URL}
import geotrellis.proj4.CRS

class CapabilitiesView[F[_]: Functor](wcsModel: WcsModel[F], serviceUrl: URL, extendedParameters: List[DomainType] = Nil) {
def toXML: F[Elem] = {
Expand Down Expand Up @@ -233,6 +234,10 @@ object CapabilitiesView {
val crs = src.nativeCrs.head
val wgs84extent = ReprojectRasterExtent(src.nativeRE, crs, LatLng).extent

val uniqueCrs: List[CRS] = (
crs :: LatLng :: wcsModel.supportedProjections
).distinct

CoverageSummaryType(
Title = LanguageStringType(src.title) :: Nil,
Abstract = Nil,
Expand All @@ -242,9 +247,7 @@ object CapabilitiesView {
UpperCorner = wgs84extent.ymax :: wgs84extent.xmax :: Nil
) :: Nil,
SupportedCRS =
new URI(URN.unsafeFromCrs(crs)) ::
new URI(URN.unsafeFromCrs(LatLng)) ::
new URI("urn:ogc:def:crs:OGC::imageCRS") :: Nil,
new URI("urn:ogc:def:crs:OGC::imageCRS") :: (uniqueCrs flatMap { crs => (URN.fromCrs(crs) map { new URI(_) }) }),
SupportedFormat = "image/geotiff" :: "image/jpeg" :: "image/png" :: Nil,
coveragesummarytypeoption = DataRecord(None, "Identifier".some, src.name)
)
Expand Down
14 changes: 9 additions & 5 deletions ogc/src/main/scala/geotrellis/server/ogc/wcs/CoverageView.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ import cats.syntax.option._
import scala.xml.Elem
import scalaxb._
import java.net.{URI, URL}
import geotrellis.proj4.CRS

class CoverageView[F[_]: Functor](wcsModel: WcsModel[F], serviceUrl: URL, identifiers: Seq[String]) {
def toXML: F[Elem] = {
val sources = if (identifiers == Nil) wcsModel.sources.store else wcsModel.sources.find(withNames(identifiers.toSet))
val sourcesMap: F[Map[String, List[OgcSource]]] = sources.map(_.groupBy(_.name))
val coverageTypeMap = sourcesMap.map(_.mapValues(CoverageView.sourceDescription))
val coverageTypeMap = sourcesMap.map(_.mapValues(CoverageView.sourceDescription(wcsModel.supportedProjections, _)))
coverageTypeMap map { coverageType =>
scalaxb
.toXML[CoverageDescriptions](
Expand All @@ -58,7 +59,7 @@ class CoverageView[F[_]: Functor](wcsModel: WcsModel[F], serviceUrl: URL, identi

object CoverageView {

def sourceDescription(sources: List[OgcSource]): CoverageDescriptionType = {
def sourceDescription(supportedProjections: List[CRS], sources: List[OgcSource]): CoverageDescriptionType = {
val source = sources.head
val nativeCrs = source.nativeCrs.head
val re = source.nativeRE
Expand Down Expand Up @@ -128,6 +129,10 @@ object CoverageView {
else None
}

val uniqueCrs: List[CRS] = (
nativeCrs :: LatLng :: supportedProjections
).distinct

CoverageDescriptionType(
Title = LanguageStringType(source.title) :: Nil,
Abstract = Nil,
Expand Down Expand Up @@ -200,9 +205,8 @@ object CoverageView {
) :: Nil
),
SupportedCRS =
new URI(URN.unsafeFromCrs(nativeCrs)) ::
new URI(URN.unsafeFromCrs(LatLng)) ::
new URI("urn:ogc:def:crs:OGC::imageCRS") :: Nil,
new URI("urn:ogc:def:crs:OGC::imageCRS") ::
(uniqueCrs flatMap { proj => URN.fromCrs(proj) map { new URI(_) } }),
SupportedFormat = "image/geotiff" :: "image/jpeg" :: "image/png" :: Nil
)
}
Expand Down
2 changes: 2 additions & 0 deletions ogc/src/main/scala/geotrellis/server/ogc/wcs/WcsModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import com.azavea.maml.ast.Expression
import cats.Functor
import cats.syntax.functor._
import geotrellis.store.query.RepositoryM
import geotrellis.proj4.CRS

/** This class holds all the information necessary to construct a response to a WCS request */
case class WcsModel[F[_]: Functor](
serviceMetadata: ows.ServiceMetadata,
sources: RepositoryM[F, List, OgcSource],
supportedProjections: List[CRS],
extendedParametersBinding: Option[ParamMap => Option[Expression => Expression]] = None
) {
def getLayers(p: GetCoverageWcsParams): F[List[OgcLayer]] = {
Expand Down
10 changes: 10 additions & 0 deletions stac-example/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ wcs = {
${layers.stac-lc8-blue-pa},
${layers.stac-lc8-rgb-pa}
]
supported-projections = [
4326,
3410,
3978,
4617,
3979,
3413,
3857,
26916
]
}

wmts = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ object Main
WcsModel[IO](
svc.serviceMetadata,
svc.layerSources(simpleSources, http4sClient),
svc.supportedProjections,
ExtendedParameters.extendedParametersBinding
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import cats.SemigroupK
import cats.effect.Sync
import cats.instances.list._
import cats.syntax.semigroup._
import geotrellis.proj4.CRS
import geotrellis.server.ogc
import geotrellis.server.ogc.{ows, MapAlgebraSource, OgcSource, RasterOgcSource}
import geotrellis.server.ogc.wms.WmsParentLayerMeta
Expand Down Expand Up @@ -72,5 +73,6 @@ case class WmtsConf(
/** WCS Service configuration */
case class WcsConf(
serviceMetadata: ows.ServiceMetadata,
layerDefinitions: List[OgcSourceConf]
layerDefinitions: List[OgcSourceConf],
supportedProjections: List[CRS]
) extends OgcServiceConf

0 comments on commit f4bd4f6

Please sign in to comment.