I have multiple markers on a GMAP.NET map that are updated via a delegate on a thread - how can I ensure that when a new coordinate is passed from the thread to the update delegate that the marker simply updates is location, not creating a new marker?
Code is below
double lat = Convert.ToDouble(latlong[0]); //latitude string part of array
double longitude = Convert.ToDouble(latlong[1]); //longitude string part of array
GMapOverlay markersOverlay = new GMapOverlay("markers");
GMarkerGoogle marker = new GMarkerGoogle(new PointLatLng(lat, longitude),
GMarkerGoogleType.green);
gmap2.Overlays.Clear();
markersOverlay.Markers.Add(marker);
gmap2.Overlays.Add(markersOverlay);
gmap2.Refresh();
The latitude and longitude are being supplied from the thread.
Cheers!
Usually with data from GPS units, you get some kind of device ID. Use this data to distinguish between different markers by using the Tag of GMapMarker:
private void AddOrUpdateMarker(string tag, double lat, double lng)
{
// assuming "markersOverlay" is a field
var marker = markersOverlay.Markers.FirstOrDefault(m => m.Tag == tag);
if (marker == null)
{
marker = new GMarkerGoogle(new PointLatLng(lat, lng), GMarkerGoogleType.green);
marker.Tag = tag;
markersOverlay.Markers.Add(marker);
}
// update the position
marker.Position = new PointLatLng(lat, lng);
}
GMapOverlay markersOverlay = new GMapOverlay("marker");
GMapOverlay mark = new GMapOverlay("addmark");
GMapMarker addmark = new GMarkerGoogle(new PointLatLng(33.6491, 73.0833), GMarkerGoogleType.lightblue);
GMapMarker addmark1 = new GMarkerGoogle(new PointLatLng(33.6844, 73.0479), GMarkerGoogleType.lightblue);
mark.Markers.Add(addmark);
GMap.NET.WindowsForms.GMapMarker marker =
new GMap.NET.WindowsForms.Markers.GMarkerGoogle(
new GMap.NET.PointLatLng(33.626057, 73.071442),
GMap.NET.WindowsForms.Markers.GMarkerGoogleType.lightblue);
markersOverlay.Markers.Add(addmark1);
markersOverlay.Markers.Add(marker);
gMapControl1.Overlays.Add(mark);
// gMapControl1.Overlays.Clear();
gMapControl1.MarkersEnabled = true;
gMapControl1.Overlays.Add(markersOverlay);
gMapControl1.Refresh();
// gMapControl1.
gMapControl1.Position = new PointLatLng(33.626057, 73.071442);
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 trying to display places within 1 km from my current location on window phone 8 map control with google places API. I am using JSON parsing to fetch latitude, longitude and Name. Now i want name to be display like a tooltip when user tap on any place circle.
//Use google API to show POI
HttpClient client = new HttpClient();
string baseUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + position.Coordinate.Latitude + "," + position.Coordinate.Longitude + "&radius=1000&keyword=hospital&key=AIzaSyBCccOYAea2ITvgqNpIHcutuExQwzQctCk";
string googleResult = await client.GetStringAsync(baseUrl);
//Parse JSON data
JObject obj = JObject.Parse(googleResult);
JArray jarr = (JArray)obj["results"];
foreach(var item in jarr)
{
string name = (string)item.SelectToken("name");
double lt = (double)item.SelectToken("geometry.location.lat");
double lg = (double)item.SelectToken("geometry.location.lng");
//Create a small circle to mark the current location.
Ellipse myCircle2 = new Ellipse();
myCircle2.Fill = new SolidColorBrush(Colors.Red);
myCircle2.Height = 10;
myCircle2.Width = 10;
myCircle2.Opacity = 50;
// Create a MapOverlay to contain the circle.
MapOverlay myLocationOverlay2 = new MapOverlay();
myLocationOverlay2.Content = myCircle2;
myLocationOverlay2.PositionOrigin = new Point(0.5, 0.5);
GeoCoordinate myGeoCoordinate2 = new GeoCoordinate(lt, lg);
myLocationOverlay2.GeoCoordinate = myGeoCoordinate2;
// Create a MapLayer to contain the MapOverlay.
MapLayer myLocationLayer2 = new MapLayer();
myLocationLayer2.Add(myLocationOverlay2);
// Add the MapLayer to the Map.
Bmap.Layers.Add(myLocationLayer2);
}
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);