Get all directions using Bing Map SDK in UWP - bing-maps

Is it possible to get all driving directions with a specified FROM and TO location in UWP using Bing Map SDK? (just like windows 10 map app)

Yes:
Get a driving or walking route and directions by calling the methods of the MapRouteFinder class - for example, GetDrivingRouteAsync or GetWalkingRouteAsync. The MapRouteFinderResult object contains a MapRoute object that you access through its Route property.
When you request a route, you can specify the following things:
•You can provide a start point and end point only, or you can provide a series of waypoints to compute the route.
•You can specify optimizations - for example, minimize the distance.
•You can specify restrictions - for example, avoid highways.
You can use sample code like this one:
private async void GetRouteAndDirections()
{
// Start at Microsoft in Redmond, Washington.
BasicGeoposition startLocation = new BasicGeoposition();
startLocation.Latitude = 47.643;
startLocation.Longitude = -122.131;
Geopoint startPoint = new Geopoint(startLocation);
// End at the city of Seattle, Washington.
BasicGeoposition endLocation = new BasicGeoposition();
endLocation.Latitude = 47.604;
endLocation.Longitude = -122.329;
Geopoint endPoint = new Geopoint(endLocation);
// Get the route between the points.
MapRouteFinderResult routeResult =
await MapRouteFinder.GetDrivingRouteAsync(
startPoint,
endPoint,
MapRouteOptimization.Time,
MapRouteRestrictions.None);
if (routeResult.Status == MapRouteFinderStatus.Success)
{
// Display summary info about the route.
tbOutputText.Inlines.Add(new Run()
{
Text = "Total estimated time (minutes) = "
+ routeResult.Route.EstimatedDuration.TotalMinutes.ToString()
});
tbOutputText.Inlines.Add(new LineBreak());
tbOutputText.Inlines.Add(new Run()
{
Text = "Total length (kilometers) = "
+ (routeResult.Route.LengthInMeters / 1000).ToString()
});
tbOutputText.Inlines.Add(new LineBreak());
tbOutputText.Inlines.Add(new LineBreak());
// Display the directions.
tbOutputText.Inlines.Add(new Run()
{
Text = "DIRECTIONS"
});
tbOutputText.Inlines.Add(new LineBreak());
foreach (MapRouteLeg leg in routeResult.Route.Legs)
{
foreach (MapRouteManeuver maneuver in leg.Maneuvers)
{
tbOutputText.Inlines.Add(new Run()
{
Text = maneuver.InstructionText
});
tbOutputText.Inlines.Add(new LineBreak());
}
}
}
else
{
tbOutputText.Text =
"A problem occurred: " + routeResult.Status.ToString();
}
}
More info here : https://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn631250.aspx#getting_a_route_and_directions

Related

Leaflet Trigger Event on Clustered Marker by external element

