wyq 1 жил өмнө
parent
commit
eb7bf5ea54

+ 71 - 189
DataSimulation.Forms/ExtensionsDev/MapControlEx.cs

@@ -188,60 +188,8 @@ public static class MapControlEx
             else if (e.SelectedObject is MapDot mapDot)
             {
                 if (mapDot == null) return;
-                var posItem = mapDot.Tag as PosData;
+                var posItem = mapDot.Tag as FlightInfo;
                 if (mapDot == null || posItem == null) return;
-                if (posItem.ClusterCount == 1)
-                {
-                    var props = posItem.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();
-                    var list = new List<(int Index, string Name, string Format, object Value)>();
-                    foreach (var prop in props)
-                    {
-                        var attrToolTip = prop.GetCustomAttribute<ToolTipAttribute>();
-                        if (attrToolTip == null) continue;
-                        string toolTipFormat = attrToolTip.Format;
-
-
-                        var val = prop.GetValue(posItem);
-
-                        string displayName = prop.Name;
-                        var attrDisplay = prop.GetCustomAttribute<DisplayAttribute>();
-                        if (attrDisplay != null && !string.IsNullOrWhiteSpace(attrDisplay.Name))
-                            displayName = attrDisplay.Name;
-
-                        int index = attrToolTip.Index;
-                        list.Add((index, displayName, toolTipFormat, val));
-                    }
-                    list = list.OrderBy(p => p.Index).ToList();
-                    foreach ((int Index, string Name, string Format, object val) in list)
-                    {
-                        string f = null;
-                        if (val is DateTime)
-                        {
-                            f = "yyyy-MM-dd HH:mm:ss";
-
-                        }
-                        else if (val is float || val is double || val is decimal)
-                        {
-                            f = "f4";
-                        }
-                        if (!string.IsNullOrWhiteSpace(Format))
-                            f = Format;
-                        string valStr;
-                        if (!string.IsNullOrWhiteSpace(f))
-                            valStr = ((dynamic)val).ToString(f);
-                        else
-                            valStr = val.ToString();
-                        ToolTipItem tipItem = new ToolTipItem();
-                        tipItem.Text = $"{Name}:{valStr}";
-                        superToolTip.Items.Add(tipItem);
-                    }
-                }
-                else
-                {
-                    ToolTipItem tipItem = new ToolTipItem();
-                    tipItem.Text = $"当前位置附近有{posItem.ClusterCount}个定位点,放大可查看";
-                    superToolTip.Items.Add(tipItem);
-                }
                 e.SuperTip = superToolTip;
             }
             else if (e.SelectedObject is MapCustomElement ele)
@@ -268,17 +216,13 @@ public static class MapControlEx
                 {
                     rectMenu?.ShowPopup(Cursor.Position);
                 }
-                else if (hitInfo.InMapDot && hitInfo.MapDot.Tag is PosData)
+                else if (hitInfo.InMapDot && hitInfo.MapDot.Tag is FlightInfo)
                 {
-                    var selectPos = (PosData)hitInfo.MapDot.Tag;
+                    var selectPos = (FlightInfo)hitInfo.MapDot.Tag;
                     if (!selectPos.Selected)
                     {
                         selectPos.Selected = true;
-                        //ctrl.UpdatePosItem(selectPos);
-                    }
-                    if (selectPos.ClusterCount == 1)
-                    {
-                        posMenu?.ShowPopup(Cursor.Position);//选中了原始MapItem
+                        ctrl.UpdateItem(selectPos);
                     }
                     else
                     {
@@ -298,13 +242,13 @@ public static class MapControlEx
                 innerData.mouseLeftDown = true;
                 innerData.barM.CloseMenus();
                 var hitInfo = ctrl.CalcHitInfo(e.Location);
-                if (hitInfo.InMapDot && hitInfo.MapDot.Tag is PosData)
+                if (hitInfo.InMapDot && hitInfo.MapDot.Tag is FlightInfo)
                 {
-                    var selectPos = hitInfo.MapDot.Tag as PosData;
+                    var selectPos = hitInfo.MapDot.Tag as FlightInfo;
                     if (!selectPos.Selected)
                     {
                         selectPos.Selected = true;
-                        //ctrl.UpdatePosItem(selectPos);
+                        ctrl.UpdateItem(selectPos);
                     }
                 }
             }
@@ -640,8 +584,10 @@ public static class MapControlEx
                 {
                     return;
                 }
+               var flight= new FlightInfo();
+                flight.FlightName = fligthName;
+                flight.Speed = speed;
 
-                string filghtName = $"DrawFlightLine_{fligthName}_{speed}";
                 ctrl.MapEditor.SetEditMode();
                 var items = innerData.flightStorge.Items.ToArray();
                 innerData.flightpath = new MapSpline()
@@ -653,11 +599,11 @@ public static class MapControlEx
                     CanRotate = true,
                     IsHitTestVisible = false,
                     CanMove = true,
-                    Tag = filghtName
+                    Tag = flight
 
                 };
                 innerData.flightStorge.Items.Add(innerData.flightpath);
