рассчитать размер плитки карты Google на уровне масштабирования n - PullRequest
3 голосов
/ 11 марта 2011

Эй. У меня есть приложение карт, которое использует карты Google. Я получаю границы с карты, а затем делаю некоторые кластерные маркеры на этом основании, но чтобы кластеры оставались на одном месте, я хотел бы знать, как сделать так, чтобы границы, которые я передаю, привязывались к Tilegrid, который использует Google. Алгоритм quadtree, который они используют для своей карты, по сути, я спрашиваю:

как получить границы для плиток, в которых находится окно просмотра. Я попытался проиллюстрировать это :) google tiles viewport cluster

Если я выполню расчет кластера по границам плитки, а не по области просмотра, то, когда я разделю ее на сетку, кластеры останутся на том же месте, потому что сетка будет абсолютной на каждом уровне масштабирования.

Также это позволяет улучшить кэширование запросов, так как запросы будут очень похожи, когда границы должны «привязываться» к плиткам, и пользователь сможет панорамировать с маркерами в близости, которые уже отображаются.

UPDATE

Я начинаю сначала ...

У меня есть это

    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));  
}

UPDATE !!!! 03.12.2011 - Почти там Плитки несколько точны, но не полностью, поэтому при панорамировании кластеры могут немного «двигаться». Из-за того, что вычисление $step = ($sbounds[3]-$sbounds[1])*1000000; не всегда одинаково на каждом уровне масштабирования, как я и ожидал, потому что я подумал бы, что плитка будет иметь такую ​​же ширину и длину в широте и долготе, как и любая другая плитка в тот же уровень масштабирования.

1 Ответ

1 голос
/ 11 марта 2011

Но что-то не так. Может кто-нибудь сказать, почему я не получаю координаты области просмотра, когда я передаю в swlg, swlat, nelg, nelat и уровень масштабирования

Сначала вы хотите решить уравнение кривой заполнения пространства со всеми четырьмя координатами границ.

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);

РЕДАКТИРОВАТЬ: Проблема решена. ОП ответил в личной почте:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...