How to get Speed from GeoCoordinate - c#

I am using GMap.Net to add ellipses as marker on map at runtime. ToolTip property of each ellipse is set to display Time and Speed when Added. Instead of number as speed I get NaN always.
On Timer's elapsed event Addellipse method is called -
void Addellipse(object sender, ElapsedEventArgs e)
{
App.Current.Dispatcher.Invoke(() =>
{
getInfo = GetLocationProperty();
Ellipse ellipse = new Ellipse()
{
Fill = Brushes.Black,
ToolTip = getInfo.CurrentTime + "\n" + getInfo.CurrentSpeed,
Height = 7,
Width = 7
};
GMapMarker marker = new GMapMarker(getInfo.CurrentPosition)
{
Shape = ellipse,
ZIndex = int.MaxValue
};
MapControl.Markers.Add(marker);
MapControl.Position = getInfo.CurrentPosition;
});
}
GetLocationProperty returns ToolTipInfo
ToolTipInfo GetLocationProperty()
{
coord = watcher.Position.Location;
if (!coord.IsUnknown)
{
returnlatlon.Lat = coord.Latitude;
returnlatlon.Lng = coord.Longitude;
tooltipInfo.CurrentPosition = returnlatlon;
tooltipInfo.CurrentTime = DateTime.Now.ToShortTimeString();
tooltipInfo.CurrentSpeed = coord.Speed.ToString();
}
return tooltipInfo;
}
here is the ToolTipInfo
public class ToolTipInfo
{
public PointLatLng CurrentPosition { get; set; }
public string CurrentTime { get; set; }
public string CurrentSpeed { get; set; }
}
and my watcher is initialized in this way in constructor
watcher = new GeoCoordinateWatcher();
watcher.TryStart(true, TimeSpan.FromMilliseconds(2000));
How can I get speed?

Related

Extracting Text Data with Location

I've been successful extracting character data with position data from pdfs but when I am trying to extract words with position data the text doesn't always come out as single words. Things like Saskatchewan could be split into S A SKA TCH EWAN. Is there anyway to fix this? I came across similar issues but the answers were for older versions of itextsharp.
public class TextLocationStrategy : LocationTextExtractionStrategy
{
public static List<PdfText> CharacterResult = new List<PdfText>();
public static List<PdfText> WordResult = new List<PdfText>();
protected override bool IsChunkAtWordBoundary(TextChunk chunk, TextChunk previousChunk)
{
float dist = chunk.GetLocation().DistanceFromEndOf(previousChunk);
if (dist < -chunk.GetLocation().GetCharSpaceWidth() || dist > chunk.GetLocation().GetCharSpaceWidth() / 4.0f)
{
return true;
}
return false;
}
public override void EventOccurred(IEventData data, EventType type)
{
try
{
if (!type.Equals(EventType.RENDER_TEXT))
{
return;
}
TextRenderInfo renderInfo = (TextRenderInfo)data;
string curFont = renderInfo.GetFont().GetFontProgram().ToString();
float curFontSize = renderInfo.GetFontSize();
IList<TextRenderInfo> text = renderInfo.GetCharacterRenderInfos();
string curText = renderInfo.GetText();
if (curText != " " && !curText.Contains(' '))
{
Vector wordStart = renderInfo.GetBaseline().GetStartPoint();
Vector wordEnd = renderInfo.GetAscentLine().GetEndPoint();
Rectangle wordRect = new Rectangle(wordStart.Get(0), wordStart.Get(1), wordEnd.Get(0) - wordStart.Get(0), wordEnd.Get(1) - wordStart.Get(1));
PdfText chunk = new PdfText
{
Text = curText,
Rectangle = wordRect,
FontFamily = curFont,
FontSize = Convert.ToInt32(curFontSize),
SpaceWidth = renderInfo.GetSingleSpaceWidth(),
HorizontalScaling = renderInfo.GetHorizontalScaling(),
Leading = renderInfo.GetLeading(),
CharacterSpacing = renderInfo.GetCharSpacing(),
StartPoint = new Autodesk.AutoCAD.Geometry.Point3d(wordStart.Get(0), wordStart.Get(1), 0.0),
EndPoint = new Autodesk.AutoCAD.Geometry.Point3d(wordEnd.Get(0), wordEnd.Get(1), 0.0)
};
WordResult.Add(chunk);
}
foreach (TextRenderInfo t in text)
{
string letter = t.GetText();
Vector letterStart = t.GetBaseline().GetStartPoint();
Vector letterEnd = t.GetAscentLine().GetEndPoint();
Rectangle letterRect = new Rectangle(letterStart.Get(0), letterStart.Get(1), letterEnd.Get(0) - letterStart.Get(0), letterEnd.Get(1) - letterStart.Get(1));
if (letter != " " && !letter.Contains(' '))
{
PdfText chunk = new PdfText
{
Text = letter,
Rectangle = letterRect,
FontFamily = curFont,
FontSize = Convert.ToInt32(curFontSize),
SpaceWidth = t.GetSingleSpaceWidth(),
HorizontalScaling = t.GetHorizontalScaling(),
Leading = t.GetLeading(),
CharacterSpacing = t.GetCharSpacing(),
StartPoint = new Autodesk.AutoCAD.Geometry.Point3d(letterStart.Get(0), letterStart.Get(1), 0.0),
EndPoint = new Autodesk.AutoCAD.Geometry.Point3d(letterEnd.Get(0), letterEnd.Get(1), 0.0)
};
CharacterResult.Add(chunk);
}
}
}
catch (Exception ex)
{
ErrorManager.ReportError(ex);
}
}
public List<PdfText> GetCharacterData()
{
List<PdfText> retVal = new List<PdfText>();
try
{
retVal = CharacterResult;
}
catch (Exception ex)
{
ErrorManager.ReportError(ex);
}
return retVal;
}
public List<PdfText> GetWordData()
{
List<PdfText> retVal = new List<PdfText>();
try
{
retVal = WordResult;
}
catch (Exception ex)
{
ErrorManager.ReportError(ex);
}
return retVal;
}
}
public class PdfText
{
public string Text { get; set; }
public Rectangle Rectangle { get; set; }
public string FontFamily { get; set; }
public int FontSize { get; set; }
public float SpaceWidth { get; set; }
public float CharacterSpacing { get; set; }
public float Leading { get; set; }
public float HorizontalScaling { get; set; }
public Point3d StartPoint { get; set; }
public Point3d EndPoint { get; set; }
}