I just starting to learn about Leaflet.js for my upcoming project.
What i am trying to accomplish:
I need to make a list of marker which displayed on the map, and when the list item is being hovered (or mouseover) it will show where the position on the map (for single marker, it should change its color. For Clustered marker, it should display Coverage Line like how it behave when we hover it.. and perhaps change its color too if possible).
The map should not be changed as well as the zoom level, to put it simply, i need to highlight the marker/ Cluster on the map.
What i have accomplished now : I am able to do it on Single Marker.
what i super frustrated about : I failed to find a way to make it happen on Clustered Marker.
I use global var object to store any created marker.
function updateMapMarkerResult(data) {
markers.clearLayers();
for (var i = 0; i < data.length; i++) {
var a = data[i];
var myIcon = L.divIcon({
className: 'prop-div-icon',
html: a.Description
});
var marker = L.marker(new L.LatLng(a.Latitude, a.Longitude), {
icon: myIcon
}, {
title: a.Name
});
marker.bindPopup('<div><div class="row"><h5>Name : ' + a.Name + '</h5></div><div class="row">Lat : ' + a.Latitude + '</div><div class="row">Lng : ' + a.Longitude + '</div>' + '</div>');
marker.on('mouseover', function(e) {
if (this._icon != null) {
this._icon.classList.remove("prop-div-icon");
this._icon.classList.add("prop-div-icon-shadow");
}
});
marker.on('mouseout', function(e) {
if (this._icon != null) {
this._icon.classList.remove("prop-div-icon-shadow");
this._icon.classList.add("prop-div-icon");
}
});
markersRef[a.LocId] = marker; // <-- Store Reference
markers.addLayer(marker);
updateMapListResult(a, i + 1);
}
map.addLayer(markers);
}
But i don't know which object or property to get the Clustered Marker reference.
And i trigger the marker event by my global variable (which only works on single marker).
...
li.addEventListener("mouseover", function(e) {
jQuery(this).addClass("btn-info");
markersRef[this.getAttribute('marker')].fire('mouseover'); // --> Trigger Marker Event "mouseover"
// TODO : Trigger ClusteredMarker Event "mouseover"
});
...
This is my current https://jsfiddle.net/oryza_anggara/2gze75L6/, any lead could be a very big help. Thank you.
Note: the only js lib i'm familiar is JQuery, i have no knowledge for others such as Angular.js
You are probably looking for markers.getVisibleParent(marker) method, to retrieve the containing cluster in case your marker is clustered.
Unfortunately, it is then not enough to fire your event on that cluster. The coverage display functionality is set on the Cluster Group, not on its individual clusters. Therefore you need to fire your event on that group:
function _fireEventOnMarkerOrVisibleParentCluster(marker, eventName) {
var visibleLayer = markers.getVisibleParent(marker);
if (visibleLayer instanceof L.MarkerCluster) {
// In case the marker is hidden in a cluster, have the clusterGroup
// show the regular coverage polygon.
markers.fire(eventName, {
layer: visibleLayer
});
} else {
marker.fire(eventName);
}
}
var marker = markersRef[this.getAttribute('marker')];
_fireEventOnMarkerOrVisibleParentCluster(marker, 'mouseover');
Updated JSFiddle: https://jsfiddle.net/2gze75L6/5/
That being said, I think another interesting UI, instead of showing the regular coverage polygon that you get when "manually" hovering a cluster, would be to spiderfy the cluster and highlight your marker. Not very easy to implement, but the result seems nice to me. Here is a quick try, it would probably need more work to make it bullet proof:
Demo: https://jsfiddle.net/2gze75L6/6/
function _fireEventOnMarkerOrVisibleParentCluster(marker, eventName) {
if (eventName === 'mouseover') {
var visibleLayer = markers.getVisibleParent(marker);
if (visibleLayer instanceof L.MarkerCluster) {
// We want to show a marker that is currently hidden in a cluster.
// Make sure it will get highlighted once revealed.
markers.once('spiderfied', function() {
marker.fire(eventName);
});
// Now spiderfy its containing cluster to reveal it.
// This will automatically unspiderfy other clusters.
visibleLayer.spiderfy();
} else {
// The marker is already visible, unspiderfy other clusters if
// they do not contain the marker.
_unspiderfyPreviousClusterIfNotParentOf(marker);
marker.fire(eventName);
}
} else {
// For mouseout, marker should be unclustered already, unless
// the next mouseover happened before?
marker.fire(eventName);
}
}
function _unspiderfyPreviousClusterIfNotParentOf(marker) {
// Check if there is a currently spiderfied cluster.
// If so and it does not contain the marker, unspiderfy it.
var spiderfiedCluster = markers._spiderfied;
if (
spiderfiedCluster
&& !_clusterContainsMarker(spiderfiedCluster, marker)
) {
spiderfiedCluster.unspiderfy();
}
}
function _clusterContainsMarker(cluster, marker) {
var currentLayer = marker;
while (currentLayer && currentLayer !== cluster) {
currentLayer = currentLayer.__parent;
}
// Say if we found a cluster or nothing.
return !!currentLayer;
}

leaftletjs-adding points dynamically and draw line string

I am trying to draw the path of a flight using leafletjs and geojson. I'll be getting the geometry from a stream.
this is what I have done so far:
let index = 0;
let geoJsonLayer;
let intervalFn = setInterval(function () {
let point = trackData.features[index++];
if(point) {
let coords = point.geometry.coordinates;
coords.pop();
coords.reverse();
geoFeature.geometry.coordinates.push(coords);
if(map.hasLayer(geoJsonLayer)) map.removeLayer(geoJsonLayer);
geoJsonLayer = L.geoJson(geoFeature, {
onEachFeature: (feature, layer) => {
const content = feature.properties.title;
layer.bindPopup(content);
}
});
geoJsonLayer.addTo(map);
// console.log(coords);
} else {
clearInterval(intervalFn);
}
}, 100);
setInterval is to simulate the part whereby I get the geometry from a stream.
now when a user clicks on the path I need to show some properties of the path, and I am trying to use the onEachFeature for that, but its not working correctly.
I suspect its because I am removing the layers (I did this to improve the performance)
Is there any other better ways to do what I am trying to achieve ?
You should probably try addLatLng()
Adds a given point to the polyline.
Your geoFeature sounds to be a single Feature, so your geoJsonLayer will contain a single layer (polyline):
let myPolyline;
geoJsonLayer.eachLayer(function (layer) {
myPolyline = layer; // Will be done only once actually.
});
// When you receive a new point…
myPolyline.addLatLng([lat, lng]);
With this you should not have to remove your layers every time.
The popup should therefore stay open, if it is shown.
Demo: https://jsfiddle.net/3v7hd2vx/265/ (click on the button to add new points)

How to use the numericRefinementList to set allowed distances?

I would like to be able to use the numericRefinementList to allow users to pick the distance from themselves an item can be? This would be using the IP geo-location feature or inputting the geo-location from browser if available.
Less than 50km
50 - 100km
100 - 150km
More than 150km
https://community.algolia.com/instantsearch.js/documentation/#numericrefinementlist
This is unfortunately not something you can do with the numericRefinementList but you can probably build a custom widget setting the aroundRadius depending on the link you've clicked on:
function radiusList(options) {
if (!options.container) {
throw new Error('radiusList: usage: radiusList({container, ...})');
}
var $container = $(options.container);
if ($container.length === 0) {
throw new Error('radiusList: cannot select \'' + options.container + '\'');
}
return {
init: function(args) {
// event delegation: set the aroundRadius of the underlying link
$(document).on('click', '.radius-link', function(e) {
e.preventDefault();
args.helper.setQueryParameter('aroundRadius', +$(this).data('radius'));
args.helper.search();
});
},
render: function(args) {
// FIXME: display the list of radius links
var html = '<ul>';
html += '<li>< 100km</li>';
html += '</ul>';
$container.html(html);
}
};
}
And then you use it with:
search.addWidget(radiusList({container: '#my-radius-list'}));

How to define cycles with observables

