Google Map Marker wrongly change position while drag drop - c#

I know we have some similar questions already but all of them can not help me solve my issue (because of the difference platform). So I put my question here with a hope that someone can help me.
I am working on a xamarin project and using Google Map API ver 2 to make a map.
When I touch on the map, I will add a new marker by using this code.
public void AddPoint(LatLng pointPossition)
{
MarkerOptions markerPoint = new MarkerOptions();
markerPoint.Anchor (0.5f, 1.0f);//The same issue occur when I remove this line
markerPoint.InvokeIcon(m_PointMoveableIcon);
markerPoint.SetPosition (pointPossition);
markerPoint.Draggable (true);
Marker marker = m_Map.AddMarker(markerPoint);//m_Map is the Google Map
m_Markers.Add(marker);//m_Markers is a list to store all created markers
}
By that way, I can create some makers on the map
All markers are draggable, so I can long click on any marker and drag it to another position, but unfortunately, the dragged marker change position suddenly, and this behavior is really bad.
I tried many solutions but not work. So, I hope someone can help me.
Thank in advance.

I had this quest now. And it's my solution is code below.
Why first number is it, i don't know, but it's works for my debugger. And 0.5 probably is half marker position.
private void Map_PinDragging(object sender, PinDragEventArgs e)
{
int m = map.Pins.IndexOf(e.Pin);
map.Pins.ElementAt(m).Position = new Xamarin.Forms.GoogleMaps.Position(e.Pin.Position.Latitude - (0.001347153801 * 0.5), e.Pin.Position.Longitude);
}
private void Map_PinDragStart(object sender, PinDragEventArgs e)
{
int m = map.Pins.IndexOf(e.Pin);
map.Pins.ElementAt(m).Position = new Xamarin.Forms.GoogleMaps.Position(e.Pin.Position.Latitude - (0.001347153801 * 0.5), e.Pin.Position.Longitude);
}
Pin DragPin;
private void Map_PinDragEnd(object sender, PinDragEventArgs e)
{
int m = map.Pins.IndexOf(e.Pin);
map.Pins.ElementAt(m).Position = new Xamarin.Forms.GoogleMaps.Position(e.Pin.Position.Latitude - (0.001347153801*0.5), e.Pin.Position.Longitude);
}
And...
This value change with my map Zoom. Needs some math there.

Related

Looking for ways to optimize multi poly-lines on canvas in wpf

I'm working on program in WPF that need to plot on one of her screens 50 poly-lines that describes movement of some energy in space. One more demand from the program is to move two lines and a dot to indicate the mouse location when its relevant.
The problem is that when the poly-lines cover a high percent of the canvas and the mouse is fly over the canvas then all start to run really slowly.
I succeeded to improve this a little but its still not good enough so I'm asking for your help please.
So because this canvas related to another one, I spited the work for two - the handler and the movement function:
private void rayTraceCanvas_MouseMove(object sender, MouseEventArgs e)
{
System.Windows.Point pos = e.GetPosition(rayTraceCanvas);
mouseMove(pos);
if (m_MouseMoveCallback != null)
m_MouseMoveCallback(m_CurrentDepth);
}
And then the movement function:
private void mouseMove(Point currentPos)
{
m_CurrentDepth = Math.Round((currentPos.Y) / (m_PixelPerDepthUnit));
m_CurrentRange = Math.Round((currentPos.X) / (m_PixelPerRangeUnit));
DepthPos.Text = "D: " + m_CurrentDepth.ToString();
RangePos.Text = "R: " + m_CurrentRange.ToString();
rayTraceWidthLine.Y1 = currentPos.Y;
rayTraceWidthLine.Y2 = currentPos.Y;
rayTraceHeightLine.X1 = currentPos.X;
rayTraceHeightLine.X2 = currentPos.X;
Canvas.SetLeft(rayTraceDotOnGraph, currentPos.X - (rayTraceDotOnGraph.Width / 2));
Canvas.SetTop(rayTraceDotOnGraph, currentPos.Y - (rayTraceDotOnGraph.Height / 2));
}
I tried this without the deleget from the handler function and its work the same so the problem isn't there.

Draw point where mouse clicked

