0,0
рейтинг
7 июля 2008 в 13:25

Что делать, если ваша карта выглядит так?

Ezem.ru - Земельный участки


Приветствую, меня зовут Влад. Я ведущий разработчик проекта Ezem.ru. На картинке сверху вы видите все участки размещенные нашими пользователи в Московской области (8000+ участков). Я хочу вам рассказать как мы решили эту задачу и какие подводные камни были на нашем пути.

Главная проблема в том, что когда у нас на карте более 500 объектов — среднестатистический офисный компьютер начинает жутко тормозить и картой пользоваться становится трудновато. Помимо основной проблемы, если выводить все участки, невозможно кликнуть на какой-то конкретный маркер, а в Москве образовалась просто какая-то черная дыра :) Мы полезли смотреть, как эту задачу решили другие пользователи Google Maps API. GPS-Club: POI: Камеры скорости, Где этот дом, МирТесен, Пушкино.org (первое что пришло на ум), либо не решили проблему с «тормозами», либо просто ограничивают кол-во объектов на экране. И проблема тут скорее не в google maps api, а в самой DOM модели, которая в убийце интернета (IE 6) уж очень тормозная.

Костыли 1. Использовать стандартные средства.
Взгляд пал на GMarkerManager. Принцип его работы прост. Подгружать в DOM только те маркеры, которые мы сейчас видим на экране, тем самым уменьшая кол-во объектов DOMа и облегчая, и без того нелегкую, жизнь браузеру…
Но посмотрев более детально на документацию был немного confused:
This class is deprecated; developers are recommended to use the open sourced MarkerManager instead.



Костыли 2. Использовать сторонние средства.
Побродив по интернету и поспрашивав у прохожих, я наткнулся на замечательную библиотеку с не менее замечательным названием "MarkerManager". Принцип ее работы такой же как и у GMarkerManager, но с небольшим отличием. Там есть функции удаления всех маркеров на экране и удалении конкретного маркера. Данный костыль вменяемо работал, но только до тех пор, пока кол-во маркеров не перевалило за 3 000. Очередной камень заключался в том, что маркеры загружались при первом заходе на страницу, и на их обработку (200кб XML), на стороне клиента, уходило довольно-таки много времени. В общем, было решено жонглировать AJAX запросами и вытаскивать ТОЛЬКО маркеры видимой области и ТОЛЬКО того зума, на котором мы сейчас находимся. Данный вариант, с небольшими поправками и работает на нашем сайте.


Костыли 3. Группировка маркеров.
Как я говорил выше, чем больше у нас маркеров сконцентрировано в одной точке, — тем сложнее пользоваться картой. Действительно, попасть по какому-то конкретному маркеру, иногда, стало просто невозможно. Было принято решение уменьшить кол-во маркеров на экране и внедрить группировку маркеров на стороне сервера. Решение довольно-таки простое, но не слишком правильное. На каждый из зумов карты были подобраны правильные размеры прямоугольников (см. картинку справа) и маркеры, попадающие в эту область, помечались как дочерние и на этом зуме показывался только 1 из них. И так для каждого негруппированного маркера и для каждого зума. Плюсы этого подхода в том, что теперь стало возможно пользоваться картой. Но в этом подходе есть крупные недостатки: обсчет занимал около 12 минут и делался РАЗ в день. Мы побороли медлительность карты, но у нас встала другая проблема: так как обсчет маркеров делался раз в день, мы не могли внедрить группировку в наши фильтры. И браузер можно было легко поставить на колени, выбрав тип: «Индивидуальное жилищное строительство (только красные маркеры)» и размер участка от 0 до 50 соток.

Костыль 4. Динамическая группировка маркеров.
Мысль о том, что браузер можно поставить на колени 2-мя кликами мыши не давала нам спокойно спать и мы решили сделать более продвинутую версию группировки:

Вариант 1. Статичные квадраты
Идею подал Олег Волчков. Заранее просчитать ВСЕ возможные квадраты карты на ВСЕ возможные зумы. Сразу же оговорюсь, что коэффициент прямоугольника для каждого из зумов разный и мы считали ТОЛЬКО Россию. У нас получилось более 23 000 000 записей и база «поправилась» на 200 МБ. Преимущество этого подхода в том, что группировка маркеров проводилась более аккуратно, чем во втором варианте. Минусы в том, что данные надо было просчитать (заняло где-то одну ночь на девелоперской тачке) и уже просчитанные данные необходимо было выделить в отдельную БД, а это потянуло бы за собой некий рефакторинг.

