Tracking location in realtime in Windows phone 8.1 - c#

Sorry if this is a dumb question, I'm a beginner to windows phone 8.1 development.
I am using MapControl to display my current location on the map but as I move my position does not get updated automatically in realtime unless I click on a button and re-initialize the position of the pushpin which was earlier created. Is there a better way where this happens in the without the user having to push the button everytime he wants to see his current location.
private async Task setMyLocation()
{
try
{
var gl = new Geolocator() { DesiredAccuracy = PositionAccuracy.High };
Geoposition location = await gl.GetGeopositionAsync(TimeSpan.FromMinutes(5), TimeSpan.FromSeconds(5));
var pin = new MapIcon()
{
Location = location.Coordinate.Point,
Title = "You are here",
NormalizedAnchorPoint = new Point() { X = 0, Y = 0 },
};
myMapView.MapElements.Add(pin);
await myMapView.TrySetViewAsync(location.Coordinate.Point, 20);
}
catch
{
myMapView.Center = new Geopoint(App.centerPin);
myMapView.ZoomLevel = 20;
Debug.WriteLine("GPS NOT FOUND");
}
App.centerPin = myMapView.Center.Position;
}
Thanks in Advance!

Rather than running a timer and polling, handle the Geolocator.PositionChanged event. This will fire each time the position changes and will be significantly more efficient.
You can set the Geolocator.MovementThreshold property so it will only fire if the user has moved a given distance and not do anything if the user stands in the same place. The threshold you pick will probably depend on how far your map is zoomed in.

The way I would do it is to put a Timer that requests information from the server at a given interval.
Take a look onto this answer containing a code snippet : Stackoverflow answer

Related

LibvclSharp winforms Go to specific Time