I'm using HelixToolkit to see and interact with STL files. I need to draw or mark a point clicked by user on the window. I have the coordinates, I know where to draw that point, but I don't know how to draw it, can someone help me? I post some code to explain what I have right now:
private void vierport3d_MouseRightClick(object sender, MouseButtonEventArgs e)
{
Point mousePos = e.GetPosition(viewPort3d);
PointHitTestParameters hitParams = new PointHitTestParameters(mousePos);
VisualTreeHelper.HitTest(viewPort3d, null, ResultCallback, hitParams);
}
public HitTestResultBehavior ResultCallback(HitTestResult result)
{
RayHitTestResult rayResult = result as RayHitTestResult;
if (rayResult != null)
{
RayMeshGeometry3DHitTestResult rayMeshResult = rayResult as RayMeshGeometry3DHitTestResult;
//HERE I HAVE THE LOCATION TO DRAW
MessageBox.Show(rayMeshResult.PointHit.X + " " + rayMeshResult.PointHit.Y + " " + rayMeshResult.PointHit.Z);
if (rayMeshResult != null)
{
// I THINK I HAVE TO DRAW THE POINT HERE
}
}
return HitTestResultBehavior.Continue;
}
PD: I show the stl on a viewport3d.
We had same scenario in our project and used a sphere to visually indicate the point.
<ht:SphereVisual3D Radius="0.75" Fill="Red" Center="{Binding ContactPoint}" />
ContactPoint is a Point3D type.
This might help, but its probably not the most effecient.
Try the following:
This will create a 3D sphere that can be rendered at the given coordinates.
var sphereSize = 0.025;
/* keep these values low, the higher the values the more detailed the sphere which may impact your rendering perfomance.*/
var phi = 12;
var theta = 12;
MeshBuilder meshBuilder = new MeshBuilder();
Pass in your x,y,z to the first parameter. i.e. the click 3D location.
meshBuilder.AddSphere( new Point3D(x,y,z), sphereSize , theta, phi);
GeometryModel3D sphereModel = new GeometryModel3D(meshBuilder.ToMesh(),MaterialHelper.CreateMaterial(Brushes.Green,null,null,1,0));
Rendering the Point in your viewport
You will need a ModelVisual3D component as a child of the HelixViewport. ( This can be implemented in C# or in XAML) its up to you, ill show both ways.
C# version
NB: You need a reference to the helixviewport if its defined in xaml. Set the x:Name:"" to something appropriate. e.g x:Name="helixViewPort"
ModelVisual3D visualizer = new ModelVisual3D();
visualizer.Content = sphereModel;
helixViewPort.Children.Add(visualizer);
XAML version
I'll assume your xaml code has at least a helix view port so you'll have to add a ModelVisual3D child to the helix viewport if there's none.
<h:HelixViewport3D x:Name="HelixPlotViewPort" >
<h:DefaultLights/>
<ModelVisual3D x:Name="Visualizer">
</ModelVisual3D>
</h:HelixViewport3D>
//Then in C# add the following
Visualizer.Content = sphereModel;
That should do it, hope it helps, do inform us if you find a better solution. :)

How can I get my graphics lines to match up properly on Winforms picturebox?

I am trying to create a program where an image is processed (the details of that are irrelevant to this question, I think), and then the user can modify / "fine tune" the image by drawing lines wherever they may be needed. For the sake of accuracy, I want the line to go from the point of one mouse click to the next. I found a previously asked / answered question on Stack Overflow that seemed to provide a good template for me; here's my code:
private void imgPicture_MouseDown(object sender, MouseEventArgs e) {
if (draw) {
if (p1.X == 0) {
p1.X = e.X;
p1.Y = e.Y;
}
else {
p2.X = e.X;
p2.Y = e.Y;
p1List.Add(p1);
p2List.Add(p2);
imgPicture.Invalidate();
p1.X = 0;
}
Graphics pictureGraphic = Graphics.FromImage(imgPicture.Image);
using (var p = new Pen(Color.Black, 4)) {
for (int x = 0; x < p1List.Count; x++) {
pictureGraphic.DrawLine(p, p1List[x], p2List[x]);
}
}
}
}
The problem is, the location where my clicks are registering are way off. Here is a snip of my program; the blue line is about where I was TRYING to create the line, the red line is where it actually showed up.
It seems like the further I get from the top left corner of the screen, the farther off the capture is.
Also, while I'm asking questions, does anyone know how I can permanently dispose of all the drawn lines that are created? So that I can click a button and all the lines disappear?
Thanks for your help! Stackoverflow is a life saver!
Thanks to Sayse and Hans Passant it's working great now! As Hans pointed out, I set the SizeMode property to Normal for the duration of the drawing function, then set it back to zoom when I was done, and it works great!
For the cleanup, all I had to do was use the Clear function on my two pointer lists, and the Dispose function on my Graphic.