Вариант 2. Группировка только по видимой области
Автор этой идеи Сергей Колчин. Каждый раз, когда мы двигаем карту, мы передаем на сервер координаты видимой нам области, — так почему-же не делить только этот прямоугольник и группировать маркеры в реальном времени? Минусом в этом случае является то, что при смещении на небольшие расстояния маркеры будут немного смещаться. Это мы посчитали некритичной проблемой потому-что, во-первых: маркеры не настолько сильно смещаются, во-вторых: пользователь обычно сразу приближает интересующий его участок, а не путешествует по карте. Этот вариант, ввиду того что он проще и работает быстрее 1-го и используется у нас на сайте по сей день.

Немного концептуального кода:

Пример запроса: http://ezem.ru/gmap/getmarkers/?appoi..

Подхаченный markermanager
/* Copyright (c) 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Version: 1.0
 * Author: Doug Ricket, others
 *
 * Marker manager is an interface between the map and the user, designed
 * to manage adding and removing many points when the viewport changes.
 *
 *
 * Algorithm: The MM places its markers onto a grid, similar to the map tiles.
 * When the user moves the viewport, the MM computes which grid cells have
 * entered or left the viewport, and shows or hides all the markers in those
 * cells.
 * (If the users scrolls the viewport beyond the markers that are loaded,
 * no markers will be visible until the EVENT_moveend triggers an update.)
 *
 * In practical consequences, this allows 10,000 markers to be distributed over
 * a large area, and as long as only 100-200 are visible in any given viewport,
 * the user will see good performance corresponding to the 100 visible markers,
 * rather than poor performance corresponding to the total 10,000 markers.
 *
 * Note that some code is optimized for speed over space,
 * with the goal of accommodating thousands of markers.
 *
 */

Файл большой, и я не стал его выкладывать. Вы можете его посмотреть по ссылке http://ezem.ru/js/gmap/markermanager.js


Функция обработчик

    public function getmarkersAction()
    {
        $params = array();
        foreach (array('zoom', 'area_min', 'area_max', 'units') as $k) {
            $params[$k] = (int)$this->_getParam($k, 0);
        }
        foreach (array('lat1', 'lat2', 'lng1', 'lng2') as $k) {
            $params[$k] = round((float)$this->_getParam($k, 0.0), 4);
        }
        $params['no_groups'] = ('true' == $this->_getParam('no_groups', null));
        $params['deal_type'] = ('sell' == $this->_getParam('deal_type', null)) ? 'sell' : 'buy';
        $params['appointment'] = explode(',', trim($this->_getParam('appointment', '')));
        $params['except_objects'] = explode(',', trim($this->_getParam('except_objects', '')));

        $dbWhere = Medialab_Items::getActiveItemsLimits();
        if (@$this->user->id) {
            $dbWhere = array('(('.implode(' AND ', $dbWhere).') OR o.uid = '.$this->user->id.')');
        }
        $dbWhere[] = "`deal`.`type` = '".$params['deal_type']."'";
        $dbWhere[] = '`marker`.`is_polygon` = 0';

        $markers = Medialab_Gmap_Marker::getMarkersDynamic($params, $dbWhere);

        $qty = 0;
        $s = "<m>\n";
        foreach ($markers as $marker) {
            $isGroup = (1 < $marker['qty']);
            $s .= '<m i="'.$marker['id'].'" '
                .'o="'.$marker['object_id'].'" ' <BR />
                .'t="'.$marker['lat'].'" ' 
                .'g="'.$marker['lng'].'" ' 
                .'q="'.$marker['qty'].'" ' 
                .'a="'.($isGroup ? 'group' : $marker['appointment_type']).'"/>'."\n";
            $qty += $marker['qty'];
        }
        $s .= '<info count="'.$qty."\"/>\n";
        $s .= '</m>';

        header('Content-Type: text/xml; charset=windows-1251');
        exit($s);
    }


