Проблема с большим количеством маркеров на карте

Я работаю над приложением для Android, которое уже существует на iPhone.

В приложении есть действие Map, в котором (я насчитал) около 800 маркеров в четырех группах, помеченных для рисования четырьмя разными цветами. Каждая группа может быть включена или выключена. Информация о маркерах у меня внутри Списка. Я создаю mapOverlay для каждой группы, затем прикрепляю это наложение к карте. Я твердо верю, что кодирование часть я сделал правильно. Но я все равно прикреплю свой код...

Дело в том, что мой Nexus One не может обрабатывать карту со всеми этими маркерами. На рисование 500 маркеров уходит около 15 секунд. Затем, когда все нарисовано, карта не совсем гладкая. Это довольно трудно масштабировать и перемещаться. Это можно сделать, но опыт плохой, и я хотел бы посмотреть, можно ли там что-то сделать. Я знаю, если бы я избегал преобразования String > Double, я мог бы сэкономить некоторое время, но сомневаюсь, что это будет значительным.

У iPhone, похоже, нет проблем с отображением всех этих маркеров. Чтобы показать их все, требуется примерно 1-2 секунды, а масштабирование и панорамирование не так уж и плохи. Замедление заметно, но все же приемлемо. Я лично считаю, что не стоит рисовать все эти маркеры, но приложение разработано кем-то другим, и я не собираюсь вносить какие-либо радикальные изменения.

Я не уверен, что делать здесь. Кажется, мне придется придумать другую функциональность, возможно, использовать местоположение GPS, если оно известно, и рисовать только маркеры в пределах некоторого радиуса, или, если местоположение не известно, использовать центр экрана (карту) и рисовать маркеры вокруг него. У меня будет разумное объяснение моим начальникам, если я сделаю эти изменения.

Я ценю, есть ли у кого-нибудь иды.

И код:

    List<Overlay> mapOverlays = mapView.getOverlays();
    Drawable drawable = this.getResources().getDrawable(R.drawable.pin_blue);
    drawable = this.getResources().getDrawable(R.drawable.pin_blue);
    ArrList = appState.GetSleepArrList();
    ItemizedOverlay itemizedoverlay = new ItemizedOverlay(drawable, this); 
    ...
    ...
       for (int m = 0; m < ArrList.size(); m++) {
            tName = ArrList.get(m).get("name").toString();
            tId = ArrList.get(m).get("id").toString();
            tLat = ArrList.get(m).get("lat").toString();;
            tLng = ArrList.get(m).get("lng").toString();;
            try {
                lat = Double.parseDouble(tLat);
                lng = Double.parseDouble(tLng);
                p1 = new GeoPoint(
                        (int) (lat * 1E6), 
                        (int) (lng * 1E6));
                OverlayItem overlayitem = new OverlayItem(p1, tName, tId);
                itemizedoverlay.addOverlay(overlayitem);
            } catch (NumberFormatException e) {
                Log.d(TAG, "NumberFormatException" + e);    
            }
        }
        mapOverlays.add(itemizedoverlay);
        mapView.postInvalidate();

................................

public class ItemizedOverlay extends ItemizedOverlay<OverlayItem>
{
    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    private Context mContext;
    public HelloItemizedOverlay(Drawable defaultMarker, Context context)
    {
        super(boundCenterBottom(defaultMarker));
        mContext = context;
    }

    public void addOverlay(OverlayItem overlay)
    {
        mOverlays.add(overlay);
        populate();
    }
    @Override
    protected OverlayItem createItem(int i)
    {
        return mOverlays.get(i);
    }
    @Override
    public int size()
    {
        return mOverlays.size();
    }
    @Override
    protected boolean onTap(int index)
    {
        final OverlayItem item = mOverlays.get(index);
                    ... EACH MARKER WILL HAVE ONCLICK EVENT THAT WILL PRODUCE CLICABLE 
                    ... BALOON WITH MARKER'S NAME.          
        return true;
    }       
}    

3 ответа

Решение

Что ж. Оказалось, я вызываю populate() каждый раз после добавления маркера. Я взял populate() из метода addOverlay() и вызываю его после завершения цикла. Все маркеры сейчас показывают практически мгновенно. Единственная проблема сейчас состоит в том, что карта очень не отвечает при меньшем увеличении (показывая много маркеров одновременно). Я не вижу решения для этого, пока не выясню, как уменьшить количество маркеров на карте, когда карта уменьшена... думая сгруппировать их как-то... в настоящее время работаю над этим...

Есть два способа сделать это упрощение маршрута.

1) Если вы получили заголовок по всем пунктам. Вы можете сохранить отклонение от курса, скажем, если различие между курсом point A and B является 0.5 Просто нарисуйте линию от A до B и игнорируйте точки между ними.

2) Если у вас нет заголовка. Сделайте треугольник, как показано на рис. Если h лежит между вашими пределами, пропустите точки между ними и проведите линию от A to B

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


Смотрите также:

Упрощение маршрута - алгоритм Дугласа Пьюкера

У меня такая же проблема при загрузке нескольких маркеров на карту, но я поставил некоторую задержку в загрузке маркера и отображаю map.first, отображаю карту и после некоторой задержки загружает весь маркер. это будет загружаться быстрее до некоторой степени.

Другие вопросы по тегам