WPF绘制深圳地铁路线图

您所在的位置:网站首页 地铁构建图 WPF绘制深圳地铁路线图

WPF绘制深圳地铁路线图

2024-07-07 10:50:17| 来源: 网络整理| 查看: 265

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

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

WPF图形概述

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

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

地铁官网效果

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

获取地铁路线数据

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

构建地铁数据模型

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

namespace DemoSubway.Models { /// /// 深圳地铁模型 /// public class ShenTie { [JsonProperty("s")] public string? Name { get; set; } [JsonProperty("i")] public string? Index { get; set; } [JsonProperty("l")] public SubwayLine[]? SubwayLines { get; set; } [JsonProperty("o")] public string? Obj { get;set; } } public class SubwayLine { [JsonProperty("st")] public St[]? Sites { get; set; } [JsonProperty("ln")] public string? LineNumber { get; set; } [JsonProperty("su")] public string? Su { get; set; } [JsonProperty("kn")] public string? KName { get; set; } [JsonProperty("c")] public string[]? Circles { get;set; } [JsonProperty("lo")] public string? Lo { get; set; } [JsonProperty("lp")] public string[]? LinePosition { get; set; } [JsonProperty("ls")] public string? Ls { get; set; } [JsonProperty("cl")] public string? Color { get; set; } [JsonProperty("la")] public string? La { get; set; } [JsonProperty("x")] public string? X { get; set; } [JsonProperty("li")] public string? Li { get; set; } } public class St { [JsonProperty("rs")] public string? Rs { get; set; } [JsonProperty("udpx")] public string? Udpx { get; set; } [JsonProperty("su")] public string? Su { get; set; } [JsonProperty("udsu")] public string? Udsu { get; set;} [JsonProperty("n")] public string? Name { get; set;} [JsonProperty("en")] public string? En { get; set; } [JsonProperty("sid")] public string? Sid { get; set; } [JsonProperty("p")] public string? Position { get; set; } [JsonProperty("r")] public string? R { get; set; } [JsonProperty("udsi")] public string? Udsi { get; set; } [JsonProperty("t")] public string? T { get; set;} [JsonProperty("si")] public string? Si { get; set; } [JsonProperty("sl")] public string? Sl { get; set;} [JsonProperty("udli")] public string? Udli { get; set; } [JsonProperty("poiid")] public string? Poiid { get; set; } [JsonProperty("lg")] public string? Lg { get; set; } [JsonProperty("sp")] public string? Sp { get; set; } } }

解析数据源

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

绘制地铁路线图

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

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

private void Window_Loaded(object sender, RoutedEventArgs e) { string jsonFile = "shentie.json"; JsonHelper jsonHelper = new JsonHelper(); var shentie = jsonHelper.Deserialize(jsonFile); this.tbTitle.Text = shentie.Name; List lstSites = new List(); for(int i = 0; i < shentie.SubwayLines?.Length; i++) { var subwayLine= shentie.SubwayLines[i]; if(subwayLine != null) { //地铁线路 var color = ColorTranslator.FromHtml($"#{subwayLine.Color}");//线路颜色 var circles = subwayLine.Circles;//线路节点 Path line = new Path(); PathFigureCollection lineFigures = new PathFigureCollection(); PathFigure lineFigure = new PathFigure(); lineFigure.IsClosed= false; var start = circles?[0].Split(" ");//线路起始位置 lineFigure.StartPoint = new System.Windows.Point(int.Parse(start[0]), int.Parse(start[1])); for (int j= 0;j< circles?.Length;j++) { var circle= circles[j].Split(" "); LineSegment lineSegment = new LineSegment(new System.Windows.Point(int.Parse(circle[0]), int.Parse(circle[1])),true); lineFigure.Segments.Add(lineSegment); } lineFigures.Add(lineFigure); line.Data = new PathGeometry(lineFigures, FillRule.Nonzero, null); line.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B)); line.StrokeThickness = 4; this.subwayBox.Children.Add(line); //地铁站点 for (int j = 0; j < subwayLine.Sites?.Length; j++) { var site = subwayLine.Sites[j]; if (site != null) { //站点标识,圆圈 Path siteCirclePath = new Path(); var sitePosition = site?.Position?.Split(" "); EllipseGeometry ellipse = new EllipseGeometry(); ellipse.Center = new System.Windows.Point(int.Parse(sitePosition[0]), int.Parse(sitePosition[1])); ellipse.RadiusX = 4; ellipse.RadiusY=4; siteCirclePath.Data=ellipse; siteCirclePath.Fill = Brushes.White; siteCirclePath.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B)); siteCirclePath.Cursor= Cursors.Hand; siteCirclePath.Focusable = true; siteCirclePath.Tag = site?.Name; siteCirclePath.MouseDown += SiteCirclePath_MouseDown; this.subwayBox.Children.Add(siteCirclePath); //站点名字 if (lstSites.Contains(site?.Name)) { continue;//对于交汇站点,只绘制一次 } //站点名称 Path siteTextPath = new Path(); FormattedText siteContent = new FormattedText(site?.Name,CultureInfo.CurrentCulture,FlowDirection.LeftToRight,new Typeface("Arial"),14,Brushes.Black, 1.25); var x = int.Parse(sitePosition[0]); var y = int.Parse(sitePosition[1]); if (j + 1 < subwayLine.Sites?.Length) { //站点位置适当偏移 var next = subwayLine.Sites[j + 1]?.Position?.Split(" "); var nextx = int.Parse(next[0]); var nexty = int.Parse(next[1]); if (x == nextx) { x = x + 6; } else if (y == nexty) { y = y + 6; } else { x = x + 1; y = y + 1; } } Geometry geometry = siteContent.BuildGeometry(new System.Windows.Point(x, y)); siteTextPath.Data = geometry; siteTextPath.Stroke = Brushes.Black; siteTextPath.Focusable = true; siteTextPath.Cursor = Cursors.Hand; siteTextPath.MouseDown += SiteTextPath_MouseDown; siteTextPath.Tag = site?.Name; this.subwayBox.Children.Add(siteTextPath); lstSites.Add(site?.Name); } } var kName = subwayLine.KName;//线路名称 var linePosition= subwayLine.LinePosition?[0].Split(" "); if(kName != null) { Path lineNamePath = new Path(); FormattedText lineNameText = new FormattedText(kName, CultureInfo.CurrentCulture,FlowDirection.LeftToRight,new Typeface("Arial"),16,Brushes.Black,1.25); var lineX = int.Parse(linePosition[0]); var lineY = int.Parse(linePosition[1]); if (subwayLine.LineNumber == "1") { lineX = lineX - 10; lineY = lineY + 20; } Geometry geometry = lineNameText.BuildGeometry(new System.Windows.Point(lineX, lineY)); lineNamePath.Data=geometry; lineNamePath.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B)); this.subwayBox.Children.Add(lineNamePath); } } } }

效果展示

本示例效果图如下所示:

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

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



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