一、综述
现实世界中的地理位置点如手机的定位点,手机信令采集信息,共享单车的骑行轨迹,和开关锁位置,渔船的北斗定位位置信息,这些信息都是实际的定位点,但是有时候在对空间大数据分析的时候,我们不会关注某一个设备,位置的用途,会关注所有在某一个大概区域的总量,以统计这个区域的热度、密度等信息,如共享单车用车热门区域、热门景点、渔船捕捞努力量等信息,这时候就要对这些实际位置点进行聚合统计,不同应用的统计标准可能各不相同,有的是按照固定区域(如渔场网格),有的是按照行政区边界统计,有的是按照自定义的网格进行统计(500m矩形网格、1km的蜂窝网格等),我们这里介绍一种Google Tile 瓦片网格,在空间大数据聚合中的应用。Google Tile相关概念的介绍,这里就不详细阐述了,推荐参考这篇博客https://blog.csdn.net/mygisforum/article/details/7582449。
二、方法
Google Tile 是分层解析的,一个坐标点在不同的层级会对应到相应的网格内,这样用户可以根据实际的应用需求进行对应层级的网格解析,然后根据对应的不同网格的统计总量,统计出在空间中标准的聚合结果。
不同语言的真实坐标和网格的转换方法如下,参考网址如下:
https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_servers
java
public class slippytest {
public static void main(String[] args) {
int zoom = 10;
double lat = 47.968056d;
double lon = 7.909167d;
System.out.println("https://tile.openstreetmap.org/" + getTileNumber(lat, lon, zoom) + ".png");
}
public static String getTileNumber(final double lat, final double lon, final int zoom) {
int xtile = (int)Math.floor( (lon + 180) / 360 * (1<<zoom) ) ;
int ytile = (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
if (xtile < 0)
xtile=0;
if (xtile >= (1<<zoom))
xtile=((1<<zoom)-1);
if (ytile < 0)
ytile=0;
if (ytile >= (1<<zoom))
ytile=((1<<zoom)-1);
return("" + zoom + "/" + xtile + "/" + ytile);
}
}
C#
public PointF WorldToTilePos(double lon, double lat, int zoom)
{
PointF p = new Point();
p.X = (float)((lon + 180.0) / 360.0 * (1 << zoom));
p.Y = (float)((1.0 - Math.Log(Math.Tan(lat * Math.PI / 180.0) +
1.0 / Math.Cos(lat * Math.PI / 180.0)) / Math.PI) / 2.0 * (1 << zoom));
return p;
}
public PointF TileToWorldPos(double tile_x, double tile_y, int zoom)
{
PointF p = new Point();
double n = Math.PI - ((2.0 * Math.PI * tile_y) / Math.Pow(2.0, zoom));
p.X = (float)((tile_x / Math.Pow(2.0, zoom) * 360.0) - 180.0);
p.Y = (float)(180.0 / Math.PI * Math.Atan(Math.Sinh(n)));
return p;
}
三、应用
1.基于手机信令原始数据,统计动态人口分布
2.基于mobike 开关锁点,统计用车热门区域
3.基于手机信令数据,统计职住关系