I am trying to use a MapPolyLine in my Map to show a real-time route, hopefully it will move/scale this time. The thing is the line is not being shown on the map, and I cannot find any programming mistake:
C#
MapLayer pathLayer;
//Constructor
pathLayer = new MapLayer();
MapPolyline line = new MapPolyline();
line.StrokeColor = Colors.Red;
line.StrokeThickness = 10;
//line.Path.Add(several points); Tested, no effect
MapOverlay overlay = new MapOverlay();
overlay.Content = line;
//overlay.GeoCoordinate = new GeoCoordinate(0,0); Tested, no effect
//overlay.PositionOrigin = new Point(0.0, 1.0); Tested, no effect
pathLayer.Add(overlay);
MyMap.Layers.Add(pathLayer);
void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
MapPolyline line = pathLayer.First(TrackPath).Content as MapPolyline;
line.Path.Add(args.Position.Coordinate); // Checked values, line.Path adds them correctly
}
EDIT: New info. The emulator shows an error when trying to add it using XAML, and the emulator shows the name of the class on the top of the map as a graphic glitch:
MapPolylines and MapPolygons should be added to the MapElements collection... not a MapLayer or a MapOverlay.
You should be able to make this example work for you.
MapPolyline line = new MapPolyline();
line.StrokeColor = Colors.Red;
line.StrokeThickness = 10;
line.Path.Add(new GeoCoordinate(47.6602, -122.098358));
line.Path.Add(new GeoCoordinate(47.561482, -122.071544));
MyMap.MapElements.Add(line);
In your GeoCoord watcher you'll have to get the line from the map's MapElements collection, and add the new position to the line's path instead of predefining like I did. This should be doable.
In Windows Phone 8.1 try add points in this way. "punkty" is my collection.
List<BasicGeoposition> PosList = new List<BasicGeoposition>();
foreach (var item in punkty)
{
PosList.Add(new BasicGeoposition()
{
Latitude = item.Position.Latitude,
Longitude = item.Position.Longitude
});
}
//Example of one point
//PosList.Add(new BasicGeoposition()
//{
// Latitude = 52.46479093,
// Longitude = 16.91743341
//});
MapPolyline line = new MapPolyline();
line.StrokeColor = Colors.Red;
line.StrokeThickness = 5;
line.Path = new Geopath(PosList);
myMap.MapElements.Add(line);
Related
I'm using GMaps.NET and GMaps.WindowsPresentation in a WPF application. One of the classes that comes with GMaps presentation is GMapPolygon and a function called CreatePath. I'm trying to test adding a line between two or multiple points using this function but I'm getting the error when parsing a list of points. Must it be a certain type of list or am I missing something.
There are no examples that I can find of plotting a line between two points in using Windows Presentation but there are for Windows Forms
This is what I'm trying to do now:
List<PointLatLng> points = new List<PointLatLng>();
points.Add(new PointLatLng(48.866383, 2.323575));
points.Add(new PointLatLng(48.863868, 2.321554));
points.Add(new PointLatLng(48.861017, 2.330030));
points.Add(new PointLatLng(48.863727, 2.331918));
GMapPolygon SectorPolygon = new GMapPolygon(points);
SectorPolygon.CreatePath( points,true);
This is the function I'm parsing to:
public virtual Path CreatePath(List<Point> localPath, bool addBlurEffect)
{
// Create a StreamGeometry to use to specify myPath.
StreamGeometry geometry = new StreamGeometry();
using(StreamGeometryContext ctx = geometry.Open())
{
ctx.BeginFigure(localPath[0], true, true);
// Draw a line to the next specified point.
ctx.PolyLineTo(localPath, true, true);
}
// Freeze the geometry (make it unmodifiable)
// for additional performance benefits.
geometry.Freeze();
// Create a path to draw a geometry with.
Path myPath = new Path();
{
// Specify the shape of the Path using the StreamGeometry.
myPath.Data = geometry;
if(addBlurEffect)
{
BlurEffect ef = new BlurEffect();
{
ef.KernelType = KernelType.Gaussian;
ef.Radius = 3.0;
ef.RenderingBias = RenderingBias.Performance;
}
myPath.Effect = ef;
}
myPath.Stroke = Brushes.MidnightBlue;
myPath.StrokeThickness = 5;
myPath.StrokeLineJoin = PenLineJoin.Round;
myPath.StrokeStartLineCap = PenLineCap.Triangle;
myPath.StrokeEndLineCap = PenLineCap.Square;
myPath.Fill = Brushes.AliceBlue;
myPath.Opacity = 0.6;
myPath.IsHitTestVisible = false;
}
return myPath;
}
Currently I need to develop a tool with chart as the major component. Chart control is also new for me. I have do a lot of reading, researching to learn and understand the whole picture of the chart control.
After all, I had stuck and question on how to draw a horizontal line (blue & red horizontal line) on stacked column chart as image shown below:
Here what I have done so far:
This is my code so far:
// X-Axis labels settings
chart.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
chart.ChartAreas[0].AxisX.Interval = 1;
// Y-Axis labels settings
//chart.ChartAreas[0].AxisY.Minimum = 100;
chart.ChartAreas[0].AxisY.Minimum = 95;
// Plotting chart
using (YieldEntities context = new YieldEntities())
{
// Extract yield loss list
var yeilds = (
from yeild in context.YeildDatas
group yeild by new { yeild.Loss } into newyeild
select new
{
Loss = newyeild.Key.Loss,
Percentage = newyeild.Sum(p => p.Percentage)
}).OrderByDescending(p => p.Percentage);
//context.YeildDatas.Select(p => new { p.Loss, Percentage = p }).Distinct();
// Create new series
foreach (var yield in yeilds)
{
chart.Series.Add(yield.Loss);
chart.Series[yield.Loss].ChartType = SeriesChartType.StackedColumn100;
}
// Label settings for first series
chart.Series[0].SmartLabelStyle.Enabled = false;
chart.Series[0].LabelAngle = -90;
chart.Series[0].Font = new Font(Font.FontFamily, 15, FontStyle.Bold);
chart.Series[0].IsValueShownAsLabel = true;
var query = context.YeildDatas.ToList();
foreach (var item in query)
{
DataPoint dp = new DataPoint();
dp.SetValueXY(item.DateString, item.Percentage);
chart.Series[item.Loss].Points.Add(dp);
}
// Set empty datapoint for each series
foreach (var yield in yeilds)
{
DataPoint nulldp = new DataPoint();
nulldp.SetValueXY("", 0);
chart.Series[yield.Loss].Points.Insert(1, nulldp);
chart.Series[yield.Loss].Points.Insert(6, nulldp);
chart.Series[yield.Loss].Points.Insert(11, nulldp);
}
chart.Legends["Legend"].IsEquallySpacedItems = true;
chart.Legends["Legend"].IsTextAutoFit = true;
}
I hope to get any expert to guide me to solve this problem.
This is only sample, you can start from there:
// Data point to pixel
var pixelX = this.chart1.ChartAreas[0].AxisX.ValueToPixelPosition(dataPointX);
var pixelY = this.chart1.ChartAreas[0].AxisY.ValueToPixelPosition(dataPointY);
// Pixel to data point
var dataPointX = this.chart1.ChartAreas[0].AxisX.PixelPositionToValue(pixelX);
var dataPointY = this.chart1.ChartAreas[0].AxisY.PixelPositionToValue(pixelY);
// Use event Paint to draw your line
private void chart1_Paint(object sender, PaintEventArgs e)
{
// Convert dataPoint to pixel
var dataPointX = this.chart1.Series[0].Points[0].XValue;
var dataPointY = this.chart1.Series[0].Points[0].YValues[0];
var pixelX = this.chart1.ChartAreas[0].AxisX.ValueToPixelPosition(dataPointX);
var pixelY = this.chart1.ChartAreas[0].AxisY.ValueToPixelPosition(dataPointY);
// Only sample, pen should be initialized outside Paint method
Pen pen = new Pen(Brushes.Red);
// Example of drawing line with width=100 pixel
e.Graphics.DrawLine(pen, pixelX, pixelY, pixelX + 100, pixelY);
}
I'm fiddling around with GMap.NET. I have a gmap.net map control on my form. There is a red x (or plus sign, if you will) in the middle of the map. I added a method that will put a marker wherever I click on the map. However, the customer would rather have a "pushpin" button on the form that the user will click, and the marker will be added where the red X is located (which is always the center of the map control, it seems). The map is drag-able and zoom-able, so the marker will be added wherever the red x is at that time.
Right now, when my program adds a marker, it translates the lat and lng from the FromLocalToLatLng gmap method:
private void gmap_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
var lat = gmap.FromLocalToLatLng(e.X, e.Y).Lat;
var lng = gmap.FromLocalToLatLng(e.X, e.Y).Lng;
var markerOverlay = new GMapOverlay("markers");
var marker = new GMarkerGoogle(new
PointLatLng(lat, lng),
GMarkerGoogleType.green_pushpin)
{
ToolTipText = "Kevin Jennings",
ToolTipMode = MarkerTooltipMode.OnMouseOver
};
gmap.Overlays.Add(markerOverlay);
markerOverlay.Markers.Add(marker);
}
In this case, though, I'm wondering if there's a way to add the marker at the map center?
I figured it out. You can get the center of the map by using the following code:
var center = gmap.Position;
Once I had the center, all I needed to do was add a marker at that position, like this:
var marker2 = new GMarkerGoogle(new
PointLatLng(center.Lat, center.Lng),
GMarkerGoogleType.green_pushpin)
{
ToolTipText = "Kevin Jennings",
ToolTipMode = MarkerTooltipMode.OnMouseOver
};
you need to use this
map.Zoom = 10;
map.Zoom = 9;
and your markers will position on the right direction..
complete code
var lat = mapa.FromLocalToLatLng(e.X, e.Y).Lat;
var lng = mapa.FromLocalToLatLng(e.X, e.Y).Lng;
MessageBox.Show(lat + " long :" + lng);
var markerOverlay = new GMapOverlay("markers");
var marker = new GMarkerGoogle(new
PointLatLng(lat, lng),
GMarkerGoogleType.green_pushpin)
{
ToolTipText = "Ubicacion depto",
ToolTipMode = MarkerTooltipMode.OnMouseOver
};
markerOverlay.Markers.Add(marker);
map.Overlays.Add(markerOverlay);
map.Zoom = 10;
map.Zoom = 9;
}
I am just playing around with bing maps at the moment. I have followed the tutorials to create routes and add mapicons etc, however I have found that a mapIcon wont show if it on the route. I have tried playing with the Z-Index property of the mapIcon, however this seemed to have little effect, as I think it only has an effect with other MapElements.
Does anyone else know a way to make this happen?
My current code for creating the route and trying to set a MapIcon on the destination is (For abit of Content MapFunctions is just a static class I've made for functons such as finding the route, get the current location etc):
private async void DrawRoute()
{
// Check if a destination has been set
if(MapFunctions.destination != null)
{
route = await MapFunctions.GetRouteAsync(MapFunctions.destination.Point);
if (route != null)
{
// Use the route to initialize a MapRouteView.
MapRouteView viewOfRoute = new MapRouteView(route.Route);
viewOfRoute.RouteColor = Colors.Yellow;
viewOfRoute.OutlineColor = Colors.Black;
// Add the new MapRouteView to the Routes collection
// of the MapControl.
MyMap.Routes.Add(viewOfRoute);
// Fit the MapControl to the route.
await MyMap.TrySetViewBoundsAsync(
route.Route.BoundingBox,
null,
Windows.UI.Xaml.Controls.Maps.MapAnimationKind.None);
AddDestinationMapElement(MapFunctions.destination.Point);
// Start timer to update the remaining time of the journey
UpdateRemainingTime_Tick(this, new Object());
dispatcherTimer.Start();
}
else
{
MessageDialog message = new MessageDialog("An error occured while trying to calculate your route. Please try again later.", "Error");
await message.ShowAsync();
}
}
}
private void AddDestinationMapElement(Geopoint dest)
{
MapIcon MapIcon1 = new MapIcon();
MapIcon1.Location = new Geopoint(new BasicGeoposition()
{
Latitude = dest.Position.Latitude,
Longitude = dest.Position.Longitude
});
MapIcon1.Visible = true;
MapIcon1.ZIndex = int.MaxValue;
MapIcon1.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Images/mapIcon.png"));
MapIcon1.NormalizedAnchorPoint = new Point(0.5, 1.0);
MapIcon1.Title = "Destination";
MyMap.MapElements.Add(MapIcon1);
}
If you want to add pushpin on top of your elements, you can use MapOverlay that will allow you to add pushpin (with image or any XAML element) into your map control:
MapOverlay pushpinStart = new MapOverlay();
pushpinStart.PositionOrigin = new Point(0.5, 0.5);
pushpinStart.Content = new Image()
{
Source =
new BitmapImage(
new Uri("../Assets/Ui/ui-pin-start.png", UriKind.Relative))
};
pushpinStart.GeoCoordinate = posCollection[0];
If you want to stay with MapIcon, then the rendering engine will calculate what's best to be displayed based on the zoom level and current location as well as other elements collision algorithm's result. So I'm not sure that what you're looking for.
And for WP8.1, here is the equivalent code:
Image iconStart = new Image();
iconStart.Source = new BitmapImage(new Uri("ms-appx:///Assets/Ui/ui-pin-start.png"));
this.Map.Children.Add(iconStart);
MapControl.SetLocation(iconStart, new Geopoint(pos[0]));
MapControl.SetNormalizedAnchorPoint(iconStart, new Point(0.5, 0.5));
I'm running into a problem with WPF and PathGeometry. I have the following Path object which is a combination of lines and arcs.
<Path Data="M100,180L220,180 M220,180L220,152 M220,152L217,150
M217,150L182,150 M180,147L180,132 M182,130L217,130 M217,130L220,127
M220,127L220,80 M220,80L100,80 M100,80L100,180 M182,150L180,147
M180,132L182,130">
Here's a simple code snippet that should draw the entire shape.
private void DrawIt()
{
Canvas canv = new Canvas();
this.Content = canv;
canv.Margin = new Thickness(0, 0, 0, 0);
canv.Background = new SolidColorBrush(Colors.White);
Path testPath = GetPath("blue");
testPath.Data = Geometry.Parse("M100,180L220,180 M220,180L220,152 M220,152L217,150 M217,150L182,150 M180,147L180,132 M182,130L217,130 M217,130L220,127 M220,127L220,80 M220,80L100,80 M100,80L100,180 M182,150L180,147 M180,132L182,130 ");
var area = testPath.Data.GetArea();
canv.Children.Add(testPath);
this.Content = canv;
}
private Path GetPath(string aColor)
{
Path imagePath = new Path();
SolidColorBrush colorBrush = (SolidColorBrush)new BrushConverter().ConvertFromString(aColor);
imagePath.Stroke = colorBrush;
imagePath.StrokeThickness = 2;
imagePath.Fill = colorBrush;
return imagePath;
}
The code above results in the following image:
My problem is that I'm trying to get the area of this image, but Path.Data.GetArea() only ever returns 0.0.
Any help would be appreciated.
You're describing multiple figures, all of them just single straight lines, because you keep issuing Move commands. If your path data was like this:
M100,180L220,180 220,152 217,150 182,150 180,147 180,132 182,130 217,130 220,127
220,80 100,80 Z
It instead describes a single figure that should draw the same shape you've shown but should also be fillable.
See Path Markup Syntax