I'm trying to set up the update loop of a simple game, built with observables in mind. The top-level components are a model, which takes input commands, and produces updates; and a view, which displays the received updates, and produces input. In isolation, both work fine, the problematic part is putting the two together, since both depend on the other.
With the components being simplified to the following:
var view = function (updates) {
return Rx.Observable.fromArray([1,2,3]);
};
var model = function (inputs) {
return inputs.map(function (i) { return i * 10; });
};
The way I've hooked things together is this:
var inputBuffer = new Rx.Subject();
var updates = model(inputBuffer);
var inputs = view(updates);
updates.subscribe(
function (i) { console.log(i); },
function (e) { console.log("Error: " + e); },
function () { console.log("Completed"); }
);
inputs.subscribe(inputBuffer);
That is, I add a subject as a placeholder for the input stream, and attach the model to that. Then, after the view is constructed, I pass on the actual inputs to the placeholder subject, thus closing the loop.
I can't help but feel this is not the proper way to do things, however. Using a subject for this seems to be overkill. Is there a way to do the same thing with publish() or defer() or something along those lines?
UPDATE: Here's a less abstract example to illustrate what I'm having problems with. Below you see the code for a simple "game", where the player needs to click on a target to hit it. The target can either appear on the left or on the right, and whenever it is hit, it switches to the other side. Seems simple enough, but I still have the feeling I'm missing something...
//-- Helper methods and whatnot
// Variables to easily represent the two states of the target
var left = 'left';
var right = 'right';
// Transition from one side to the other
var flip = function (side) {
if (side === left) {
return right;
} else {
return left;
}
};
// Creates a predicate used for hit testing in the view
var nearby = function (target, radius) {
return function (position) {
var min = target - radius;
var max = target + radius;
return position >= min && position <= max;
};
};
// Same as Observable.prototype.scan, but it also yields the initial value immediately.
var initScan = function (values, init, updater) {
var initValue = Rx.Observable.return(init);
var restValues = values.scan(init, updater);
return initValue.concat(restValues);
};
//-- Part 1: From input to state --
var process = function (inputs) {
// Determine new state based on current state and input
var update = function(current, input) {
// Input value ignored here because there's only one possible state transition
return flip(current);
};
return initScan(inputs, left, update);
};
//-- Part 2: From display to inputs --
var display = function (states) {
// Simulate clicks from the user at various positions (only one dimension, for simplicity)
var clicks = Rx.Observable.interval(800)
.map(function (v) {return (v * 5) % 30; })
.do(function (v) { console.log("Shooting at: " + v)})
.publish();
clicks.connect();
// Display position of target depending on the model
var targetPos = states.map(function (state) {
return state === left ? 5 : 25;
});
// Determine which clicks are hits based on displayed position
return targetPos.flatMapLatest(function (target) {
return clicks
.filter(nearby(target, 10))
.map(function (pos) { return "HIT! (# "+ pos +")"; })
.do(console.log);
});
};
//-- Part 3: Putting the loop together
/**
* Creates the following feedback loop:
* - Commands are passed to the process function to generate updates.
* - Updates are passed to the display function to generates further commands.
* - (this closes the loop)
*/
var feedback = function (process, display) {
var inputBuffer = new Rx.Subject(),
updates = process(inputBuffer),
inputs = display(updates);
inputs.subscribe(inputBuffer);
};
feedback(process, display);
I think I understand what you are trying to achieve here:
How can I get a sequence of input events going in one direction that feed into a model
But have a sequence of output events going in the other direction that feed from the model to the view
I believe the answer here is that you probably want to flip your design. Assuming an MVVM style design, instead of having the Model know about the input sequence, it becomes agnostic. This means that you now have a model that has a InputRecieved/OnInput/ExecuteCommand method that the View will call with the input values. This should now be a lot easier for you to deal with a "Commands in one direction" and "Events in the other direction" pattern. A sort of tip-of-the-hat to CQRS here.
We use that style extensively on Views+Models in WPF/Silverlight/JS for the last 4 years.
Maybe something like this;
var model = function()
{
var self = this;
self.output = //Create observable sequence here
self.filter = function(input) {
//peform some command with input here
};
}
var viewModel = function (model) {
var self = this;
self.filterText = ko.observable('');
self.items = ko.observableArray();
self.filterText.subscribe(function(newFilterText) {
model.filter(newFilterText);
});
model.output.subscribe(item=>items.push(item));
};
update
Thanks for posting a full sample. It looks good. I like your new initScan operator, seems an obvious omission from Rx.
I took your code an restructured it the way I probably would have written it. I hope it help. The main things I did was encapsulted the logic into the model (flip, nearby etc) and have the view take the model as a parameter. Then I did also have to add some members to the model instead of it just being an observable sequence. This did however allow me to remove some extra logic from the view and put it in the model too (Hit logic)
//-- Helper methods and whatnot
// Same as Observable.prototype.scan, but it also yields the initial value immediately.
var initScan = function (values, init, updater) {
var initValue = Rx.Observable.return(init);
var restValues = values.scan(init, updater);
return initValue.concat(restValues);
};
//-- Part 1: From input to state --
var process = function () {
var self = this;
var shots = new Rx.Subject();
// Variables to easily represent the two states of the target
var left = 'left';
var right = 'right';
// Transition from one side to the other
var flip = function (side) {
if (side === left) {
return right;
} else {
return left;
}
};
// Determine new state based on current state and input
var update = function(current, input) {
// Input value ignored here because there's only one possible state transition
return flip(current);
};
// Creates a predicate used for hit testing in the view
var isNearby = function (target, radius) {
return function (position) {
var min = target - radius;
var max = target + radius;
return position >= min && position <= max;
};
};
self.shoot = function(input) {
shots.onNext(input);
};
self.positions = initScan(shots, left, update).map(function (state) {
return state === left ? 5 : 25;
});
self.hits = self.positions.flatMapLatest(function (target) {
return shots.filter(isNearby(target, 10));
});
};
//-- Part 2: From display to inputs --
var display = function (model) {
// Simulate clicks from the user at various positions (only one dimension, for simplicity)
var clicks = Rx.Observable.interval(800)
.map(function (v) {return (v * 5) % 30; })
.do(function (v) { console.log("Shooting at: " + v)})
.publish();
clicks.connect();
model.hits.subscribe(function(pos)=>{console.log("HIT! (# "+ pos +")");});
// Determine which clicks are hits based on displayed position
model.positions(function (target) {
return clicks
.subscribe(pos=>{
console.log("Shooting at " + pos + ")");
model.shoot(pos)
});
});
};
//-- Part 3: Putting the loop together
/**
* Creates the following feedback loop:
* - Commands are passed to the process function to generate updates.
* - Updates are passed to the display function to generates further commands.
* - (this closes the loop)
*/
var feedback = function (process, display) {
var model = process();
var view = display(model);
};
feedback(process, display);
I presume that because you do not "assign" the inputs after the model is created, you are aiming for a non-mutative approach to instantiating your model and view. However, your model and your view seem to depend on one another. To resolve this issue, you can use a third party to facilitate the relationship between the two objects. In this case, you can simply use a function for dependency injection...
var log = console.log.bind(console),
logError = console.log.bind(console, 'Error:'),
logCompleted = console.log.bind(console, 'Completed.'),
model(
function (updates) {
return view(updates);
}
)
.subscribe(
log,
logError,
logCompleted
);
By providing the model a factory to create a view, you give the model the ability to fully instantiate itself by instantiating it's view, but without knowing how the view is instantiated.
As per my comment on the question itself, here's the same sort of code you're writing done with a scheduler in Windows. I would expect a similar interface in RxJS.
var scheduler = new EventLoopScheduler();
var subscription = scheduler.Schedule(
new int[] { 1, 2, 3 },
TimeSpan.FromSeconds(1.0),
(xs, a) => a(
xs
.Do(x => Console.WriteLine(x))
.Select(x => x * 10)
.ToArray(),
TimeSpan.FromSeconds(1.0)));
The output I get, with three new numbers every second, is:
1
2
3
10
20
30
100
200
300
1000
2000
3000
10000
20000
30000

