Not able to clear previous directions gmap3 jquery - direction

I am trying to generate the direction on a button click. User selects locations point a and point b and then press a button and code draw direction from that point a to point b. I have successfully completed this code but I am not able to remove the previous directions drawn on map. Please see the image link http://i.stack.imgur.com/z1fqo.png
. I want to remove the a,b direction from the map as it was last direction.
$et_main_map.gmap3({
getroute:{
options:{
origin:org,
destination:dest,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
console.log(results);
if (!results) return;
$(this).gmap3({
directionsrenderer:{
divId:'directionPath',
options:{
directions:results,
suppressMarkers: true
}
}
});
}
}
});
The above code adds the directions.
The below code is not removing the directions on map.
$et_main_map.gmap3({
clear: {
name:["directionRenderer"]
}
});
I have tried many things for eg followed below links.
http://gmap3.net/forum/viewtopic.php?id=341
Gmap3 Clear Directions
Please help me.
Thanks

You should give directionsrenderer function an ID ("whatEverYourID") so that it will be recognized when clear function is called:
$et_main_map.gmap3({
getroute:{
options:{
origin: org,
destination: dest,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
console.log(results);
if (!results) return;
// this is addition lines for handling directions container------
if (!$("#dircontainer").length>0) {
$("<div id='dircontainer' class='googlemap'></div>").insertAfter("#map");
} else {
// this will clear previous the googlemap directions html container
$("#dircontainer").html("");
}
// --------------------------------------------------------------
$(this).gmap3({
// clear previous direction
clear: {
id: "whatEverYourID"
},
map:{
options:{
center:[tolat, tolong],
zoom: 10
}
},
directionsrenderer:{
container: $("#dircontainer"),
options:{
directions:results
},
// this is the ID you have to add
id: "whatEverYourID"
}
});
}
}
});
I hope it will help

I needed to update my gmap3 library. For those who want to fix this issue just update gmap3.js to version 5.1.1. This will fix the issue.

Related

AFrame Text change rotation

I'm making a virtual tour using AFrame, with a <a-sky> for the 360° images, some <a-circle> for hotspots, and <a-text> below circles for indications.
My goal is to make texts always parallel to the screen. I already try the aframe-look-at-component on the camera, but it's not what I was looking for because they face a point instead of facing the screen.
So my next idea was to create an invisible cursor, and copy his rotation the the texts, but I'm not sure of this because I don't know if the cursor update his rotation or if it's only base on the cam rotation.
Anyway the main source of this problem was I don't know how to change the rotation of my text after creation, I tried mytext.object3D.rotation, mytext.setAttribute('rotation', newRotation), and also object3D.lookAt(), but either it didn't matter, or it wasn't what I was looking for.
What is the best way to achieve this ?
Here my hotspot component (which create the texts based on some props):
AFRAME.registerPrimitive('a-hotspot', {
defaultComponents: {
hotspot: {}
},
mappings: {
for: 'hotspot.for',
to: 'hotspot.to',
legend: 'hotspot.legend',
'legend-pos': 'hotspot.legend-pos',
'legend-rot': 'hotspot.legend-rot'
}
});
AFRAME.registerComponent('hotspot', {
schema: {
for: { type: 'string' },
to: { type: 'string' },
legend: { type: 'string' },
'legend-pos': { type: 'vec3', default: {x: 0, y: -0.5, z:0}},
'legend-rot': { type: 'number', default: 0 },
positioning: { type: 'boolean', default: false }
},
init: function () {
this.shiftIsPress = false
window.addEventListener('keydown', this.handleShiftDown.bind(this))
window.addEventListener('keyup', this.handleShiftUp.bind(this))
this.tour = document.querySelector('a-tour');
if (this.data.legend)
this.addText();
this.el.addEventListener('click', this.handleClick.bind(this));
},
// Creating the text, based on hotspots props
addText: function () {
var hotspot = this.el,
position = new THREE.Vector3(hotspot.object3D.position.x, hotspot.object3D.position.y, hotspot.object3D.position.z),
text = document.createElement('a-text'),
loadedScene = document.querySelector('a-tour').getAttribute('loadedScene')
position.x += this.data['legend-pos'].x
position.y += this.data['legend-pos'].y
position.z += this.data['legend-pos'].z
console.log(this.data['legend-rot'])
// Set text attributes
text.id = `text_${this.data.for}_to_${this.data.to}`
text.setAttribute('position', position)
text.setAttribute('color', '#BE0F34')
text.setAttribute('align', 'center')
text.setAttribute('value', this.data.legend)
text.setAttribute('for', this.data.for)
if (loadedScene && loadedScene !== this.data.for) text.setAttribute('visible', false)
// Insert text after hotspot
hotspot.parentNode.insertBefore(text, hotspot.nextSibling)
},
// This part is supposed to edit the rotation
// to always fit to my idea
tick: function () {
if (this.el.getAttribute('visible')) {
var cursorRotation = document.querySelector('a-cursor').object3D.getWorldRotation()
//document.querySelector(`#text_${this.data.for}_to_${this.data.to}`).object3D.lookAt(cursorRotation)
this.updateRotation(`#text_${this.data.for}_to_${this.data.to}`)
}
},
// This parts manage the click event.
// When shift is pressed while clicking on hotspot, it enable another component
// to stick a hotspot to the camera for help me to place it on the scene
// otherwise, it change the 360° image and enbable/disable hotspots.
handleShiftDown: function (e) {
if (e.keyCode === 16) this.shiftIsPress = true
},
handleShiftUp: function (e) {
if (e.keyCode === 16) this.shiftIsPress = false
},
handleClick: function (e) {
var target = 'target: #' + this.el.id
var tour = this.tour.components['tour']
if (this.shiftIsPress)
tour.el.setAttribute('hotspot-helper', target)
else
tour.loadSceneId(this.data.to, true);
}
});
I really don't know what to do..
EDIT: I found a part solution:
If I had geometry to my text (and material with alphaTest: 1 for hide it), setAttribute('rotation') work, and I base it on camera rotation. The problem is that after that, the camera is locked, don't understand why ^^
var cursorRotation = document.querySelector('a-camera').object3D.rotation
document.querySelector(`#text_${this.data.for}_to_${this.data.to}`).setAttribute('rotation', cursorRotation)
Thanks,
Navalex
I finally found the solution !
Instead of document.querySelector('a-camera').object3D.rotation, I used document.querySelector('a-camera').getAttribute('rotation') and it's work nice !
Be sure to check out the example here: https://stemkoski.github.io/A-Frame-Examples/sprites.html
The 'box' sign is always visible to user

