To reproduce: - Use a DataTable as a data source for SqlGeospatialDataReader. - An exception will occur. Workaround: Convert the data table to a simple list of custom objects.
How to reproduce: public partial class Form3 : Form { public Form3() { InitializeComponent(); MapLayer pointLayer = new MapLayer("PointG"); pointLayer.ClusterStrategy = new ElementClusterStrategy(); pointLayer.ClusterDistance = 100; this.radMap1.Layers.Add(pointLayer); MapPin pin1 = new MapPin(new PointG(45d, 15d)) { BackColor = Color.Coral, ToolTipText = "Tool Tip1" }; MapPin pin2 = new MapPin(new PointG(44d, 18d)) { BackColor = Color.Coral, ToolTipText = "Tool Tip2" }; this.radMap1.Layers["PointG"].Add(pin1); this.radMap1.Layers["PointG"].Add(pin2); this.SetupProviders(); } private void radMap1_ToolTipTextNeeded(object sender, Telerik.WinControls.ToolTipTextNeededEventArgs e) { MapCluster cluster = sender as MapCluster; if (cluster != null && cluster.ClusteredItems.Count == 1) { cluster.ToolTipText = ((MapPin)cluster.ClusteredItems[0]).ToolTipText; } } private void SetupProviders() { string cacheFolder = @"..\..\cache"; BingRestMapProvider bingProvider = new BingRestMapProvider(); bingProvider.Culture = System.Threading.Thread.CurrentThread.CurrentCulture; bingProvider.ImagerySet = ImagerySet.Road; bingProvider.UseSession = true; bingProvider.BingKey = "..."; LocalFileCacheProvider cache = new LocalFileCacheProvider(cacheFolder); bingProvider.CacheProvider = cache; this.radMap1.MapElement.Providers.Add(bingProvider); bingProvider.InitializationComplete += bingProvider_InitializationComplete; } private void bingProvider_InitializationComplete(object sender, EventArgs e) { this.radMap1.BringIntoView(new PointG(45d, 15d), 5); } } Workaround: handle the ToolTipNeededEvent private void radMap1_ToolTipTextNeeded(object sender, Telerik.WinControls.ToolTipTextNeededEventArgs e) { MapCluster cluster = sender as MapCluster; if (cluster != null && cluster.ClusteredItems.Count == 1) { cluster.ToolTipText = ((MapPin)cluster.ClusteredItems[0]).ToolTipText; } }
You can find attached a sample project, video, demonstrating the steps and a screenshot of the error. Workaround: public class MyMapVisualElementFactory : MapVisualElementFactory { public override MapVisualElement CreatePolyline(Collection<PointG> points) { return new MyMapPolyline(points); } } public class MyMapPolyline : MapPolyline { private FieldInfo pathsField; private FieldInfo boundingRectsField; private FieldInfo isInViewportField; public MyMapPolyline(Collection<PointG> points) : base(points) { this.pathsField = typeof(MapPolyline).GetField("paths", BindingFlags.Instance | BindingFlags.NonPublic); this.boundingRectsField = typeof(MapPolyline).GetField("boundingRects", BindingFlags.Instance | BindingFlags.NonPublic); this.isInViewportField = typeof(MapPolyline).GetField("isInViewport", BindingFlags.Instance | BindingFlags.NonPublic); } public override void ViewportChanged(IMapViewport viewport, ViewportChangeAction action) { if ((action & ViewportChangeAction.All) == action) { long mapSize = MapTileSystemHelper.MapSize(viewport.ZoomLevel); List<GraphicsPath> paths = new List<GraphicsPath>(); List<RectangleL> boundingRects = new List<RectangleL>(); long start = viewport.PanOffset.Width; int maxWraparounds = 1; while (start + mapSize < viewport.ViewportInPixels.Width) { maxWraparounds++; start += mapSize; } for (int i = -1; i <= maxWraparounds; i++) { GraphicsPath path = new GraphicsPath(); List<PointF> drawPoints = new List<PointF>(); foreach (PointG p in this.Points) { PointL pixel = MapTileSystemHelper.LatLongToPixelXY(p.Latitude, p.Longitude, viewport.ZoomLevel); drawPoints.Add(new PointF(pixel.X + i * mapSize, pixel.Y)); } path.AddLines(drawPoints.ToArray()); RectangleF rect = path.GetBounds(); RectangleF view = new RectangleF(viewport.ViewportInPixels.X, viewport.ViewportInPixels.Y, viewport.ViewportInPixels.Width, viewport.ViewportInPixels.Height); if (rect.IntersectsWith(view)) { paths.Add(path); } boundingRects.Add(new RectangleL((long)rect.X, (long)rect.Y, (long)rect.Width, (long)rect.Height)); } this.pathsField.SetValue(this, paths); this.boundingRectsField.SetValue(this, boundingRects); } if (action != ViewportChangeAction.None) { this.isInViewportField.SetValue(this, false); List<RectangleL> boundingRects = this.boundingRectsField.GetValue(this) as List<RectangleL>; foreach (RectangleL rect in boundingRects) { if (viewport.ViewportInPixels.IntersectsWith(rect)) { this.isInViewportField.SetValue(this, true); } } } } } public class MyMapVisualElementFactory : MapVisualElementFactory { public override MapVisualElement CreatePolyline(Collection<PointG> points) { return new MyMapPolyline(points); } } public class MyMapPolyline : MapPolyline { private FieldInfo pathsField; private FieldInfo boundingRectsField; private FieldInfo isInViewportField; public MyMapPolyline(Collection<PointG> points) : base(points) { this.pathsField = typeof(MapPolyline).GetField("paths", BindingFlags.Instance | BindingFlags.NonPublic); this.boundingRectsField = typeof(MapPolyline).GetField("boundingRects", BindingFlags.Instance | BindingFlags.NonPublic); this.isInViewportField = typeof(MapPolyline).GetField("isInViewport", BindingFlags.Instance | BindingFlags.NonPublic); } public override void ViewportChanged(IMapViewport viewport, ViewportChangeAction action) { if ((action & ViewportChangeAction.All) == action) { long mapSize = MapTileSystemHelper.MapSize(viewport.ZoomLevel); List<GraphicsPath> paths = new List<GraphicsPath>(); List<RectangleL> boundingRects = new List<RectangleL>(); long start = viewport.PanOffset.Width; int maxWraparounds = 1; while (start + mapSize < viewport.ViewportInPixels.Width) { maxWraparounds++; start += mapSize; } for (int i = -1; i <= maxWraparounds; i++) { GraphicsPath path = new GraphicsPath(); List<PointF> drawPoints = new List<PointF>(); foreach (PointG p in this.Points) { PointL pixel = MapTileSystemHelper.LatLongToPixelXY(p.Latitude, p.Longitude, viewport.ZoomLevel); drawPoints.Add(new PointF(pixel.X + i * mapSize, pixel.Y)); } path.AddLines(drawPoints.ToArray()); RectangleF rect = path.GetBounds(); RectangleF view = new RectangleF(viewport.ViewportInPixels.X, viewport.ViewportInPixels.Y, viewport.ViewportInPixels.Width, viewport.ViewportInPixels.Height); if (rect.IntersectsWith(view)) { paths.Add(path); } boundingRects.Add(new RectangleL((long)rect.X, (long)rect.Y, (long)rect.Width, (long)rect.Height)); } this.pathsField.SetValue(this, paths); this.boundingRectsField.SetValue(this, boundingRects); } if (action != ViewportChangeAction.None) { this.isInViewportField.SetValue(this, false); List<RectangleL> boundingRects = this.boundingRectsField.GetValue(this) as List<RectangleL>; foreach (RectangleL rect in boundingRects) { if (viewport.ViewportInPixels.IntersectsWith(rect)) { this.isInViewportField.SetValue(this, true); } } } } }
How to reproduce: change the Windows culture to Greek and start the OSM example
How to reproduce: check the attached video Workaround: create a custom MapSearchBarElement public class MyRadMap : RadMap { public override string ThemeClassName { get { return typeof(RadMap).FullName; } } protected override RadMapElement CreateMapElement() { return new MyRadMapElement(); } } public class MyRadMapElement : RadMapElement { protected override Type ThemeEffectiveType { get { return typeof(RadMapElement); } } protected override MapSearchBarElement CreateSearchBarElement() { return new MyMapSearchBarElement(this); } } public class MyMapSearchBarElement : MapSearchBarElement { public MyMapSearchBarElement(MyRadMapElement mapElement) : base(mapElement) { } protected override Type ThemeEffectiveType { get { return typeof(MapSearchBarElement); } } protected override void SearchProviderSearchError(object sender, SearchErrorEventArgs e) { IMapSearchProvider provider = sender as IMapSearchProvider; provider.SearchCompleted -= SearchProviderSearchCompleted; provider.SearchError -= SearchProviderSearchError; if (this.ElementTree != null) { UnsubscribeToTextBoxEvents(this.SearchTextBoxElement); RadMessageBox.SetThemeName(this.ElementTree.ThemeName); RadMessageBox.Show(e.Error.Message); SubscribeToTextBoxEvents(this.SearchTextBoxElement); } } protected override void SubscribeToTextBoxEvents(RadTextBoxElement textBox) { textBox.TextChanged += OnSearchTextBoxTextChanged; textBox.KeyDown += OnSearchTextBoxKeyDown; } protected override void UnsubscribeToTextBoxEvents(RadTextBoxElement textBox) { textBox.TextChanged -= OnSearchTextBoxTextChanged; textBox.KeyDown -= OnSearchTextBoxKeyDown; } private void OnSearchTextBoxKeyDown(object sender, System.Windows.Forms.KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { this.Search(this.SearchTextBoxElement.Text); } } }
1. Open the demo application >> Map >> Search example. 2. Enter some text and press Enter. 3. Move the mouse a little bit and you will notice the search box looses focus. Workaround: this.radMap1.MapElement.SearchBarElement.SearchTextBoxElement.TextBoxItem.LostFocus+=TextBoxItem_LostFocus; private void TextBoxItem_LostFocus(object sender, EventArgs e) { this.radMap1.MapElement.SearchBarElement.SearchTextBoxElement.TextBoxItem.TextBoxControl.Focus(); }
In the scenario below one should be able to access the defined UserData value in the SearchCompleted event handler How to reproduce: protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.radMap1.ShowSearchBar = true; BingRestMapProvider bingProvider = this.radMap1.Providers[0] as BingRestMapProvider; this.radMap1.MapElement.SearchBarElement.SearchProvider = bingProvider; this.radMap1.MapElement.SearchBarElement.SearchProvider.SearchCompleted += BingProvider_SearchCompleted; } private void BingProvider_SearchCompleted(object sender, SearchCompletedEventArgs e) { Telerik.WinControls.UI.Map.RectangleG allPoints = new Telerik.WinControls.UI.Map.RectangleG(double.MinValue, double.MaxValue, double.MaxValue, double.MinValue); this.radMap1.Layers["Pins"].Clear(); foreach (Telerik.WinControls.UI.Map.Bing.Location location in e.Locations) { Telerik.WinControls.UI.Map.PointG point = new Telerik.WinControls.UI.Map.PointG(location.Point.Coordinates[0], location.Point.Coordinates[1]); MapPin pin = new MapPin(point); pin.Size = new System.Drawing.Size(20, 40); pin.BackColor = Color.Red; pin.ToolTipText = location.Address.FormattedAddress; this.radMap1.MapElement.Layers["Pins"].Add(pin); allPoints.North = Math.Max(allPoints.North, point.Latitude); allPoints.South = Math.Min(allPoints.South, point.Latitude); allPoints.West = Math.Min(allPoints.West, point.Longitude); allPoints.East = Math.Max(allPoints.East, point.Longitude); } if (e.Locations.Length > 0) { if (e.Locations.Length == 1) { this.radMap1.BringIntoView(new Telerik.WinControls.UI.Map.PointG(e.Locations[0].Point.Coordinates[0], e.Locations[0].Point.Coordinates[1])); } else { this.radMap1.MapElement.BringIntoView(allPoints); this.radMap1.Zoom(this.radMap1.MapElement.ZoomLevel - 1); } } else { RadMessageBox.Show("No result found for the provided search query!"); } } Telerik.WinControls.UI.Map.Bing.SearchRequest request; private void radButton1_Click(object sender, EventArgs e) { Telerik.WinControls.UI.MapLayer pinsLayer = new MapLayer("Pins"); this.radMap1.Layers.Add(pinsLayer); request = new SearchRequest(); request.Query = "San Marino"; request.SearchOptions.Count = 10; request.SearchOptions.QueryParse = true; request.UserData = "Tooltip"; BingRestMapProvider bingProvider = this.radMap1.Providers[0] as BingRestMapProvider; bingProvider.SearchAsync(request); } Workaround: if possible cache the data to be accessed at a later stage