Решения для множества маркеров в одной и той же координате, Google Map mashup - PullRequest
10 голосов
/ 28 января 2010

Я делаю коллаж, где миниатюры будут отображаться на карте Google.

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

Вы видели какое-нибудь креативное решение этой проблемы? Спасибо

Ответы [ 5 ]

9 голосов
/ 16 марта 2011

Кластеризация, безусловно, полезна, но она не решает первоначальный вопрос - как отображать маркеры, если они имеют одинаковые точные координаты. Google Maps API v3 просто не делает этого. Он просто отображает один из них.

Решения кластеризации, предложенные @RedBlueThing, не решают эту проблему.

Есть несколько вариантов. Один из них был предложен @Bryan - выполнить некоторую предварительную обработку вручную и поместить описательную информацию в информационное окно для последнего маркера.

В качестве альтернативы - что я предпочитаю - это предварительно обработать маркеры, чтобы чуть-чуть (10 м или около того) изменить координаты тех, которые имеют одинаковое точное местоположение. Если вы можете позволить себе отказаться от такого уровня точности. См. Одно из таких решений здесь http://techxplorer.com/2010/02/05/managing-markers-with-the-same-coordinates-in-a-google-map/. Я дополнительно изменил код - см. Здесь https://gist.github.com/873142.

3 голосов
/ 28 января 2010

Существует несколько библиотек Javascript, которые реализуют кластеризацию и очень легко интегрируются в существующий мэшап:

  • MarkerClusterer - я использовал это дляМешап и легко интегрируемый с хорошим набором значков по умолчанию.
  • ClusterMarker - я не использовал этот, но он кажется довольно функциональным.

Вы также можете прочитать это сообщение в блоге который идет по различным альтернативам.

3 голосов
/ 28 января 2010

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

Если они находятся в точно таких же координатах и ​​никогда не расходятся, то вам нужно будет реализовать что-то, что всплывает на экране при наведении курсора на кластерный маркер (например, плавающий DIV, который содержит список миниатюр для человек для выбора / просмотра или даже контекстного меню, в котором они могут щелкнуть правой кнопкой мыши кластер и выбрать отдельный элемент)

0 голосов
/ 19 сентября 2016

У меня есть элегантное и красивое решение:

@Override
public boolean onClusterClick(Cluster<ProfileCardDTO> cluster)
{
    if (inProcessOfClick.size() > 0)
    {
        changeRenderMarkerType(doctorMarkerRenderer.getMarkerType());
        for (Polyline line : polylines)
        {
            line.remove();
        }
        polylines.clear();
    }
    boolean same = true;
    ProfileCardDTO tmpProfile = null;
    for (ProfileCardDTO profile : cluster.getItems())
    {
        if (tmpProfile != null)
        {
            if ((Math.abs(Float.parseFloat(tmpProfile.getPractice().getLatitude()) - Float
                    .parseFloat(profile
                            .getPractice()
                            .getLatitude())) > 0.00001f) || (Math.abs(Float.parseFloat(tmpProfile
                    .getPractice().getLongitude()) - Float.parseFloat(profile
                    .getPractice()
                    .getLongitude())) > 0.00001f))
            {
                same = false;
                break;
            }
        }
        tmpProfile = profile;
    }
    if (zoomLevel >= 12 && same)
    {
        inProcessOfClick.clear();
        int count = cluster.getSize();
        double a = 360.0 / count;
        double radius = 0.0006;
        if (zoomLevel < 17.7)
        {
            radius = 0.0005;
        } else if (zoomLevel < 18.7)
        {
            radius = 0.0003;
        } else if (zoomLevel < 19.7)
        {
            radius = 0.00015;
        } else if (zoomLevel <= 20.7)
        {
            radius = 0.00007;
        } else if (zoomLevel > 20.7)
        {
            radius = 0.00005;
        }
        int i = 0;
        final long duration = 500;
        final long start = SystemClock.uptimeMillis();
        final Interpolator interpolator = new LinearInterpolator();
        for (ProfileCardDTO profile : cluster.getItems())
        {
            MarkerOptions mrk = new MarkerOptions();
            double x = radius * Math.cos((a * i) / 180 * Math.PI);
            double y = radius * Math.sin((a * i) / 180 * Math.PI);
            LatLng latLngEnd = new LatLng(profile.getPosition().latitude + x, profile
                    .getPosition().longitude + y);
            LatLng latLngStart = profile.getPosition();
            mrk.position(latLngStart);
            doctorMarkerRenderer.onBeforeClusterItemRendered(profile, mrk);
            Marker tmpMrk = clusterManager.getMarkerCollection().addMarker(mrk);
            Handler handler = new Handler();
            handler.post(new Runnable()
            {
                @Override
                public void run()
                {
                    long elapsed = SystemClock.uptimeMillis() - start;
                    if (elapsed > duration)
                        elapsed = duration;
                    float t = interpolator.getInterpolation((float) elapsed / duration);
                    double lng = t * latLngEnd.longitude + (1 - t) * latLngStart.longitude;
                    double lat = t * latLngEnd.latitude + (1 - t) * latLngStart.latitude;
                    tmpMrk.setPosition(new LatLng(lat, lng));
                    if (t < 1.0)
                    {
                        handler.postDelayed(this, 10);
                    } else
                    {
                        PolylineOptions line =
                                new PolylineOptions().add(cluster.getPosition(),
                                        cluster.getPosition(),
                                        latLngEnd,
                                        latLngEnd)
                                        .width(5).color(Color.BLACK);
                        polylines.add(getGoogleMap().addPolyline(line));
                    }
                }
            });
            doctorMarkerRenderer.getmMarkerCache().put(profile, tmpMrk);
            clusterManager.addItem(profile);
            inProcessOfClick.add(profile);
            i++;
        }
        tmpCluster = cluster;
        bringMarkerToTop(selectedDoctorMiniProfile);
        new Handler().postDelayed(() ->
        {
            if (doctorMarkerRenderer.getMarker(cluster) != null)
                doctorMarkerRenderer.getMarker(cluster).setAlpha(0.5f);
        }, 250);
    } else
    {
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for (ProfileCardDTO profile : cluster.getItems())
        {
            Practice2 location = profile.getLocation();
            LatLng latLng = new LatLng(Double.parseDouble(location.getLatitude()), Double.parseDouble(location
                    .getLongitude()));
            builder.include(latLng);
        }
        LatLngBounds latLngBounds = builder.build();
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(latLngBounds, getResources().getDimensionPixelSize(R.dimen.map_padding));
        getGoogleMap().animateCamera(cameraUpdate, ANIMATE_DURATION_MS, new GoogleMap.CancelableCallback()
        {
            @Override
            public void onFinish()
            {
                changeRenderMarkerType(doctorMarkerRenderer.getMarkerType());
            }

            @Override
            public void onCancel()
            {
            }
        });
    }
    return true;
}

Полный код фрагмента: https://github.com/master255/MapFragment

0 голосов
/ 12 сентября 2014

Используйте кластеризацию .make группу маркеров, так как cluster.one кластер представит много маркеров внутри.

...