How to add POI with Wikitude?

I'm new for developer AR With POI
I'm using wikitude for developer AR.I do follow from HERE
This code in js file:
var World = {
loaded: false,
init: function initFn() {
AR.context.onLocationChanged = World.onLocationChanged;
},
onLocationChanged: function onLocationChangedFn(latitude, longitude, altitude, accuracy) {
AR.context.onLocationChanged = null;
World.createMarkerAtLocation(latitude + 0.01, longitude - 0.0005, altitude - 0.06);
},
createMarkerAtLocation: function createMarkerAtLocationFn(latitude, longitude, altitude) {
var markerLocation = new AR.GeoLocation(latitude, longitude, altitude);
var markerDrawable = new AR.ImageDrawable(World.markerDrawable, 3);
var markerObject = new AR.GeoObject(markerLocation, {
drawables: {
cam: markerDrawable
}
});
},
worldLoaded: function worldLoadedFn() {
document.body.removeChild(document.getElementById('loadingMessage'));
}
};
World.init();
And I Run in my android.But my app is not show POIs.
My Question
1. How do I did for POI show in my apps
Excuse me!.I'm not good English
Make sure that your device is getting an location. To see if it gets a location you can add the following lines inside the "function onLocationChangedFn"
alert('Location received');
This should pop up a message once a location has been received.