namespace GMap.NET.WindowsPresentation { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Effects; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Threading; using GMap.NET; using GMap.NET.Internals; /// /// GMap.NET control for Windows Presentation /// >> for testing purpose only >> /// [ToolboxItem(false)] public partial class GMapControlNew : UserControl, Interface { readonly Core Core = new Core(); GRect region = new GRect(); bool RaiseEmptyTileError = false; delegate void MethodInvoker(); PointLatLng selectionStart; PointLatLng selectionEnd; Typeface tileTypeface = new Typeface("Arial"); double zoomReal; bool showTileGridLines = false; FormattedText googleCopyright; FormattedText yahooMapCopyright; FormattedText virtualEarthCopyright; FormattedText openStreetMapCopyright; FormattedText arcGisMapCopyright; /// /// pen for empty tile borders /// public Pen EmptyTileBorders = new Pen(Brushes.White, 1.0); /// /// pen for Selection /// public Pen SelectionPen = new Pen(Brushes.Blue, 3.0); /// /// /// /// pen for empty tile background /// public Brush EmptytileBrush = Brushes.Navy; /// /// occurs on empty tile displayed /// public event EmptyTileError OnEmptyTileError; /// /// text on empty tiles /// public FormattedText EmptyTileText = new FormattedText("We are sorry, but we don't\nhave imagery at this zoom\n level for this region.", System.Globalization.CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("Arial"), 16, Brushes.White); /// /// max zoom /// public int MaxZoom = 2; /// /// min zoom /// public int MinZoom = 2; /// /// map zooming type for mouse wheel /// public MouseWheelZoomType MouseWheelZoomType = MouseWheelZoomType.MousePositionAndCenter; /// /// center mouse OnMouseWheel /// public bool CenterPositionOnMouseWheel = true; /// /// map dragg button /// public MouseButton DragButton = MouseButton.Right; /// /// zoom increment on mouse wheel /// public double ZoomIncrement = 1.0; /// /// shows tile gridlines /// [Category("GMap.NET")] public bool ShowTileGridLines { get { return showTileGridLines; } set { showTileGridLines = value; InvalidateVisual(); } } /// /// current selected area in map /// private RectLatLng selectedArea; [Browsable(false)] public RectLatLng SelectedArea { get { return selectedArea; } set { selectedArea = value; InvalidateVisual(); } } /// /// map boundaries /// public RectLatLng? BoundsOfMap = null; /// /// list of markers /// public readonly ObservableCollection Markers = new ObservableCollection(); /// /// current map transformation /// internal Transform MapRenderTransform; /// /// current markers overlay offset /// internal TranslateTransform MapTranslateTransform = new TranslateTransform(); /// /// map zoom /// [Category("GMap.NET")] public double Zoom { get { return zoomReal; } set { if(zoomReal != value) { if(value > MaxZoom) { zoomReal = MaxZoom; } else if(value < MinZoom) { zoomReal = MinZoom; } else { zoomReal = value; } double remainder = (double) System.Decimal.Remainder((Decimal) value, (Decimal) 1); if(remainder != 0) { double scaleValue = remainder + 1; { MapRenderTransform = new ScaleTransform(scaleValue, scaleValue, ActualWidth / 2, ActualHeight / 2); } if(IsLoaded) { //DisplayZoomInFadeImage(); } ZoomStep = Convert.ToInt32(value - remainder); Core_OnMapZoomChanged(); InvalidateVisual(); } else { MapRenderTransform = null; ZoomStep = Convert.ToInt32(value); InvalidateVisual(); } } } } protected bool DesignModeInConstruct { get { //Are we in Visual Studio Designer? return System.ComponentModel.DesignerProperties.GetIsInDesignMode(this); } } Canvas mapCanvas = null; /// /// markers overlay /// internal Canvas MapCanvas { get { if(mapCanvas == null) { // if(ObjectsLayer.VisualChildrenCount > 0) { Border border = VisualTreeHelper.GetChild(ObjectsLayer, 0) as Border; ItemsPresenter items = border.Child as ItemsPresenter; DependencyObject target = VisualTreeHelper.GetChild(items, 0); mapCanvas = target as Canvas; } } return mapCanvas; } } public GMaps Manager { get { return GMaps.Instance; } } public GMapControlNew() { InitializeComponent(); if(!DesignModeInConstruct) { ObjectsLayer.ItemsSource = Markers; // removes white lines between tiles! SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Unspecified); // set image proxy Manager.ImageProxy = new WindowsPresentationImageProxy(); //Core.RenderMode = GMap.NET.RenderMode.WPF; //Core.OnNeedInvalidation += new NeedInvalidation(Core_OnNeedInvalidation); //Core.OnMapZoomChanged += new MapZoomChanged(Core_OnMapZoomChanged); Loaded += new RoutedEventHandler(GMapControl_Loaded); Unloaded += new RoutedEventHandler(GMapControl_Unloaded); googleCopyright = new FormattedText(Core.googleCopyright, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("GenericSansSerif"), 9, Brushes.Navy); yahooMapCopyright = new FormattedText(Core.yahooMapCopyright, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("GenericSansSerif"), 9, Brushes.Navy); virtualEarthCopyright = new FormattedText(Core.virtualEarthCopyright, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("GenericSansSerif"), 9, Brushes.Navy); openStreetMapCopyright = new FormattedText(Core.openStreetMapCopyright, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("GenericSansSerif"), 9, Brushes.Navy); arcGisMapCopyright = new FormattedText(Core.arcGisCopyright, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("GenericSansSerif"), 9, Brushes.Navy); MapType = MapType.GoogleMap; OpacityAnimation = CreateOpacityAnimation(1); ZoomAnimation = CreateZoomAnimation(2); MoveAnimation = CreateMoveAnimation(2); } } DoubleAnimation CreateZoomAnimation(double toValue) { var da = new DoubleAnimation(toValue, new Duration(TimeSpan.FromMilliseconds(555))); da.AccelerationRatio = 0.1; da.DecelerationRatio = 0.9; da.FillBehavior = FillBehavior.HoldEnd; da.Freeze(); return da; } DoubleAnimation CreateMoveAnimation(double toValue) { var da = new DoubleAnimation(toValue, new Duration(TimeSpan.FromMilliseconds(555))); da.AccelerationRatio = 0.1; da.DecelerationRatio = 0.9; da.FillBehavior = FillBehavior.HoldEnd; da.Freeze(); return da; } DoubleAnimation CreateOpacityAnimation(double toValue) { var da = new DoubleAnimation(toValue, new Duration(TimeSpan.FromMilliseconds(555))); da.AccelerationRatio = 0.5; da.DecelerationRatio = 0.5; da.FillBehavior = FillBehavior.HoldEnd; da.Freeze(); return da; } void BeginAnimateOpacity(TileVisual target) { target.Opacity = 0.4; target.BeginAnimation(TileVisual.OpacityProperty, OpacityAnimation, HandoffBehavior.Compose); } void BeginAnimateZoom(TileVisual target) { //target.TranslateTransform.BeginAnimation(TranslateTransform.XProperty, MoveAnimation, HandoffBehavior.Compose); //target.TranslateTransform.BeginAnimation(TranslateTransform.YProperty, MoveAnimation, HandoffBehavior.Compose); //target.ScaleTransform.BeginAnimation(ScaleTransform.ScaleYProperty, ZoomAnimation, HandoffBehavior.Compose); //target.ScaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, ZoomAnimation, HandoffBehavior.Compose); } DoubleAnimation OpacityAnimation; DoubleAnimation ZoomAnimation; DoubleAnimation MoveAnimation; QuadTree QuadTree = new QuadTree(); bool update = true; Dictionary images = new Dictionary(); System.Windows.Size TilesSize = new System.Windows.Size(); Stopwatch _stopwatch = new Stopwatch(); ushort _frameCounter; ushort _frameCounterUpdate; int count = 0; protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { base.OnRenderSizeChanged(sizeInfo); { System.Windows.Size constraint = sizeInfo.NewSize; region = new GRect(-50, -50, (int) constraint.Width + 100, (int) constraint.Height + 100); TilesLayer.Width = sizeInfo.NewSize.Width; TilesLayer.Height = sizeInfo.NewSize.Height; QuadTree.Bounds = new Rect(sizeInfo.NewSize); } //var sizeInPx = Projection.GetTileMatrixSizePixel(ZoomStep); //TilesLayer.Width = sizeInPx.Width; //TilesLayer.Height = sizeInPx.Height; if(IsLoaded) { Refresh(); } } void CompositionTargetEx_FrameUpdating(object sender, RenderingEventArgs e) { if(update) { _frameCounterUpdate++; update = false; #region -- add image -- for(int x = 0; x < TilesSize.Width; x++) { for(int y = 0; y < TilesSize.Height; y++) { var rawTile = new RawTile(MapType.GoogleHybrid, new GPoint(x, y), ZoomStep); var rectTilePx = new Rect(x*Projection.TileSize.Width, y*Projection.TileSize.Height, Projection.TileSize.Width, Projection.TileSize.Height); TileVisual image = null; if(!images.TryGetValue(rawTile, out image)) { var layers = GMaps.Instance.GetAllLayersOfType(rawTile.Type); ImageSource[] imgs = new ImageSource[layers.Length]; // get tiles for(int i = 0; i < layers.Length; i++) { Exception ex; var res = GMaps.Instance.GetImageFrom(layers[i], rawTile.Pos, rawTile.Zoom, out ex) as WindowsPresentationImage; if(res != null) { imgs[i] = res.Img; } } // combine visual image = new TileVisual(imgs, rawTile); images.Add(rawTile, image); Canvas.SetZIndex(image, -1); } bool ri = (region.IntersectsWith(new GRect((int) (rectTilePx.X + renderOffset.X), (int) (rectTilePx.Y + renderOffset.Y), (int) rectTilePx.Width, (int) rectTilePx.Height))); if(TilesLayer.Children.Contains(image)) { if(ri) { image.MoveTo(Math.Round(rectTilePx.X) + 0.6 + renderOffset.X, Math.Round(rectTilePx.Y) + 0.6 + renderOffset.Y); } else { TilesLayer.Children.Remove(image); } } else { if(ri) { image.MoveTo(Math.Round(rectTilePx.X) + 0.6 + renderOffset.X, Math.Round(rectTilePx.Y) + 0.6 + renderOffset.Y); BeginAnimateOpacity(image); { TilesLayer.Children.Add(image); } } } //break; } //break; } count = TilesLayer.Children.Count; #endregion } if(_stopwatch.ElapsedMilliseconds >= 1000) { _stopwatch.Stop(); perfInfo.Text = "FPS: " + (ushort) (_frameCounter/_stopwatch.Elapsed.TotalSeconds) + " | " + (ushort) (_frameCounterUpdate/_stopwatch.Elapsed.TotalSeconds) + " | " + count + " tiles"; _frameCounter = 0; _frameCounterUpdate = 0; _stopwatch.Reset(); _stopwatch.Start(); } else { _frameCounter++; } } void GMapControl_Loaded(object sender, RoutedEventArgs e) { CompositionTargetEx.FrameUpdating += new EventHandler(CompositionTargetEx_FrameUpdating); _stopwatch.Start(); Refresh(); //Core.StartSystem(); //Core_OnMapZoomChanged(); } void GMapControl_Unloaded(object sender, RoutedEventArgs e) { CompositionTargetEx.FrameUpdating -= new EventHandler(CompositionTargetEx_FrameUpdating); _stopwatch.Stop(); //Core.OnMapClose(); } private void Refresh() { update = true; InvalidateVisual(); } //rotected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize) /// //MapBase parentMap = this.ParentMap; //foreach(UIElement element in base.Children) //{ // Rect finalRect = new Rect(0.0, 0.0, parentMap.ViewportSize.Width, parentMap.ViewportSize.Height); // LocationRect positionRectangle = GetPositionRectangle(element); // if(positionRectangle != null) // { // finalRect = parentMap.Mode.LocationToViewportPoint(positionRectangle); // } // else // { // Point point; // Location position = GetPosition(element); // if((position != null) && parentMap.TryLocationToViewportPoint(position, out point)) // { // PositionOrigin positionOrigin = GetPositionOrigin(element); // point.X -= positionOrigin.X * element.DesiredSize.Width; // point.Y -= positionOrigin.Y * element.DesiredSize.Height; // finalRect = new Rect(point.X, point.Y, element.DesiredSize.Width, element.DesiredSize.Height); // } // } // Point positionOffset = GetPositionOffset(element); // finalRect.X += positionOffset.X; // finalRect.Y += positionOffset.Y; // element.Arrange(finalRect); //} //return parentMap.ViewportSize; // //protected override Size MeasureOverride(Size availableSize) //{ // MapBase parentMap = this.ParentMap; // Guid lastProjectPassTag = this.lastProjectPassTag; // this.lastProjectPassTag = Guid.NewGuid(); // foreach(UIElement element in base.Children) // { // IProjectable projectable = element as IProjectable; // if(projectable != null) // { // ProjectionUpdateLevel pendingUpdate = this.pendingUpdate; // if(((Guid) element.GetValue(ProjectionUpdatedTag)) != lastProjectPassTag) // { // pendingUpdate = ProjectionUpdateLevel.Full; // } // if(pendingUpdate != ProjectionUpdateLevel.None) // { // projectable.ProjectionUpdated(pendingUpdate); // } // element.SetValue(ProjectionUpdatedTag, this.lastProjectPassTag); // } // } // this.pendingUpdate = ProjectionUpdateLevel.None; // foreach(UIElement element2 in base.Children) // { // LocationRect positionRectangle = GetPositionRectangle(element2); // if(positionRectangle != null) // { // Rect rect2 = parentMap.Mode.LocationToViewportPoint(positionRectangle); // element2.Measure(new Size(rect2.Width, rect2.Height)); // } // else // { // if((element2 is ContentPresenter) && (VisualTreeHelper.GetChildrenCount(element2) > 0)) // { // IProjectable child = VisualTreeHelper.GetChild(element2, 0) as IProjectable; // if(child != null) // { // child.ProjectionUpdated(ProjectionUpdateLevel.Full); // UIElement element3 = child as UIElement; // if(element3 != null) // { // element3.InvalidateMeasure(); // } // } // } // element2.Measure(parentMap.ViewportSize); // } // } // return parentMap.ViewportSize; //} #region -- etc -- void Core_OnMapZoomChanged() { //UpdateMarkersOffset(); foreach(var i in Markers) { //i.ForceUpdateLocalPosition(this); } var routes = Markers.Where(p => p != null && p.Route.Count > 1); if(routes != null) { foreach(var i in routes) { //i.RegenerateRouteShape(this); } } } /// /// on core needs invalidation /// void Core_OnNeedInvalidation() { try { this.Dispatcher.BeginInvoke(DispatcherPriority.Render, new MethodInvoker(Refresh)); } catch { } } /// /// updates markers overlay offset /// void UpdateMarkersOffset() { if(MapCanvas != null) { if(MapRenderTransform != null) { var tp = MapRenderTransform.Transform(new System.Windows.Point(Core.renderOffset.X, Core.renderOffset.Y)); MapTranslateTransform.X = tp.X; MapTranslateTransform.Y = tp.Y; } else { MapTranslateTransform.X = Core.renderOffset.X; MapTranslateTransform.Y = Core.renderOffset.Y; } MapCanvas.RenderTransform = MapTranslateTransform; } } /// /// gets image of the current view /// /// public ImageSource ToImageSource() { FrameworkElement obj = this; // Save current canvas transform Transform transform = obj.LayoutTransform; obj.LayoutTransform = null; // fix margin offset as well Thickness margin = obj.Margin; obj.Margin = new Thickness(0, 0, margin.Right - margin.Left, margin.Bottom - margin.Top); // Get the size of canvas System.Windows.Size size = new System.Windows.Size(obj.ActualWidth, obj.ActualHeight); // force control to Update obj.Measure(size); obj.Arrange(new Rect(size)); RenderTargetBitmap bmp = new RenderTargetBitmap( (int) size.Width, (int) size.Height, 96, 96, PixelFormats.Pbgra32); bmp.Render(obj); if(bmp.CanFreeze) { bmp.Freeze(); } // return values as they were before obj.LayoutTransform = transform; obj.Margin = margin; return bmp; } /// /// creates path from list of points /// /// /// public Path CreateRoutePath(List localPath) { // Create a StreamGeometry to use to specify myPath. StreamGeometry geometry = new StreamGeometry(); using(StreamGeometryContext ctx = geometry.Open()) { ctx.BeginFigure(localPath[0], false, false); // 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; BlurEffect ef = new BlurEffect(); { ef.KernelType = KernelType.Gaussian; ef.Radius = 3.0; ef.RenderingBias = RenderingBias.Quality; } myPath.Effect = ef; myPath.Stroke = Brushes.Navy; myPath.StrokeThickness = 5; myPath.StrokeLineJoin = PenLineJoin.Round; myPath.StrokeStartLineCap = PenLineCap.Triangle; myPath.StrokeEndLineCap = PenLineCap.Square; myPath.Opacity = 0.6; } return myPath; } /// /// sets zoom to max to fit rect /// /// area /// public bool SetZoomToFitRect(RectLatLng rect) { int maxZoom = Core.GetMaxZoomToFitRect(rect); if(maxZoom > 0) { PointLatLng center = new PointLatLng(rect.Lat - (rect.HeightLat / 2), rect.Lng + (rect.WidthLng / 2)); Position = center; if(maxZoom > MaxZoom) { maxZoom = MaxZoom; } if(ZoomStep != maxZoom) { Zoom = maxZoom; } return true; } return false; } /// /// sets to max zoom to fit all markers and centers them in map /// /// z index or null to check all /// public bool ZoomAndCenterMarkers(int? ZIndex) { RectLatLng? rect = GetRectOfAllMarkers(ZIndex); if(rect.HasValue) { return SetZoomToFitRect(rect.Value); } return false; } /// /// gets rectangle with all objects inside /// /// z index or null to check all /// public RectLatLng? GetRectOfAllMarkers(int? ZIndex) { RectLatLng? ret = null; double left = double.MaxValue; double top = double.MinValue; double right = double.MinValue; double bottom = double.MaxValue; IEnumerable Overlays; if(ZIndex.HasValue) { Overlays = Markers.Where(p => p != null && p.ZIndex == ZIndex); } else { Overlays = Markers; } if(Overlays != null) { foreach(var m in Overlays) { if(m.Shape != null && m.Shape.IsVisible) { // left if(m.Position.Lng < left) { left = m.Position.Lng; } // top if(m.Position.Lat > top) { top = m.Position.Lat; } // right if(m.Position.Lng > right) { right = m.Position.Lng; } // bottom if(m.Position.Lat < bottom) { bottom = m.Position.Lat; } } } } if(left != double.MaxValue && right != double.MinValue && top != double.MinValue && bottom != double.MaxValue) { ret = RectLatLng.FromLTRB(left, top, right, bottom); } return ret; } #endregion #region UserControl Events //double move; protected override void OnMouseWheel(MouseWheelEventArgs e) { base.OnMouseWheel(e); if(e.Delta > 0) { ZoomStep++; //ZoomAnimation = CreateZoomAnimation(ZoomStep); // move -= Projection.TileSize.Width; //MoveAnimation = CreateMoveAnimation(move); } else { ZoomStep--; //ZoomAnimation = CreateZoomAnimation(ZoomStep); //move += Projection.TileSize.Width; //MoveAnimation = CreateMoveAnimation(move); } //Refresh(); } bool isSelected = false; System.Windows.Point? mouseDown = null; static readonly System.Windows.Point Empty = new System.Windows.Point(); protected override void OnMouseDown(MouseButtonEventArgs e) { if(CanDragMap && e.ChangedButton == DragButton && e.ButtonState == MouseButtonState.Pressed) { mouseDown = e.GetPosition(TilesLayer); dragPoint.X = mouseDown.Value.X - renderOffset.X; dragPoint.Y = mouseDown.Value.Y - renderOffset.Y; Mouse.Capture(TilesLayer); } base.OnMouseDown(e); } protected override void OnMouseUp(MouseButtonEventArgs e) { base.OnMouseUp(e); mouseDown = null; Mouse.Capture(null); } System.Windows.Point renderOffset = new System.Windows.Point(); System.Windows.Point dragPoint = new System.Windows.Point(); protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if(mouseDown.HasValue) { System.Windows.Point p = e.GetPosition(TilesLayer); //TileOffset.Y += p.Y - mouseDown.Value.Y; //TileOffset.X += p.X - mouseDown.Value.X; renderOffset.X = p.X - dragPoint.X; renderOffset.Y = p.Y - dragPoint.Y; Refresh(); } } #endregion #region IGControl Members public void ReloadMap() { Core.ReloadMap(); } public GeoCoderStatusCode SetCurrentPositionByKeywords(string keys) { GeoCoderStatusCode status = GeoCoderStatusCode.Unknow; PointLatLng? pos = Manager.GetLatLngFromGeocoder(keys, out status); if(pos.HasValue && status == GeoCoderStatusCode.G_GEO_SUCCESS) { Position = pos.Value; } return status; } public PointLatLng FromLocalToLatLng(int x, int y) { if(MapRenderTransform != null) { var tp = MapRenderTransform.Inverse.Transform(new System.Windows.Point(x, y)); x = (int) tp.X; y = (int) tp.Y; } return Core.FromLocalToLatLng(x, y); } public GPoint FromLatLngToLocal(PointLatLng point) { GPoint ret = Core.FromLatLngToLocal(point); if(MapRenderTransform != null) { var tp = MapRenderTransform.Transform(new System.Windows.Point(ret.X, ret.Y)); ret.X = (int) tp.X; ret.Y = (int) tp.Y; } if(MapTranslateTransform != null) { ret.Offset(-(int) MapTranslateTransform.X, -(int) MapTranslateTransform.Y); } return ret; } public bool ShowExportDialog() { #if SQLite if(Cache.Instance.ImageCache is GMap.NET.CacheProviders.SQLitePureImageCache) { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); { dlg.CheckPathExists = true; dlg.CheckFileExists = false; dlg.AddExtension = true; dlg.DefaultExt = "gmdb"; dlg.ValidateNames = true; dlg.Title = "GMap.NET: Export map to db, if file exsist only new data will be added"; dlg.FileName = "DataExp"; dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); dlg.Filter = "GMap.NET DB files (*.gmdb)|*.gmdb"; dlg.FilterIndex = 1; dlg.RestoreDirectory = true; if(dlg.ShowDialog() == true) { bool ok = GMaps.Instance.ExportToGMDB(dlg.FileName); if(ok) { MessageBox.Show("Complete!", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Information); } else { MessageBox.Show(" Failed!", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Warning); } return ok; } } } else { MessageBox.Show("Failed! Only SQLite support ;/", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Warning); } #endif return false; } public bool ShowImportDialog() { #if SQLite if(Cache.Instance.ImageCache is GMap.NET.CacheProviders.SQLitePureImageCache) { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); { dlg.CheckPathExists = true; dlg.CheckFileExists = false; dlg.AddExtension = true; dlg.DefaultExt = "gmdb"; dlg.ValidateNames = true; dlg.Title = "GMap.NET: Import to db, only new data will be added"; dlg.FileName = "DataImport"; dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); dlg.Filter = "GMap.NET DB files (*.gmdb)|*.gmdb"; dlg.FilterIndex = 1; dlg.RestoreDirectory = true; if(dlg.ShowDialog() == true) { Cursor = Cursors.Wait; bool ok = GMaps.Instance.ImportFromGMDB(dlg.FileName); if(ok) { MessageBox.Show("Complete!", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Information); ReloadMap(); } else { MessageBox.Show(" Failed!", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Warning); } Cursor = Cursors.Arrow; return ok; } } } else { MessageBox.Show("Failed! Only SQLite support ;/", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Warning); } #endif return false; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] internal int ZoomStep { get { return Core.Zoom; } set { if(value > MaxZoom) { Core.Zoom = MaxZoom; } else if(value < MinZoom) { Core.Zoom = MinZoom; } else { bool changed = (Core.Zoom != value); Core.Zoom = value; if(changed) { foreach(UIElement u in TilesLayer.Children) { var m = u as TileVisual; if(m != null) { if(images.ContainsKey(m.Tile)) { images.Remove(m.Tile); m.Source.Clear(); } } } TilesLayer.Children.Clear(); var sizeinTiles = Projection.GetTileMatrixSizeXY(ZoomStep); TilesSize.Width = sizeinTiles.Width; TilesSize.Height = sizeinTiles.Height; if(IsLoaded) { Refresh(); } } } } } [Browsable(false)] public PointLatLng Position { get { return Core.CurrentPosition; } set { Core.CurrentPosition = value; UpdateMarkersOffset(); } } [Browsable(false)] public GPoint CurrentPositionGPixel { get { return Core.CurrentPositionGPixel; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] public string CacheLocation { get { return Cache.Instance.CacheLocation; } set { Cache.Instance.CacheLocation = value; } } [Browsable(false)] public bool IsDragging { get { return Core.IsDragging; } } [Browsable(false)] public RectLatLng CurrentViewArea { get { return Core.CurrentViewArea; } } [Category("GMap.NET")] public MapType MapType { get { return Core.MapType; } set { Core.MapType = value; } } [Browsable(false)] public PureProjection Projection { get { return Core.Projection; } } [Category("GMap.NET")] public bool CanDragMap { get { return Core.CanDragMap; } set { Core.CanDragMap = value; } } public GMap.NET.RenderMode RenderMode { get { return GMap.NET.RenderMode.WPF; } } #endregion #region IGControl event Members public event PositionChanged OnPositionChanged { add { Core.OnCurrentPositionChanged += value; } remove { Core.OnCurrentPositionChanged -= value; } } public event TileLoadComplete OnTileLoadComplete { add { Core.OnTileLoadComplete += value; } remove { Core.OnTileLoadComplete -= value; } } public event TileLoadStart OnTileLoadStart { add { Core.OnTileLoadStart += value; } remove { Core.OnTileLoadStart -= value; } } public event MapDrag OnMapDrag { add { Core.OnMapDrag += value; } remove { Core.OnMapDrag -= value; } } public event MapZoomChanged OnMapZoomChanged { add { Core.OnMapZoomChanged += value; } remove { Core.OnMapZoomChanged -= value; } } /// /// occures on map type changed /// public event MapTypeChanged OnMapTypeChanged { add { Core.OnMapTypeChanged += value; } remove { Core.OnMapTypeChanged -= value; } } #endregion } static class Extensions { public static void CenterAt(this FrameworkElement element, System.Windows.Point center) { CenterAt(element, center.X, center.Y); } public static void CenterAt(this FrameworkElement element, double x, double y) { MoveTo(element, x - element.Width / 2, y - element.Height / 2); } public static void MoveTo(this UIElement element, double x, double y) { Canvas.SetLeft(element, x); Canvas.SetTop(element, y); } public static void MoveTo(this UIElement element, System.Windows.Point position) { MoveTo(element, position.X, position.Y); } public static void MoveOffset(this UIElement element, double xOffset, double yOffset) { if(element == null || double.IsNaN(xOffset) || double.IsNaN(yOffset)) { return; } var coordinates = element.GetCoordinates(); Canvas.SetLeft(element, coordinates.X + xOffset); Canvas.SetTop(element, coordinates.Y + yOffset); } public static System.Windows.Point GetCoordinates(this UIElement element) { return new System.Windows.Point(Canvas.GetLeft(element), Canvas.GetTop(element)); } public static System.Windows.Rect GetRect(this UIElement element) { return new System.Windows.Rect(element.GetCoordinates(), element.RenderSize); } } }