瓦片范围计算(根据范围和级别)(Scala)

package com.geoway.gspark.common

import com.vividsolutions.jts.geom.{Envelope, GeometryFactory, Polygon}

import scala.collection.mutable.ArrayBuffer
import com.vividsolutions.jts.io.WKTReader
import org.geotools.geometry.jts.JTSFactoryFinder

/**
  * Created by wangchaojie on 2018/6/29.
  * 地图瓦片帮助类
  */
object MapTileUtil {
  var originPoint: Point = new Point(-180, 90)

  def main(args: Array[String]): Unit = {
    val wkt: String = "POLYGON((78.718774  39.478792,79.775255  39.478792,79.570621  38.888686,78.718774  39.478792))"
    val arrayBuffer: Array[String] = GetGrids(wkt, 5)
    for (i <- 0 to arrayBuffer.length - 1) {
      println(arrayBuffer(i))
    }
  }

  /*
   created by wcj 2018-6-29
   根据传入空间wkt串和级别获取相交的空间格网数组
   */
  def GetGrids(queryWkt: String, level: Int): Array[String] = {
    val arrayBuffer: ArrayBuffer[String] = new ArrayBuffer[String]()

    var resolution: Double = TileLevel.getTileResolution(level)
    val geometryFactory = JTSFactoryFinder.getGeometryFactory(null)
    val reader = new WKTReader(geometryFactory)
    val polygon: Polygon = reader.read(queryWkt).asInstanceOf[Polygon]
    var envelope: Envelope = polygon.getEnvelopeInternal()

    var tileRowCol: MapRowCol = GetTileRowCol(envelope, resolution)
    val totalTileCount = ( tileRowCol.endCol - tileRowCol.startCol  + 1) * (tileRowCol.endRow - tileRowCol.startRow + 1)//瓦片总个数

    for (col <- tileRowCol.startCol  to  tileRowCol.endCol) {
      for (row <- tileRowCol.startRow to tileRowCol.endRow) {
        arrayBuffer += GetEnvRange(row, col, resolution)
      }
    }
    arrayBuffer.toArray
  }
  /*
  created by wcj 2018-6-29
  根据行列号和空间分辨率获取格网空间wkt串
   */
  def GetEnvRange(row: Int, col: Int, resolution: Double): String = {
    val tileSize = 256
    val minX = resolution * tileSize * col + originPoint.x
    val maxX = resolution * tileSize * (col + 1) + originPoint.x
    val minY = originPoint.y - resolution * tileSize * (row + 1)
    val maxY = originPoint.y - resolution * tileSize * row
    "POLYGON((%s %s,%s %s,%s %s,%s %s,%s %s))".format(minX, maxY, maxX, maxY, maxX, minY, minX, minY, minX, maxY)
  }

  /*
  created by wcj 2018-6-29
  根据外接矩形和分辨率获取起止行列号
   */
  def GetTileRowCol(env: Envelope, resolution: Double): MapRowCol = {
    var startRow: Int = Math.floor(Math.abs((env.getMaxY() - originPoint.y)) / 256 / resolution).toInt
    var endRow: Int = Math.floor(Math.abs((env.getMinY() - originPoint.y)) / 256 / resolution).toInt
    var startCol: Int = Math.floor((env.getMinX() - originPoint.x) / 256 / resolution).toInt
    var endCol: Int = Math.floor((env.getMaxX() - originPoint.x) / 256 / resolution).toInt
    new MapRowCol(startRow, endRow, startCol, endCol)
  }
}

class Point(_x: Double, _y: Double) {
  var x: Double = _x
  var y: Double = _y
}

class MapRowCol(_startRow: Int, _endRow: Int, _startCol: Int, _endCol: Int) {
  var startRow = _startRow
  var endRow = _endRow
  var startCol = _startCol
  var endCol = _endCol
}

 /*
     created by wcj 2018-6-29 13:42:51
     根据级别获取分辨率,采用国际180度切片方案,原点-180,90,dpi 96 ,Size 256
    */
    def getTileResolution(level: Int):Double={
    level match {
      case 0 =>0.703125000000001
      case 1 =>0.351562500000001
      case 2 =>0.17578125
      case 3 =>8.78906250000002E-02
      case 4 =>4.39453125000001E-02
      case 5 =>0.02197265625
      case 6 =>0.010986328125
      case 7 =>5.49316406250001E-03
      case 8 =>0.00274658203125
      case 9 =>0.001373291015625
      case 10 =>6.86645507812501E-04
      case 11 =>3.43322753906251E-04
      case 12 =>1.71661376953125E-04
      case 13 =>8.58306884765626E-05
      case 14 =>4.29153442382813E-05
      case 15 =>2.14576721191407E-05
      case 16 =>1.07288360595703E-05
      case 17 =>5.36441802978517E-06
      case 18 =>2.68220901489258E-06
      case 19 =>1.34110450744629E-06
    }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数智侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值