首页 > 编程知识 正文

切片良率计算公式,geoserver切片缓存

时间:2023-05-06 10:06:22 阅读:271647 作者:3838

GeoServer WMTS切片计算 各级别关系计算规则(1)计算Pixel Size(2)计算Scale(3)切片行列号计算

在geoserver中打开GridSets,选择WGS 84的切片进行查看

可以看到如下信息

各级别关系 LevelPixel SizeScaleTilesip1 : sm * ni +1p /21 : (s/2)2m * 2n计算规则


level=0时,切片如图所示

(1)计算Pixel Size

由于像素为256256,切片数量为21,经纬度范围为经度360度(-180到180),纬度180度(-90到90),
所以删除21的切片宽为2562=512像素,高为256像素
所以Pixel Size=360/512=0.703125 ,即每个像素代表0.703125度
当level=i时,由于被分割成了360度被分割成了2*2i张图片,每张图片为256个像素大小,故
p i x e l S i z e = 360 256 ∗ 2 ∗ 2 i pixel Size=frac{360}{256*2*2^{i}} pixelSize=256∗2∗2i360​

(2)计算Scale

∵ 地球半径为6378137米,
∴ 实际距离D=2πR=2π6378137=40,075,016.685578491904米

在OpenGIS的WMTS标准实现中,确定比例尺分母时采用的是标准显示像素尺寸(1个像素大小)0.28mm×0.28mm。虽然实际的像素大小并不可知,但0.28mm对于当前的显示器是较为普遍的实际尺寸。
(参考链接:
(1条消息) Geoserver学习笔记-3、服务标准(WMTS详解)_@柿子树的博客-CSDN博客_geoserver wmts https://blog.csdn.net/weixin_38670190/article/details/104953940)

图上距离d=256 * 2 * 0.28/1000=0.14336米
比例尺=d/D=0.14336/40,075,016.685578491904=1:279,541,132.0143589
level=i时,

单个像素长度 = 0.28mm=0.00028m像素个数 = 256 * 2 * 2i图上距离(即地图360对应的像素总长度)为0.00028 * 256 * 2 * 2i地图实际距离(地球周长)=2πR=2 * π * 6378137
- s c a l e = 0.00028 ∗ 256 ∗ 2 ∗ 2 i 2 ∗ π ∗ 6378137 scale=frac{0.00028 * 256 * 2 * 2^{i}}{2*π*6378137} scale=2∗π∗63781370.00028∗256∗2∗2i​ (3)切片行列号计算 public void Calculate(){ ///四至范围可以通过xml文件读取 ///http://localhost:8080/geoserver/gwc/service/wmts?layer=zny:ShuniuquDOM&REQUEST=GetCapabilities ///<ows:Title>ShuniuquDOM</ows:Title> ///<ows:WGS84BoundingBox> ///< ows:LowerCorner > 99.14775967969356 27.1615889820084 </ ows:LowerCorner > ///< ows:UpperCorner > 99.1598915388142 27.175144923792043 </ ows:UpperCorner > ///</ ows:WGS84BoundingBox > var xmin = 99.14775967969356; var ymin = 27.1615889820084; var xmax = 99.1598915388142; var ymax = 27.175144923792043; var dx = xmax - xmin; var dy = ymax - ymin; var env = Map.Extent; //与视域范围无交集,无需渲染 if (env.xMin > xmax || env.yMin > ymax || env.xMax < xmin || env.yMax < ymin) return; //只需加载与视域范围相交的部分 if (env.xMin > xmin) xmin = env.xMin; if (env.xMax < xmax) xmax = env.xMax; if (env.yMin > ymin) ymin = env.yMin; if (env.yMax < ymax) ymax = env.yMax; //图层最值点转为像素坐标 var p1 = Map.mapToDevicePoint(new SGPoint(xmin,ymin)); var p2 = Map.mapToDevicePoint(new SGPoint(xmax,ymax)); int level = 0; //图层横长型,用经差进行适配 if (dx/dy> env.width/ env.height) { //屏幕像素宽度 var pw = Math.Ceiling(p2.x - p1.x); var pixelSize = dx / pw; double d = 0; for (int i = 0; i < 22; i++) { var std = 360 / (256 * 2 * Math.Pow(2, i)); d = std - pixelSize; if (d < 0) { level = i; break; } } } //图层竖长型,用纬差进行适配 else { var ph = Math.Ceiling(p2.y - p1.y); var pixelSize = dy / ph; double d = 0; for (int i = 0; i < 22; i++) { var std = 180 / (256 * Math.Pow(2, i)); d = std - pixelSize; if (d < 0) { level = i; break; } } } var StandPixelSze = 180 / (256 * Math.Pow(2, level)); //展开为360度,最左侧实际为-180,但是由于原点在左上角,,所以需要要x+180,90-y #region 左上角点 var col1 = Math.Floor((xmin + 180) / 360.0 * 2 * Math.Pow(2, level)); var row1 = Math.Floor((90 - ymax) / 180.0 * Math.Pow(2, level)); #endregion #region 右下角点 var col2 = Math.Floor((xmax + 180) / 360.0 * 2 * Math.Pow(2, level)); var row2 = Math.Floor((90 - ymin) / 180.0 * Math.Pow(2, level)); #endregion //需要渲染的所有切片(从上到下,从左到右) for(var col = col1; col <= col2; col++) { for(var row = row1; row <= row2; row++) { //照片实际四至坐标 double x1 = col * StandPixelSze * 256 - 180; double y1 = 90 - (row + 1) * StandPixelSze * 256; double x2 = x1 + 256 * StandPixelSze; double y2 = y1 + 256 * StandPixelSze; var layerName = "ShuniuquDOM"; var url = $"http://localhost:8081/geoserver/gwc/service/wmts?layer=zny:{layerName}&style=&tilematrixset=EPSG:4326&" + $"Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&" + $"TileMatrix=EPSG:4326:{level}&TileCol={col}&TileRow={row}"; Console.WriteLine(url); } }}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。