I'm new about Laflet Routing Machine (liedman) https://www.liedman.net/leaflet-routing-machine/ and I would like to update the first route calculated every 30 seconds because I would like refresh it and I don't need to make many server request.
I'll make a setInterval but at the moment I need to know if it works and if this is the way... this is my code:
routingControl = L.Routing.control({
waypoints: [
L.latLng(43.12, 11.99),
L.latLng(43.37, 12.08)
]
createMarker: function() { return null; },
routeWhileDragging: false,
draggableWaypoints: false,
reverseWaypoints: false,
fitSelectedRoutes: true,
addWaypoints: false
}).addTo(OSM_Map);
var newLat = routingControl.options.waypoints[0].lat+0.01;
var newLng = routingControl.options.waypoints[0].lng+0.01;
setTimeout(function () {
routingControl.options.waypoints=[
L.latLng(newLat, newLng),
routingControl.options.waypoints[1]
];
}, 10000);
With setTimeout I change the start point (adding 0.01) and checking the waypoints with console.dir they are changed but not the drawn route... how I can refresh it?
The options are only used when initializing the routing control. Changing them afterwards does nothing, since the control uses its own waypoints internally.
You should be able to use the setWaypoints function like this
setInterval(function () {
var newWaypoint = routingControl.getWaypoints()[0].latLng;
var newLat = newWaypoint.lat + 0.01;
var newLng = newWaypoint.lng + 0.01;
routingControl.setWaypoints([
L.latLng(newLat, newLng),
routingControl.options.waypoints[1]
]);
}, 10000);
Unlike the options, the getWaypoints always returns the current waypoints, so you can freely modify them.
setWaypoints will then trigger a change event for the routes and update them accordingly.
Here's a working fiddle you can play around with
Related
I am trying to implement a in browser raster drawing plugin for the leaflet library that that extends the leaflets GridLayer api. Essentially for every tile there is function createTile that returns a canvas with some drawing on it. and leaflet shows the tile in correct position.
initialize: function(raster_data){
this.raster_data = raster_data;
},
createTile: function (tile_coords) {
let _tile = document.createElement('canvas');
let _tile_ctx = _tile.getContext('2d');
// do some drawing here with values from this.raster_data
return _tile;
}
This implementation is so far working fine. Than I thought of offloading drawing with offscreen-canvas in a webworker. so I restructured the code like this
initialize: function(raster_data){
this.raster_data = raster_data;
this.tile_worker = new Worker('tile_renderer.js')
},
createTile: function (tile_coords) {
let _tile = document.createElement('canvas').transferControlToOffscreen();
this.tile_worker.postMessage({
_tile: _tile,
_raster_data: this.raster_data
},[_tile])
return _tile;
}
This works but every now and then i see a canvas that is just blank. That thing is quite random I don't know start from where and how should I debug this. can this be a problem that I am using a single worker for rendering every tile? any help is appreciated. Here is an example of a blank canvas.
This a known bug: https://crbug.com/1202481
The issue appears when too many OffscreenCanvases are sent to the Worker serially.
The workaround is then to batch send all these OffscreenCanvases in a single call to postMessage().
In your code you could achieve this by storing all the objects to be sent and use a simple debouncing strategy using a 0 timeout to send them all at once:
createTile: function (tile_coords) {
let _tile = document.createElement('canvas');
_tile.setAttribute('width', 512);
_tile.setAttribute('height', 512);
let _off_tile = _tile.transferControlToOffscreen();
this.tiles_to_add.push( _off_tile ); // store for later
clearTimeout( this.batch_timeout_id ); // so that the callback is called only once
this.batch_timeout_id = setTimeout( () => {
// send them all at once
this.tileWorker.postMessage( { tiles: this.tiles_to_add }, this.tiles_to_add );
this.tiles_to_add.length = 0;
});
return _tile;
}
Live example: https://artistic-quill-tote.glitch.me/
this is my first time using swup js with the js plugin. https://swup.js.org/plugins/js-plugin
I can see that the trigger to go to the clicked page lies inside the object array of options.
My question is there anyway I can trigger the "next" from external function
const options = [
{
from: '(.*)',
to: '(.*)',
in: function(next) {
document.querySelector('#swup').style.opacity = 0;
TweenLite.to(document.querySelector('#swup'), 0.5, {
opacity: 1,
onComplete: next
});
},
out: (next) => {
document.querySelector('#swup').style.opacity = 1;
TweenLite.to(document.querySelector('#swup'), 0.5, {
opacity: 0,
onComplete: next
});
}
}
];
const swup = new Swup({
plugins: [new SwupJsPlugin(options)]
});
how do I trigger the "next " from another outside function not within Const options?
for example
counts trigger = function(){
options.next();
thanks
this doesn't work
thanks
You cannot do that. Swup JS plugin uses the defined options to run in and out functions at the right time while passing the next argument to it.
The next argument is present only as a way to let swup know that the animation has finished and it can continue in whatever it needs to do next.
I'm migrating from Google Maps API to Apple MapKit JS for the simple reason I have a developer account with them and they offer more free hits.
Anyway, actual examples of MapKit JS are a bit thin (or at least Google isn't finding them - draw what conspiracy theories you will), so although I've got the basics going of displaying an embeded map, I can't seem to do the next step which is route between two points (Apple's documentation also seems impenetrable as they don't show examples).
Here's my script for a basic map:
<script>
mapkit.init({
authorizationCallback: function(done) {
done('[MY-TOKEN]');
}
});
var MarkerAnnotation = mapkit.MarkerAnnotation
var myMarker = new mapkit.Coordinate(55.9496320, -3.1866360)
var myRegion = new mapkit.CoordinateRegion(
new mapkit.Coordinate(55.9496320, -3.1866360),
new mapkit.CoordinateSpan(0.003, 0.003)
);
var map = new mapkit.Map("map");
var myAnnotation = new MarkerAnnotation(myMarker, { color: "#9b6bcc", title: "theSpace On The Mile"});
map.showItems([myAnnotation]);
map.region = myRegion;
</script>
Now I want to:
• Show a walking route between two points
• Include waypoints on the route
Could someone show the code that would achieve this? Once I can see an example I know I'll get it ;-)
Ok, so I've found a solution to this so sharing it here for the benefit of others.
Let's start by saying Apple's MapKit JS doesn't appear to have a waypoints option as offered by Google Maps API - so the way around that is to create a map that stores the markers in an array and then routes from one to the next. The code stores the location of the last waypoint in a variable, and doesn't bother to draw a route to the last waypoint if this is the first one in the array (obviously).
<script>
// Initiallise MapKit - you'll need your own long-lived token for this
mapkit.init({
authorizationCallback: function(done) {
done('[MY-TOKEN]');
}
});
// Function to draw the route once MapKit has returned a response
function directionHandler(error, data) {
data["routes"].forEach(function(route, routeIdx) {
if (routeIdx !== 0) { return; }
overlays = [];
route['path'].forEach(function(path) {
// This styles the line drawn on the map
let overlayStyle = new mapkit.Style({
lineWidth: 3,
strokeColor: "#9b6bcc"
});
let overlay = new mapkit.PolylineOverlay(path, {
style: overlayStyle
});
overlays.push(overlay);
});
map.addOverlays(overlays);
});
}
// This asks MapKit for directions and when it gets a response sends it to directionHandler
function computeDirections(origin,destination) {
let directionsOptions = {
origin: origin,
destination: destination,
transportType: mapkit.Directions.Transport.Walking
};
directions.route(directionsOptions, directionHandler);
}
// This sets the initial region, but is overridden when all points have been potted to automatically set the bounds
var myRegion = new mapkit.CoordinateRegion(
new mapkit.Coordinate(55.9496320, -3.1866360),
new mapkit.CoordinateSpan(0.05, 0.05)
);
var map = new mapkit.Map("map");
map.region = myRegion;
var myAnnotations = [];
// lastWaypoint variable is 'unset' initially so the map doesn't try and find a route to the lastWaypoint for the first point of the route
var lastWaypoint = "unset";
var directions = new mapkit.Directions();
// Array of co-ordinates and label for marker
waypoints = [
{name:'Sofi’s Bar',lat:55.9746308,lon:-3.1722282},
{name:'TThe Roseleaf Cafe',lat:55.975992,lon:-3.173474},
{name:'Hemingway’s',lat:55.9763631,lon:-3.1706564},
{name:'Teuchter’s Landing',lat:55.9774693,lon:-3.1713826},
{name:'The King’s Wark',lat:55.9761425,lon:-3.1695419},
{name:'Malt and Hops',lat:55.975885,lon:-3.1698957},
{name:'The Carrier’s Quarters',lat:55.9760813,lon:-3.1685323},
{name:'Noble’s',lat:55.974905,lon:-3.16714},
{name:'The Fly Half',lat:55.9747906,lon:-3.1674496},
{name:'Port O’ Leith',lat:55.974596,lon:-3.167525}
];
// Loop through the array and create marker for each
waypoints.forEach(function(data) {
var myAnnotation = new mapkit.MarkerAnnotation(new mapkit.Coordinate(data['lat'],data['lon']), {
color: "#9b6bcc",
title: data['name']
});
myAnnotations.push(myAnnotation);
// As long as this isn't the first point on the route, draw a route back to the last point
if(lastWaypoint!="unset") {
computeDirections(lastWaypoint,new mapkit.Coordinate(data['lat'],data['lon']));
}
lastWaypoint = new mapkit.Coordinate(data['lat'],data['lon']);
});
map.showItems(myAnnotations);
</script>
This map is for a pub crawl around Leith, so the trasportType is 'Walking', but change that to 'Automobile' if you so wish.
With credit to Vasile whose MapKit JS Demo (https://github.com/vasile/mapkit-js-demo) helped me understand a lot more about the options.
I am not really good at js and trying to use Bing map in our website but it shows the map few times and doesnt show the map most of the time. Below is the code snippet of loading map function, can someone please let me know whats wrong in this function, I am using this from other application:
function loadMap(storeData) {
var coordinates = {};
var map;
var stores = storeData.stores;
if( (typeof stores !== 'undefined') && (typeof stores[0].coordinates !== 'undefined') ) {
coordinates.lat = stores[0].coordinates.lat;
coordinates.lng = stores[0].coordinates.lng;
}else {
coordinates.lat = 33.74831008911133;
coordinates.lng = -84.39111328125;
}
map = new Microsoft.Maps.Map($('#bingMap')[0], {
credentials: 'mykey',
liteMode: true,
enableClickableLogo: false,
center: new Microsoft.Maps.Location(coordinates.lat, coordinates.lng)
});
self.center = new Microsoft.Maps.Location(coordinates.lat, coordinates.lng);
map.setView({zoom: 13});
return map;
}
I have tried below few steps I got from other stackoverflow queries but it didnt help me:-(
setTimeout(this.loadMap(storeData), 2000); Microsoft.Maps.Events.addHandler(map,'resize')
The problem is in your setTimeout call:
You see, setTimeout receives 2 parameters:
A function to execute
Timeout in ms
in your case, you used setTimeout(this.loadMap(storeData), 2000); which doesn't pass the function to the setTimeout but the result of the execution. In addition, this code will also execute this.loadMap immediately and not in 2 seconds.
To solve this, you can just use:
setTimeout(function() { this.loadMap(storeData)}, 2000);
or: (#Sysix's solution)
setTimeout(this.loadMap.bind(this), 2000, storeData);
I am trying to use a highcharts chart and I want to "simulate" live data coming in, so, when a user presses the "start live stream" button it activates a function from I suppose JavaScript on the web page and then calls the angular controller function that has around 10 second delay.
The way I can query the json data from the controller is from an http request and I use how far back in weeks I want to query the data (I have as far back as 100 weeks). So I want to have a function on the web page the starts at 99 and 100 and pass in the variable to the angular function to query from 100-99 weeks ago and add the data to the chart. Wait 10 seconds and query now instead 99-98 until it gets to zero.
I am pretty new to JS in general so I'm not too sure how to start but I have read about the setTimeout function. Any suggestions or better way to go about this would be much appreciated.
My current http request looks like this and is static:
$http({
url: '/api/v1/datapoints',
method: 'POST',
data: '{"start":"99w-ago","end":"98w-ago","tags":[{"name":"SolarData"}]}'
}).then(function(predixTimeSeriesData){
$scope.solarData = predixTimeSeriesData.data.tags[0].results[0].values.map(
function(curVal, index, arr) {
return [curVal[0], curVal[1]];
}
);
console.log($scope.solarData);
/*
I use $scope.solatData in my chart on the html page like
<line-series-chart data={{solarData}}></line-series-chart>
so this is why I am thinking I need to have the time interval on the view page
instead of the controller because i cannot control my chart from there
*/
});
You can use the $interval service of angular, something like this:
function myController($scope, $http, $interval) {
var currentWeek = 99;
var fetchInterval;
$scope.solatData = [];
$scope.fetch = function() {
$http.get("someUrl", {
params: {
week: currentWeek
}
}).then(function(data){
// This will also update your graph, assuming it is implemented
// to watch changes on the data
$scope.solatData = $scope.solatData.concat(data);
currentWeek++;
});
}
$scope.start = function() {
fetchInterval = $interval($scope.fetch, 10000);
}
// Clear the interval when the scope/controller is 'destroyed'
$scope.$on('$destroy', function() {
$interval.cancel(fetchInterval);
});
// kick off initial start
$scope.start();
}