分享:根據svg節點對象類型和路徑值轉換坐標值


功能用處:

對svg文件的路徑節點填充時會使用(相鄰兩個坐標區域內的四邊形的填充顏色不重復)。

需要對svg文件中的Path節點或者 Polyline 節點做顏色填充.並且相鄰的兩個區域之間的顏色不允許重復。

代碼如下:

        /// <summary>
        /// 根據svg節點對象類型和路徑值轉換成標准的坐標值
        /// </summary>
        /// <param name="pointType">線條類型,可以是 Path 或者 Polyline</param>
        /// <param name="pointValue">
        /// 線條值
        /// <para>如 Path 節點的“d”屬性</para>
        /// <para>如 Polyline 節點的“points”屬性</para>
        /// </param>
        /// <returns>返回浮點類型的二維平面坐標點集合</returns>
        IList<PointF> ConvertPoints(string pointType, string pointValue)
        {
            IList<PointF> points = new List<PointF>();

            string[] pointArray = { };

            if (pointType.ToLower() == "points")
            {
                //Polyline 節點
                pointArray = pointValue.Split(new char[] { ' ', ',' });

                for (int i = 0; i < pointArray.Length; i = i + 2)
                {
                    if (i + 1 >= pointArray.Length)
                        break;

                    if (string.IsNullOrEmpty(pointArray[i]) || string.IsNullOrEmpty(pointArray[i + 1]))
                        continue;

                    try
                    {
                        PointF item = new PointF();
                        item.X = float.Parse(pointArray[i]);
                        item.Y = float.Parse(pointArray[i + 1]);
                        points.Add(item);
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
            else if (pointType.ToLower() == "d")
            {
                //Path 節點

                if (!pointValue.StartsWith("m"))
                {
                    return new List<PointF>();
                }

                pointValue = pointValue.Substring(1);
                PointF prePos = new PointF();
                //過濾掉 path 路徑符號
                pointArray = pointValue.Split(new char[] { ' ', 'c', 'l', 's', 'v', 'q', 't', 'm', 'z' });
                foreach (string thisPoint in pointArray)
                {
                    if (string.IsNullOrEmpty(thisPoint))
                        continue;

                    try
                    {
                        string[] pThis = thisPoint.Split(',');
                        PointF item = new PointF();
                        item.X = prePos.X + float.Parse(pThis[0]);
                        item.Y = prePos.Y + float.Parse(pThis[1]);
                        points.Add(item);

                        prePos = item;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }

            return points;
        }

然后根據坐標集合獲取一個 四邊形的坐標對象:

        /// <summary>
        /// 根據節點ID和節點坐標的二維平面x,y坐標集合獲取坐標值對象
        /// </summary>
        /// <param name="points">浮點類型的二維平面坐標點集合</param>
        /// <param name="nodeId">Svg節點ID</param>
        /// <returns>Svg位置對象</returns>
        public ObjectPosition GetObjectPosition(IList<PointF> points, string nodeId)
        {
            ObjectPosition thisPos = new ObjectPosition(nodeId);

            for (int i = 0; i < points.Count; i++)
            {
                PointF pos = points[i];
                if (i == 0)
                {
                    thisPos.Init(pos.X, pos.Y);
                }
                else
                {
                    thisPos.SetPoint(pos.X, pos.Y);
                }
            }

            return thisPos;
        }

然后初始化坐標,並且獲取四邊形的坐標值:

        /// <summary>
        /// 初始化坐標
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void Init(float x, float y)
        {
            X1 = x;
            X2 = x;
            Y1 = y;
            Y2 = y;
        }

        /// <summary>
        /// 設置四邊形坐標值
        /// <remarks>原則:大中取大,小中取小.</remarks>
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void SetPoint(float x, float y)
        {
            if (x < X1) X1 = x;
            else if (x > X2) X2 = x;
            if (y < Y1) Y1 = y;
            else if (y > Y2) Y2 = y;
        }

最后使用:

        /// <summary>
        /// 通過svg文件或者加載的Svg內容獲取svg對象的坐標對象
        /// </summary>
        /// <returns>
        /// <para>key:節點名稱</para>
        /// <para>value:節點坐標對象</para>
        /// </returns>
        public Dictionary<string, ObjectPosition> GetSvgObjectPositions()
        {
            Dictionary<string, ObjectPosition> mapList = new Dictionary<string, ObjectPosition>();

            HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();
            //加載Svg內容
            document.LoadHtml(this.SvgString);

            var polylines = document.DocumentNode.SelectNodes("//polyline");
            if (polylines != null)
            {
                for (int i = 0; i < polylines.Count; i++)
                {
                    if (polylines[i].Attributes["id"] == null)
                        continue;
                    if (polylines[i].Attributes["points"] == null)
                        continue;

                    string nodeId = polylines[i].Attributes["id"].Value;
                    IList<PointF> points = this.ConvertPoints("points", polylines[i].Attributes["points"].Value);
                    ObjectPosition posInfo = this.GetObjectPosition(points, nodeId);
                    mapList.Add(posInfo.NodeID, posInfo);
                }
            }

            var paths = document.DocumentNode.SelectNodes("//path");
            if (paths != null)
            {
                for (int i = 0; i < paths.Count; i++)
                {
                    if (paths[i].Attributes["id"] == null)
                        continue;
                    if (paths[i].Attributes["d"] == null)
                        continue;

                    string nodeId = paths[i].Attributes["id"].Value;
                    IList<PointF> points = this.ConvertPoints("d", paths[i].Attributes["d"].Value);
                    ObjectPosition posInfo = this.GetObjectPosition(points, nodeId);
                    mapList.Add(posInfo.NodeID, posInfo);
                }
            }

            return mapList;
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM