Colocar componente de vue2-google-maps dentro del mapa

publicado por: Anonymous

Estoy haciendo uso del paquete “vue2-google-maps” en una aplicacion desarrollada con Laravel 5.7. En este caso estoy creando un componente con el nombre google-map. Dendro de este componente se utiliza gmap-autocomplete y gmap-map. El componente està registrado en app.js y funciona correctamente tanto el mapa como el input autocomplete.
El problema es que el input se ubica arriba del mapa y lo que deseo es que esté dentro del mapa.

Actualmente estoy logrando esto:
introducir la descripción de la imagen aquí

Deseo que quede como la siguiente imagen:

input autocomplete dentro del mapa

Esto normalmente lo lograría(sin usar vue ni dicho paquete) con las siguientes lineas:

let inputSearch = document.getElementById('pac-input');
searchBoxAdd = new google.maps.places.SearchBox(inputSearch );
myMap.controls[google.maps.ControlPosition.TOP_CENTER].push(searchBoxAdd );

Pero en este caso ya no es lo mismo. Según la documentación, vi que puedo acceder al objeto “map” agregando ref="mapRef" a mi componente gmap-map y agregando

mounted () {
    this.$refs.mapRef.$mapPromise.then((map) => {
      // En este punto ya tengo mi objeto map.
    })
  }

En base a esta información probé hacer lo siguiente:

mounted () {
        this.$refs.mapRef.$mapPromise.then((map) => {
          let inputSearch = document.getElementById('pac-input');
          searchBoxAdd = new google.maps.places.SearchBox(inputSearch );
        map.controls[google.maps.ControlPosition.TOP_CENTER].push(searchBoxAdd );
        })

Pero sigue sin cargar el input en el interior del mapa y en consola me muestra el siguiente error:

controls.js:118 Uncaught (in promise) TypeError: Cannot read property
‘zIndex’ of undefined

Les dejo mi componente principal, que sería “google-maps”

<template>
    <div>
        <div>
            <h2>Search and add a marker</h2>
            <label>
                <div class="form-inline">
                    <gmap-autocomplete
                        class="form-control"
                        @place_changed="setPlace">
                    </gmap-autocomplete>
                    <button @click="addMarker" class="btn btn-primary btn-flat">Add</button>
                </div>
            </label>
            <br/>
        </div>
        <br>
        <gmap-map ref="mapRef"
            :center="center"
            :zoom="12"
            style="width:100%;  height: 400px;"
        >
            <gmap-marker
                :key="index"
                v-for="(m, index) in markers"
                :position="m.position"
                @click="center=m.position"
            ></gmap-marker>
        </gmap-map>
    </div>
</template>

<script>
    import {gmapApi} from 'vue2-google-maps';

    export default {
        name: "GoogleMap",

        data() {
            return {
                // default to Montreal to keep it simple
                // change this to whatever makes sense
                center: { lat: 45.508, lng: -73.587 },
                markers: [],
                places: [],
                currentPlace: null
            };
        },

        mounted() {
            this.geolocate();
        },

        methods: {
            // receives a place object via the autocomplete component
            setPlace(place) {
                this.currentPlace = place;
            },
            addMarker() {
                if (this.currentPlace) {
                    const marker = {
                        lat: this.currentPlace.geometry.location.lat(),
                        lng: this.currentPlace.geometry.location.lng()
                    };
                    this.markers.push({ position: marker });
                    this.places.push(this.currentPlace);
                    this.center = marker;
                    this.currentPlace = null;
                }
            },
            geolocate: function() {
                navigator.geolocation.getCurrentPosition(position => {
                    this.center = {
                        lat: position.coords.latitude,
                        lng: position.coords.longitude
                    };

                });
            }
        }
    };
</script>

Gracias. Saludos!

solución

Ya logré solucionarlo, lo hice con los siguientes pasos:

  1. Agregar ref="mapRef" a la etiqueta gmap-map. Con esto mas adelante podré tener acceso al objeto “map”. La etiqueta debe quedar así:

    <gmap-map ref="mapRef"
    :center="center"
    :zoom="12"
    :options="mapOptions" // Para ocultar el control "mapTypeControl"
     style="width:100%;  height: 400px;"
    >
    </gmap-map>
    
  2. Mi control queda del siguiente modo:

     <div class="hide">
       <div class="input-group col-md-6" id="myAutocomplete">
       <div class="input-group-prepend">
           <span class="input-group-text bg-primary" id="basic-text1">
                <i class="fa fa-search text-white" aria-hidden="true"></i>
           </span>
       </div>
       <gmap-autocomplete
           class="form-control my-0 py-1"
           @place_changed="setPlace">
       </gmap-autocomplete>
       </div>
    </div>
    

    El div “padre” con la clase “hide” es importante, sino el input se mostrará en la pagina antes de terminar de cargar el mapa y luego lo moverá a su interior. Con esto, cuando esta listo el mapa lo muestra en su interior directamente. El resto ya son estilos…

  3. Voy a agregar una configuración extra para ocultar mapTypeControl .Esto NO es obligatorio.

      data() {
                return {
                    // default to Montreal to keep it simple
                    // change this to whatever makes sense
                    center: { lat: 45.508, lng: -73.587 },
                    markers: [],
                    places: [],
                    currentPlace: null,
                    mapOptions: {
                        mapTypeControl: false
                    }
                };
            },
    
  4. Una vez que el componente esta montado, es decir en el evento “mounted()” voy a usar el objeto “map” para agregar mi componente. El código debe quedar así:

    mounted() {
            this.$refs.mapRef.$mapPromise.then((map) => {
                var myControl = document.getElementById('myAutocomplete');
    
                myControl.index = 1; // Esto es importante sino arroja error.
    
                map.controls[google.maps.ControlPosition.TOP_CENTER].push(myControl);
            })
        },
    

Una vez hecho todo esto, obtengo el siguiente resultado:

Resultado

Espero que le sirva a alguien. Saludos!

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *