M
M
mazahaler2019-01-26 20:42:05
JavaScript
mazahaler, 2019-01-26 20:42:05

How to remove a single marker from a map [Google Map API]?

Hello, the task is to add and remove markers on the map (and build a curve along the route). It worked out to add, but somehow it didn’t work with the removal:
(This is Vue.js)

<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>

The problem is that the marker is not removed. How can this be fixed?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2019-01-26
@mazahaler

Your markers are duplicated - you add them on the places_changed event and again when building a polyline. So you deleted one, and the other in the same place (the others are duplicated many times) remained.
What exactly should be done:

  1. Make infowindow a property of the component. Initialize it in the same place as the map itself.
  2. Move the assignment of the marker click handler from updateMap to the places_changed handler where the marker is first created. It should turn out something like this:
    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. The updateMap method itself should be greatly reduced in size (and it won’t hurt to change its name - to updatePolyline, for example):
    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. As for working with DOM tree elements:
    document.getElementById('map')
    <...>
    document.getElementById('inputPlace')

    That's not how things are done. There is such a thing - ref . I advise you to take a look.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question