金融 >

WPF绘制深圳地铁路线图

2023-06-01 23:17:22   来源:博客园

经常坐地铁,却不知道地铁多少条线路?哪个站下车?今天就带领大家熟悉并绘制深圳地铁路线图。

WPF在绘制矢量图方面有非常强大的优势,利用WPF可以绘制出各种矢量图形,如线,圆,多边形,矩形,及组合图形。今天以绘制深圳地铁路线图为例,简述WPF在图形绘制方面的一些知识,仅供学习分享使用,如有不足之处,还请指正。


(资料图片)

WPF图形概述

与传统的.NET开发使用GDI+进行绘图不同,WPF拥有自己的一套图形API,绘图为矢量图。绘图可以在任何一种布局控件中完成,wpf会根据容器计算相应坐标。最常用的是Canvas和Grid。基本图形包括以下几个,都是Shaper类的派生类。

  1. Line,直线段,可以设置Stroke
  2. Rectangle,有Stroke也有Fill
  3. Ellipse,椭圆,同上
  4. Polygon,多边形。由多条直线线段围成的闭合区域,同上。
  5. Polyline,折线,不闭合,由多条首尾相接的直线段组成
  6. Path,路径,闭合。可以由若干直线、圆弧、贝塞尔曲线(由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋)组成。很强大。

地铁官网效果

首先打开深圳地铁官网【https://www.szmc.net/map/】,可查看深圳地铁的路线图,如下所示:

获取地铁路线数据

通过对地铁官网的网络接口接收数据分析,可以获取地铁数据的原始JSON文件,将原始JSON文件保存到本地,在程序中进行引用,如下所示:

构建地铁数据模型

在得到shentie.json文件后,通过分析,构建模型类,如下所示:

1 namespace DemoSubway.Models  2 {  3     ///   4     /// 深圳地铁模型  5     ///   6     public class ShenTie  7     {  8         [JsonProperty("s")]  9         public string? Name { get; set; } 10  11         [JsonProperty("i")] 12         public string? Index { get; set; } 13  14         [JsonProperty("l")] 15         public SubwayLine[]? SubwayLines { get; set; } 16  17         [JsonProperty("o")] 18         public string? Obj { get;set; } 19     } 20  21     public class SubwayLine 22     { 23         [JsonProperty("st")] 24         public St[]? Sites { get; set; } 25  26         [JsonProperty("ln")] 27         public string? LineNumber { get; set; } 28  29         [JsonProperty("su")] 30         public string? Su { get; set; } 31  32         [JsonProperty("kn")] 33         public string? KName { get; set; } 34  35         [JsonProperty("c")] 36         public string[]? Circles { get;set; } 37  38         [JsonProperty("lo")] 39         public string? Lo { get; set; } 40  41         [JsonProperty("lp")] 42         public string[]? LinePosition { get; set; } 43  44         [JsonProperty("ls")] 45         public string? Ls { get; set; } 46  47         [JsonProperty("cl")] 48         public string? Color { get; set; } 49  50         [JsonProperty("la")] 51         public string? La { get; set; } 52  53         [JsonProperty("x")] 54         public string? X { get; set; } 55  56         [JsonProperty("li")] 57         public string? Li { get; set; } 58     } 59  60     public class St 61     { 62         [JsonProperty("rs")] 63         public string? Rs { get; set; } 64  65         [JsonProperty("udpx")] 66         public string? Udpx { get; set; } 67  68         [JsonProperty("su")] 69         public string? Su { get; set; } 70  71         [JsonProperty("udsu")] 72         public string? Udsu { get; set;} 73  74         [JsonProperty("n")] 75         public string? Name { get; set;} 76  77         [JsonProperty("en")] 78         public string? En { get; set; } 79  80         [JsonProperty("sid")] 81         public string? Sid { get; set; } 82  83         [JsonProperty("p")] 84         public string? Position { get; set; } 85  86         [JsonProperty("r")] 87         public string? R { get; set; } 88  89         [JsonProperty("udsi")] 90         public string? Udsi { get; set; } 91  92         [JsonProperty("t")] 93         public string? T { get; set;} 94  95         [JsonProperty("si")] 96         public string? Si { get; set; } 97  98         [JsonProperty("sl")] 99         public string? Sl { get; set;}100 101         [JsonProperty("udli")]102         public string? Udli { get; set; }103 104         [JsonProperty("poiid")]105         public string? Poiid { get; set; }106 107         [JsonProperty("lg")]108         public string? Lg { get; set; }109 110         [JsonProperty("sp")]111         public string? Sp { get; set; }112     }113 }

解析数据源

通过反序列化,将shentie.json文件内容,加载到内存并实例化为ShenTie对象,在此需要用到第三方库【Newtonsoft.Json】,如下所示:

绘制地铁路线图

地铁路线图在WPF主页面显示,用Grid作为容器【subwayBox】,如下所示:

1  9 10     11         12             13             14         15         16             17         18         19             20 21             22         23     24 

ShenTie对象创建成功后,就可以获取路线数据,然后创建地铁路线元素,如下所示:

1 private void Window_Loaded(object sender, RoutedEventArgs e)  2 {  3     string jsonFile = "shentie.json";  4     JsonHelper jsonHelper = new JsonHelper();  5     var shentie = jsonHelper.Deserialize(jsonFile);  6     this.tbTitle.Text = shentie.Name;  7     List lstSites = new List();  8     for(int i = 0; i < shentie.SubwayLines?.Length; i++)  9     { 10         var subwayLine= shentie.SubwayLines[i]; 11         if(subwayLine != null) 12         { 13             //地铁线路 14             var color = ColorTranslator.FromHtml($"#{subwayLine.Color}");//线路颜色 15             var circles = subwayLine.Circles;//线路节点 16             Path line = new Path(); 17             PathFigureCollection lineFigures = new PathFigureCollection(); 18             PathFigure lineFigure = new PathFigure(); 19             lineFigure.IsClosed= false; 20             var start = circles?[0].Split(" ");//线路起始位置 21             lineFigure.StartPoint = new System.Windows.Point(int.Parse(start[0]), int.Parse(start[1])); 22  23             for (int j= 0;j< circles?.Length;j++) 24             { 25                 var circle= circles[j].Split(" "); 26                 LineSegment lineSegment = new LineSegment(new System.Windows.Point(int.Parse(circle[0]), int.Parse(circle[1])),true); 27                 lineFigure.Segments.Add(lineSegment); 28             } 29             lineFigures.Add(lineFigure); 30             line.Data = new PathGeometry(lineFigures, FillRule.Nonzero, null); 31             line.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B)); 32             line.StrokeThickness = 4; 33             this.subwayBox.Children.Add(line); 34             //地铁站点 35             for (int j = 0; j < subwayLine.Sites?.Length; j++) 36             { 37                 var site = subwayLine.Sites[j]; 38                 if (site != null) 39                 { 40                      41                     //站点标识,圆圈 42                     Path siteCirclePath = new Path(); 43                     var sitePosition = site?.Position?.Split(" "); 44                     EllipseGeometry ellipse = new EllipseGeometry(); 45                     ellipse.Center = new System.Windows.Point(int.Parse(sitePosition[0]), int.Parse(sitePosition[1])); 46                     ellipse.RadiusX = 4;  47                     ellipse.RadiusY=4; 48                     siteCirclePath.Data=ellipse; 49                     siteCirclePath.Fill = Brushes.White; 50                     siteCirclePath.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B)); 51                     siteCirclePath.Cursor= Cursors.Hand; 52                     siteCirclePath.Focusable = true; 53                     siteCirclePath.Tag = site?.Name; 54                     siteCirclePath.MouseDown += SiteCirclePath_MouseDown; 55                     this.subwayBox.Children.Add(siteCirclePath); 56                     //站点名字 57                     if (lstSites.Contains(site?.Name)) 58                     { 59                         continue;//对于交汇站点,只绘制一次 60                     } 61                     //站点名称 62                     Path siteTextPath = new Path(); 63                     FormattedText siteContent = new FormattedText(site?.Name,CultureInfo.CurrentCulture,FlowDirection.LeftToRight,new Typeface("Arial"),14,Brushes.Black, 1.25); 64                     var x = int.Parse(sitePosition[0]); 65                     var y = int.Parse(sitePosition[1]); 66                     if (j + 1 < subwayLine.Sites?.Length) 67                     { 68                         //站点位置适当偏移 69                         var next = subwayLine.Sites[j + 1]?.Position?.Split(" "); 70                         var nextx = int.Parse(next[0]); 71                         var nexty = int.Parse(next[1]); 72                         if (x == nextx) 73                         { 74                             x = x + 6; 75                         } 76                         else if (y == nexty) 77                         { 78                             y = y + 6; 79                         } 80                         else 81                         { 82                             x = x + 1; 83                             y = y + 1; 84                         } 85                     } 86                     Geometry geometry = siteContent.BuildGeometry(new System.Windows.Point(x, y)); 87                     siteTextPath.Data = geometry; 88                     siteTextPath.Stroke = Brushes.Black; 89                     siteTextPath.Focusable = true; 90                     siteTextPath.Cursor = Cursors.Hand; 91                     siteTextPath.MouseDown += SiteTextPath_MouseDown; 92                     siteTextPath.Tag = site?.Name; 93                     this.subwayBox.Children.Add(siteTextPath); 94                     lstSites.Add(site?.Name); 95                 } 96             } 97  98             var kName = subwayLine.KName;//线路名称 99             var linePosition= subwayLine.LinePosition?[0].Split(" ");100             if(kName != null)101             {102                 Path lineNamePath = new Path();103                 FormattedText lineNameText = new FormattedText(kName, CultureInfo.CurrentCulture,FlowDirection.LeftToRight,new Typeface("Arial"),16,Brushes.Black,1.25);104                 var lineX = int.Parse(linePosition[0]);105                 var lineY = int.Parse(linePosition[1]);106                 if (subwayLine.LineNumber == "1")107                 {108                     lineX = lineX - 10;109                     lineY = lineY + 20;110                 }111                 Geometry geometry = lineNameText.BuildGeometry(new System.Windows.Point(lineX, lineY));112                 lineNamePath.Data=geometry;113                 lineNamePath.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B));114                 this.subwayBox.Children.Add(lineNamePath);115             }116         }117     }118 }

效果展示

本示例效果图如下所示:

在获取的JSON文件中,有些属性名都是简写,所以在编写示例代码过程中,对有些属性的理解并不准确,需要不断测试优化,绘制出的地铁路线图可能与实际存在稍微的差异,如站点名称,路线名称等内容的位置。

以上就是本篇文章的全部内容,旨在学习分享,传播知识。

标签:

相关阅读

WPF绘制深圳地铁路线图

金融

经常坐地铁,却不知道地铁多少条线路?哪个站下车?今天就带领大家熟悉并绘制深圳地铁路线图。WPF在绘制矢

2023-06-01

畅享高品质出行,第五代途胜L成为不二之选

金融

当电车行业还在智能化驾驶赛道上争夺时,焕然一新的第五代途胜(参数|询价)L已经完成了自我超越,直击长途驾

2023-06-01

荷甲附加赛海伦芬vs特温特比赛前瞻 谁能占

金融

北京时间6月2日凌晨0:45,荷甲迎来附加赛首回合的较量,海伦芬主场迎战特温特,两队将为一个海伦芬vs特温特

2023-06-01

欧元区5月制造业PMI跌至44.8|天天即时

金融

标普全球6月1日发布数据,欧元区5月制造业PMI终值为44 8,预期44 6,较4月前值45 8进一步下跌。

2023-06-01

旗下哥伦比亚金矿再遭袭击 紫金矿业回应;

金融

【科技圈】苹果全球首场电商直播近130万人围观5月31日晚七点,天猫AppleStore官方旗舰店开启了苹果(Apple

2023-06-01

WPF绘制深圳地铁路线图

金融

经常坐地铁,却不知道地铁多少条线路?哪个站下车?今天就带领大家熟悉并绘制深圳地铁路线图。WPF在绘制矢

2023-06-01

畅享高品质出行,第五代途胜L成为不二之选

金融

当电车行业还在智能化驾驶赛道上争夺时,焕然一新的第五代途胜(参数|询价)L已经完成了自我超越,直击长途驾

2023-06-01

荷甲附加赛海伦芬vs特温特比赛前瞻 谁能占得先机 全球新资讯

金融

北京时间6月2日凌晨0:45,荷甲迎来附加赛首回合的较量,海伦芬主场迎战特温特,两队将为一个海伦芬vs特温特

2023-06-01

欧元区5月制造业PMI跌至44.8|天天即时

金融

标普全球6月1日发布数据,欧元区5月制造业PMI终值为44 8,预期44 6,较4月前值45 8进一步下跌。

2023-06-01

旗下哥伦比亚金矿再遭袭击 紫金矿业回应;从苹果应用商店下架?百度网盘回应丨大公司动态

金融

【科技圈】苹果全球首场电商直播近130万人围观5月31日晚七点,天猫AppleStore官方旗舰店开启了苹果(Apple

2023-06-01

汤姆猫:业绩连降、股东减持1.07亿股,商誉占净资产比逾90%

金融

近期,汤姆猫回复了深交所问询函,针对2022年度日均活跃用户数较高但业绩大幅下降、商誉减值准备计提是否充

2023-06-01

继续来讲风水学的两大派别 一、理气派 理气派是繁杂

金融

继续来讲风水学的两大派别。一、理气派 理气派是繁杂的派别,理论框架内容几乎把易理涵

2023-06-01

嘉善城区货车禁行线路_禁行线路 今日热搜

金融

1、禁行线路。2、道路交通术语。3、即禁止车辆、行人通行的车道、线路、道路的简称。本文到此结束,希望对

2023-06-01

年轻人社交新方式 72.6%的受访青年生活里有“搭子” 当前快讯

金融

“饭搭子”“游戏搭子”“健身搭子”……这段时间,“搭子社交”的相关话题引发网友讨论关注。对于“搭子”

2023-06-01

6月1日华北地区纯碱价格偏弱运行

金融

6月1日华北地区纯碱偏弱运行,轻质纯碱主流市场报价2100-2300元 吨左右,国内纯碱一般运行行情,下游多按需

2023-06-01

遇见旗袍是于万千人群中的惊鸿一瞥 沿途洒满了爱的芬芳

旗袍,中国和世界华人女性的传统服装,被誉为中国国粹和女性国服。虽然其定义和产生的时间至今还存有诸多争议,但它仍然是中国悠久服饰文化

北京市电影院有序恢复开放 周五预售部分场次已满座

7月21日,北京市政府发布《北京市电影局关于在疫情防控常态化条件下有序推进电影院恢复开放的通知》,宣布全市低风险地区影院,可于7月24日

近期持续强降雨影响 第46届武汉渡江节因长江水位过高取消

武汉7·16渡江节组委会14日发布公告,由于长江武汉关水位超警戒水位,按照规定取消2020年第46届武汉7·16渡江节。受近期持续强降雨影响,

“非遗”普及受众最看重“动手”参观大师工作室非常享受

过去一段时间,国家级非遗项目灰塑传承人邵成村,多次在陈家祠等工作现场,向身边那些带着好奇目光的人们讲解灰塑的种种技术细节:草根灰、

璧山冷酒夜市 丰富市民夜间文旅活动

7月13日,位于璧山区南门唐城夜市街区的璧山冷酒夜市开街。这是璧山区打造夜间经济消费载体、培育夜间经济活动品牌的举措之一。璧山市民一

年内两市超过500家上市公司完成回购 累计回购金额超332亿元

近期A股市场持续震荡,不少上市公司或其重要股东推出回购、增持计划,用真金白银力挺股价。记者根据同花顺数据统计,今年以来,两市超过500

持续发力补链强链加大研发抢占市场 渝企跑出“加速度”

玥湖路渝快电充换电站 一辆新能源汽车,离不开研发、动力、配套等多个环节。作为汽车制造重镇,重庆在这些环节的多个板块上,正在加速奔跑

重启上市公司资本运作 康佳集团去年半导体业务营业收入为3.22亿元

近日,康佳集团正式对外发布2021年年度业绩报告。2021年,康佳集团实现全年营收491 07亿元,归属于母公司的净利润为9 05亿元,同比增长89 5

伟禄集团连续6年增长 去年营收同比增长37.5%

深港通标的之一的深圳企业伟禄集团近日公布2021年业绩。财报数据显示,伟禄集团全年营业收入11 95亿港元,同比增长37 5%,连续6年稳步增长;

龙头企业去年净利倍增 整个行业营收规模有望创造历史新高位

近日,面板龙头TCL科技、京东方分别发布2021年度业绩快报,两家企业去年归属于上市公司股东的净利润分别增长129 3%、412 86%,实现超过百亿

深圳国企全力为市民 守好“菜篮子”“米袋子”保障量足价稳

疫情防控形势下,民生物资供应是否充足成为市民最为关注的问题之一。连日来,深农集团、深粮控股等企业,充分发挥国企担当,全力为深圳市民