欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于WPF實(shí)現(xiàn)繪制地鐵路線圖

 更新時(shí)間:2023年06月02日 11:16:24   作者:公子小六  
經(jīng)常坐地鐵,卻不知道地鐵多少條線路?哪個(gè)站下車?本文就來帶大家利用WPF繪制深圳地鐵路線圖,從而帶大家掌握WPF在圖形繪制方面的一些知識(shí),希望對大家有所幫助

經(jīng)常坐地鐵,卻不知道地鐵多少條線路?哪個(gè)站下車?今天就帶領(lǐng)大家熟悉并繪制深圳地鐵路線圖。

WPF在繪制矢量圖方面有非常強(qiáng)大的優(yōu)勢,利用WPF可以繪制出各種矢量圖形,如線,圓,多邊形,矩形,及組合圖形。今天以繪制深圳地鐵路線圖為例,簡述WPF在圖形繪制方面的一些知識(shí),僅供學(xué)習(xí)分享使用,如有不足之處,還請指正。

WPF圖形概述

與傳統(tǒng)的.NET開發(fā)使用GDI+進(jìn)行繪圖不同,WPF擁有自己的一套圖形API,繪圖為矢量圖。繪圖可以在任何一種布局控件中完成,wpf會(huì)根據(jù)容器計(jì)算相應(yīng)坐標(biāo)。最常用的是Canvas和Grid?;緢D形包括以下幾個(gè),都是Shaper類的派生類。

  • Line,直線段,可以設(shè)置Stroke
  • Rectangle,有Stroke也有Fill
  • Ellipse,橢圓,同上
  • Polygon,多邊形。由多條直線線段圍成的閉合區(qū)域,同上。
  • Polyline,折線,不閉合,由多條首尾相接的直線段組成
  • Path,路徑,閉合??梢杂扇舾芍本€、圓弧、貝塞爾曲線(由線段與節(jié)點(diǎn)組成,節(jié)點(diǎn)是可拖動(dòng)的支點(diǎn),線段像可伸縮的皮筋)組成。很強(qiáng)大。

地鐵官網(wǎng)效果

首先打開深圳地鐵官網(wǎng)【https://www.szmc.net/map/】,可查看深圳地鐵的路線圖,如下所示:

獲取地鐵路線數(shù)據(jù)

通過對地鐵官網(wǎng)的網(wǎng)絡(luò)接口接收數(shù)據(jù)分析,可以獲取地鐵數(shù)據(jù)的原始JSON文件,將原始JSON文件保存到本地,在程序中進(jìn)行引用,如下所示:

構(gòu)建地鐵數(shù)據(jù)模型

在得到shentie.json文件后,通過分析,構(gòu)建模型類,如下所示:

namespace DemoSubway.Models
{
    /// <summary>
    /// 深圳地鐵模型
    /// </summary>
    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; }
    }
}

解析數(shù)據(jù)源

通過反序列化,將shentie.json文件內(nèi)容,加載到內(nèi)存并實(shí)例化為ShenTie對象,在此需要用到第三方庫【Newtonsoft.Json】,如下所示:

繪制地鐵路線圖

地鐵路線圖在WPF主頁面顯示,用Grid作為容器【subwayBox】,如下所示:

<Window x:Class="DemoSubway.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DemoSubway"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBlock x:Name="tbTitle" FontSize="30" HorizontalAlignment="Center"></TextBlock>
        </StackPanel>
        <Viewbox Stretch="Fill" Grid.Row="1">
            <Grid x:Name="subwayBox">
            </Grid>
        </Viewbox>
    </Grid>
</Window>