-                innerData.hoverPoint = new MapDot() { CanResize = false, CanMove = false, Tag = filghtName, Size = 8 };
+                innerData.hoverPoint = new MapDot() { CanResize = false, CanMove = false, Tag = flight, Size = 8 };
                 innerData.hoverPoint.Fill = ColorHelper.GetColor(innerData.hoverPoint.Tag.ToString());
                 innerData.flightStorge.Items.Add(innerData.hoverPoint);
                 //提示框
@@ -712,7 +658,10 @@ public static class MapControlEx
             innerData.distinctPath.Points.Clear();
         }
 
-        string filghtName = $"DrawFlightLine_{fligthName}_{speed}";
+        var flight = new FlightInfo();
+        flight.FlightName = fligthName;
+        flight.Speed = speed;
+
         ctrl.MapEditor.SetEditMode();
         innerData.flightpath = new MapSpline()
         {
@@ -723,11 +672,11 @@ public static class MapControlEx
             CanRotate = true,
             IsHitTestVisible = false,
             CanMove = true,
-            Tag = filghtName
+            Tag = flight
 
         };
         innerData.flightStorge.Items.Add(innerData.flightpath);
-        innerData.hoverPoint = new MapDot() { CanResize = false, CanMove = false, Tag = filghtName, Size = 8 };
+        innerData.hoverPoint = new MapDot() { CanResize = false, CanMove = false, Tag = flight, Size = 8 };
         innerData.hoverPoint.Fill = ColorHelper.GetColor(innerData.hoverPoint.Tag.ToString());
         innerData.flightStorge.Items.Add(innerData.hoverPoint);
         //提示框
@@ -769,29 +718,68 @@ public static class MapControlEx
         var ctrl = sender as MapControl;
 
         var location = ctrl.ScreenPointToCoordPoint(e.Location);
-        var strs = innerData.flightpath.Tag.ToString().Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
-        string name = strs[1];
-        double speed = Convert.ToDouble(strs[2]);
+        var strs = innerData.flightpath.Tag as FlightInfo;
+        string name = strs.FlightName;
+        double speed = strs.Speed;
         double lon = Math.Round(location.GetX(), 3);
         double lat = Math.Round(location.GetY(), 3);
+
+        var flight = new FlightInfo(name, speed, lon, lat);
         innerData.hoverPoint = new MapDot()
         {
             CanResize = false,
             CanMove = false,
-            ToolTipPattern = $"航迹:{name}\r\n{lon},{lat}°",
-            Tag = innerData.flightpath.Tag,
+            ToolTipPattern = flight.ToString(),
+            Tag = flight,
             Size = 8
         };
         innerData.hoverPoint.Location = location;
         innerData.hoverPoint.Fill = ColorHelper.GetColor(innerData.hoverPoint.Tag.ToString());
-        innerData.flightStorge.Items.Add(innerData.hoverPoint);
-        innerData.flightpath.Points.Add(innerData.hoverPoint.Location);
-        if (!innerData._flightCache.Keys.Any(m => m.FlightLon == lon && m.FlightName == name && m.Speed == speed && m.FlightLat == lat))
+
+        if (!innerData._flightCache.Keys.Any(m => m.Equals(flight)))
         {
-            innerData._flightCache.Add(new FlightInfo(name, speed, lon, lat), innerData.hoverPoint);
+            innerData.flightStorge.Items.Add(innerData.hoverPoint);
+            innerData.flightpath.Points.Add(innerData.hoverPoint.Location);
+            innerData._flightCache.Add(flight, innerData.hoverPoint);
         }
     }
 
