Маркеры

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.
Выберите платформу: Android iOS JavaScript

Маркеры обозначают отдельные места на карте. Вы можете настроить свои маркеры, изменив цвет по умолчанию или заменив значок маркера пользовательским изображением. Информационные окна могут предоставить маркеру дополнительный контекст.

Примеры кода

Репозиторий ApiDemos на GitHub включает образец, демонстрирующий различные функции маркера:

Джава

Котлин

Вступление

Маркеры обозначают местоположения на карте. Маркер по умолчанию использует стандартный значок, общий для внешнего вида Google Maps. Через API можно изменить цвет, изображение или точку привязки значка. Маркеры — это объекты типа Marker , которые добавляются на карту с помощью метода GoogleMap.addMarker(markerOptions) .

Маркеры разработаны, чтобы быть интерактивными. Они получают события click по умолчанию и часто используются с прослушивателями событий для вызова информационных окон . Установка для свойства draggable маркера значения true позволяет пользователю изменять положение маркера. Используйте долгое нажатие, чтобы активировать возможность перемещения маркера.

По умолчанию, когда пользователь касается маркера, панель инструментов карты появляется в правом нижнем углу карты, предоставляя пользователю быстрый доступ к мобильному приложению Google Maps. Вы можете отключить панель инструментов. Дополнительные сведения см. в руководстве по элементам управления .

Начало работы с маркерами

В этом выпуске Maps Live рассказывается об основах добавления маркеров на карту с помощью Maps SDK для Android.

Добавить маркер

В следующем примере показано, как добавить маркер на карту. Маркер создается с координатами -33.852,151.211 (Сидней, Австралия), и при нажатии на него в информационном окне отображается строка «Маркер в Сиднее».

Джава


@Override
public void onMapReady(GoogleMap googleMap) {
    // Add a marker in Sydney, Australia,
    // and move the map's camera to the same location.
    LatLng sydney = new LatLng(-33.852, 151.211);
    googleMap.addMarker(new MarkerOptions()
        .position(sydney)
        .title("Marker in Sydney"));
    googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}

      

Котлин


override fun onMapReady(googleMap: GoogleMap) {
    // Add a marker in Sydney, Australia,
    // and move the map's camera to the same location.
    val sydney = LatLng(-33.852, 151.211)
    googleMap.addMarker(
        MarkerOptions()
            .position(sydney)
            .title("Marker in Sydney")
    )
    googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}

      

Показать дополнительную информацию о маркере

Общим требованием является отображение дополнительной информации о месте или местоположении, когда пользователь касается маркера на карте. См. руководство по информационным окнам .

Связать данные с маркером

Вы можете сохранить произвольный объект данных с маркером, используя Marker.setTag() , и получить объект данных, используя Marker.getTag() . В приведенном ниже примере показано, как с помощью тегов можно подсчитать количество нажатий маркера:

Джава


/**
 * A demo class that stores and retrieves data objects with each marker.
 */
public class MarkerDemoActivity extends AppCompatActivity implements
    GoogleMap.OnMarkerClickListener,
    OnMapReadyCallback {

    private final LatLng PERTH = new LatLng(-31.952854, 115.857342);
    private final LatLng SYDNEY = new LatLng(-33.87365, 151.20689);
    private final LatLng BRISBANE = new LatLng(-27.47093, 153.0235);

    private Marker markerPerth;
    private Marker markerSydney;
    private Marker markerBrisbane;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_markers);
        SupportMapFragment mapFragment =
            (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    /** Called when the map is ready. */
    @Override
    public void onMapReady(GoogleMap map) {
        // Add some markers to the map, and add a data object to each marker.
        markerPerth = map.addMarker(new MarkerOptions()
            .position(PERTH)
            .title("Perth"));
        markerPerth.setTag(0);

        markerSydney = map.addMarker(new MarkerOptions()
            .position(SYDNEY)
            .title("Sydney"));
        markerSydney.setTag(0);

        markerBrisbane = map.addMarker(new MarkerOptions()
            .position(BRISBANE)
            .title("Brisbane"));
        markerBrisbane.setTag(0);

        // Set a listener for marker click.
        map.setOnMarkerClickListener(this);
    }

    /** Called when the user clicks a marker. */
    @Override
    public boolean onMarkerClick(final Marker marker) {

        // Retrieve the data from the marker.
        Integer clickCount = (Integer) marker.getTag();

        // Check if a click count was set, then display the click count.
        if (clickCount != null) {
            clickCount = clickCount + 1;
            marker.setTag(clickCount);
            Toast.makeText(this,
                marker.getTitle() +
                    " has been clicked " + clickCount + " times.",
                Toast.LENGTH_SHORT).show();
        }

        // Return false to indicate that we have not consumed the event and that we wish
        // for the default behavior to occur (which is for the camera to move such that the
        // marker is centered and for the marker's info window to open, if it has one).
        return false;
    }
}

      

