Cannot fit bounds in mapbox-gl , in Vue app - vue.js

I am using vue 2.6.10 and I have the following dependencies vue-mapbox 0.4.1 and mapbox-gl 1.3.2
The map works, but I cannot get all the points of the map, create bounds and make the map zoom there.
What I am doing now, based on this and this
In my template
<MglMap
ref="map"
#load="mapLoaded()">
and then in my javascript
import Mapbox from "mapbox-gl";
components: { Mapbox}
methods :{
mapLoaded(){
let coords = [];
//coords is array , contains arrays like [-118.578, 51.524]
let bounds = coords.reduce((bounds, coord)=> {
return bounds.extend(coord);
}, this.mapbox.LngLatBounds(coords[0], coords[0])
);
this.$refs['map'].map.fitBounds(bounds, { padding: 20 });
}
},
created(){
this.mapbox = Mapbox;
}
This should work, but I keep getting
TypeError: this.setSouthWest is not a function
so I guess there is a problem in this.mapbox.LngLatBounds(coords[0], coords[0]) , maybe the this.mapbox. or the LngLatBounds does not work.
If I console log the coords[0], prints an array [10.467778, 37.600833]
What am I missing? Thanks

I have got the same error. Turns out I have missed "new" keyword.
You can try adding the "new" keyword for "this.mapbox.LngLatBounds"
The following code worked for me.
import mapboxgl from 'mapbox-gl';
Vue.prototype.$maps = mapboxgl
this.map = new this.$maps.Map({container: 'mapContainer', // container ID
style: 'mapbox://styles/mapbox/streets-v11', // style URL
zoom: 9 // starting zoom
});
const sourceMarker = new this.$maps.Marker().setLngLat(origin).addTo(this.map);
const destMarker = new this.$maps.Marker().setLngLat(destination).addTo(this.map);
const bounds = new this.$maps.LngLatBounds(origin, destination);
this.map.fitBounds(bounds);

Related

Vuejs3 external library undefined funtion

I am currently working on a Vuejs3 application with the fabricjs library added.
Now I am trying to add an external library called fabricPublisherTools in the application. But the method/function "_registerSnaps" that is being called is somehow "undefined".
The external library gives me the following working example.
<script type="module">
import {fabricAddSnapper,fabricAddSmartGuides} from 'https://cdn.jsdelivr.net/gh/mtrudw/fabricPublisherTools/dist/fabricPublisherTools.min.js';
fabricAddSnapper();
fabricAddSmartGuides();
var canvas = new fabric.Canvas('c4');
var rect = new fabric.Rect({left: 100,top:100,width:150,height:100,fill:'blue'});
var rect2 = new fabric.Rect({left: 500,top:500,width:150,height:100,fill:'green'});
var rect3 = new fabric.Rect({left: 400,top:200,width:150,height:100,fill:'yellow'});
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
rect.doesSnap();
rect2.doesSnap();
rect3.doesSnap();
canvas.add(rect,rect2,rect3);
</script>
The way I implemented in Vuejs3 is as follows:
<script setup>
import { onMounted } from "vue"
import { fabric } from 'fabric';
import {fabricAddSmartGuides,fabricAddSnapper,fabricAddUndoRedo} from 'https://cdn.jsdelivr.net/gh/mtrudw/fabricPublisherTools/dist/fabricPublisherTools.min.js';
let canvas;
const setupEditor = () => {
fabricAddSnapper();
fabricAddSmartGuides();
canvas = new fabric.Canvas('canvas');
canvas.setHeight(500);
canvas.setWidth(500);
canvas.backgroundColor = "#f00";
canvas.setDimensions({width: 500, height: 500});
var rect = new fabric.Rect({left: 100,top:100,width:150,height:100,fill:'blue'});
var rect2 = new fabric.Rect({left: 500,top:500,width:150,height:100,fill:'green'});
var rect3 = new fabric.Rect({left: 400,top:200,width:150,height:100,fill:'yellow'});
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
rect.doesSnap();
rect2.doesSnap();
rect3.doesSnap();
canvas.add(rect,rect2,rect3);
canvas.renderAll();
}
onMounted(() => {
setupEditor()
})
</script>
It gives me the following error when I try to run it:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'bind')
And its about this line:
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
When I console log "_registerSnaps" I see it's undefined which means something has not been appended/added by the library.
I just don't know if I did something wrong when I imported the library that caused the problem.
What exactly am I doing wrong?
Thank you in advance.
If bind is what's undefined, have you checked if your problem is with _getSmartGuides since that is what calls the bind() function?
You'll need to call fabricAddSmartGuides();
purely from reading the (fabricPublisherTools) source: _getSmartGuides is created in fabricAddSmartGuides(). Do you / where do you call fabricAddSmartGuides ?

HERE Maps JS API 3.1.30.17 used in VUE - Error for style group 'non-collision' in Firefox

