While working with a Vue library for managing Maps called vue3-google-map, I encountered an issue when trying to define certain polylines that would not allow me to select the center of the marked area:
Here is my map template:
<template>
<GoogleMap
ref="mapRef"
class="mimapa"
:api-key="apiKey"
:center="center"
:zoom="16"
:zoomControl="controls"
:fullscreenControl="controls"
:streetViewControl="controls"
>
<q-icon class="pin" :name="pin.icon" :size="pin.size" :color="pin.color" />
<q-btn
class="full-width btnMio"
color="secondary"
:label="btnLabel"
@click="getLocation()"
:disable="btnPosition"
v-close-popup
/>
<Polygon v-for="(zone, Index) in DeliveryZones" :key="Index" :options="zone"/>
</GoogleMap>
<div class="text-subtitle1 text-center">
Locate your exact position on the map.
</div>
</template>
This is my JavaScript code for the map
<script>
import { computed, defineComponent, ref, inject, onUpdated } from "vue";
import { GoogleMap, Polygon } from "vue3-google-map";
import { useGeolocation } from "../boot/useGeolocation";
import axios from 'axios'
var pointInPolygon = require('point-in-polygon');
export default defineComponent({
name: "Map",
components: { GoogleMap, Polygon },
setup() {
onUpdated(() => {
// window.setTimeout(() => {
setGeocerca() <------ HERE PROBLEM
// }, 3000);
})
const mapPoint = inject('mapPoint')
const { coords } = useGeolocation();
const center = computed(() => ({
lat: coords.value.latitude,
lng: coords.value.longitude,
}));
const pin = ref(
{
color: 'secondary',
icon: 'person_pin_circle',
size: 'xl'
}
);
const apiKey = ref('MY_API_KEY')
const mapRef = ref();
const controls = ref(false);
const btnPosition = ref();
const btnLabel = ref('Estoy Aquí...');
const DeliveryZones =
[
{
name: 'Zona1',
strokeColor: "#00ff7a",
strokeOpacity: 0.5,
strokeWeight: 1,
fillColor: "#00ff7a",
fillOpacity: 0.05,
price: 2,
paths: [
{lat: 10.3816643, lng:-66.9812285 },
{lat: 10.3549424, lng:-66.9818722 },
{lat: 10.3549002, lng:-66.9317471},
{lat: 10.382213, lng:-66.9317471 },
{lat: 10.3816643, lng:-66.9812285 },
]
},
{
name: 'Zona2',
strokeColor: "#ff0000",
strokeOpacity: 0.5,
strokeWeight: 1,
fillColor: "#ff0000",
fillOpacity: 0.05,
price: 3,
paths: [
{lat: 10.38, lng:-66.98 },
{lat: 10.35, lng:-66.99 },
{lat: 10.36, lng:-66.93},
{lat: 10.37, lng:-66.95},
{lat: 10.38, lng:-66.98 },
]
}
]
let centerCurrent = null;
let tarifa = null;
function setPoligonToArray(poligon){
let arreglo = []
let arr=[]
for (let cords of poligon){
arr = [cords.lat, cords.lng]
arreglo.push(arr)
}
return arreglo
}
let prueba = 0
function setGeocerca() {
if(mapRef.value.ready) {
mapRef.value.map.addListener("center_changed",() => {
let activo = 0
for (const zone of DeliveryZones) {
const selectedPoint = [mapRef.value.map.getCenter().lat(), mapRef.value.map.getCenter().lng()]
if(pointInPolygon(selectedPoint, setPoligonToArray(zone.paths)) === true)
{
activo++
}
}
if(activo > 0) {
btnPosition.value = false
btnLabel.value = "Estoy Aquí..."
pin.value = {
color: 'secondary',
icon: 'person_pin_circle',
size: 'xl'
}
}else {
btnPosition.value = true
btnLabel.value = "Delivery no disponible para esta zona"
pin.value = {
color: 'primary',
icon: 'location_off',
size: 'xl'
}
}
});
}else{
console.log('Afuera' + prueba)
}
}
function getLocation() {
if (mapRef.value.ready) {
// mapPoint.value = mapRef.value.map.getCenter();
const selectedPoint = [mapRef.value.map.getCenter().lat(), mapRef.value.map.getCenter().lng()]
for (const zone of DeliveryZones) {
if(pointInPolygon(selectedPoint, setPoligonToArray(zone.paths)) === true)
{
tarifa = zone.price;
console.log(tarifa)
}
console.log(zone.name + ' = '+ pointInPolygon(selectedPoint, setPoligonToArray(zone.paths))); // true
}
const mapQuery = "https://maps.googleapis.com/maps/api/geocode/json?latlng="+selectedPoint+"&key=" + apiKey.value
console.log(mapQuery)
axios.get(mapQuery).then((result) => {
mapPoint.value = result.data.results[3].formatted_address;
})
}
}
return { center, getLocation, mapRef, controls, mapPoint, DeliveryZones, btnPosition, btnLabel, pin, apiKey};
},
});
</script>
onUpdated(() => { // window.setTimeout(() => { setGeocerca() <------ HERE THE PROBLEM IS JUST THIS FUNCTION DOES NOT WAIT FOR THE MAP TO LOAD AND GIVE ERROR THAT THE MAP REF OBJECT DOES NOT EXIST, OF COURSE IF I ACTIVATE THE TIMEOUT IT WORKS BUT IF THE LOAD TIME OF THE MAPREF COMPONENT IS GREATER THAN 3000 THE ERROR COMES BACK. // }, 3000); })