分享:根据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;
        }

 

posted @ 2013-06-20 11:17  easeyeah  阅读(3368)  评论(0编辑  收藏  举报