УБЕРИТЕ BR из кода. Пришлось его вставить, иначе хабрапарсер глючит. Не знаю почему, но без него он вытягивает кусок кода в одну строку и появляется скроллинг.

Класс, который занимается всем грязным :)
class Medialab_Gmap_Marker
{
    /* *
     * Размер блока в градусах для масштаба 0.
     * 72x128 задаёт 6x6 блоков в видимой области
     * 64x96 -- 8x8
     * * */
    public static $blockSize = array(
        'lat'  => 64.0,
        'lng'  => 96.0
    );

    /**
     * Calculates map block dimensions for the provided zoom
     *
     * @param int $zoom Map zoom
     * @return array Block dimensions in lat/lng
     */
    public static function getBlockSize($zoom = 10)
    {
        $rect = array();
        foreach (array('lat', 'lng') as $k) {
            $rect[$k] = round(self::$blockSize[$k] / (1 << $zoom), 4);
            $rect[$k.'_half'] = round($rect[$k] / 2, 4);
        }
        return $rect;
    }

    /**
     * Fetches markers for visible map area, dynamically grouping them if needed
     *
     * @param array $params Array of search params, provide at least (lat, lng) pairs
     *                      for top left/bottom right corners, and current zoom.
     * @param array $dbWhere Additional SQL query conditions (optional)
     * @return array Found items
     *
     * TODO: SW/NE corners instead of top left/bottom right for better consistence w/ Google Maps API
     */
    public static function getMarkersDynamic(array $params, array $dbWhere = array())
    {
        $block = self::getBlockSize($params['zoom']);

        $dbWhere[] = '(`marker`.`lat` BETWEEN '.$params['lat1'].' AND '.$params['lat2'].')';
        // Longitude 180 -> -180 degrees wrap workaround
        if ($params['lng2'] < $params['lng1']) {
            $dbWhere[] = '((`marker`.`lng` BETWEEN '.$params['lng1'].' AND 180.0) OR (`marker`.`lng` BETWEEN -180.0 AND '.$params['lng2'].'))';
        } else {
            $dbWhere[] = '(`marker`.`lng` BETWEEN '.$params['lng1'].' AND '.$params['lng2'].')';
        }
        if (($params['area_min'] || $params['area_max']) && $params['units']) {
            $unit = DB::FindFirst('ezem_units', array('rate'), array('id' => $params['units']));
            if ($params['area_min']) {
                $dbWhere[] = '`o`.`area` >= '.($params['area_min'] * $unit['rate']);
            }
            if ($params['area_max']) {
                $dbWhere[] = '`o`.`area` <= '.($params['area_max'] * $unit['rate']);
            }
        }
        $a = $params['appointment'];

        if (count($a) && $a[0]) {
            $dbWhere[] = "`appointment`.`type` IN ('".implode("', '", $a)."')";
        }
        $a = $params['except_objects'];
        if (count($a) && $a[0]) {


            $dbWhere[] = '`o`.`id` NOT IN ('.implode(', ', $a).')';
        }

        $dbGroupBy = '`marker`.`id`';
        if (($params['zoom'] < 13) && !$params['no_groups']) {
            // Group only for zooms <= 12 and with no 'no_groups' flag set
            $dbGroupBy = '`grp_lat`, `grp_lng`';
        }

        $query = '
            SELECT
                `marker`.`id`,
                `marker`.`object_id`,
                `appointment`.`type` AS `appointment_type`,
                AVG(`marker`.`lat`) AS `lat`,
                AVG(`marker`.`lng`) AS `lng`,
                FLOOR((`marker`.`lat` - '.$params['lat1'].') / '.$block['lat'].') AS `grp_lat`,
                FLOOR((`marker`.`lng` - '.$params['lng1'].') / '.$block['lng'].') AS `grp_lng`,
                COUNT(`marker`.`id`) AS `qty`
            FROM
                `ezem_gmap` AS `marker`
                JOIN `ezem_object` AS `o` ON (`o`.`id` = `marker`.`object_id`)
                JOIN `ezem_appointment` AS `appointment` ON (`appointment`.`id` = `o`.`appointment_id`)
                JOIN `ezem_deal` AS `deal` ON (`deal`.`id` = `o`.`deal_id`)
            WHERE
                '.implode(' AND ', $dbWhere).'
            GROUP BY
                '.$dbGroupBy;
        return DB::Query($query);
    }
}