ShenTie對象創(chuàng)建成功后,就可以獲取路線數(shù)據(jù),然后創(chuàng)建地鐵路線元素,如下所示:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    string jsonFile = "shentie.json";
    JsonHelper jsonHelper = new JsonHelper();
    var shentie = jsonHelper.Deserialize<ShenTie>(jsonFile);
    this.tbTitle.Text = shentie.Name;
    List<string> lstSites = new List<string>();
    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;//線路節(jié)點(diǎn)
            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);
            //地鐵站點(diǎn)
            for (int j = 0; j < subwayLine.Sites?.Length; j++)
            {
                var site = subwayLine.Sites[j];
                if (site != null)
                {
                    //站點(diǎn)標(biāo)識(shí),圓圈
                    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);
                    //站點(diǎn)名字
                    if (lstSites.Contains(site?.Name))
                    {
                        continue;//對于交匯站點(diǎn),只繪制一次
                    }
                    //站點(diǎn)名稱
                    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)
                    {
                        //站點(diǎn)位置適當(dāng)偏移
                        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文件中,有些屬性名都是簡寫,所以在編寫示例代碼過程中,對有些屬性的理解并不準(zhǔn)確,需要不斷測試優(yōu)化,繪制出的地鐵路線圖可能與實(shí)際存在稍微的差異,如站點(diǎn)名稱,路線名稱等內(nèi)容的位置。

以上就是基于WPF實(shí)現(xiàn)繪制地鐵路線圖的詳細(xì)內(nèi)容,更多關(guān)于WPF繪制地鐵路線圖的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#實(shí)現(xiàn)判斷字符串中是否包含中文的方法

    C#實(shí)現(xiàn)判斷字符串中是否包含中文的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)判斷字符串中是否包含中文的方法,非常實(shí)用的功能,需要的朋友可以參考下
    2014-08-08
  • C# Winform中DataGridView導(dǎo)出為Excel的實(shí)現(xiàn)示例

    C# Winform中DataGridView導(dǎo)出為Excel的實(shí)現(xiàn)示例

    本文主要介紹了C# Winform中DataGridView導(dǎo)出為Excel的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢的功能思路詳解

    unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢的功能思路詳解

    這篇文章主要介紹了unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢的功能思路詳解,實(shí)現(xiàn)起來其實(shí)并不復(fù)雜,涉及的技術(shù)點(diǎn)有pc端和移動(dòng)端屏幕拖動(dòng)事件,二維向量的相關(guān)運(yùn)算,手勢匹配算法,事件系統(tǒng)設(shè)計(jì)模式,需要的朋友可以參考下
    2023-12-12
  • ASP.NET C#中Application的用法教程

    ASP.NET C#中Application的用法教程

    這篇文章主要給大家介紹了關(guān)于ASP.NET C#中Application的用法,在介紹Application的用法之前,先給大家介紹了Session的用法供大家參考學(xué)習(xí),文中介紹的非常詳細(xì),需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-05-05
  • C#操作ftp類完整實(shí)例

    C#操作ftp類完整實(shí)例

    這篇文章主要介紹了C#操作ftp類,以一個(gè)完整實(shí)例形式詳細(xì)分析了C#操作FTP文件傳輸所涉及的FTP連接、文件傳輸、參數(shù)設(shè)置、文件刪除等技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-09-09
  • C# List介紹及具體用法

    C# List介紹及具體用法

    這篇文章主要介紹了C# List介紹及具體用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • C#利用win32 Api 修改本地系統(tǒng)時(shí)間、獲取硬盤序列號(hào)

    C#利用win32 Api 修改本地系統(tǒng)時(shí)間、獲取硬盤序列號(hào)

    這篇文章主要介紹了C#利用win32 Api 修改本地系統(tǒng)時(shí)間、獲取硬盤序列號(hào)的方法及代碼分享,需要的朋友可以參考下
    2015-03-03
  • 微信公眾號(hào)被動(dòng)消息回復(fù)原理解析

    微信公眾號(hào)被動(dòng)消息回復(fù)原理解析

    這篇文章主要介紹了公眾號(hào)被動(dòng)消息回復(fù)原理解析,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-06-06
  • C#解決訪問API顯示基礎(chǔ)連接已經(jīng)關(guān)閉的問題

    C#解決訪問API顯示基礎(chǔ)連接已經(jīng)關(guān)閉的問題

    最近在 Web 部署百度 AI 圖像識(shí)別 AipSdk.dll 封裝庫的時(shí)候,在調(diào)用OCR圖像識(shí)別 API 的時(shí)候,顯示為 “ 基礎(chǔ)連接已經(jīng)關(guān)閉: 接收時(shí)發(fā)生錯(cuò)誤,” ,并且運(yùn)行后直接崩潰,所以本文給大家介紹了C#解決訪問API顯示基礎(chǔ)連接已經(jīng)關(guān)閉的問題,需要的朋友可以參考下
    2024-12-12
  • C#發(fā)送數(shù)據(jù)到剪貼板及從剪貼板中取數(shù)據(jù)的方法

    C#發(fā)送數(shù)據(jù)到剪貼板及從剪貼板中取數(shù)據(jù)的方法

    這篇文章主要介紹了C#發(fā)送數(shù)據(jù)到剪貼板及從剪貼板中取數(shù)據(jù)的方法,涉及C#針對剪貼板數(shù)據(jù)的讀寫操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07

最新評論