Задать вопрос
@mazahaler

Как удалить один маркер с карты?

Задача добавлять и удалять маркеры на карте (и строить кривую по маршруту). Добавлять получилось, а с удалением как-то никак:

<template>
    <div class="container-fluid">
        <div class="row main">
            <div class="col-md-6 col-sm-12">
                <div class="input-group mb-3">
                    <input type="text" class="form-control newCoordinates" id="inputPlace"
                           placeholder="Введите наименование места"
                           autofocus="true" v-model="place" />
                </div>
                <ul class="list-group">
                    <li class="list-group-item d-flex justify-content-between align-items-center"
                        v-for="(marker, index) in markers">{{marker.title}}
                        <span class="badge-close" title="Delete marker" @click="removeMarker(index)">X</span>
                    </li>
                </ul>

            </div>
            <div class="col-md-6 col-sm-12">
                <div id="map"></div>
            </div>
        </div>
    </div>
</template>

<script>
    import $Scriptjs from 'scriptjs'

    export default {
        name: 'MapComponent',
        props: {},
        data() {
            return {
                map: '',
                place: "",
                markers: [],
                polyline: undefined,
                marker: undefined,
            }
        },
        mounted() {
            $Scriptjs('https://maps.googleapis.com/maps/api/js?key=AIzaSyBJmqB5hgGSqi9SKeC5UVs_OXguUF-aark&libraries=places', () => {
                this.initMap()
                this.initAutocomplete()
            });
        },
        methods: {
            removeMarker(index) {

                this.marker = this.markers[index];
                this.marker.setMap(null);
                this.markers.splice(index, 1);
                this.updateMap();
            },
            initMap() {
                this.map = new google.maps.Map(document.getElementById('map'), {
                    zoom: 3,
                    center: {lat: 0, lng: -180},
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                });

            },
            updateMap() {
                let infowindow = new google.maps.InfoWindow();

                let path = [];

                for (let i in this.markers) {
                    this.marker = new google.maps.Marker({
                        position: new google.maps.LatLng(this.markers[i].getPosition().lat(), this.markers[i].getPosition().lng()),
                        map: this.map,
                        title: this.markers[i].title
                    });

                    // this.marker.setMap(null); ////Если это НЕ комментить, то удаляются нормально, но не показывает инфу при нажатии на маркеры

                    google.maps.event.addListener(this.marker, 'click', ((marker, i) => {
                        return function () {
                            infowindow.setContent(marker.title);
                            infowindow.open(this.map, marker);
                        }
                    })(this.marker, i));

                    //Delete polyline after removed marker
                    if (this.polyline) {
                        this.polyline.setMap(null);
                    }

                    //Get coord. for polyline path
                    let lastCoordinates = {
                        lat: this.markers[i].getPosition().lat(),
                        lng: this.markers[i].getPosition().lng()
                    };
                    path.push(lastCoordinates);

                }

                this.polyline = new google.maps.Polyline({
                    path: path,
                    geodesic: true,
                    strokeColor: '#FF0000',
                    strokeOpacity: 1.0,
                    strokeWeight: 2
                });

                this.polyline.setMap(this.map);
            },

            initAutocomplete() {
                // Create the search box and link it to the UI element.
                let input = document.getElementById('inputPlace');
                let searchBox = new google.maps.places.SearchBox(input);
                this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);

                // Bias the SearchBox results towards current map's viewport.
                this.map.addListener('bounds_changed', () => {
                    searchBox.setBounds(this.map.getBounds());
                });

                // Listen for the event fired when the user selects a prediction and retrieve
                // more details for that place.
                searchBox.addListener('places_changed', () => {
                    let places = searchBox.getPlaces();

                    if (places.length === 0) {
                        return;
                    }

                    // For each place, get the icon, name and location.
                    let bounds = new google.maps.LatLngBounds();
                    places.forEach((place) => {
                        if (!place.geometry) {
                            console.log("Returned place contains no geometry");
                            return;
                        }

                        // Create a marker for each place.
                        this.markers.push(new google.maps.Marker({
                            map: this.map,
                            title: place.name,
                            position: place.geometry.location
                        }));
                        this.place = "";
                        if (place.geometry.viewport) {
                            // Only geocodes have viewport.
                            bounds.union(place.geometry.viewport);
                        } else {
                            bounds.extend(place.geometry.location);
                        }
                    });
                    this.map.fitBounds(bounds);
                    this.updateMap();
                });
            }
        },

    }
</script>

Проблема в том, что маркер не удаляется. Как это можно исправить?
  • Вопрос задан
  • 404 просмотра
Подписаться 1 Средний Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
У вас маркеры дублируются - вы их добавляете по событию places_changed и повторно при построении polyline. Так что один вы удалили, а другой в том же месте (другие - дублируются многократно) остался.

Что конкретно следует предпринять:

  1. Сделайте infowindow свойством компонента. Инициализируйте его там же где и саму карту.
  2. Перенесите назначение обработчика клика маркера из updateMap в обработчик places_changed, туда, где маркер создаётся впервые. Должно получится как-то так:

    const marker = new google.maps.Marker({
      map: this.map,
      title: place.name,
      position: place.geometry.location,
    });
    google.maps.event.addListener(marker, 'click', () => {
      this.infowindow.setContent(marker.title);
      this.infowindow.open(this.map, marker);
    });
    this.markers.push(marker);

  3. Сам метод updateMap должен сильно сократиться в размерах (да и имя ему сменить не помешает - на updatePolyline, например):

    updateMap() {
      if (this.polyline) {
        this.polyline.setMap(null);
      }
    
      this.polyline = new google.maps.Polyline({
        path: this.markers.map(n => n.getPosition()),
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
        map: this.map,
      });
    },

  4. Что касается работы с элементами DOM-дерева:

    document.getElementById('map')
    <...>
    document.getElementById('inputPlace')

    Так дела не делаются. Стоит переписать с использованием ref.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы