[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/SharpMap/SharpMap/main/Examples/WinFormSamples/SampleTool.cs [Back]  [Original]

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Common.Logging;
using GeoAPI.Geometries;
using SharpMap;
using SharpMap.Data;
using SharpMap.Forms;
using SharpMap.Forms.Tools;
using SharpMap.Layers;

namespace WinFormSamples
{
    public class SampleTool : MapTool, IDisposable
    {
        private ILog Logger = LogManager.GetLogger(typeof(SampleTool));

        public SampleTool() : base("Sample", "A sample tool that does nothing really useful")
        {
            Logger.Debug(fmh => fmh("Created \"{0}\"-Tool, {1}", Name,Description));
            Enabled = true;
        }

        void IDisposable.Dispose()
        {
            HandleCancel();
        }

        private ToolTip _toolTip;

        public SampleTool(MapBox mapBox1) : this()
        {
            MapControl = mapBox1;
            MapControl.MapChanged += (sender, args) => { HandleCancel(); };
            _cts.Token.Register(HandleCancel);
        }

        public override bool DoKeyDown(Coordinate mapPosition, KeyEventArgs keyEventArgs)
        {
            Logger.Debug(fmh => fmh("KeyDown {1} at {0}", mapPosition, keyEventArgs.KeyCode));
            return base.DoKeyDown(mapPosition, keyEventArgs);
        }

        public override bool DoKeyUp(Coordinate mapPosition, KeyEventArgs keyEventArgs)
        {
            Logger.Debug(fmh => fmh("KeyUp {1} at {0}", mapPosition, keyEventArgs.KeyCode));
            return base.DoKeyUp(mapPosition, keyEventArgs);
        }

        public override bool DoMouseDoubleClick(Coordinate mapPosition, MouseEventArgs mouseEventArgs)
        {
            Logger.Debug(fmh => fmh("MouseDoubleClick {1} at {0}", mapPosition, mouseEventArgs.Button));
            return base.DoMouseDoubleClick(mapPosition, mouseEventArgs);
        }

        public override bool DoMouseDown(Coordinate mapPosition, MouseEventArgs mouseEventArgs)
        {
            Logger.Debug(fmh => fmh("MouseDown {1} at {0}", mapPosition, mouseEventArgs.Button));
            return base.DoMouseDown(mapPosition, mouseEventArgs);
        }

        public override bool DoMouseEnter()
        {
            Logger.Debug(fmh => fmh("MouseEnter"));
            return base.DoMouseEnter();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);
            if (!Enabled)
            {
                if (_toolTip != null) _toolTip.RemoveAll();
            }
        }

        private CancellationTokenSource _cts = new CancellationTokenSource();

        public override bool DoMouseHover(Coordinate mapPosition)
        {
            Logger.Debug(fmh => fmh("MouseHover at {0}", mapPosition));

            _cts.Cancel();
            _cts.Token.WaitHandle.WaitOne();
            _cts.Dispose();

            _cts = new CancellationTokenSource();
            _cts.Token.Register(HandleCancel);
            
            var t = new Task(FindGeoNearPoint, mapPosition, _cts.Token);
            t.Start();
            t.ContinueWith(res => ShowToolTip(res.Result));

            return base.DoMouseHover(mapPosition);
        }

        BackgroundWorker _bw = new BackgroundWorker();

        void HandleCancel()
        {
            if (_toolTip != null)
            {
                MapControl.Invoke(new MethodInvoker(() =>
                {
                    _toolTip.Hide(MapControl);
                    _toolTip.Dispose();
                }));
                _toolTip = null;
            }
        }

        private void ShowToolTip(FeatureDataRow fdr)
        {
            if (fdr != null)
            {
                
                MapControl.BeginInvoke(new Action(() =>
                {
                    var _t = new ToolTip();
                    _toolTip = _t;
                    _t/*oolTip*/.ToolTipTitle = fdr.Table.TableName;
                    
                    _t/*oolTip*/.Show(ToText(fdr), MapControl);
                }));
            }
            else
            {
                //MapControl.BeginInvoke(new MethodInvoker( () => _toolTip.Hide(MapControl)));
            }
        }

        private string ToText(FeatureDataRow fdr)
        {
            var sb = new StringBuilder();
            if (fdr.Geometry != null)
            {
                sb.AppendFormat("Geometry:\n  Type: {0}\n  SRID: {1}\n", 
                    fdr.Geometry.GeometryType, fdr.Geometry.SRID);
                switch (fdr.Geometry.Dimension)
                {
                    case Dimension.Surface:
                        sb.AppendFormat("  Area: {0}\n", fdr.Geometry.Area);
                        break;
                    case Dimension.Curve:
                        sb.AppendFormat("  Length: {0}\n", fdr.Geometry.Length);
                        break;
                    case Dimension.Point:
                        sb.AppendFormat("  Position: {0}\n", fdr.Geometry.AsText());
                        break;
                }
            }

            sb.Append("Data:\n");
            foreach (DataColumn col in fdr.Table.Columns)
                sb.AppendFormat("  {0}: {1}\n", col.Caption, fdr[col] == DBNull.Value ? "NULL" : fdr[col]);

            Logger.Debug(fmh => fmh("\n{0}\n{1}", fdr.Table.TableName,  sb.ToString(0, sb.Length-1)));

            return sb.ToString(0, sb.Length - 1);
        }

        private FeatureDataRow FindGeoNearPoint(object/*Coordinate*/ coord)
        {
            var mapPosition = (Coordinate) coord;
            var env = new Envelope(mapPosition);
            env.ExpandBy(5 * Map.PixelWidth);
            var g = NetTopologySuite.Geometries.Prepared.PreparedGeometryFactory.Prepare(Map.Factory.ToGeometry(env));

            var fdrs = new List();
            var fds = new FeatureDataSet();
            var tableCount = 0;

            var layersToQuery = GetLayersToQuery(Map);

            for (var i = layersToQuery.Count - 1; i >= 0; i--)
            {
                if (_cts.Token.IsCancellationRequested)
                {
                    Logger.Debug("Cancellation requested");
                    return null;
                }

                var l = layersToQuery[i];
                if (l.Enabled && l.MinVisible < Map.Zoom &&
                    l.MaxVisible >= Map.Zoom)
                {
                    if (!l.IsQueryEnabled) continue;
                    l.ExecuteIntersectionQuery(env, fds);
                    for (var j = tableCount; j < fds.Tables.Count; j++)
                    {
                        var fdt = fds.Tables[j];
                        for (var k = 0; k < fdt.Rows.Count; k++)
                        {
                            var fdr = (FeatureDataRow) fdt.Rows[k];
                            if (g.Intersects(fdr.Geometry))
                            {
                                var distance = g.Geometry.InteriorPoint.Distance(fdr.Geometry);
                                if (fdr.Geometry.Dimension == Dimension.Surface)
                                    distance += 5* Map.PixelWidth;
                                fdrs.Add(Tuple.Create(distance, fdr));
                            }
                        }
                    }
                    tableCount = fds.Tables.Count;
                }

            }
            if (fdrs.Count > 0)
            {
                fdrs.Sort((t1, t2) => t1.Item1.CompareTo(t2.Item1));
                return fdrs[0].Item2;
            }
            return null;
        }

        private static List GetLayersToQuery(Map map)
        {
            var res = new List();
            for (var i = 0; i < map.BackgroundLayer.Count; i++)
            {
                if (map.BackgroundLayer[i] is ICanQueryLayer)
                {
                    if (((ICanQueryLayer)map.BackgroundLayer[i]).IsQueryEnabled)
                        res.Add((ICanQueryLayer)map.BackgroundLayer[i]);
                }
            }
            for (var i = 0; i < map.Layers.Count; i++)
            {
                if (map.Layers[i] is ICanQueryLayer)
                {
                    if (((ICanQueryLayer)map.Layers[i]).IsQueryEnabled)
                        res.Add((ICanQueryLayer)map.Layers[i]);
                }
            }
            return res;
        }

        public MapBox MapControl { get; private set; }

        public override bool DoMouseLeave()
        {
            Logger.Debug(fmh => fmh("MouseLeave"));
            //_toolTip.RemoveAll();
            return base.DoMouseLeave();
        }

        public override bool DoMouseMove(Coordinate mapPosition, MouseEventArgs mouseEventArgs)
        {
            Logger.Debug(fmh => fmh("MouseMove {1} at {0}", mapPosition, mouseEventArgs.Button));
            //_toolTip.RemoveAll();
            return base.DoMouseMove(mapPosition, mouseEventArgs);
        }

        public override bool DoMouseUp(Coordinate mapPosition, MouseEventArgs mouseEventArgs)
        {
            Logger.Debug(fmh => fmh("MouseUp {1} at {0}", mapPosition, mouseEventArgs.Button));
            return base.DoMouseUp(mapPosition, mouseEventArgs);
        }

        public override bool DoMouseWheel(Coordinate mapPosition, MouseEventArgs mouseEventArgs)
        {
            Logger.Debug(fmh => fmh("MouseWheel {1} at {0}", mapPosition, mouseEventArgs.Button));
            return base.DoMouseWheel(mapPosition, mouseEventArgs);
        }

        public override void Cancel()
        {
            Logger.Debug(fmh => fmh("Cancel"));
            base.Cancel();
        }

        public override void DoPaint(PaintEventArgs e)
        {
            Logger.Debug(fmh => fmh("Paint"));
            base.DoPaint(e);
        }
    }
}

Web Proxy Viewer  |  New URL  |  Original Page