Котлин


/**
 * A demo class that stores and retrieves data objects with each marker.
 */
class MarkerDemoActivity : AppCompatActivity(),
    OnMarkerClickListener, OnMapReadyCallback {
    private val PERTH = LatLng(-31.952854, 115.857342)
    private val SYDNEY = LatLng(-33.87365, 151.20689)
    private val BRISBANE = LatLng(-27.47093, 153.0235)

    private var markerPerth: Marker? = null
    private var markerSydney: Marker? = null
    private var markerBrisbane: Marker? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_markers)
        val mapFragment =
            supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment!!.getMapAsync(this)
    }

    /** Called when the map is ready.  */
    override fun onMapReady(map: GoogleMap) {
        // Add some markers to the map, and add a data object to each marker.
        markerPerth = map.addMarker(
            MarkerOptions()
                .position(PERTH)
                .title("Perth")
        )
        markerPerth?.tag = 0
        markerSydney = map.addMarker(
            MarkerOptions()
                .position(SYDNEY)
                .title("Sydney")
        )
        markerSydney?.tag = 0
        markerBrisbane = map.addMarker(
            MarkerOptions()
                .position(BRISBANE)
                .title("Brisbane")
        )
        markerBrisbane?.tag = 0

        // Set a listener for marker click.
        map.setOnMarkerClickListener(this)
    }

    /** Called when the user clicks a marker.  */
    override fun onMarkerClick(marker: Marker): Boolean {

        // Retrieve the data from the marker.
        val clickCount = marker.tag as? Int

        // Check if a click count was set, then display the click count.
        clickCount?.let {
            val newClickCount = it + 1
            marker.tag = newClickCount
            Toast.makeText(
                this,
                "${marker.title} has been clicked $newClickCount times.",
                Toast.LENGTH_SHORT
            ).show()
        }

        // Return false to indicate that we have not consumed the event and that we wish
        // for the default behavior to occur (which is for the camera to move such that the
        // marker is centered and for the marker's info window to open, if it has one).
        return false
    }
}

      

Вот несколько примеров сценариев, когда полезно хранить и извлекать данные с помощью маркеров:

  • Ваше приложение может поддерживать разные типы маркеров, и вы хотите по-разному обрабатывать их, когда пользователь нажимает на них. Для этого вы можете сохранить String с маркером, указывающим тип.
  • Возможно, вы взаимодействуете с системой, которая имеет уникальные идентификаторы записей, где маркеры представляют определенные записи в этой системе.
  • Данные маркера могут указывать приоритет, который следует использовать при определении z-индекса маркера.

Сделать маркер перетаскиваемым

Вы можете изменить положение маркера после его добавления на карту, если для его свойства draggable установлено значение true . Нажмите и удерживайте маркер, чтобы включить перетаскивание. Когда вы уберете палец с экрана, маркер останется в этом положении.

По умолчанию маркеры нельзя перетаскивать. Вы должны явно указать маркеру возможность перетаскивания либо с помощью MarkerOptions.draggable(boolean) перед его добавлением на карту, либо Marker.setDraggable(boolean) после его добавления на карту. Вы можете прослушивать события перетаскивания маркера, как описано в разделе События перетаскивания маркера .

Фрагмент ниже добавляет перетаскиваемый маркер в Перте, Австралия.

Джава


final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .draggable(true));

      

Котлин


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .draggable(true)
)

      

Настроить маркер

В этом видеоролике показаны способы использования маркеров для визуализации местоположений на карте.

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

Маркеры поддерживают настройку с помощью следующих свойств:

Должность (обязательно)
Значение LatLng для положения маркера на карте. Это единственное обязательное свойство для объекта Marker .
Якорь
Точка на изображении, которая будет помещена в положение LatLng маркера. По умолчанию это середина нижней части изображения.
Альфа
Устанавливает непрозрачность маркера. По умолчанию 1.0.
Заголовок
Строка, которая отображается в информационном окне, когда пользователь касается маркера.
Фрагмент
Дополнительный текст, отображаемый под заголовком.
Икона
Растровое изображение, отображаемое вместо изображения маркера по умолчанию.
Перетаскиваемый
Установите значение true , если вы хотите разрешить пользователю перемещать маркер. По умолчанию false .
Видимый
Установите значение false , чтобы сделать маркер невидимым. По умолчанию true .
Плоская или рекламная ориентация
По умолчанию маркеры используют ориентацию рекламного щита, то есть они ориентированы на экран устройства, а не на поверхность карты. Поворот, наклон или масштабирование карты не меняют ориентацию маркера. Вы можете установить ориентацию маркера так, чтобы он располагался плоско относительно земли. Плоские маркеры поворачиваются при повороте карты и меняют перспективу при наклоне карты. Как и маркеры рекламных щитов, плоские маркеры сохраняют свой размер при увеличении или уменьшении масштаба карты.
Вращение
Ориентация маркера, указанная в градусах по часовой стрелке. Положение по умолчанию изменяется, если маркер плоский. Положение по умолчанию для плоского маркера выровнено по северу. Когда маркер не плоский, положение по умолчанию направлено вверх, а поворот таков, что маркер всегда обращен к камере.

В приведенном ниже фрагменте создается простой маркер со значком по умолчанию.

Джава


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation));

      

Котлин


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
)

      

Настроить цвет маркера

Можно настроить цвет изображения маркера по умолчанию, передав объект BitmapDescriptor icon(). Вы можете использовать набор предопределенных цветов в объекте BitmapDescriptorFactory или задать собственный цвет маркера с помощью BitmapDescriptorFactory.defaultMarker(float hue) . Оттенок — это значение от 0 до 360, представляющее точки на цветовом круге.

Джава


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));

      

Котлин


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
)

      

Настройка непрозрачности маркера

Вы можете управлять непрозрачностью маркера с помощью метода MarkerOptions.alpha(). Альфа должна быть указана как число с плавающей запятой от 0,0 до 1,0, где 0 — полностью прозрачный, а 1 — полностью непрозрачный.

Джава


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(new MarkerOptions()
    .position(melbourneLocation)
    .alpha(0.7f));

      

Котлин


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .alpha(0.7f)
)

      

Настройте изображение маркера

Вы можете заменить изображение маркера по умолчанию пользовательским изображением маркера, часто называемым значком. Пользовательские значки всегда задаются как BitmapDescriptor и определяются с помощью одного из методов класса BitmapDescriptorFactory .

fromAsset(String assetName)
Создает пользовательский маркер, используя имя растрового изображения в каталоге ресурсов.
fromBitmap(Bitmap image)
Создает пользовательский маркер из растрового изображения.
fromFile(String fileName)
Создает пользовательский значок, используя имя файла растрового изображения, расположенного во внутренней памяти.
fromPath(String absolutePath)
Создает настраиваемый маркер на основе абсолютного пути к файлу растрового изображения.
fromResource(int resourceId)
Создает пользовательский маркер, используя идентификатор ресурса растрового изображения.

В приведенном ниже фрагменте создается маркер с пользовательским значком.

Джава


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation)
        .title("Melbourne")
        .snippet("Population: 4,137,400")
        .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));

      

Котлин


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .title("Melbourne")
        .snippet("Population: 4,137,400")
        .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow))
)

      

Свести маркер

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

Чтобы изменить ориентацию маркера, задайте для свойства flat маркера значение true .

Джава


final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .flat(true));

      

Котлин


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .flat(true)
)

      

Повернуть маркер

Вы можете вращать маркер вокруг его опорной точки с помощью Marker . setRotation() . Поворот измеряется в градусах по часовой стрелке от положения по умолчанию. Когда маркер расположен на карте плоско, положение по умолчанию — север. Когда маркер не плоский, положение по умолчанию направлено вверх, а поворот таков, что маркер всегда обращен к камере.

В приведенном ниже примере маркер поворачивается на 90°. Установка точки привязки на 0.5,0.5 приводит к тому, что маркер вращается вокруг своего центра, а не вокруг своей базы.

Джава


final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .anchor(0.5f,0.5f)
        .rotation(90.0f));

      

Котлин


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .anchor(0.5f, 0.5f)
        .rotation(90.0f)
)

      

Z-индекс маркера