Windows Phone - check if MapCore.SetView doesn't zoom too much

I am using method SetView to zoom for two points in map but when they are too close I am too zoomed. So I hope I can check something like this:
myMap.SetView(bounds);
if (myMap.ZoomLevel > Constants.DefaultZoomLevel)
myMap.ZoomLevel = Constants.DefaultZoomLevel;
But method SetView isn't immediately set ZoomLevel property. What can I do to fix it? How can I set some zoom level border? Thanks
Edit:
I found that in 8.0 sdk there is ZoomLevelChanged event? This could be useful for me. So is there possible how to get it worked in 7.1?
I tried several solutions and these are my results (I needed working for WP7.1, with just targeting for WP8 there could be easier solution):
Use of TargetZoomLevel
Like this:
myMap.ZoomLevel = Math.Min(myMap.TargetZoomLevel, maxZoomLevel);
Doesn't solve my problem because SetView set ZoomLevel after this code execute. Map was just blinking between ZoomLevel from SetView and maxZoomLevel (I have timer for checking positions so that is why it was blinking and isn't good for me).
Use of MapZoom event
Like this:
private void map1_MapZoom(object sender, Microsoft.Phone.Controls.Maps.MapZoomEventArgs e)
{
if (((Map)sender).ZoomLevel > maxZoomLevel)
{
e.Handled = true;
}
}
Problem: MapZoom event handler is not fired when SetView it's used.
Check distance and set ZoomLevel if distance is little:
public static double GetDistanceBetweenPoints(LatLon firstPoint, LatLon secondPoint)
{
var sCoord = new GeoCoordinate(firstPoint.Lat, firstPoint.Lon);
var eCoord = new GeoCoordinate(secondPoint.Lat, secondPoint.Lon);
return sCoord.GetDistanceTo(eCoord);
}
usage:
var distance = LocationHelper.GetDistanceBetweenPoints(carPosition, userPosition);
if (distance < MinMetersDistance)
myMap.ZoomLevel = maxZoomLevel;
Problem: Again blinking. Sometimes I set ZoomLevel by this code. Other time it was set by SetView.
My real solution:
I just check distance between two points like in previous dot. But this time if the distance was little I just create new points from the old ones and set them in new positions (latitude and longitude) which was in min distance (one on the left side I moved more to left and second on the right side I moved more to right). Then I used SetView on new points.

Weird shape resizing behavior in WPF

I am making a WPF application that will let the user draw and resize shapes.
The resizing part is done using adorners, and the shapes are my own classes derived from Shape.
For example I have a Polyline, and for each of it's points I am adorning a Thumb with a handler on it's DragDelta event:
void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
PolylineEx polyline = this.AdornedElement as PolylineEx;
ResizingThumb thumb = sender as ResizingThumb;
int index = (int)thumb.Tag;
Point newPoint = new Point(
polyline.Points[index].X + e.HorizontalChange,
polyline.Points[index].Y + e.VerticalChange);
Trace.WriteLine(String.Format("Arranging point {0}:{1},{2}", index, newPoint.X, newPoint.Y));
polyline.Points[index] = newPoint;
}
Well, the problem is that sometimes (often), dragging a thumb is not smooth at all. First I thought it was a performance issue, because of a new Point being created every time (and other things), but then I noticed that sometimes the point is set up at weird coordinates that have nothing to do with the position of the mouse.
I've also uploaded a sample project HERE, could someone who knows his way around wpf take a look and enlighten me of what is happening?
Also, if anyone thinks of a better way for doing this, any feedback would be highly appreciated.
Thank you.
Edit: HERE is a new link to the project files.
I'm ending up answering my own question :)
I think the problem was here:
protected override System.Windows.Media.Geometry DefiningGeometry
{
get
{
StreamGeometry geometry = new StreamGeometry();
using (StreamGeometryContext context = geometry.Open())
{
context.BeginFigure(Points[0], false, true);
foreach (Point pt in Points)
{
context.LineTo(pt, true, true);
}
geometry.Freeze();
return geometry;
}
}
}
I switched to using PathGeometry & LineSegments and it works fine now.

Categories