Take the sum of a list as variable and edit it at runtime

I'm trying to calculate the end value of a specific variable that depends whether a checkbox is checked. This is however dynamically done.
What I'm trying to achieve:
The example above works fine but it starts going wrong when I start to uncheck the check boxes. It subtracts by the double amount of the time and I have no idea why:
My Code (TimeSpent is the variable that I want to have at the end):
Class
public class Activity
{
public int ID { get; set; }
public int IncidentID { get; set; }
public string Description { get; set; }
public int TimeSpent { get; set; }
public static int StartX { get; set; } = 10;
public static int StartY { get; set; } = 10;
private TextBox textBox = null;
private CheckBox checkBox = null;
public Activity(int iD, int incidentID, string description, int timeSpent)
{
this.ID = iD;
this.IncidentID = incidentID;
this.Description = description;
this.TimeSpent = timeSpent;
}
public Activity()
{ }
public bool isChecked() {
return checkBox.Checked;
}
public void setTimeSpent(int timeSpent) {
this.TimeSpent = timeSpent;
textBox.Text = timeSpent.ToString();
}
public int getTimeSpent()
{
return Int32.Parse(textBox.Text);
}
public void DrawToForm(Panel p)
{
var label = new Label();
textBox = new TextBox();
checkBox = new CheckBox();
checkBox.Checked = true;
textBox.Size = new System.Drawing.Size(40, 20);
label.Text = Description.ToString();
label.AutoSize = true;
textBox.Text = TimeSpent.ToString();
label.Left = StartX;
label.Top = StartY;
StartX += 430;// Move position to right
textBox.Left = StartX;
textBox.Top = StartY;
StartX += 160;// Move position to right
checkBox.Left = StartX;
checkBox.Top = StartY;
StartX = 10;// Reset to start
StartY += 50;// Move position to down
p.Controls.Add(label);
p.Controls.Add(textBox);
p.Controls.Add(checkBox);
}
}
GUI:
private void Btn_Validate_Click(object sender, EventArgs e)
{
tb_TotalTime.Text = calculateTotalTime().ToString();
}
public int calculateTotalTime()
{
int total = 0;
foreach (Activity a in activities)
{
if(a.isChecked())
{
total += a.getTimeSpent();
}else
{
total -= a.getTimeSpent();
}
}
return total;
}
Why is subtracting not done correctly?
You subtract when the checkbox is not checked:
if(a.isChecked())
{
total += a.getTimeSpent();
}
else
{
total -= a.getTimeSpent();// << THIS
}
So with the setup of your 2nd image (top 2 unchecked bottom one checked) you do this:
0 - 5 - 5 + 5 = -5
The 0 comes from the default value of Total (int)
To fix this you could just remove the else clause as you don't need to subtract billable time ever.
You should remove subtracting at all.
So change it to :
if(a.isChecked())
{
total += a.getTimeSpent();
}
You have total=0, you have not added all values before calculating. So you don't need subtracting.
Your logic is add if Check subtract if unchecked. Your logic should be add if Checked only.
private void Btn_Validate_Click(object sender, EventArgs e)
{
tb_TotalTime.Text = calculateTotalTime().ToString();
}
public int calculateTotalTime()
{
int total = 0;
foreach (Activity a in activities)
{
if (a.isChecked())
{
total += a.getTimeSpent();
}
}
return total;
}