Why isn't my AJAX call to an HTTPHandler working?

I am attempting to re-create the solution seen here for keeping a session alive by using an HTTPHandler and making an AJAX call to it.
The solution does not appear to have worked, and when I tried to debug it by adding an alert(); just before the $.get(); the alert(); never got fired off. I copied and pasted the code from the example, so I'm not missing a semicolon or something. I even set an alert(); before the setTimeout(); and that one worked!
function setHeartbeat() {
alert("I get here!");
setTimeout("heartbeat()", 300000); // every 5 min
}
function heartbeat() {
alert("I never seem to fire off!");
$.get(
"/SessionHeartbeat.ashx",
null,
function(data) {
setHeartbeat();
},
"json"
);
}
Any thoughts?
Both slon and Hans Kesting were right one the money.
The working javascript is:
$(document).ready(function () {
//alert("Document is ready.");
// set the initial call
setHeartbeat();
function setHeartbeat() {
//alert("setHeartbeat");
setInterval(function () {
heartbeat();
}, 10000); // every 10 sec
}
function heartbeat() {
//alert("heartbeat");
$.get(
"/SessionHeartbeat.ashx",
null,
function(data) {
setHeartbeat();
},
"json"
);
}
});
Thank you both!

Polymer property not updating when set from Javascript

I have made this simple property (Polymer 2.x):
static get properties() {
return {
bpm: {
type: Number,
value: () => {
return 0
},
observer: "_bpm"
}
}
}
I tried to update it using this.bpm = 60; in a function called when clicking a button. If I output the value using console.log(this.bpm); it displays the correct value, but my heading <h2 id="bpm">[[bpm]]</h2> is not updated and the observer is not called.
When bpm is set using something like <paper-slider value="{{bpm}}"></paper-slider> it works.
What am I doing wrong? Thank you for your help!
It will be easier for the community to know that this question was answered into the comments of the requests.
Initial problem : Binding value not updated because bpm property was set from a function outside of the element.
Correction : Here a working JSFiddle (to use in chrome) used to demonstrate how to use the binding.
I also faced similar issue due to setting the property from a different function. Putting it here for reference.
My code:
Polymer({
is: 'test-test',
properties: {
min: {
type: Number,
value: -1,
observer: '_minChangedd'
}
},
_minChangedd: function (val) {
console.log(val);
},
ready: function () {
setInterval(function () {
this.min = this.min + 1;
}, 500);
},
});
Problem:
The setInterval function had its own this and so the expression this.min actually refers to min of setInterval.
Using arrow functions resolved the issue, by replacing the call with setInterval(() => {...});

How to load Google Maps API with RequireJS?

