本章节将上一章节创建的瓦片发布为TMS服务
本章节将使用akka建立http服务并访问影像瓦片。
使用maven构建测试案例,maven参见上一章节
具体代码如下:
import geotrellis.raster._
import geotrellis.raster.render._
import geotrellis.spark._
import geotrellis.spark.io.{FilteringLayerReader, ValueReader, _}
import geotrellis.vector._
import geotrellis.vector.io._
import geotrellis.vector.io.json._
import akka.actor._
import akka.event.{Logging, LoggingAdapter}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import spray.json._
import akka.stream.{ActorMaterializer, Materializer}
import scala.concurrent._
import com.typesafe.config.ConfigFactory
import zf.MaskBandsRandGandNIR.{G_BAND, NIR_BAND, R_BAND}
import geotrellis.proj4.{CRS, LatLng}
import zf.Calculations
object Serve extends App with Service {
val catalogPath = new java.io.File("data/catalog1").toURI.
//创建存储区
val attributeStore: AttributeStore =
AttributeStore(catalogPath)
//创建valuereader,用来读取每个tile的value
val valueReader: ValueReader[LayerId] =
ValueReader(attributeStore, catalogPath)
//渲染色带
etColormap="0:ffffe5ff;1:f7fcb9ff;2:d9f0a3ff;3:addd8eff;4:78c679ff;5:41ab5dff;6:238443ff"
val colorMapForRender = ColorMap.fromStringDouble(etColormap).get
/** raster transformation to perform at request time */
def rasterFunction(): Tile => Tile = {
tile : Tile =>tile.convert(DoubleConstantNoDataCellType)
}
override implicit val system = ActorSystem("tutorial-system")
override implicit val executor = system.dispatcher
override implicit val materializer = ActorMaterializer()
override val logger = Logging(system, getClass)
Http().bindAndHandle(root, "0.0.0.0", 8080)
}
trait Service {
implicit val system: ActorSystem
implicit def executor: ExecutionContextExecutor
implicit val materializer: Materializer
val logger: LoggingAdapter
def valueReader: ValueReader[LayerId]
def pngAsHttpResponse(png: Png): HttpResponse =
HttpResponse(entity = HttpEntity(ContentType(MediaTypes.`image/png`), png.bytes))
def root =
pathPrefix(Segment / IntNumber ) {
(zoom) =>
val fn: Tile => Tile = Serve.rasterFunction()
// ZXY route:
pathPrefix(IntNumber / IntNumber) { (x, y) =>
complete {
Future {
// Read in the tile at the given z/x/y coordinates.
val tileOpt: Option[Tile] =
try {
val reader = Serve.valueReader.reader[SpatialKey, Tile](LayerId("landsat", zoom))
Some(reader.read(x, y)
} catch {
case _: ValueNotFoundError =>
None
}
for (tile <- tileOpt) yield {
val product: Tile = fn(tile)
val cm: ColorMap = Serve.colorMapForRender()
val png: Png = product.renderPng(cm)
pngAsHttpResponse(png)
}
}
}
}
} ~
// Static content routes:
pathEndOrSingleSlash {
getFromFile("static/index.html")
} ~
pathPrefix("") {
getFromDirectory("static")
}
}
前端渲染使用leaflet.js,Index.html代码如下:
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<script src="js/jquery-1.8.3.min.js"></script>
<script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js" integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA==" crossorigin=""></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js" integrity="sha256-siofc4Uwjlra3YWkwthOn8Uj69cNN4aMug/iOHNiRgs=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" integrity="sha256-XzD3RpaHPv7lzX9qt+2n1j5cWj48O24KsgaGYpKN8x8=" crossorigin="anonymous" />
<script type="text/javascript" src="ol/ol.js"></script>
<script type="text/javascript" src="ol/olgis.js"></script>
<link rel="stylesheet" type="text/css" href="ol/ol.css">
<style type="text/css">
body, #map {
height: 100%;
}
</style>
</head>
<body>
<div id="map">
</div>
<script type="text/javascript">
var remoteurl = new L.tileLayer("http://localhost:8080/{z}/{x}/{y}", {maxNativeZoom: 13, maxZoom: 18});
var base = new L.tileLayer("http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png");
//link leaflet map with html
var map = L.map('map');
map.setView([35.294351, 140.110349], 7);
base.addTo(map);
remoteurl.addTo(map);
</script>
</body>
</html>