I got some trouble about implementing google map in vuejs. I was create polygon component like this:
<script>
export default {
name: "MapPolygon",
props: {
google: {
type: Object,
required: true
},
map: {
type: Object,
required: true
},
paths: {
type: Array,
required: true
}
},
mounted() {
const { Polygon } = this.google.maps;
new Polygon({
paths: this.paths,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: this.map,
});
},
render() {}
}
</script>
then when i click some data the polygon can't show on the map. This is my code:
<template>
<map-loader :map-config="mapConfig">
<template slot-scope="{google, map}">
<map-polygon
:google="google"
:map="map"
:paths="zone">
</map-polygon>
</template>
</map-loader>
</template>
<script>
import MapLoader from "../../../components/maps/MapLoader";
import MapPolygon from "../../../components/maps/MapPolygon";
export default {
name: "PolaRuang",
components: {MapPolygon, MapLoader},
data() {
return {
zone: [],
}
},
computed: {
mapConfig() {
return {
...mapSettings
}
},
},
methods: {
getMap(polaRuangId){
this.spinner = true;
axios.post(`/truang/service/pola/showPolaRuang/${polaRuangId}`)
.then(response => {
this.zonaRuang = response.data;
this.spinner = false;
})
.catch(error => {
this.spinner = false;
this.$toasted.global.error(error.response.data);
})
},
}
}
</script>
if i set the zone data static, the polygon show on the map, but when i set dynamic the polygon can't show. Could anyone here to help me to fixing this problem?
Thank You!
The problem was solved
i am adding the watch function for watching the newPath inside the polygon components. So, this is the code :
<script>
export default {
name: "MapPolygon",
props: {
google: {
type: Object,
required: true
},
map: {
type: Object,
required: true
},
paths: {
type: Array,
required: true
}
},
watch: {
async paths (newPaths) {
const { Polygon } = this.google.maps;
let polygon = new Polygon({
paths: newPaths,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35,
});
polygon.setMap(this.map);
}
},
mounted() {
const { Polygon } = this.google.maps;
new Polygon({
paths: this.paths,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: this.map,
});
},
render() {}
}
</script>
Related
I'm trying to make this work on my vue3 project but came to a very weird issue.
The same code works fine on vue2 but not on vue3 and there is no error shown, has anyone tried to use Google Data Driven Maps styling and figure out a way to use them in vue3?
Vue 3 Map(the map is loaded, but there is no data-driven styling included, no errors provided in console).: https://jsfiddle.net/dgalic/2pebj6ct/4/
const { createApp } = Vue
createApp({
name: 'MapStyling',
data: function() {
return {
no_data: [null, "", undefined, "null"],
mapName: "route-manager-map",
bounds: {},
map: {},
markers: {},
polylines: {},
};
},
mounted() {
this.defineMap()
},
methods: {
defineMap() {
/* eslint-disable */
// this.bounds = new google.maps.LatLngBounds();
const element = document.getElementById(this.mapName);
const options = {
center: { lat: 30.266666, lng: -97.733330 },
zoom: 12,
mapId: "map_id",
};
this.map = new google.maps.Map(element, options);
const featureLayer = this.map.getFeatureLayer(
google.maps.FeatureType.POSTAL_CODE
)
featureLayer.style = function (placeFeature) {
let fillColor = "blue";
if (postal_codes.includes(placeFeature.feature.displayName)) {
return {
fillColor,
fillOpacity: 0.5,
}
} else {
return {
fillColor,
fillOpacity: 0
}
}
}
const postal_codes = [
'78701',
'78702',
'78703',
'78704',
'78705'
]
}
}
}).mount('#app')
.google-map {
width: 100%;
height: 600px;
margin: 0 auto;
background: #e5e3df;
}
<script src="https://unpkg.com/vue#3"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=API-KEY&libraries=places&v=beta"></script>
<div id="app">
<div
class="google-map"
:id="mapName"
></div>
</div>
Vue 2 Map(works fine, same code): https://jsfiddle.net/dgalic/1wutoja2/8/
new Vue({
el: '#app',
name: 'MapStyling',
data: function() {
return {
no_data: [null, "", undefined, "null"],
mapName: "route-manager-map",
bounds: {},
map: {},
markers: {},
polylines: {},
};
},
mounted() {
this.defineMap()
},
methods: {
defineMap() {
/* eslint-disable */
// this.bounds = new google.maps.LatLngBounds();
const element = document.getElementById(this.mapName);
const options = {
center: {
lat: 30.266666,
lng: -97.733330
},
zoom: 12,
mapId: "map_id",
};
this.map = new google.maps.Map(element, options);
const featureLayer = this.map.getFeatureLayer(
google.maps.FeatureType.POSTAL_CODE
)
featureLayer.style = function(placeFeature) {
let fillColor = "blue";
if (postal_codes.includes(placeFeature.feature.displayName)) {
return {
fillColor,
fillOpacity: 0.5,
}
} else {
return {
fillColor,
fillOpacity: 0
}
}
}
// featureLayer = JSON.parse(JSON.stringify(featureLayer))
console.log(featureLayer.h.get('mapId'))
const postal_codes = [
'78701',
'78702',
'78703',
'78704',
'78705'
]
}
}
}).mount('#app')
.google-map {
width: 100%;
height: 600px;
margin: 0 auto;
background: #e5e3df;
}
<script src="https://unpkg.com/vue#2"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=API-KEY&libraries=places&v=beta"></script>
<div id="app">
<div class="google-map" :id="mapName"></div>
</div>
Any help or feedback would be much appreciated.
Below is a standard code taken from Google Map api V3 documentation. If you chnage the polygon options to editable and draggable, when you hover/click on the vertices of the polygon, you get the following error:
Uncaught TypeError: Cannot read property '__e3_' of null
The error is inconsistent in that it appears on an ad-hoc basis.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8
});
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.POLYGON,
drawingControl: false,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
},
markerOptions: { icon: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png' },
polygonOptions: {
fillColor: '#ffff00',
fillOpacity: 1,
strokeWeight: 5,
clickable: true,
editable: true,
draggable:true,
zIndex: 1
}
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'overlaycomplete', function (event) {
drawingManager.setDrawingMode(null);
});
}
initMap();
Is this a bug in the api ?
Would appreciate any input on this matter.
Many thanks.
Now I have my store: stuStore set up which contains some mock-up data.
I have another page which is a Google Map.
Student data structure: {name, geolocation,value, etc....}
I would like to display each of students info based on their locations which is inside of stuStore onto the google Map.
Here is the code:
Ext.define('myapp.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
fullscreen: true,
requires: [
'Ext.TitleBar',
'Ext.Video',
'Ext.Map',
'Ext.Panel',
'Ext.tab.*',
'Ext.*'
],
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'myapp',
iconCls:'maps',
xtype: 'map',
useCurrentLocation: true,
store: 'myapp.store.stuStore'
}
How can I do it?
Update 1
var mapdemo = Ext.create('Ext.Map', {
mapOptions: {
center: new google.maps.LatLng(-37.73228, 144.86900), //nearby San Fran
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.DEFAULT
}
},
title: 'MyApp',
iconCls: 'maps',
fullscreen: true,
xtype: 'map',
id: 'mainMap',
useCurrentLocation: false,
listeners: {
maprender: function (comp, googleMap) {
var store, latlng, marker;
store = Ext.getStore('myapp.store.stuStore');
store.each(function (record, index, length) {
latlng = new google.maps.LatLng(record.get('Lat'), record.get('Lng'));
marker = new google.maps.Marker({
position: latlng,
map: this
});
});
}
}
}),
infowindow = new google.maps.InfoWindow({
content: 'Sencha HQ'
});
Ext.define('myapp.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
fullscreen: true,
config: {
tabBarPosition: 'bottom',
items: [mapdemo],
}
});
This is my updated code in view\Main.js
But I don't get any markers and it keeps throwing an error:
Uncaught TypeError: Cannot call method 'each' of undefined
Incidentally, the icon on the toolbar which is docked at bottom of the screen is gone as well.
What can I try next?
You can create markers based on store records by looping through them in the maprender event callback like this:
Ext.define('myapp.controller.MapController', {
extend: 'Ext.app.Controller',
config: {
refs: {
mapComponent: 'main map'
},
control: {
mapComponent: {
maprender: 'onMaprender',
}
}
},
onMaprender: function(mapComponent, googleMap) {
var store, latLng, marker;
// Get store
store = Ext.getStore('myapp.store.stuStore')
// On each store record
store.each(function(record, index, length) {
// Get position
latLng = new google.maps.LatLng(record.get('lat'), record.get('lng'));
// Create marker
marker = new google.maps.Marker({
position: latLng,
map: googleMap
});
});
}
});
Have a look at this Sencha Fiddle I put together.
I am trying to let a user drop up to 10 markers and remove them onClick. I also have it updating a "div" with the coordinates of the markers on the map when a user adds a marker or drags. I have everything working except for when the user deletes a marker, it's still seems to be on the map when I loop through the markers. Any idea what I'm doing wrong?
jsFiddle: jsfiddle.net/ryanverdel/WRyrJ/
Code:
$(document).ready(function () {
var markerCount = 0;
$("#test1").gmap3({
map: {
options: {
center: [-2.2214281090541204, -78.695068359375],
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
scrollwheel: true,
disableDoubleClickZoom: true,
streetViewControl: false,
},
events: {
click: function (map, event) {
if(markerCount < 10){
$(this).gmap3(
{
marker: {
latLng: event.latLng,
options:{
draggable: true,
animation: google.maps.Animation.DROP,
},
events: {
click: function(marker) {
marker.setMap(map);
marker.setMap(null);
marker = null;
delete marker;
console.log(marker);
markerCount--;
},
dragend: function(marker) {
$("#inputArray").empty();
setTimeout(function(){
var markers = $("#test1").gmap3({
get: {
all: true
}
});
$.each(markers, function(i, marker){
$("#inputArray").append('<p>{"latitude":' + marker.position.lat() +', '+ '"longitude":' + marker.position.lng() +'},'+'</p>');
});
}, 400);
}
},
},
});
markerCount++;
$("#inputArray").empty();
setTimeout(function(){
var markers = $("#test1").gmap3({
get: {
all: true
}
});
$.each(markers, function(i, marker){
$("#inputArray").append('<p>{"latitude":' + marker.position.lat() +', '+ '"longitude":' + marker.position.lng() +'},'+'</p>');
});
}, 400);
}
else{
return false;
};
}
}
}
});
});
This sort of thing is maybe less than straightforward in gmap3. You need a slightly different mindset compared with that required for the direct google.maps API.
Thee main poitns :
You need to provide the markers with an id, name or tag
You need to remove the marker with clear
You need to make judicious use of callbacks (the gmap3 way).
Here's your code unravelled into a set of functions, with the necessary fixes applied
$(document).ready(function () {
var mapOpts = {
center: [-2.2214281090541204, -78.695068359375],
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
scrollwheel: true,
disableDoubleClickZoom: true,
streetViewControl: false,
};
function genId() {
return '' + (new Date()).getTime();
}
function addMarker(map, event) {
if (markerCount < 10) {
var uid = genId();
$(this).gmap3({
marker: {
latLng: event.latLng,
options: {
draggable: true,
animation: google.maps.Animation.DROP
},
events: {
click: function() {
clearMarker(uid);
},
dragend: listMarkers
},
id: uid
}
});
markerCount++;
listMarkers();
} else {
return false;
};
}
function listMarkers() {
$("#test1").gmap3({
get: {
all: true,
callback: function(results) {
$("#inputArray").empty();
$.each(results, function (i, marker) {
$("#inputArray").append('<p>{"latitude":' + marker.position.lat() + ', ' + '"longitude":' + marker.position.lng() + '},' + '</p>');
});
}
}
});
}
function clearMarker(uid) {
$('#test1').gmap3({
clear: {
id: uid,
callback: function() {
listMarkers();
markerCount--;
}
}
});
}
var markerCount = 0;
$("#test1").gmap3({
map: {
options: mapOpts,
events: {
click: addMarker
}
}
});
});
DEMO
Is it possible to load many different layers from the same fusiontable in a map? Im trying that, and its not working. Is it a limitation with fusiontablelayer?
var Mu = new google.maps.FusionTablesLayer({
query: {
select: 'geometry',
from: '1Md0G-C9PCc4ulq7hDyOPn8ZCaJ0a5WHyATrPC3Q',
where: "name = '02005'"
},
styles: [{
polygonOptions: {
fillColor: "#ff9900",
fillOpacity: 0.7,
strokeColor: "#808080",
strokeWeight: 6
}
}]
});
Mu.setMap(map);
var mun = new google.maps.FusionTablesLayer({
query: {
select: 'geometry',
from: '1Md0G-C9PCc4ulq7hDyOPn8ZCaJ0a5WHyATrPC3Q',
},
styles: [{
polygonOptions: {
fillColor: "#008000",
fillOpacity: 1.0,
strokeColor: "#000080",
strokeWeight: 1
}
}]
});
mun.setMap(map);
As described in the documentation under "Limits", it is possible to load up to 5 FusionTablesLayers on a single map (shouldn't matter whether it is from the same table or multiple tables), only one of those layers can be dynamically styled with up to 5 styles.