I am struggling to load gmaps api with requireJS . This is what I've tried:
requirejs.config({
urlArgs: "noCache=" + (new Date).getTime(),
paths : {
"jquery": "vendor/jquery-1.8.2.min",
"bootstrap": "vendor/bootstrap.min",
"underscore": "libs/underscore-min",
"backbone": "libs/backbone-min",
"template": "libs/template",
"gmaps": "http://maps.google.com/maps/api/js?v=3&sensor=false"
},
shim: {
'backbone': {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'bootstrap': {
deps: ['jquery']
},
'gmaps': {
deps: ['jquery']
},
'main':{
deps: ['jquery','gmaps']
}
}
});
require(["main"], function (main) {})
But inside main.js when I try to instantiate the geocoder i got ,,undefined is not a function" error.
var geocoder = new google.maps.Geocoder();
Any ideas what could I be doing wrong?
I've managed to sort it out with the async plugin.
A quick example is:
require.config({
paths: {
'async': 'lib/requirejs-plugins/src/async'
}
});
define(['async!http://maps.google.com/maps/api/js?sensor=false'], function() {
// Google Maps API and all its dependencies will be loaded here.
});
Thanks to user1706254 cause official documentation : https://github.com/millermedeiros/requirejs-plugins/ was using the keyword 'define' that wasn't working for me but 'require' is working fine.
I couldn't load directly :
require(["goog!maps,3,other_params:sensor=false"], function(){});
But using the asynchronous way did the trick :
require(['async!http://maps.google.com/maps/api/js?sensor=false'], function(){});
You don't need the async plugin to use Google Maps with require.js. The goal can be achieved using only a simple shim config:
require.config({
paths: {
gmaps: '//maps.googleapis.com/maps/api/js?' // question mark is appended to prevent require.js from adding a .js suffix
},
shim: {
gmaps: {
exports: 'google.maps'
}
}
});
require(['gmaps'], function (gmaps) {
var center = {lat: -34.397, lng: 150.644};
var map = new gmaps.Map(document.getElementById('map'), {
center: center,
zoom: 8
});
new gmaps.Marker({
map: map,
position: center
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script>
<div id="map" style="width: 100%; height: 200px"></div>
Following on from hjuster here's a quick example of how to use the async plugin
https://gist.github.com/millermedeiros/882682
There is also goog plugin (requires async and propertyParser), available on github
Usage example for google maps:
require(["goog!maps,3,other_params:sensor=false"], function(){});
#hjuster's answer led me the way and I've solved by a callback function.
define(['async!http://maps.google.com/maps/api/js?key=YOURKEY!callback'],
function (_ExpectedMap) {
callback();
});
Notice the !callback at the end of the url starts with async!, callback method is being called when load operation is done.
function callback()
{
//Now load google maps API dependant libraries
require(['gmapsLib'], function (googlemaps) {
window.GMaps = googlemaps;
}
}
There is another question I lately noticed, another function (onLoad) is in use instead of callback to prevent from timeout error. Interesting.
Couldn't make the plugins work for some reason, but this workaround saved my day:
require(['https://apis.google.com/js/client.js?onload=doNothing'], function() {
// Poll until gapi is ready
function checkGAPI() {
if (gapi && gapi.client) {
self.init();
} else {
setTimeout(checkGAPI, 100);
}
}
checkGAPI();
});
});
Just check if gapi is ready every 100 millisec, until it finally loads.
Found the code in this article http://dailyjs.com/2012/12/06/backbone-tutorial-2/
I guess you can also try it with
if (google && google.maps && google.maps.Geocoder) {
// now google.maps.Geocoder is gonna be defined for sure :)
}

How to remove rendered route using gmap3 plugin?

I use GMAP3 plugin to render driving direction. And would like to add a clear button so it can be clear but I haven't been able to find the right syntax in GMAP3. Here is the my js code, modified from the sample in gmap3.net. I have markers plotted already and latlng are retreived from plotted markers instead of from clicks position on the map.
function removePath() {
$(mapID).gmap3({
action: 'clear',
name: 'directionRenderer'
// tag: 'path' // works too with tag instead of name
});
function updatePath() {
$(mapID).gmap3({
action: 'getRoute',
options: {
origin: m1.getPosition(),
destination: m2.getPosition(),
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function (results) {
if (!results) return;
$(mapID).gmap3({
action: 'setDirections',
directions:results,
});
}
});
};
function updateDirection(mm) { // Directions between m1 and m2
var mmID = $(mm).prop('id');
...
if (mmID == 'clearDirection') {
...
removePath();
return;
};
...
if (m1 && m2) { updatePath(); };
};
function initmap() {
$(mapID).gmap3(
{
action: 'init',
options: defaultMapOptions
},
// add direction renderer to configure options (else, automatically created with default options)
{ action: 'addDirectionsRenderer',
preserveViewport: true,
markerOptions: { visible: false },
options: {draggable:true},
tag: 'path'
},
// add a direction panel
{ action: 'setDirectionsPanel',
id: 'directions'
}
);
};
A is in place in HTML documents as directions panel. It has a a wrapper which is hidden when the route is cleared by using jquery css property change. The wrapper div's display property is changed back to 'block' whenever value is assigned to either m1 or m2.
<body>
...
<div id="direction_container" class="shadowSE">
....
<div id="directions"></div>
....
</div>
</body>
Its absolutely working fine.
$map.gmap3({ action: 'clear', name: 'directionRenderer' });
*Instructions-
If you later draw the route then you must write below code otherwise directions not display.
$map.gmap3({ action: 'addDirectionsRenderer', preserveViewport: true,
markerOptions: { visible: false} },
{ action: 'setDirectionsPanel', id: 'directions' });
Thanks...
Use this:
$(mapID).gmap3({action:"clear", name:"directionRenderer"});
The chosen answer above didn't work for me. I'm unsure if it's version related, but the solution I'm using is more simple:
$(your-selector).gmap3({clear: {}});
Afterwards, you can draw a new route without reconnecting the directions rendered with the map.

Resources