计算谷歌地图缩放级别n的图块大小

发布于 2024-10-21 12:16:02 字数 2928 浏览 4 评论 0原文

嘿。我有一个使用谷歌地图的地图应用程序。我得到了地图上的边界,然后在此基础上做了一些聚类标记,但是为了能够使聚类保持在同一个位置,我想知道如何使我通过的边界捕捉到谷歌使用的tilegrid。他们用于地图的四叉树算法本质上是我要求的是

如何获得视口所在图块的边界。我试图说明它:) googletilesviewportcluster

如果我在图块边界而不是视口上进行集群计算,当我将其分割为网格时,簇将保留在同一位置,因为网格在每个缩放级别都是绝对的。

此外,这还允许更好的查询缓存,因为当边界必须“捕捉”到图块时,查询将非常相似,并且用户将能够平移已经显示的邻近标记。

更新

我要重新开始...

我已经有了这个

    function TileMyBounds($sx, $sy, $nx, $ny, $zoom)
{

        function TileMyBounds($sx, $sy, $nx, $ny, $zoom)
{
    list($nmx,$nmy) = $this->LatLonToMeters($ny/1000000, $nx/1000000);
    list($ntx, $nty) = $this->MetersToTile($nmx, $nmy, $zoom);
    $nbounds = $this->TileLatLonBounds($ntx, $nty, $zoom);
    list($smx,$smy) = $this->LatLonToMeters($sy/1000000, $sx/1000000);
    list($stx, $sty) = $this->MetersToTile($smx, $smy, $zoom);
    $sbounds = $this->TileLatLonBounds($stx, $sty, $zoom);

    $step = ($sbounds[3]-$sbounds[1])*1000000;

    return array($sbounds[0]*1000000, $sbounds[1]*1000000, $nbounds[2]*1000000, $nbounds[3]*1000000, $step);
}

,我使用它的函数如下所示:

function clusterGrid($zoom,$nelt,$nelg,$swlt,$swlg)
    {
    $singlemarkers = array();
    $clusters = array();

list($swlg, $swlt, $nelg, $nelt, $step) = $this->TileMyBounds($swlg, $swlt, $nelg, $nelt, $zoom);
$calcbounds = $this->TileMyBounds($swlg, $swlt, $nelg, $nelt, $zoom);
$queryconcat = "";
$length_lng = ceil(($nelg-$swlg)/$step);
$length_lat = ceil(($nelt-$swlt)/$step);
$orgnelg = $nelg;
$orgswlt = $swlt;

for($i=0;$i < $length_lng + 1; $i++) {
    $nelg -= $step;
    $temp_swlt = $swlt;

    for($j=0; $j < $length_lat + 1; $j++) {

        $temp_swlt += $step;

        if($nelg > $orgnelg) continue;
        if($temp_swlt > $nelt) continue;
        if($nelg < $swlg) continue;
        if($temp_swlt < $orgswlt) continue;

        $q = $this->db->select('
            COUNT(*) AS CO,
            (MAX(lat)+MIN(lat))/2 AS lat,
            (MAX(lng)+MIN(lng))/2 AS lng')
        ->where('`lat` BETWEEN '.$temp_swlt.' AND '.($temp_swlt+$step).' AND 
            `lng` BETWEEN '.($nelg-$step).' AND '.$nelg)
        ->get('markers');
        $queryconcat += $this->db->last_query(); 
        $result = $q->row_array();

        if($result['CO'] == 0) {
            continue;
        }
            $clusters[] = array('lat' => ($result['lat']), 'lng' => ($result['lng']), 'size' => $result['CO']);
        }
    }
return array('singlemarkers' => '', 'clustermarkers' => $clusters, 'bounds' => $calcbounds, 'lengths' => array($length_lng, $length_lat));  
}

更新!!!! 12/03/2011 - 快到了 这些图块有些精确,但并不完全精确,因此在平移时,簇可以稍微“移动”。由于 $step = ($sbounds[3]-$sbounds[1])*1000000; 计算在每个缩放级别并不总是相同,正如我所期望的那样,因为我认为一个图块在纬度和经度上与任何其他相同缩放级别的图块具有相同的宽度和长度。

Hey. I have a maps application that uses google maps. I get the bounds off the map, and then I do some clustering markers on that grounds, but to be able to have the clusters stay at the same place, I'd like to know how to make the boundaries that I pass snap into the tilegrid that google uses. The quadtree algorithm they use for their map essentially what I'm asking for is

how do I get the bounds for the tiles that the viewport is in. I've tried to illustrate it :)
google tiles viewport cluster

If I do the cluster calc on the tile bounds and not the viewport, when I split it up in a grid, the clusters will stay in the same place, because the grid will be absolute at each zoom level.

Also this allows for better query caching, as the queries will be a lot similar when the bounds have to "snap in" to the tiles, AND the user will be able to pan with markers in proximity being displayed already.

UPDATE

I'm starting over...

I've got this

    function TileMyBounds($sx, $sy, $nx, $ny, $zoom)
{

        function TileMyBounds($sx, $sy, $nx, $ny, $zoom)
{
    list($nmx,$nmy) = $this->LatLonToMeters($ny/1000000, $nx/1000000);
    list($ntx, $nty) = $this->MetersToTile($nmx, $nmy, $zoom);
    $nbounds = $this->TileLatLonBounds($ntx, $nty, $zoom);
    list($smx,$smy) = $this->LatLonToMeters($sy/1000000, $sx/1000000);
    list($stx, $sty) = $this->MetersToTile($smx, $smy, $zoom);
    $sbounds = $this->TileLatLonBounds($stx, $sty, $zoom);

    $step = ($sbounds[3]-$sbounds[1])*1000000;

    return array($sbounds[0]*1000000, $sbounds[1]*1000000, $nbounds[2]*1000000, $nbounds[3]*1000000, $step);
}

and the function where I use it looks like this:

function clusterGrid($zoom,$nelt,$nelg,$swlt,$swlg)
    {
    $singlemarkers = array();
    $clusters = array();

list($swlg, $swlt, $nelg, $nelt, $step) = $this->TileMyBounds($swlg, $swlt, $nelg, $nelt, $zoom);
$calcbounds = $this->TileMyBounds($swlg, $swlt, $nelg, $nelt, $zoom);
$queryconcat = "";
$length_lng = ceil(($nelg-$swlg)/$step);
$length_lat = ceil(($nelt-$swlt)/$step);
$orgnelg = $nelg;
$orgswlt = $swlt;

for($i=0;$i < $length_lng + 1; $i++) {
    $nelg -= $step;
    $temp_swlt = $swlt;

    for($j=0; $j < $length_lat + 1; $j++) {

        $temp_swlt += $step;

        if($nelg > $orgnelg) continue;
        if($temp_swlt > $nelt) continue;
        if($nelg < $swlg) continue;
        if($temp_swlt < $orgswlt) continue;

        $q = $this->db->select('
            COUNT(*) AS CO,
            (MAX(lat)+MIN(lat))/2 AS lat,
            (MAX(lng)+MIN(lng))/2 AS lng')
        ->where('`lat` BETWEEN '.$temp_swlt.' AND '.($temp_swlt+$step).' AND 
            `lng` BETWEEN '.($nelg-$step).' AND '.$nelg)
        ->get('markers');
        $queryconcat += $this->db->last_query(); 
        $result = $q->row_array();

        if($result['CO'] == 0) {
            continue;
        }
            $clusters[] = array('lat' => ($result['lat']), 'lng' => ($result['lng']), 'size' => $result['CO']);
        }
    }
return array('singlemarkers' => '', 'clustermarkers' => $clusters, 'bounds' => $calcbounds, 'lengths' => array($length_lng, $length_lat));  
}

UPDATE!!!! 12/03/2011 - Almost there
The tiles are somewhat precise, yet not entirely, so when panning around, the clusters can "move around" a little. Due to the fact that the $step = ($sbounds[3]-$sbounds[1])*1000000; calculation is not always the same at each zoom level, as I would've expected because I would think that a tile would have the same width and length in lat and lon as any other tile at the same zoom level.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

作妖 2024-10-28 12:16:02

但是有些事情不太对劲。谁能告诉我为什么当我传入 swlg、swlat、nelg、nelat 和缩放级别时没有获得视口坐标

您想首先用所有 4 个边界坐标求解空间填充曲线方程。

list($lng, $lat) = array ($row['lng'], $row['lat']);
list($mx, $my) = $mercator->LatLonToMeters($lat, $lng);
list($tx, $ty) = $mercator->MetersToTile($mx, $my, MAXZOOM);
list($tx, $ty) = array ($tx, ((1 << MAXZOOM) - 1) - $ty );
list($minx, $miny) = $this->PixelsToMeters( $tx*$this->tileSize, $ty*$this->tileSize, $zoom );
list($maxx, $maxy) = $this->PixelsToMeters( ($tx+1)*$this->tileSize, ($ty+1)*$this->tileSize, $zoom );
return array($minx, $miny, $maxx, $maxy);

list($lng, $lat) = array ($row['lng'], $row['lat']);
list($mx, $my) = $mercator->LatLonToMeters($lat, $lng);
list($tx, $ty) = $mercator->MetersToTile($mx, $my, MAXZOOM);
list($tx, $ty) = array ($tx, ((1 << MAXZOOM) - 1) - $ty );
$bounds = $this->TileBounds($tx, $ty, $zoom);
list($minLat, $minLon) = $this->MetersToLatLon($bounds[0], $bounds[1]);
list($maxLat, $maxLon) = $this->MetersToLatLon($bounds[2], $bounds[3]);
return array($minLat, $minLon, $maxLat, $maxLon);

编辑:问题已解决。 OP在私人邮件中回复:

But something's not quite right. Can anyone tell why I'm not getting the viewport coordinates when I pass in swlg,swlat,nelg,nelat and the zoom level

You want to solve the space-filling-curve equation first with all 4 bounds coordinates.

list($lng, $lat) = array ($row['lng'], $row['lat']);
list($mx, $my) = $mercator->LatLonToMeters($lat, $lng);
list($tx, $ty) = $mercator->MetersToTile($mx, $my, MAXZOOM);
list($tx, $ty) = array ($tx, ((1 << MAXZOOM) - 1) - $ty );
list($minx, $miny) = $this->PixelsToMeters( $tx*$this->tileSize, $ty*$this->tileSize, $zoom );
list($maxx, $maxy) = $this->PixelsToMeters( ($tx+1)*$this->tileSize, ($ty+1)*$this->tileSize, $zoom );
return array($minx, $miny, $maxx, $maxy);

or

list($lng, $lat) = array ($row['lng'], $row['lat']);
list($mx, $my) = $mercator->LatLonToMeters($lat, $lng);
list($tx, $ty) = $mercator->MetersToTile($mx, $my, MAXZOOM);
list($tx, $ty) = array ($tx, ((1 << MAXZOOM) - 1) - $ty );
$bounds = $this->TileBounds($tx, $ty, $zoom);
list($minLat, $minLon) = $this->MetersToLatLon($bounds[0], $bounds[1]);
list($maxLat, $maxLon) = $this->MetersToLatLon($bounds[2], $bounds[3]);
return array($minLat, $minLon, $maxLat, $maxLon);

EDIT: Problem is solved. OP answered in private Mail:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文