+
+    public static void UpdateItem<T>(this MapControl ctrl, T item, bool setCenter = false) where T : FlightInfo, new()
+    {
+        if (item == null) return;
+        var innerData = ctrl.Tag as InnerData;
+        if (innerData._flightCache.ContainsKey(item))
+        {
+            var mapDot = innerData._flightCache[item] as MapDot;
+            mapDot.Location = new GeoPoint(item.FlightLat, item.FlightLon);//外部修改了位置
+            if (mapDot.Size != (item.Selected ? _selectedDotSize : _dotSize))//外部修改了选中状态
+            {
+                mapDot.Size = item.Selected ? _selectedDotSize : _dotSize;
+                mapDot.StrokeWidth = item.Selected ? 0 : 1;
+               
+                if (mapDot.ClusteredItems.Any())
+                    (mapDot.ClusteredItems[0] as MapDot).Size = _selectedDotSize;
+                if (item.Selected)
+                {
+                    //让选中的Item在上层
+                    var idx = innerData.flightStorge.Items.IndexOf(mapDot);
+                    innerData.flightStorge.Items.Swap(idx, innerData.flightStorge.Items.Count - 1);
+                    //innerData.posStorge.Items.Add(mapDot);
+
+                    //需要将上次选中的点设置为未选中
+                    if (innerData.preSelectedItem != null)
+                    {
+                        innerData.preSelectedItem.Size = _dotSize;
+                        (innerData.preSelectedItem.Tag as FlightInfo).Selected = false;
+                    }
+                    innerData.preSelectedItem = mapDot;
+                }
+            }
+            if (setCenter)
+                ctrl.SetCenterPoint(item.FlightLon, item.FlightLat, false);
+        }
+    }
     public static void DelFlightItem<T>(this MapControl ctrl, IEnumerable<T> data) where T : FlightInfo, new()
     {
         var fs = data.ToList();
@@ -854,7 +842,7 @@ public static class MapControlEx
     private static void ShowFlightLine<T>(this MapControl ctrl, InnerData innerData, List<T> points) where T : FlightInfo, new()
     {
         var first = points.First();
-        string filghtName = $"DrawFlightLine_{first.FlightName}_{first.Speed}";
+        string filghtName = first.GetFilghtName();
         var flightpath = new MapSpline()
         {
             Stroke = Color.FromArgb(127, 255, 0, 199),
@@ -885,10 +873,11 @@ public static class MapControlEx
 
                     var hoverPointj = new MapDot()
                     {
+                      
                         CanResize = false,
                         CanMove = true,
-                        ToolTipPattern = $"航迹:{finfo.FlightName}\r\n{finfo.FlightLon},{finfo.FlightLat}°",
-                        Tag = flightpath.Tag,
+                        ToolTipPattern = finfo.ToString(),
+                        Tag = finfo,
                         Size = 8
                     };
                     hoverPointj.Location = location;
@@ -1071,7 +1060,6 @@ public static class MapControlEx
         btnExportCsv.ItemClick += (sender, e) =>
         {
             if (!innerData._flightCache.Any()) return;
-            bool exportSigTime = false;
             Dictionary<string, string> cellFormats = new Dictionary<string, string>();//单元格的format
             var props = innerData._flightCache.Keys.GetType().GetGenericArguments().First().GetProperties(BindingFlags.Public | BindingFlags.Instance);
             List<(int ColumnIndex, PropertyInfo Prop, string Header)> listPorps = new List<(int, PropertyInfo, string)>();
@@ -1079,8 +1067,7 @@ public static class MapControlEx
             {
                 ExportCellAttribute attrExport = prop.GetCustomAttribute<ExportCellAttribute>();
                 if (attrExport == null) continue;
-                if (prop.Name == nameof(PosData.SigTime))
-                    exportSigTime = true;
+
                 if (!string.IsNullOrWhiteSpace(attrExport.Format))
                 {
                     cellFormats.Add(prop.Name, attrExport.Format);
@@ -1187,16 +1174,12 @@ public static class MapControlEx
                 gc.MainView = view;
                 gc.ViewCollection.Add(view);
                 view.OptionsPrint.ShowPrintExportProgress = false;
-                bool exportSigTime = false;
                 Dictionary<string, string> cellFormats = new Dictionary<string, string>();//单元格的format
                 var props = innerData._flightCache.Keys.GetType().GetGenericArguments().First().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                 foreach (var prop in props)
                 {
                     ExportCellAttribute attrExport = prop.GetCustomAttribute<ExportCellAttribute>();
                     if (attrExport == null) continue;
-                    if (prop.Name == nameof(PosData.SigTime))
-                        exportSigTime = true;
-
                     if (!string.IsNullOrWhiteSpace(attrExport.Format))
                     {
                         cellFormats.Add(prop.Name, attrExport.Format);
@@ -2627,106 +2610,5 @@ public static class MapControlEx
     }
     #endregion
 
-    //定位点聚合器
-    class PosClusterer : IClusterer
-    {
-        private MapControl ctrl;
-        private IMapDataAdapter owner;
-        private MapViewport preViewPoint;
-        private DebounceDispatcher dispatcher = new DebounceDispatcher();
-
-        public bool IsBusy { get; private set; }
-
-        public MapItemCollection Items { get; private set; }
-        public PosClusterer(MapControl ctrl)
-        {
-            this.ctrl = ctrl;
 
-        }
-        public void SetOwner(IMapDataAdapter owner)
-        {
-            this.owner = owner;
-            Items = new MapItemCollection(owner);
-        }
-
-        public void Clusterize(IEnumerable<MapItem> sourceItems, MapViewport viewport, bool sourceChanged)
-        {
-            IsBusy = true;
-            if (sourceChanged)
-                DoClusterize(sourceItems, viewport, sourceChanged);
-            else
-                dispatcher.Debounce(100, () => DoClusterize(sourceItems, viewport, sourceChanged));
-        }
-
-        private void DoClusterize(IEnumerable<MapItem> sourceItems, MapViewport viewport, bool sourceChanged)
-        {
-            if (preViewPoint == null)
-            {
-                preViewPoint = viewport;
-                return;
-            }
-            if (!sourceChanged && preViewPoint.ZoomLevel == viewport.ZoomLevel)//地图移动或者MapControl大小发生了改变时直接操作Items避免闪烁
-            {
-                preViewPoint = viewport;
-            }
-            else//地图进行了缩放
-            {
-                Items.Clear();
-                var cache = new Dictionary<int, List<MapItem>>();
-                foreach (MapDot item in sourceItems)
-                {
-                    var point = ctrl.CoordPointToScreenPoint(item.Location);
-                    int pointX = (int)point.X;
-                    int pointY = (int)point.Y;
-                    bool visible = true;
-                    if (pointX <= _dotSize || pointX > ctrl.Width - _dotSize)
-                        visible = false;
-                    else if (pointY <= _dotSize || pointY > ctrl.Height - _dotSize)
-                        visible = false;
-                    pointX /= (_dotSize * 2);
-                    pointY /= (_dotSize * 2);
-                    var key = pointX << 16 | pointY;
-                    if (!visible)
-                        key = -key;
-                    if (!cache.ContainsKey(key))
-                        cache.Add(key, new List<MapItem>());
-                    cache[key].Add(item);
-                }
-                var innerData = ctrl.Tag as InnerData;
-                innerData._clusterCache.Clear();
-                LinkedList<MapItem> temp = new LinkedList<MapItem>();
-                foreach (var kv in cache)
-                {
-                    var firstDot = kv.Value[0] as MapDot;
-                    var firstObj = firstDot.Tag as PosData;
-                    firstDot.Size = kv.Value.Count > 1 ? _dotSize + 2 : _dotSize;
-                    firstObj.ClusterCount = kv.Value.Count;
-                    firstObj.ClusterKey = kv.Key;
-                    innerData._clusterCache.Add(kv.Key, firstDot);
-                    temp.AddLast(firstDot);
-                }
-                Items.AddRange(temp);
-
-                cache.Clear();
-                preViewPoint = viewport;
-                owner.OnClustered();
-            }
-            this.IsBusy = false;
-        }
-        //计算多个坐标的中心位置  
-        public GeoPoint GetCenterPointFromListOfCoordinates(List<MapItem> geoCoordinateList)
-        {
-            int total = geoCoordinateList.Count;
-            double lat = 0, lon = 0;
-            foreach (MapDot g in geoCoordinateList)
-            {
-                lat += (g.Location as GeoPoint).Latitude * Math.PI / 180;
-                lon += (g.Location as GeoPoint).Longitude * Math.PI / 180;
-            }
-            lat /= total;
-            lon /= total;
-            return new GeoPoint(lat * 180 / Math.PI, lon * 180 / Math.PI);
-        }
-
-    }
 }

+ 1 - 1
DataSimulation.Repostory/DataSimulation.Repostory.csproj

@@ -95,7 +95,7 @@
     <Compile Include="Model\TaskInfo.cs" />
     <Compile Include="Model\TaskSimulation.cs" />
     <Compile Include="Model\XlInfo.cs" />
-    <Compile Include="PosData.cs" />
+    <Compile Include="FlightInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="SimulationCache.cs" />
     <Compile Include="TaskCache.cs" />

+ 14 - 95
DataSimulation.Repostory/PosData.cs → DataSimulation.Repostory/FlightInfo.cs

@@ -71,101 +71,6 @@ namespace DataSimulation.Repostory
         public int Index { get; set; } = 10000;
     }
 
-    /// <summary>
-    /// 定位点绑定到地图的对象
-    /// </summary>
-    public class PosData : BaseModel<long>
-    {
-        /// <summary>
-        /// 信号时刻
-        /// </summary>
-        [Display(Name = "信号时刻")]
-        [DisplayFormat(DataFormatString = "yyyy-MM-dd HH:mm:ss.fff")]
-        [ExportCell(ColumnIndex = 0)]//如果导出了SigTime,则内部会自动按照SigTime降序排列后再导出
-        [ToolTip(Index = 0)]
-        public DateTime SigTime { get; set; }
-
-        /// <summary>
-        /// 定位经度
-        /// </summary>
-        [Display(Name = "定位经度", AutoGenerateField = false)]
-        [ExportCell("f4")]
-        [ToolTip("f4")]
-        public double PosLon { get; set; }
-
-        /// <summary>
-        /// 定位纬度
-        /// </summary>
-        [Display(Name = "定位纬度", AutoGenerateField = false)]
-        [ExportCell("f4")]
-        [ToolTip("f4")]
-        public double PosLat { get; set; }
-
-
-        /// <summary>
-        /// 定位经度
-        /// </summary>
-        [Display(Name = "镜像经度", AutoGenerateField = false)]
-        [ExportCell("f4")]
-        [ToolTip("f4")]
-        public double MirrLon { get; set; }
-
-        /// <summary>
-        /// 定位纬度
-        /// </summary>
-        [Display(Name = "镜像纬度", AutoGenerateField = false)]
-        [ExportCell("f4")]
-        [ToolTip("f4")]
-        public double MirrLat { get; set; }
-
-        /// <summary>
-        /// 当前点是否被选中(默认false)
-        /// </summary>
-        [Display(Name = "是否选中", AutoGenerateField = false)]
-        [NotMapped]
-        public bool Selected { get; set; }
-
-        /// <summary>
-        /// 当前点是否可见(默认true)
-        /// </summary>
-        [Display(Name = "是否可见", AutoGenerateField = false)]
-        [NotMapped]
-        public bool Visible { get; set; } = true;
-
-        /// <summary>
-        /// 用于生成颜色的一个key,相同的key具有相同的颜色,当ColorKey为html颜色时则使用此颜色(如#A1B2FF),默认红色#CC3333
-        /// </summary>、
-        [Display(Name = "颜色标记", AutoGenerateField = false)]
-        [NotMapped]
-        public string ColorKey { get; set; } = "#CC3333";
-
-        /// <summary>
-        /// 判断定位点是否在一个框选的矩形区域内
-        /// </summary>
-        /// <param name="startLon"></param>
-        /// <param name="startLat"></param>
-        /// <param name="endLon"></param>
-        /// <param name="endLat"></param>
-        /// <returns></returns>
-        public bool InRectangle(double startLon, double startLat, double endLon, double endLat)
-        {
-            return PosLon >= startLon && PosLon <= endLon && PosLat >= startLat && PosLat <= endLat;
-        }
-
-        /// <summary>
-        /// 内部调用的属性
-        /// </summary>
-        [Display(AutoGenerateField = false)]
-        [NotMapped]
-        public int ClusterCount { get; set; } = 1;
-
-        /// <summary>
-        /// 内部调用的属性
-        /// </summary>
-        [Display(AutoGenerateField = false)]
-        [NotMapped]
-        public int ClusterKey { get; set; } = int.MinValue;
-    }
 
     [Serializable]
     public class FlightInfo
@@ -201,6 +106,20 @@ namespace DataSimulation.Repostory
         [ExportCell("f3")]
         public double FlightLat { get; set; }
 
+        [Display(Name = "是否选中", AutoGenerateField = false)]
+        [NotMapped]
+        public bool Selected { get; set; }
+
+
+        public override string ToString()
+        {
+            return $"航迹:{FlightName}\r\n{FlightLon},{FlightLat}°";
+        }
+        public string GetFilghtName()
+        {
+           return $"DrawFlightLine_{FlightName}_{Speed}";
+        }
+
         /// <summary>
         /// 判断定位点是否在一个框选的矩形区域内
         /// </summary>