returning actual Height and Width to wpf rectangle after dynamic change

I have an app with the main window which contains a rectangle and a button that leads to another window in which the user enters information. After entering info, user clicks on a button and it returns him to the main window and changes the size accordingly. What I am trying to achieve is to return the ActualHeight and ActualWidth to the rectangle if a user presses the button in the main window again, kind of a refresh of rectangle.
All the code is in the Main Window Button click event. If you need any specific information about the code, i will gladly give it to you.
private void buttonStart_Click(object sender, RoutedEventArgs e)
{
Questionnaire q = new Questionnaire();
q.ShowDialog();
var size = q.textBoxNumberOfEmployees.Text;
if (int.Parse(size) > 5 && int.Parse(size) < 15)
{
Rect1.Height = Rect1.ActualHeight - 10;
Rect1.Width = Rect1.ActualWidth - 5;
}
else if (int.Parse(size) > 15 && int.Parse(size) < 30)
{
Rect1.Height = Rect1.ActualHeight - 15;
Rect1.Width = Rect1.ActualWidth - 10;
}
else if (int.Parse(size) > 30 && int.Parse(size) < 100)
{
Rect1.Height = Rect1.ActualHeight - 30;
Rect1.Width = Rect1.ActualWidth - 15;
}
else
{
Rect1.Height = Rect1.ActualHeight;
Rect1.Width = Rect1.ActualWidth;
}
You can store the original height and width of rectangle in variables in form load. Use those variables to make rectangle to original size bebore opening new window in button click.
Following code goes at the top inside your form.
private int rect1width;
private int rect1height;
In your form__load you write this at the end.
rect1width = Rect1.ActualWidth;
rect1height = Rect1.ActualHeight;
In your button click code following code goes at top.
Rect1.Width = rect1width;
Rect1.Height = rect1height;
Here is some seemingly long code, but it uses an MVC type design pattern and compounds with the state pattern. The only thing really missing to make it true MVC is Observers and observable interfaces that would subscribe to the Questionnaire.
public interface RectangleState
{
int myHeight { get; set; }
int myWidth { get; set; }
}
public class RectangleModel
{
private static Rectangle Rect1;
public RectangleModel(Rectangle rect1 )
{
Rect1 = rect1;
}
private RectangleState state;
public RectangleState State
{
get
{
return state;
}
set
{
state = value;
ModifyState(value.myHeight, value.myWidth);
}
}
private void ModifyState(int Height, int Width)
{
Rect1.Height = Height;
Rect1.Width = Width;
}
}
public class SmallState : RectangleState
{
public int myHeight { get; set; } = 20;
public int myWidth { get; set; } = 80;
}
public class MediumState : RectangleState
{
public int myHeight { get; set; } = 25;
public int myWidth { get; set; } = 90;
}
public class LargeState : RectangleState
{
public int myHeight { get; set; } = 35;
public int myWidth { get; set; } = 120;
}
public class NormalState : RectangleState
{
public int myHeight { get; set; } = 30;
public int myWidth { get; set; } = 100;
}
Now all you need to do is plug in the conditions:
RectangleModel RM = new RectangleModel(myRectangle); // store this in your class as property;
int size = 0;
int.TryParse(q.textBoxNumberOfEmployees.Text, out size);
if (size > 5 && size < 15)
{
RM.State = new SmallState();
}
else if (size > 15 && size < 30)
{
RM.State = new MediumState();
}
else if (size > 30 && size < 100)
{
RM.State = new LargeState();
}
else
{
RM.State = new NormalState();
}
If later you decide you want to change the default values on any of these you can change them. If you wish to add a new Rectangle shape or size you can add it. If you wish to create an adapter to further modify the rectangle, you can do so. This is a nice pattern. I know the answer looks overdone, but I think you will find it works solidly and is quite flexible when plugged into the code that accesses your questionaire.

CircleRadius (CustomMap renderer) only works if I use it in my InitializeComponent immediately and not inside a foreach loop xamarin forms

If I execute my CircleRadius inside my InitializeComponent immediately then I see it on the map, but if I want to create it once I load my data (loadPins function) then It does not appear on the map. It seems like it has to be loaded immediately or else it will not load. How can I adjust the code so it gets puts on hold until It gets added?
XAML and my customMap:
<local:CustomMap x:Name="mymap" MapType="Street" IsShowingUser="true"/>
The Code:
public MapPage()
{
InitializeComponent();
loadPins ();
/*
var position = new Position (56.264945, 12.579809);
mymap.Circle = new CustomCircle {
Position = position,
Radius = 2500
};
*/
// If I use the code above then I get a circleradius on the map.
}
async void loadPins ()
{
var getEnd = await phpApi.getEnd ();
foreach (var currentItems in getEnd ["results"]) {
latstring = currentItems ["Lat"].ToString ();
lngstring = currentItems ["Lng"].ToString ();
var storeLng = Double.Parse (lngstring, CultureInfo.InvariantCulture);
var storeLat = Double.Parse (latstring, CultureInfo.InvariantCulture);
var pin = new Pin ();
pin.Position = new Position (storeLat, storeLng);
pin.Label = "Test";
pin.Address = "-";
mymap.Circle = new CustomCircle {
Position = pin.Position,
Radius = 100000
}; //I cannot see this one on the map.
mymap.Pins.Add (pin);
}
}
This is my customMap:
public class CustomMap : Map
{
public MapContentType ContentType { get; set; }
public double CircleRadius { get; set; }
public List<Position> Positions { get; set; }
public CustomCircle Circle { get; set; }
public CustomMap()
{
this.ContentType = MapContentType.Normal;
this.CircleRadius = 500;
this.Positions = new List<Position> ();
}
}
And my CustomCircle:
public class CustomCircle
{
public Position Position { get; set; }
public double Radius { get; set; }
}
And my renderer:
public class CustomMapRendererCircle : MapRenderer
{
MKCircleRenderer circleRenderer;
protected override void OnElementChanged (ElementChangedEventArgs<View> e)
{
base.OnElementChanged (e);
if (e.OldElement != null) {
var nativeMap = Control as MKMapView;
nativeMap.OverlayRenderer = null;
var nativeMapCircle = Control as MKMapView;
nativeMapCircle.OverlayRenderer = null;
}
if (e.NewElement != null) {
var formsMapCircle = (CustomMap)e.NewElement;
var nativeMapCircle = Control as MKMapView;
var circle = formsMapCircle.Circle;
nativeMapCircle.OverlayRenderer = GetOverLayRendererTwo;
if (circle != null) {
var circleOverlay = MKCircle.Circle (new CoreLocation.CLLocationCoordinate2D (circle.Position.Latitude, circle.Position.Longitude), circle.Radius);
nativeMapCircle.AddOverlay (circleOverlay);
}
}
}
MKOverlayRenderer GetOverLayRendererTwo (MKMapView mapView, IMKOverlay overlay)
{
if (circleRenderer == null) {
circleRenderer = new MKCircleRenderer (overlay as MKCircle);
circleRenderer.FillColor = UIColor.Green;
circleRenderer.Alpha = 0.2f;
}
return circleRenderer;
}
}
}
you might be facing a well known bug with iOS build
try using this tweak,put the code which is not working inside a time for some delaying , for me this worked
if(Device.OS == TargetPlatform.Android)
customMap.MoveToRegion (MapSpan.FromCenterAndRadius (customMap.CustomPins [0].Pin.Position, Distance.FromMiles (55.0)));
if (Device.OS == TargetPlatform.iOS) {
Device.StartTimer (TimeSpan.FromMilliseconds (500), () => {
customMap.MoveToRegion (MapSpan.FromCenterAndRadius (customMap.CustomPins [0].Pin.Position, Distance.FromMiles (55.0)));
return false;
});
}
}