I am putting together a winforms app using libvclsharp wrapper.
It is a basic app that hosts 4 x VideoView windows and plays 4 different mp4 videos.
It plays ok and seems stable mostly, but the lib has some odd quirks that i cant seem to find an answer to
I need to click a button on the form and sent all the videos to a specific time, they are all the same length at the moment
using
_mediaPlayer1 = new MediaPlayer(_libVLC1);
_mediaPlayer2 = new MediaPlayer(_libVLC1);
_mediaPlayer3 = new MediaPlayer(_libVLC1);
_mediaPlayer4 = new MediaPlayer(_libVLC1);
media1 = new Media(_libVLC1, #"D:Video.mp4", FromType.FromPath);
media2 = new Media(_libVLC1, #"D:Video2.mp4", FromType.FromPath);
media3 = new Media(_libVLC1, #"D:Video3.mp4", FromType.FromPath);
media4 = new Media(_libVLC1, #"D:Video4.mp4", FromType.FromPath);
_mediaPlayer1.Media = media1;
_mediaPlayer2.Media = media2;
_mediaPlayer3.Media = media3;
_mediaPlayer4.Media = media4;
videoView1.MediaPlayer = _mediaPlayer1;
videoView2.MediaPlayer = _mediaPlayer2;
videoView3.MediaPlayer = _mediaPlayer3;
videoView4.MediaPlayer = _mediaPlayer4;
so to send all 4 to same time i use
foreach (var player in _PlayersCollection)
{
player.Time = 12000);
}
the problem is when click button the if the videos are playing it moves straight to the new time location.
if the videos are paused the videos twitch like they are moving just one frame, then you if click again they jump to the right time location.
this is very annoying and i cant see a reason why.
I saw a tip online to suggest setting the output renderer for the lib to D3d9 instead of D3d11 but i cant find any examples of how to change that for this lib.
Does anyone have any suggestions please who is familiar with lib on winforms.
thanks
I also noticed this problem in vlc.dotnet
Looks like the player does not like it's time too be changed to fast.
My solution was to limit the update rate of my tracker.
Some thing similar may work for you.
long lngLastScrollTimeStamp=0;
private void trkVideo_Scroll(object sender, EventArgs e)
{
if (((Stopwatch.GetTimestamp() / TimeSpan.TicksPerMillisecond) - lngLastScrollTimeStamp) > 250)
{
vlcControl1.Time = trkVideo.Value;
lngLastScrollTimeStamp = Stopwatch.GetTimestamp() / TimeSpan.TicksPerMillisecond;
}
}

MOGRE 1.8.1 + WPF (C#) - Back Buffer is not valid when user changes resolution or computer goes to sleep

I'm working with MOGRE 1.8.1 to embed 3D models within a WPF application. I've run into an issue where the application crashes when the user changes resolution or their computer goes to sleep. I believe this is because the render system is trying to draw to a surface that it doesn't have access to anymore.
I'm not exactly sure what to do; I've tried using the dispose method to kill MOGRE and reboot it later (by catching the windows event), but have run into a memory leak. The pause render method included within the MOGRE library does not seem to work either. Does anyone have any ideas on how to circumvent this issue?
Notes
You can find the example I'm running here. Main difference is that I'm using the 1.8.1 .dlls instead -> http://www.codeproject.com/Articles/29190/Blend-the-OGRE-Graphics-Engine-into-your-WPF-proje , but the error is present in both.
OgreImage.cs is where the issues are happening.
Thank you for your help.
This error happen when the device is lost, so you have to add your control in the function RenderFrame()
//WallPaper, CTRL + ALT + DEL, etc
if (this.isDeviceLost)
{
//Recreate the texture render
ReInitRenderTarget();
//Restore device lost
_renderWindow._beginUpdate();
_renderWindow._endUpdate();
_reloadRenderTargetTime = -1;
this.isDeviceLost = false;
}
And this is my ReInitRenderTarget() function
protected void ReInitRenderTarget()
{
DetachRenderTarget(true, false);
DisposeRenderTarget();
_texture = TextureManager.Singleton.CreateManual(
"OgreImageSource RenderTarget",
ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME,
TextureType.TEX_TYPE_2D,
(uint)ViewportSize.Width, (uint)ViewportSize.Height,
0, Mogre.PixelFormat.PF_R8G8B8A8,
(int)TextureUsage.TU_RENDERTARGET);//, null, false, 8);
_renTarget = _texture.GetBuffer().GetRenderTarget();
_reloadRenderTargetTime = 0;
int viewportCount = ViewportDefinitions.Length;
viewports = new Viewport[viewportCount];
for (int i = 0; i < viewportCount; i++)
{
Viewport viewport;
ViewportDefinition vd = ViewportDefinitions[i];
viewport = _renTarget.AddViewport(vd.Camera, zIndexCounter++, vd.Left, vd.Top, vd.Width, vd.Height);
viewport.BackgroundColour = vd.BackgroundColour;
viewports[i] = viewport;
}
var ev = ViewportsChanged;
if (ev != null) ev();
viewportDefinitionsChanged = false;
}

Microsoft Band UV sensor data unfamiliar

I'm using Microsoft Band of development on Windows Phone 8.1. Trying to figure out he full capability of the UV sensor. I found few examples, that find the UV level. They show that an enum can be used:
namespace Microsoft.Band.Sensors
{
public enum UVIndexLevel
{
None = 0,
Low = 1,
Medium = 2,
High = 3,
VeryHigh = 4,
}
}
Would also want to know, what's the scale of these enums. As I know there's like 0 to 11+ levels of UI. What ranges are those enums?
I'm basically using line of code:
{
bandClient.SensorManager.UV.ReadingChanged += Ultraviolet_ReadingChanged;
await bandClient.SensorManager.UV.StartReadingsAsync();
*Later on code*
await bandClient.SensorManager.UV.StopReadingsAsync();
bandClient.SensorManager.UV.ReadingChanged -= Ultraviolet_ReadingChanged;
}
The async method:
async void Ultraviolet_ReadingChanged(object sender, BandSensorReadingEventArgs<IBandUVReading> e)
{
IBandUVReading ultra = e.SensorReading;
UVIndexLevel potatoUV = ultra.IndexLevel;
}
But for some reason, I don't get Indexes most of the time. I sometimes get readings around 8 million to 10 million (or thousands) when in direct sunlight. Values are in "int" (Though sometimes gives the enums).
I am interested, on how I can measure it. Also, exactly what UV is it reading? I know there are many kinds of UV exposures. But how can I use this data?
If it's a range, then maybe I can put a range value, but I need to somehow sample it, what UV Index it has and give that information to the user. And use the index in later calculations.
ALSO...
I happened to fall on a bug. While testing the UV, when I was standing in direct light, the reading did not display. Only once I moved to another UV level, it changed (But never back to the first one). But seems like the first reading either does not change (As method is "readingchanged") or is the default location. However much sense this makes. Is there a way to call out the reading on button click?
If need be, I can search the examples I used, for mode depth of the code. But most of it is here.
A new Band SDK will be available soon and will fix the UV sensor data not correctly returned. Stay tune!
This sensor is a bit different than the others. It does require the user to do the action to acquire the data and then the data can be gathered.
Here is a code which is working on a WP8.1 with a Band.
DateTime start;
private async void Button_Click(object sender, RoutedEventArgs e)
{
try
{
this.viewModel.StatusMessage = "Connecting to Band";
// Get the list of Microsoft Bands paired to the phone.
IBandInfo[] pairedBands = await BandClientManager.Instance.GetBandsAsync();
if (pairedBands.Length < 1)
{
this.viewModel.StatusMessage = "This sample app requires a Microsoft Band paired to your phone. Also make sure that you have the latest firmware installed on your Band, as provided by the latest Microsoft Health app.";
return;
}
// Connect to Microsoft Band.
using (IBandClient bandClient = await BandClientManager.Instance.ConnectAsync(pairedBands[0]))
{
start = DateTime.Now;
this.viewModel.StatusMessage = "Reading ultraviolet sensor";
// Subscribe to Ultraviolet data.
bandClient.SensorManager.UV.ReadingChanged += UV_ReadingChanged;
await bandClient.SensorManager.UV.StartReadingsAsync();
// Receive Accelerometer data for a while.
await Task.Delay(TimeSpan.FromMinutes(5));
await bandClient.SensorManager.UV.StopReadingsAsync();
bandClient.SensorManager.UV.ReadingChanged -= UV_ReadingChanged;
}
this.viewModel.StatusMessage = "Done";
}
catch (Exception ex)
{
this.viewModel.StatusMessage = ex.ToString();
}
}
void UV_ReadingChanged(object sender, Microsoft.Band.Sensors.BandSensorReadingEventArgs<Microsoft.Band.Sensors.IBandUVReading> e)
{
var span = (DateTime.Now - start).TotalSeconds;
IBandUVReading ultra = e.SensorReading;
string text = string.Format("Ultraviolet = {0}\nTime Stamp = {1}\nTime Span = {2}\n", ultra.IndexLevel, ultra.Timestamp, span);
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { this.viewModel.StatusMessage = text; }).AsTask();
start = DateTime.Now;
}

Motion Detection

I really cannot get my head around this, so I hope that someone can give me a little hand ^^
I'm trying to detect motion in C# via my webcam.
So far I've tried multiple libraries (AForge Lib), but failed because I did not understand how to use it.
At first I just wanted to compare the pixels from the current frame with the last one, but that turned out to work like utter s**t :I
Right now, my webcam runs an event "webcam_ImageCaptured" every time the picture from the webcam, which is like 5-10 fps.
But I cannot find a simple way to get the difference from the two images, or at least something that works decent.
Has anybody got an idea on how I could do this rather simple (as possible as that is)?
Getting motion detection to work using the libraries you mention is trivial. Following is an AForge (version 2.2.4) example. It works on a video file but you can easily adapt it to the webcam event.
Johannes' is right but I think playing around with these libraries eases the way to understanding basic image processing.
My application processes 720p video at 120FPS on a very fast machine with SSDs and around 50FPS on my development laptop.
public static void Main()
{
float motionLevel = 0F;
System.Drawing.Bitmap bitmap = null;
AForge.Vision.Motion.MotionDetector motionDetector = null;
AForge.Video.FFMPEG.VideoFileReader reader = new AForge.Video.FFMPEG.VideoFileReader();
motionDetector = GetDefaultMotionDetector();
reader.Open(#"C:\Temp.wmv");
while (true)
{
bitmap = reader.ReadVideoFrame();
if (bitmap == null) break;
// motionLevel will indicate the amount of motion as a percentage.
motionLevel = motionDetector.ProcessFrame(bitmap);
// You can also access the detected motion blobs as follows:
// ((AForge.Vision.Motion.BlobCountingObjectsProcessing) motionDetector.Processor).ObjectRectangles [i]...
}
reader.Close();
}
// Play around with this function to tweak results.
public static AForge.Vision.Motion.MotionDetector GetDefaultMotionDetector ()
{
AForge.Vision.Motion.IMotionDetector detector = null;
AForge.Vision.Motion.IMotionProcessing processor = null;
AForge.Vision.Motion.MotionDetector motionDetector = null;
//detector = new AForge.Vision.Motion.TwoFramesDifferenceDetector()
//{
// DifferenceThreshold = 15,
// SuppressNoise = true
//};
//detector = new AForge.Vision.Motion.CustomFrameDifferenceDetector()
//{
// DifferenceThreshold = 15,
// KeepObjectsEdges = true,
// SuppressNoise = true
//};
detector = new AForge.Vision.Motion.SimpleBackgroundModelingDetector()
{
DifferenceThreshold = 10,
FramesPerBackgroundUpdate = 10,
KeepObjectsEdges = true,
MillisecondsPerBackgroundUpdate = 0,
SuppressNoise = true
};
//processor = new AForge.Vision.Motion.GridMotionAreaProcessing()
//{
// HighlightColor = System.Drawing.Color.Red,
// HighlightMotionGrid = true,
// GridWidth = 100,
// GridHeight = 100,
// MotionAmountToHighlight = 100F
//};
processor = new AForge.Vision.Motion.BlobCountingObjectsProcessing()
{
HighlightColor = System.Drawing.Color.Red,
HighlightMotionRegions = true,
MinObjectsHeight = 10,
MinObjectsWidth = 10
};
motionDetector = new AForge.Vision.Motion.MotionDetector(detector, processor);
return (motionDetector);
}
Motion detection is a complex matter, and it requires a lot of computing power.
Try to limit what you want to detect first. With increasing complexity: Do your want to detect whether there is motion or not? Do you want to detect how much motion? Do you want to detect which areas of the image are actually moving?
I assume you just want to know when something changed:
subtract adjacent frames from each other
calc the sum of all squares of all pixel differences
divide by number of pixels
watch the number for your webcam stream. It will have a certain ground noise and will significantly go up when something moves.
try to limit to a certain color channel only, this may improve things

Windows Phone Location API

I am developing a location based social networking application and am using a geocoordinatewatcher on high accuracy and a movement threshold of 20m to obtain the user's location. My question is about the frequency of the location fixes. From the documentation, I gather that a movement threshold of 20m simply means that the position changed event is not triggered if the current location is 20m away from the location at the previous position changed event. This suggests that location fixes still happen, but they do not trigger the event handler if <20m. How does the device then decide how often to perform a location fix? Does changing the movement threshold change this in any way? Any extra documentation which I may have missed is welcome!
Thank you!
I think you are wanting to know about how MovementThreshold works and how to set that up.
basically you can say:
public class MyClass
{
private IGeoPositionWatcher<GeoCoordinate> _geoCoordinateWatcher;
/// <summary>
/// Gets the geo coordinate watcher.
/// </summary>
private IGeoPositionWatcher<GeoCoordinate> GeoCoordinateWatcher
{
get
{
if (_geoCoordinateWatcher == null)
{
_geoCoordinateWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
((GeoCoordinateWatcher)_geoCoordinateWatcher).MovementThreshold = 3;
}
return _geoCoordinateWatcher;
}
}
}
Someplace else you might have
DispatcherTimer currentSpeedTimer = new DispatcherTimer();
currentSpeedTimer.Interval = new TimeSpan(0, 0, 1);
currentSpeedTimer.Tick += (sender, e) =>
{
if (this.GeoCoordinateWatcher.Position.Location.HorizontalAccuracy < 10)
{
if (DateTime.Now - this.GeoCoordinateWatcher.Position.Timestamp.DateTime > new TimeSpan(0, 0, 2))
{
CurrentSpeed = 0;
}
else
{
CurrentSpeed = double.IsNaN(this.GeoCoordinateWatcher.Position.Location.Speed) ? 0 : this.GeoCoordinateWatcher.Position.Location.Speed;
}
}
};
currentSpeedTimer.Start();
It's also worth pointing out that I found working with .NET Reactive Extensions and the IGeoPositionWatcher worked out really well for me.
http://msdn.microsoft.com/en-us/data/gg577609.aspx
To me it sounds like if current location > 20m from previous position fires event..
if there is a way to change the threshold, that seems will trigger differently, however maximum resolution could be 20m as that's usually what satellites have as max res, if I remember correct, not sure.

Categories