I've build a simple Here Map using Vue 2 and the JS API in version 3.1.30.17. The map works fine in all browsers except Firefox v102.
This is the error message in Firefox:
Tangram [error]: Error for style group 'non-collision' for tile 20/7/68/41/7 CanvasRenderingContext2D.drawImage: Passed-in canvas is empty: loadTexture#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:417267
e/sn.addWorker/<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:63015
EventListener.handleEvent*e/sn.addWorker#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:62515
e/value/<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:515089
value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:515502
value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:514847
e/value/this.initializing<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:511497
promise callback*value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:511472
Ul#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:335:441
p.eh#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:378:446
p.Ge#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:329:436
p.Ge#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:376:356
S#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:369:214
T.prototype.u#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:410:166
T#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:401:290
... The error is even bigger
The following method I'm using to init Here Maps inside Vue's mounted:
async initializeHereMap() {
const mapContainer = this.$refs.hereMap;
const H = window.H;
// Initialize the platform object:
this.platform = new H.service.Platform({
apikey: this.apiKey,
});
await this.geocode(this.platform, this.originAddress)
.then(data => this.routingParameters.origin = data[0]);
await this.geocode(this.platform, this.destinationAddress)
.then(data => this.routingParameters.destination = data[0]);
// Obtain the default map types from the platform object
const defaultLayers = this.platform.createDefaultLayers({
lg: window.navigator.language,
});
// Instantiate (and display) a map object:
const map = new H.Map(mapContainer, defaultLayers.vector.normal.map, {
zoom: this.zoom,
center: this.center,
padding: {
top: this.padding,
bottom: this.padding,
left: this.padding,
right: this.padding,
},
});
// create map pins
const mapPinOrigin = this.addMapPin('A', 40);
const mapPinDestination = this.addMapPin('B', 40);
let linestring = new H.geo.LineString();
linestring.pushPoint(this.routingParameters.origin);
linestring.pushPoint(this.routingParameters.destination);
// Create a polyline to display the route:
let routeLine = new H.map.Polyline(linestring, {
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
});
// Create a marker for the start point:
let startMarker = new H.map.Marker(this.routingParameters.origin, { icon: mapPinOrigin });
// Create a marker for the end point:
let endMarker = new H.map.Marker(this.routingParameters.destination, { icon: mapPinDestination });
// Add the route polyline and the two markers to the map:
map.addObjects([routeLine, startMarker, endMarker]);
// Set the map's viewport to make the whole route visible:
map.getViewModel().setLookAtData({bounds: routeLine.getBoundingBox()});
// add behavior control
if (this.behaviors) new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// add UI
if (this.controls) H.ui.UI.createDefault(map, defaultLayers);
},
Is there some one facing the same issue and could solved it?
Did you follow this example on: https://developer.here.com/tutorials/how-to-implement-a-web-map-using-vuejs/ ?
Tangram error is related to rendering e.g. when render map objects (like icons, markers, polylines etc.) and map vector tiles.
I don't think so that this issue related to HERE JS Map API.
Because all examples on https://developer.here.com/documentation/examples/maps-js are working well on my FireFox 102.0.1
It could be some map objects like icons or markers etc. are created in some moment but is not finished yet and then try to push onto map? Creating an icon in some asynchron function?
Or in like your code:
await this.geocode(this.platform, this.originAddress)
.then(data => this.routingParameters.origin = data[0]);
You don't know when func geocode will be finished (e.g. due slow internet connectivity)
It could be this command above is not done yet, but your code is already start to run this code:
linestring.pushPoint(this.routingParameters.origin);<-- 'this.routingParameters.origin' could be null
linestring.pushPoint(this.routingParameters.destination);
// Create a polyline to display the route:
let routeLine = new H.map.Polyline(linestring, { <-- Could cause Tangram error because 'linestring' is strange due undefined origin yet!
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
});
The polyline options is not correct in:
new H.map.Polyline(linestring, {
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
}
Why in above the 'linestring' is second time in options?
Please follow correct syntax on:
https://developer.here.com/documentation/maps/3.1.31.0/api_reference/H.map.Polyline.html#.Options

Access or modify petite-vue data outside app

I'm using petite-vue as I need to do very basic UI updates in a webpage and have been drawn to its filesize and simplicity. I'd like to control the UI's state of visible / invisible DOM elements and class names and styles of various elements.
I have multiple JavaScript files in my app, I'd like to be able to make these changes from any of them.
In Vue JS it was possible to do things like this...
const vueApp = new Vue({ el: "#vue-app", data(){
return { count: 1}
}})
setTimeout(() => { vueApp.count = 2 }, 1000)
I'm trying the same with Petite Vue but it does nothing.
// Petite Vue
const petiteVueApp = PetiteVue.createApp({
count: 0,
}).mount("#petite-vue");
setTimeout(() => { petiteVueApp.count = 2 }, 1000);
Logging the app gives just a directive and mount attribute, I can't find the count (nb if you log the above app it will show the count, because of that line petiteVueApp.count = 2, that isn't the data)
Demo:
https://codepen.io/EightArmsHQ/pen/YzemBVB
Can anyone shed any light on this?
There is an example which does exactly this in the docs which I overlooked.
https://github.com/vuejs/petite-vue#global-state-management
It requires an import of the #vue/reactivity which can be imported from the petite-vue bundle.
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
setTimeout(() => { vueApp.count = 2 }, 1000)
const store = reactive({
count: 0,
inc() {
this.count++
}
})
createApp({
store
}).mount("#petite-vue")
setTimeout(() => { store.count = 2 }, 1000);
Updated working example:
https://codepen.io/EightArmsHQ/pen/ExEYYXQ
Interesting. Looking at the source code it seems that we would want it to return ctx.scope instead of return this.
Your workaround seems like the best choice if using petite-vue as given, or you could fork petite-vue and change that one line (I haven't tested this).

I am trying to load a texture onto a Sphere in Nuxt using Three

I am trying to add a texture to a sphere, specifically by mapping an image to it using TextureLoader.
However, I can add the material perfectly fine, without the image that is. For example, if I removed the line "map: TextureLoader().load(earthUV)" and replaced it with "color: 0xFF0000", the sphere would load perfectly fine with no errors, but with the TextureLoader I just receive the error log found below.
Please feel free to ask questions as I do not know what else I should provide to help fix this error.
Error Log:
TypeError: Cannot set properties of undefined (setting 'manager')
at Loader (three.module.js?5a89:34164:1)
at TextureLoader (three.module.js?5a89:34947:1)
at VueComponent.mounted (about.vue?9043:39:1)
at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1863:1)
at callHook (vue.runtime.esm.js?2b0e:4235:1)
at Object.insert (vue.runtime.esm.js?2b0e:3158:1)
at invokeInsertHook (vue.runtime.esm.js?2b0e:6390:1)
at Vue.patch [as __patch__] (vue.runtime.esm.js?2b0e:6538:1)
at Vue._update (vue.runtime.esm.js?2b0e:3960:1)
at Vue.updateComponent (vue.runtime.esm.js?2b0e:4075:1)
Please find the code for my attempt below:
<template>
<div>
<canvas ref="aboutCanvas"></canvas>
</div>
</template>
<script>
import {
Scene,
PerspectiveCamera,
WebGLRenderer,
Mesh,
SphereGeometry,
MeshBasicMaterial,
TextureLoader,
} from "three";
import earthUV from "~/assets/earthUV.jpg";
export default {
mounted() {
const scene = new Scene();
const camera = new PerspectiveCamera(
75,
innerWidth / innerHeight,
0.1,
1000
);
const renderer = new WebGLRenderer({
canvas: this.$refs.aboutCanvas,
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
// Create a sphere
const sphere = new Mesh(
new SphereGeometry(5, 50, 50),
new MeshBasicMaterial({
map: TextureLoader().load(earthUV)
})
);
// Add objects into scene
scene.add(sphere);
camera.position.z = 10;
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
},
};
</script>
When creating a TextureLoader, you have to use the new keyword. You can use that single TextureLoader multiple times to load as many textures as you need.
const texLoader = new TextureLoader();
const sphere = new Mesh(
new SphereGeometry(5, 50, 50),
new MeshBasicMaterial({
map: texLoader.load(earthUV)
})
);

Unable to create polygon graphic using SketchViewModel() in arcgis js 4.11

I am using vuejs as my frontend framework and esri-loader to load arcgis js 4.11 in vue.I am beginner in arcgis js api and trying to use SketchViewModel to draw a polygon. However, when I use create() function, I am getting sketchVM.create is not a function as error.
I followed arcgis js 4.11 SketchViewModel's documentation
I have divided the code for arcgis js in two methods:- one method is responsible for loading map and view, and another is used to draw polygon.
views/mapView.vue
<script>
...
draw(){
loadModules(
[
"esri/layers/GraphicsLayer",
"esri/widgets/Sketch/SketchViewModel",
"esri/geometry/geometryEngine"
],
{
url: "https://js.arcgis.com/4.11/" // use a specific version
}
).then(
([
SketchViewModel,
geometryEngine,
GraphicsLayer
]) => {
console.log("Area section active")
this.view.surface.style.cursor = "crosshair"; // change cursor style to crosshair
this.graphicsLayer = new GraphicsLayer();
// needed to sketch polygon
var sketchVM = new SketchViewModel({
layer: this.graphicsLayer, // graphics layer over which polygon will be added
view: this.view, // view where polygon will be rendered
updateOnGraphicClick: true, // to allow graphic updation on through click event
defaultUpdateOptions:{
tool:'reshape', // this will set reshape as default tool for update event
},
polygonSymbol: { // style and type for polygon symbol
type: "simple-fill",
color: "rgba(138,43,226, 0.8)",
style: "solid",
outline: {
color: "white",
width: 1
}
}
});
sketchVM.on("create", (event)=>{
if(event.state === "complete"){
console.log(geometryEngine.planarArea(this.graphicsLayer.graphics.items[0].geometry, "square-meters"))
}
});
sketchVM.on("update", (event)=>{
// if() // event to remove graphic on pressing delete key
console.log("Updated value state : ",event.state)
});
console.log("drawing mode on")
sketchVM.create("polygon", {mode:"click"}); // getting error at this line
console.log("draw view returned")
return this.view;
}
);
},
...
</script>