Z-индекс определяет порядок стека этого маркера относительно других маркеров на карте. Маркер с высоким z-индексом рисуется поверх маркеров с более низким z-индексом. Значение z-индекса по умолчанию равно 0 .

Установите z-index для объекта параметров маркера, вызвав MarkerOptions.zIndex() , как показано в следующем фрагменте кода:

Джава


map.addMarker(new MarkerOptions()
    .position(new LatLng(10, 10))
    .title("Marker z1")
    .zIndex(1.0f));

      

Котлин


map.addMarker(
    MarkerOptions()
        .position(LatLng(10.0, 10.0))
        .title("Marker z1")
        .zIndex(1.0f)
)

      

Вы можете получить доступ к z-индексу маркера, вызвав Marker.getZIndex() , и вы можете изменить его, вызвав Marker.setZIndex() .

Маркеры всегда рисуются над слоями листов и другими наложениями, не являющимися маркерами (наложениями земли, ломаными линиями, многоугольниками и другими формами), независимо от z-индекса других наложений. Маркеры считаются находящимися в отдельной группе z-индекса по сравнению с другими наложениями.

Подробнее о влиянии z-index на события кликов читайте ниже.

Обработка событий маркера

Maps API позволяет прослушивать события маркеров и реагировать на них. Чтобы прослушивать эти события, вы должны установить соответствующий прослушиватель на объекте GoogleMap , которому принадлежат маркеры. Когда событие происходит на одном из маркеров на карте, будет вызван обратный вызов слушателя с соответствующим объектом Marker , переданным в качестве параметра. Чтобы сравнить этот объект Marker с вашей собственной ссылкой на объект Marker , вы должны использовать equals() , а не == .

Вы можете прослушать следующие события:

События нажатия маркера

Вы можете использовать OnMarkerClickListener для прослушивания событий кликов по маркеру. Чтобы установить этот прослушиватель на карте, вызовите GoogleMap.setOnMarkerClickListener(OnMarkerClickListener) . Когда пользователь нажимает на маркер, будет onMarkerClick(Marker) , и маркер будет передан в качестве аргумента. Этот метод возвращает логическое значение, указывающее, использовали ли вы событие (т. е. хотите ли вы подавить поведение по умолчанию). Если он возвращает false , то в дополнение к вашему пользовательскому поведению будет использоваться поведение по умолчанию. Поведение по умолчанию для события щелчка маркера состоит в том, чтобы показать его информационное окно (если оно доступно) и переместить камеру так, чтобы маркер оказался в центре карты.

Влияние z-index на события кликов:

  • Когда пользователь щелкает кластер маркеров, событие щелчка запускается для маркера с самым высоким z-индексом.
  • На каждый клик запускается не более одного события. Другими словами, щелчок не передается маркерам или другим наложениям с более низкими значениями z-индекса.
  • Щелчок по кластеру маркеров приводит к тому, что последующие щелчки циклически проходят по кластеру, выбирая каждый по очереди. Порядок цикла сначала отдает приоритет z-индексу, а затем близости к точке щелчка.
  • Если пользователь щелкает за пределами кластера, API пересчитывает кластер и сбрасывает состояние цикла щелчков, чтобы он начинался с самого начала.
  • Событие щелчка проходит через кластеры маркеров к другим фигурам и наложениям перед перезапуском цикла.
  • Маркеры считаются находящимися в отдельной группе z-индекса по сравнению с другими наложениями или формами (полилиниями, многоугольниками, кругами и/или наложениями на землю), независимо от z-индекса других наложений. Если несколько маркеров, наложений или фигур накладываются друг на друга, событие щелчка сначала циклически проходит через кластер маркеров, а затем запускается для других интерактивных наложений или фигур в зависимости от их значений z-index.

События перетаскивания маркера

Вы можете использовать OnMarkerDragListener для прослушивания событий перетаскивания маркера. Чтобы установить этот прослушиватель на карту, вызовите GoogleMap.setOnMarkerDragListener . Чтобы перетащить маркер, пользователь должен долго нажимать на маркер. Когда пользователь убирает палец с экрана, маркер остается в этом положении. Когда маркер перетаскивается, onMarkerDragStart(Marker) . Пока маркер перетаскивается, onMarkerDrag(Marker) вызывается постоянно. В конце перетаскивания onMarkerDragEnd(Marker) . Вы можете получить позицию маркера в любое время, вызвав Marker.getPosition() .