Firecracker Kind of Animation in Windows 8 Metro

I am trying to make an animation in which a rocket like thing will go up the screen and blast into various parts and follow its path down and fade just like actual firecracker. I have tried to make it using an update loop and a draw loop and then rendering the images on a bitmap. But there is a lot of lag there in the animation. I want to implement this thing at the end of my game and when a user taps the screen the rocket will go to that place and then explode. The code which I have tried is here...
public class Plotter : UserControl, IDisposable
{
Random _rand = new Random((int)DateTime.Now.Ticks);
WriteableBitmap _particleBmp;
EventBlob[] _data;
private int NUMPBLOBS = 25;
private const int CANWIDTH = 1366;
private const int CANHEIGHT = 768;
double _lastx, _lasty;
public Plotter()
{
}
public async Task PlotterMethod(Point current)
{
_lastx = current.X;
_lasty = current.Y;
await Setup();
}
private async Task Setup()
{
_particleBmp = await Util.LoadBitmap("tspark.png");
CompositionTarget.Rendering += CompositionTarget_Rendering;
_data = new EventBlob[NUMPBLOBS];
int ang = 0;
for (int i = 0; i < NUMPBLOBS; i++)
{
EventBlob eb = new EventBlob();
eb.img = _particleBmp;
eb.SourceRect = new Rect(0, 0, 30, 30);
eb.Position.X = _rand.Next((int)_lastx - 10, (int)_lastx + 10);
eb.Position.Y = _rand.Next((int)_lasty - 10, (int)_lasty + 10);
eb.VX = 5;
eb.VY = 5;
eb.angle = ang;
ang += 36 / 5;
eb.Opacity = 1;
eb.BlendMode = WriteableBitmapExtensions.BlendMode.Additive;
eb.FadeRate = _rand.NextDouble() * 0.005 + 0.002;
Color c = new Color();
c.A = (byte)0;
c.R = (byte)_rand.Next(0, 255);
c.G = (byte)_rand.Next(0, 255);
c.B = (byte)_rand.Next(0, 255);
eb.Color = c;
_data[i] = eb;
}
}
int counterupdate = 0;
void CompositionTarget_Rendering(object sender, object e)
{
if (counterupdate % 2 == 0)
{
Update();
DrawBitmap();
}
counterupdate++;
}
int count = 0;
bool opacitycheck = true;
private void Update()
{
bool isallclear = true;
for (int i = 0; i < _data.Length; i++)
{
var p = _data[i];
if (i < 51)
{
p.VX = 2 * Math.Cos(p.angle);
p.VY = 2 * Math.Sin(p.angle);
}
p.Position.X += p.VX;
p.Position.Y += p.VY;
if (opacitycheck)
{
if (p.Color.A + 30 < 255)
p.Color.A += 30;
else
{
opacitycheck = false;
p.Color.A = 255;
}
}
else
{
if (p.Color.A - 30 > 0)
p.Color.A -= 30;
else
{
p.Color.A = 0;
}
}
if (p.Color.A != 0)
{
isallclear = false;
}
}
count++;
if (isallclear)
{
_data = new EventBlob[0];
CompositionTarget.Rendering -= CompositionTarget_Rendering;
NUMPBLOBS = 0;
opacitycheck = true;
Completed(this, null);
}
}
private void DrawBitmap()
{
using (TargetBmp.GetBitmapContext())
{
TargetBmp.Clear();
for (int i = 0; i < _data.Length; i++)
{
var b = _data[i];
this.TargetBmp.Blit(b.Position, b.img, b.SourceRect, b.Color, b.BlendMode);
}
TargetBmp.Invalidate();
}
}
public WriteableBitmap TargetBmp { get; set; }
public Image Imagemain { get; set; }
public event EventHandler<object> Completed;
public void Dispose()
{
}
}
public class EventBlob
{
public double Opacity { get; set; }
public double FadeRate { get; set; }
public Color Color;
public Rect SourceRect { get; set; }
public WriteableBitmap img { get; set; }
public Point Position;
public double VX { get; set; }
public double VY { get; set; }
public WriteableBitmapExtensions.BlendMode BlendMode;
public double angle { get; set; }
}
and in my main page i have called it like this...
async void MainPage_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (LayoutRoot.Children.Count < 6)
{
Plotter asd = new Plotter();
await asd.PlotterMethod(e.GetCurrentPoint(LayoutRoot).Position);
WriteableBitmap _wb = new WriteableBitmap(1366, 786);
asd.TargetBmp = _wb;
Image image = new Image();
image.Height = 786;
image.Width = 1366;
image.Stretch = Stretch.Fill;
image.Source = _wb;
asd.Imagemain = image;
asd.Completed += asd_Completed;
LayoutRoot.Children.Add(image);
}
}
void asd_Completed(object sender, object e)
{
var obj = (Plotter)sender;
LayoutRoot.Children.Remove(obj.Imagemain);
obj.Dispose();
}
but there is too much of lag if I create 4 of these objects the fps goes down to 10.
Please suggest a better way or a way to optimize this code. Thanks.
Try implementing the parallel feature of C# , For Reference check
http://www.parallelcsharp.com/
I hope this will solve your Problem

Categories

Resources