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);
}
Related
Can someone explain me how I can create chart like this one using itextsharp library.
As you can see here, this chart has attached table with legends to its bottom side. And each bar has year attached to it. I want to create something like that.
Second picture. This is what i have so far. I don't have year attached to each bar, and my legends are not beneath each bar like in top graph. If someone could guide me how to create identical graph like one on top i would be grateful. Thanks in advance!
How can I turn those labels to be displayed horizontally, and put those legends beneath years in table like one in picture number 1.
// Chart Centers By Year
var chartCentersByYear = new Chart
{
Width = 1000,
Height = 450,
RenderType = RenderType.ImageTag,
AntiAliasing = AntiAliasingStyles.Graphics,
TextAntiAliasingQuality = TextAntiAliasingQuality.High
};
chartCentersByYear.Titles.Add("Centers By Year");
chartCentersByYear.Titles[0].Font = new Font("Arial", 16f);
chartCentersByYear.Titles[0].Alignment = System.Drawing.ContentAlignment.TopLeft;
chartCentersByYear.ChartAreas.Add("");
chartCentersByYear.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
chartCentersByYear.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
chartCentersByYear.Series.Add("Count");
chartCentersByYear.Series.Add("Cases");
chartCentersByYear.Series[0].ChartType = SeriesChartType.Column; //Pie
chartCentersByYear.Series[1].ChartType = SeriesChartType.StepLine; //StepLine
chartCentersByYear.Series[1].BorderDashStyle = ChartDashStyle.DashDot;
chartCentersByYear.Series[1].BorderWidth = 3;
chartCentersByYear.Series[0].Color = Color.Brown;
chartCentersByYear.Legends.Add("1");
chartCentersByYear.Legends.Add("2");
chartCentersByYear.Legends[0].HeaderSeparator = LegendSeparatorStyle.Line;
chartCentersByYear.Legends[0].HeaderSeparatorColor = Color.Black;
chartCentersByYear.Legends[0].ItemColumnSeparator = LegendSeparatorStyle.Line;
chartCentersByYear.Legends[0].ItemColumnSeparatorColor = Color.Black;
chartCentersByYear.Legends[1].HeaderSeparator = LegendSeparatorStyle.Line;
chartCentersByYear.Legends[1].HeaderSeparatorColor = Color.Black;
chartCentersByYear.Legends[1].ItemColumnSeparator = LegendSeparatorStyle.Line;
chartCentersByYear.Legends[1].ItemColumnSeparatorColor = Color.Black;
//For the Legend
LegendCellColumn firstColumn = new LegendCellColumn();
firstColumn.ColumnType = LegendCellColumnType.SeriesSymbol;
firstColumn.HeaderBackColor = Color.WhiteSmoke;
chartCentersByYear.Legends[0].CellColumns.Add(firstColumn);
chartCentersByYear.Legends[1].CellColumns.Add(firstColumn);
LegendCellColumn secondColumn = new LegendCellColumn();
secondColumn.ColumnType = LegendCellColumnType.Text;
secondColumn.Text = "#LEGENDTEXT";
secondColumn.HeaderBackColor = Color.WhiteSmoke;
LegendItem newItemCount = new LegendItem();
newItemCount.Cells.Add(LegendCellType.Text, "Count", System.Drawing.ContentAlignment.MiddleCenter);
newItemCount.BorderWidth = 1;
newItemCount.BorderDashStyle = ChartDashStyle.Solid;
LegendItem newItemCases = new LegendItem();
newItemCases.Cells.Add(LegendCellType.Text, "Cases", System.Drawing.ContentAlignment.MiddleCenter);
newItemCases.BorderWidth = 1;
newItemCases.BorderDashStyle = ChartDashStyle.Solid;
// Getting data from a stored procedure
var totalCentersByYearResult = new Repository().GetTotalCentersByYear();
foreach (IGD_spInternationalReportCenterWithTots1_Result item in totalCentersByYearResult)
{
// For Series
chartCentersByYear.Series[0].Points.AddXY(item.YearEcmo, item.Count);
chartCentersByYear.Series[1].Points.AddY(item.Cases);
// For Legend
newItemCount.Cells.Add(LegendCellType.Text, item.Count.ToString(), System.Drawing.ContentAlignment.MiddleCenter);
newItemCases.Cells.Add(LegendCellType.Text, item.Cases.ToString(), System.Drawing.ContentAlignment.MiddleCenter);
}
chartCentersByYear.Legends[0].CustomItems.Add(newItemCount);
chartCentersByYear.Legends[0].CustomItems.Add(newItemCases);
chartCentersByYear.Legends[0].Docking = Docking.Bottom;
chartCentersByYear.Legends[1].Docking = Docking.Bottom; //Top
chartCentersByYear.Series[0].YAxisType = AxisType.Primary;
chartCentersByYear.Series[1].YAxisType = AxisType.Secondary;
//For two coordinate systems
chartCentersByYear.ChartAreas[0].AxisY2.LineColor = Color.Transparent;
chartCentersByYear.ChartAreas[0].AxisY2.MajorGrid.Enabled = false;
chartCentersByYear.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True;
chartCentersByYear.ChartAreas[0].AxisY2.IsStartedFromZero = chartCentersByYear.ChartAreas[0].AxisY.IsStartedFromZero;
using (var chartimage = new MemoryStream())
{
chartCentersByYear.SaveImage(chartimage, ChartImageFormat.Png);
Byte[] newChart = chartimage.GetBuffer(); //return chartimage.GetBuffer();
var image = Image.GetInstance(newChart); //Image.GetInstance(Chart());
image.ScalePercent(50f);
image.SetAbsolutePosition(document.LeftMargin + 40, document.BottomMargin + 100);
document.Add(image);
}
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 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);
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 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);