显示瓦片地图
需求场景:给出瓦片地图各个层级的比例尺,窗口显示地图的需要Tile的行列号,及各自的顶点坐标。
需要理解的GIS概念:
比例尺(Scale)
地图上的一厘米代表着实际上的多少厘米。比如 1:1,155,583.42 意思是地图上1cm 等于实际11.5558342km。
DPI
屏幕每英寸含有的像素点,一般屏幕是取96
1英寸 = 2.54 CM
1像素 = 0.0254/96 M (地图上) 真实距离还要乘以 Scale
地图分别率(Resolution)
1个像素 对应多少个地理单位,这里地理单位依赖于切割地图的坐标系,一般就是经纬度
如果地理坐标系是wgs84,地图的单位是度,dpi为96
比例尺与分辨率之间的换算公式
Resolution = 1个像素对应的真实米 / 1度对应的真实米
1个像素真实米 = 0.0254/96 * Scale
1度对应真实米 = 2 * Math.PI * 6378137 / 360 约等 111194.872221777米
地图切图的原点是经纬度(-180,90),地图的瓦片大小是tileSize,给定要显示的中心点经纬度(lonX,latY),
计算出需要在WScreen和HScreen的窗口中显示的tile范围及定点坐标。
double tileSize = PGIS_TILE_WIDTH * pResolution; //瓦片地理长度 double windowW = WScreen * pResolution; //窗口地理长度 double windowH = HScreen * pResolution; //窗口左上角地理偏移量 double windowOffsetW = WScreen/2 * pResolution; double windowOffsetH = HScreen/2 * pResolution; //左上角 的地理坐标 (这样计算是假设窗口的中心点与显示的地图中心点重合) double leftW = cenlon - windowOffsetW; //经度 向左 越小 double leftH = (cenlat + windowOffsetH); // 向上 是纬度越大 所以是加 //step1:第一张瓦片的行列号, pFirstW = floor((leftW-maporiX)/tileSize);//向右经度变大,所以是终点经度减 pFirstH = floor((maporiY-leftH)/tileSize); //向下纬度变小,所以是起点纬度减 //窗口范围内可以显示tile的张数 Wcount = ceil(windowW/tileSize) + 1; Hcount = ceil(windowH/tileSize) + 1; //step2:最后一张tile的 行列号 pEndH = pFirstH + Hcount - 1; pEndW = pFirstW + Wcount - 1 ; //窗口左上角像素坐标(这里是以地图切割原点是0,0) double pixX = (leftW-maporiX)/pResolution; double pixY = (maporiY - leftH)/pResolution; //step3:第一张tile左上角照片 偏移量(窗口左上角的像素坐标是0,0) leftxTopDiffToCtrl = pixX - pFirstW * PGIS_TILE_WIDTH; leftyTopDiffToCtrl = pixY - pFirstH * PGIS_TILE_HEIGHT;
至此,我们可以计算出,每一张tile在窗口坐标系下的像素坐标点,完成地图的显示。用户平移地图的操作,就是改变地图中心点经纬度坐标,重新计算要显示的瓦片的行列号,及第一张瓦片左上角相对于窗口的像素坐标值。
参考链接:
http://www.thinkgis.cn/topic/541a5206da8db186fd0673ba