Портал реализован на Zend Framework, Smarty, Yandex Server и Jquery. Работающий пример того, о чем я говорил, можно посмотреть у нас на сайте.

p.s. В планах на ближайшее будущее: добавить поддержку полигонов и заменить Yandex search на sphinx, но об этом уже в следующих статьях.
p.p.s Мы до сих пор ищем толковых программистов.
Владислав Комиссаров @Mastyf
карма
79,1
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое

Комментарии (81)

  • 0
    познавательно, спасибо.
    • 0
      вот только не понял, "Что делать, если ваша карта выглядит так?" ? если отмечено миллион флажков на карте, то что с ними делаете Вы, отображаете N штук и все?
      • +1
        Если вы посмотрите на рабочий пример - то увидите желтенькие группировочные маркеры и по клику на него у вас появится список маркеров в этой области.
        • 0
          понял
        • 0
          мне сразу попались несколько «группировочных» маркеров с одной записью в каждом. Глюк?
          • 0
            2 одинаковых на одном экране?
            • 0
              нет, в каждом было написано «найдено 1 предложение», предложения были разные, и сейчас не воспроизводится : (
        • 0
          Смените, а то кладбище какое то..
    • 0
      альтернативиное название статьи - как раскукожить объекты на гугль мапс
  • 0
    Привет, Влад ;-)
    Мне нравится, что проект сделан "с душой"
    По поводу карты - да, немного напргает подгрузка маркеров, если двигаться по карте. Но если это не так часто происходит, то конечно можно пренебречь. Или не "затенять" карту при подгрузке, чтобы это не так сильно бросалось в глаза.
    • 0
      Тут мы сделали упор на скорость, так как самый чистый вариант с "постепенной" загрузкой маркеров довольно-таки ресурсоемкий. А мы все-таки ориентируемся на регионы и слабые офисные компьютеры.
      • +1
        Вы забыли посмотреть как проблема реализована в самом продвинутом по части жонглировании обьектов сайте - викимапии.
        Если коротко - у них запрос обьектов изначально производиться по секторам. Сектор соотвествует по своим размерам картинке сегмента карты и позиционируется также.
        Это к тому же позволяет влет кэшировать эти запросы и обслуживать кучу народа.
        А у вас - чуть сдвинул карту и пошла ОЧЕНЬ не хилая нагрузка на сервер.
        А у меня(я не викимапия) - "за последние 24 часа было запрошено 478040 уникальных сегментов карты"
        Сортировка выдачи производиться просто - 100 самых больших обьектов.
        А ваша "уж больно регулярная" карта мне не понравилась.
        Хотя, если честно , попробую часть вашего подхода себе поставить. А то с картинками на карте труба иногда
        • 0
          Тот способ, который реализован в викимаии у нас называется Статичные квадраты.

          Когда проводили тестирование, вариант с динамической группировкой оказался быстрее статичных квадратов. Объяснение этому простое - лишняя нагрузка на БД и табличка с 23+ кк записей.
          • +3
            Эээ нет, вы меня не поняли.
            Какраз нагрузка на сервер становиться сильно меньше
            Способ ЗАГРУЗКИ обьектов в викимапии подразумевает подгрузку карты "статическими квадами" В одном кваде они до 400 обьектов передают.
            Сортировка и выдача 100 нужных - на клиенте.
            Адресс сегмента также говорит на каком зуме показать надо.
            Не требуется хранить 23+кк секторов.
            Глянул в кеш мемкешеда.. есть - отдал, или переживал и отдал.
            Нету - сгенерил и отдал. И положил в кеш - ну на неделю например.
            Генериться квад быстро. Берется из кеша сильно быстрее.

            А что у вас - сдвинул карту и на секунду-две-три подвис непонятно зачем.
            Вы бы хоть управление оставляли, подгружая обьекты в фоне.

            Еще раз скажу - это не способ хранения обьектов. Хотя по адрессу квадтри очень удобно делать выборку.
            Это не способ борьбы с наложением одних обьектов на другие.
            Это адресация клиентом серверных данных.

            у вас - ОДИН запрос на сервер с данными
            lat1 55.522411831398216
            lat2 55.98762792516235
            lng1 37.2216796875
            lng2 38.0126953125

            за 281мсек

            чуть сдвинул - другой запрос
            надо - 4 или больше запросов по размерам и положениям квадов данного зума.
            Получаем 4 запроса за 80-150мсек. Которые выполняются паралельно...
            Чуть сдвинул -ничего не меняется.
            Чуть более сдвинул - ничего не меняется.
            И только если сдвинул на 128 и больше пикселей - подгружаются сегмент. Один-два-три или более.

            Тоесть в вашем случае можно даже ничего не менять.
            Просто попросить клиент малек по другому данные фетчить.
            Итого реальное колличество запросов на сервер - упадет.
            Потому что - карта загрузилась и сразу запросила много много сегментов.. - можно отдать из кеша - адресса, параметры, а значит и данные неизменны..
            а потом вал запросов от клиента прекращается.

            Сейчас у вас мало народа на сайте. Особенно если хабр эффект вычесть.
            Но когданить он будет. Пожалейте сервер. Не насилуйте его
            • 0
              при очень больших обьемах данных есть смысл вообще генерировать тайлы и подставлять их как оверлеи, нагрузка на сервер при генерации картинок конечно будет больше, но отдавать надо будет по сути только статику
              • 0
                Простите, но у нас АКТИВНЫЕ обьекты на карте :)
                • 0
                  Ну это понятно, я не говорю, что в вашем случае это идеальное решение.
                  Хотя по клику на карте ничто не мешает вам отрисовать маркер поверх картинки и показать у него infowindow. Координаты клика то у вас есть.
                  • 0
                    не захочу я кликать на то что без HINTа...
                    решение, типа как вы говорите, используется гуглом в слое панорамио + карта этих самых кликов.
                    но у них именно что картиночная задача
                    • 0
                      Не бывает на 100% идеальных решений.
            • 0
              Благодарю за разъяснение. Решение интересное.
              • +1
                Если угодно могу скинуть клиентские и серверные коды по адресации сегментов.
                Честно декодированные с викимапии :)
                • 0
                  Буду примерно благодарен.

                  mastyf (гав гав гав) gmail.com
                • 0
                  И мне, и мне. bolter.fire (вызнаетечто) гмэйл.ком
                  Заранее спасибо.
                • 0
                  Мож мне на эту тему пост создать?
                  • 0
                    Где пост?
                    Или опять на мыло?
                    • 0
                      пост(две чтук) будут сегодня
            • 0
              Т.е если я сдвинул на 120 пикселей и увидел свой дом, то на ним все равно ничего не прорисуется т.к. до 128 не дотянул?
              Ну и у мемкэша есть такая особенность, что они иногда случается падает, и тогда надо заново генерить весь кэш, а если он упадет в пик посещаемости?
              Все-таки в геопроектах лучше не пытаться запускать ракеты на дизельном топливе, есть специальные геосервера со своим внутренним кэшем. Мы, например, использовали Spatial DB в связке с VE, очень удобно и практично.
              • 0
                мемкешед падает? Обновите версия сервера\клиента - у ЖЖ он почемуто не падает.
                +У меня три кешеда запушено. Если упадет один - переживу.
                Если вы сдвинете карту на 120 пикселей - вы увидите свой дом. Потому что раз мааааленький кусочек этого дома был виден - подгрузился весь сегмент.
                И только когда сдвинете малек больше - увидите сарай за домом, точнее подгрузиться новый сегмент
  • 0
    Я даже испугался, увидев это) Статья интересная, спасибо
  • 0
    Хмм, еще один способ есть.
    Показывают наиболее популярные точки в зависимости от зума, а при приближении показывать менее приоритетные в данной зоне. Загвоздка только одна как определить наиболее популярные для конкретного пользователя, но и это решаемо=)
    • +1
      Ну согласитесь, в нашем случае эту систему не внедрить :)
    • 0
      На Автокадабре сделано таким образом. Есть фильтр по интересности и он меняется при зумме. Кроме этого подгружаются только те объекты, которые видны + ещё немного за краями карты, что бы они отображались сразу, когда пользователь немножко двигает карту
  • 0
    Класс. До примерно половины из этого я дошёл сам, но группировку маркеров сделать так и не успел. Теперь видимо возьмусь заново.
  • 0
    Иногда маркеры не группируются. Если немного удалить, когда в сгруппированном маркере много других маркеров и нажать "Показать эту область"
    • 0
      Так и задумано. Представляете что будет, если пользователь кликнув на группировочный маркер кликнет на "Посмотреть эту область" и увидит еще несколько группировочных маркеров? :)
    • 0
      Так и задумано: начиная с определённого масштаба по ссылке "показать эту область" показываем все найденные маркеры без группировки.
  • 0
    $dbWhere - отправляется в вашу бд?
    • 0
      Приведён не весь код, на самом деле :-)
  • 0
    Если не сложно, объясните смысл использования только статичных методов и свойств в классе Medialab_Gmap_Marker.
    • 0
      Не видели смысла использовать не статичные методы и классы.
      • 0
        Я начинаю чувствовать, что это как ООП vs. «не ООП» :-)
    • +3
      тут, видимо, класс выполняет роль namespace'a
  • 0
    Уменьшите до масштаба, когда в группу попадает хотя-бы 500 объектов (а "лучше" 1000), кликните на нее и выберите "посмотреть эту область". Догадываюсь, что результат будет не такой, какой Вы ожидали.
    Это баг или фича?
    • 0
      И еще, в половине случаев, когда я клацаю на фишку, карта сдвигается, чтобы отобразить попап. В "новой" части карты не прорисовываются объекты.
    • 0
      К сожалению, это вынужденная мера. А то клиенту придется прорисоывать несколько тысяч маркеров :)

      p.s. Мы ввели ограничение с какого зума можно отключить группировку.
  • +1
    Хаха медиалабовсской движок)) ну норм статья + еще один способ
    • 0
      Если бы видели в каком состоянии был движок Медиалаба когда мы начали работу над ним - вы бы так не радовались :)
      • 0
        он был в нормальном состоянии хотя я хз чо было до меня я в лабе не долг работаю с февраля
  • +2
    Может я скажу сейчас ужасную вещь, но есть flash компоненты и сервисы для работы с картами.
    например http://www.umapper.com/
    даже без тестов могу сказать, что на 200кб xml флеш не подавится :)
    • 0
      забыл ссылку на сам компонент - http://afcomponents.com/components/umap_as3/
      думаю, если погуглить, найдутся аналоги и для google maps, если это принципиально
    • 0
      Идея интересная, спасибо.
    • 0
  • 0
    Спасибо за статью.
    Небольшое не замечание, но предположение.
    Кликаем на группе, если облачко не помещается, то карта сдвигаеся, но объекты на открывшемся участке не обновляются. Может попробовать после закрытия облачка обновить карту?
    • 0
      Тогда есть вариант, что маркер который вы только что открыли, упрыгает на пару сантиметров :)
      • 0
        А ведь на раз :)
        Может текущее решение и есть наименьшее из зол :) А может мне нормальных идей в голову не приходит :)
  • 0
    Кроме вышеупомянутых российских проектов, есть зарубежные, успешно решившую такую проблему. Например, realestate.com.au.
  • –2
    ...и облегчая, и без того нелегкую, жизнь браузеру //не понравилась структура предложения. Как будто после облегчения она может стать тяжелее. Да и распространенное определение не обособляется, если стоит до определяемого слова.
  • +1
    По-моему было бы логичнее разбивать не на квадраты, а на круги и делать группировку по радиусу окружности.
    Сами сталкивались с такими граблями, по сути пришли к схожему по логике решению, но у нас группировка была на всех уровнях до тех пор, пока количество маркеров не становилось разумным.
    Кстати, хинт, попробуйте передавать данные не в XML, XML-parser в IE - ужасно тормознутое исчадие ада. Предлагаю попробовать JSON, например.
    • 0
      Был прототип и на JSON. Разницы в скорости не заметили.
      • 0
        У меня еще пара вопросов:
        1. var isFirstLoaded = 1;
        т.е. JS у вас расчитан только на один инстанс карты на странице?
        2. Я так понял, при перемещении карты, у вас все маркеры отрисовываются заново, так?
        Я осмелюсь предложить вам такой способ, при перемещении карты строго влево\вправо или вниз\вверх, брать bounds старого окна, и высчитывать разницу с новым окном. Тоесть если ваш вьюпорт имеет размер 200х200 и latitude скажем (0, 20), то при перемещении вправо на 10 пикселей вам не надо брать заново всю зону (1, 21) хотя было бы разумнее не стирать старые маркеры, а просто запросить новые по квадрату (20, 21)
    • 0
      Я наверное опять со своей викимапией влезу.. но чем вам не нравиться plain/text(csv)?
      Вы же передаете регуляные, абсолютно табличные данные
      • 0
        мне - нравится, я как вариант предложил. Как альтернативу XML.
        • 0
          Вы предложили JSON который тоже малек избыточен для задач подгрузки обьектов.
          • 0
            Самый идеальный способ в плане оптимизации в таком случае - это подгружать уже готовые .js файлы с созданными внутри них обьектами. Все остальные способы оставляют накладные расходы.
  • 0
    было бы юзаьельней если бы вместо плюсика на маркере было число объектов в группе

    п.с. перезагрузка карты после каждого передвижения очень раздражает
  • 0
    эээ... а что мешало использовать стандартный пример из API

    http://gmaps-utility-library.googlecode.…

    ?
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Ибо машинным способом определить налазят ли N объектов друг на друга потребудет от нас примерно N^2 операций.
        С чего вдруг ? За O(N log N) она вполне решается. Диаграмма Воронова => Триангуляция Делоне => кандидаты на объединение...
        • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Не наш случай — в этом примере вообще нет группировки, все маркеры заранее разбрасываются по отрезкам масштаба.
  • +1
    Побольше бы таких сайтов, где думают о загрузке пользовательского ПК. А то поназапускают какие-нить пионеры JavaScript снежинок и другой дребедени...
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Вы самого главного не сказали — кластеры считаются динамически или генерятся заранее? Впрочем, несколько тысяч — наверное, можно и на лету. Не оценивали, сколько времени уходит на кластеризацию на минимальном масштабе?
  • 0
    как решение можно забивать координаты маркеров скриптом на сервере в масив яваскрипа, ну, в смысле генерировать кусок яваскрипта на сервере. не сестировал на больших обьемах, но работает быстро и клиента не нагружает.
  • –1
    Там исправьте "Работающий пример того, о чем я говорил, можно посмотреть у нас на сайте.", на "Неработающий пример того, о чем я говорил, можно посмотреть у нас на сайте.", потому что работающий пример явно не работает.
  • 0
    я ноутбуки чаще меняю...... как можно googleearth с одного компа на другой перекинуть?
  • 0
    Вот мой вариант реализации динамической группировки большого количества данных на карте: http://www.australia.com/Search.aspx?q=w…

    Обращение к серверу происходит только один раз, так ка находиться не очень большое количество данных одновременно.
    Производиться динамическая группировка маркеров в отличие от зума карты, при этом всплывающее окно окно переделывается в список, содержащий сгруппированные элементы.

    Если кому интересно, исходники вот здесь: http://www.australia.com/js/TaMultimap.j…
    Код реализован как расширение класса GMap2.
  • 0
    Есть вопрос! Нужно делать почти такое же но с областями покрытия. К примеру, области отображаются кругами (реализуется через GPolygon), естественно их размеры пропроциональны масштабу, т.е. покрывает одну и ту же площадь земной поверхности, не так как у маркеров(размер маркера всегда один и тот же не зависимо от масштаба).
    Так вот, задача состоит в том если на карте нанесено огромное количество таких областей, как их объединить в группу или аппроксимировать, чтобы не нагружать пользовательскую машину. Эксперимент для 10000 областей положил браузер на 5 минут....
  • 0
    Сразу же оговорюсь, что коэффициент прямоугольника для каждого из зумов разный и мы считали ТОЛЬКО Россию.


    Эта проблема не сложно решается для карт с проекцией сферического Меркатора типа Яндекса и Гугла;)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.