Esempio n. 1
0
        /// <summary>
        /// 解析直线
        /// </summary>
        /// <param name="line"></param>
        private void ParseLine(Point2d ptStart, Point2d ptEnd)
        {
            if (!CommandUtils.IsOrthogonalLine(ptStart, ptEnd))
            {
                //表格里会有斜线代表空格,直接跳过
                //throw new AcTableParseException(string.Format("只支持正交的直线 {0:s} {1:s}", ptStart.ToString(), ptEnd.ToString()));
                return;
            }
            List <AcTableLine> list;

            if (CommandUtils.Compare(ptStart.X, ptEnd.X) == 0)
            {
                list = _tableVLines;
            }
            else
            {
                list = _tableHLines;
            }
            bool add = false;

            foreach (AcTableLine tl in list)
            {
                if (tl.AcceptSegment(ptStart, ptEnd))
                {
                    tl.AddSegment(ptStart, ptEnd);
                    add = true;
                    break;
                }
            }
            if (!add)
            {
                list.Add(new AcTableLine(ptStart, ptEnd));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 构造器
        /// 这里默认线段已经是正交的,应在调用之前做好判断
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        public AcTableLine(Point2d pt1, Point2d pt2)
        {
            if (CommandUtils.Compare(pt1.X, pt2.X) == 0)
            {
                _direction = AcTableLineDirection.V;
                _xory      = pt1.X;
            }
            else
            {
                _direction = AcTableLineDirection.H;
                _xory      = pt2.Y;
            }
            Point2d start, end;

            if (CommandUtils.Compare(pt1.Y, pt2.Y) > 0 || CommandUtils.Compare(pt1.X, pt2.X) < 0)
            {
                start = pt1;
                end   = pt2;
            }
            else
            {
                start = pt2;
                end   = pt1;
            }
            _start = start;
            _end   = end;
            _segments.Add(new AcLineSegment(start, end));
        }
Esempio n. 3
0
        /// <summary>
        /// 是否接受一个线段,即该线段是否可以归到这条格线中
        /// 这里默认线段已经是正交的,应在调用之前做好判断
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public bool AcceptSegment(Point2d pt1, Point2d pt2)
        {
            AcTableLineDirection direction;
            double xory = 0;

            if (CommandUtils.Compare(pt1.X, pt2.X) == 0)
            {
                direction = AcTableLineDirection.V;
                xory      = pt1.X;
            }
            else
            {
                direction = AcTableLineDirection.H;
                xory      = pt1.Y;
            }
            return(direction == _direction && (_segments.Count == 0 || CommandUtils.Compare(xory, _xory) == 0));
        }
Esempio n. 4
0
        /// <summary>
        /// 清理无效的格线
        /// 有时候表格里会有非格线的直线或多段线(比如钢筋图样),需要清理掉
        /// 清理的原则是要求格线的头或尾,必须在某个正交方向的格线上
        /// </summary>
        private void CleanLines()
        {
            //清理横线
            AcTableLine preHLine = null;

            foreach (AcTableLine hLine in _tableHLines.ToArray())
            {
                hLine.CrossPointCount = 0;
                foreach (AcTableLine vLine in _tableVLines)
                {
                    Point2d pt = new Point2d(vLine.XorY, hLine.XorY);
                    if (hLine.HasSegmentOn(pt, _tolerance) && vLine.HasSegmentOn(pt, _tolerance))
                    {
                        hLine.CrossPointCount += 1;
                    }
                }
                if (hLine.CrossPointCount <= 1)
                {
                    _tableHLines.Remove(hLine);
                }
                else if (preHLine != null && preHLine.XorY - hLine.XorY <= _tolerance) //表格容错,挨的太近的格线,删除掉一根交叉点小的
                {
                    //string s = string.Format("{0:f3},{1:f3},{2:f3},{3:f3}", preHLine.XorY, hLine.XorY, preHLine.XorY - hLine.XorY, _tolerance);
                    //System.Windows.Forms.MessageBox.Show(s);
                    if (preHLine.CrossPointCount < hLine.CrossPointCount)
                    {
                        _tableHLines.Remove(preHLine);
                        preHLine = hLine;
                    }
                    else
                    {
                        _tableHLines.Remove(hLine);
                    }
                }
                else
                {
                    preHLine = hLine;
                }
            }
            //清理竖线
            AcTableLine preVLine = null;

            foreach (AcTableLine vLine in _tableVLines.ToArray())
            {
                vLine.CrossPointCount = 0;
                foreach (AcTableLine hLine in _tableHLines)
                {
                    Point2d pt = new Point2d(vLine.XorY, hLine.XorY);
                    if (hLine.HasSegmentOn(pt, _tolerance) && vLine.HasSegmentOn(pt, _tolerance))
                    {
                        vLine.CrossPointCount += 1;
                    }
                }
                if (vLine.CrossPointCount <= 1)
                {
                    _tableVLines.Remove(vLine);
                }
                else if (preVLine != null && vLine.XorY - preVLine.XorY < _tolerance) //表格容错,挨的太近的格线,删除掉一根交叉点小的
                {
                    if (preVLine.CrossPointCount < vLine.CrossPointCount)
                    {
                        _tableVLines.Remove(preVLine);
                        preVLine = vLine;
                    }
                    else
                    {
                        _tableVLines.Remove(vLine);
                    }
                }
                else
                {
                    preVLine = vLine;
                }
            }
            //有时候表格会有双层外框,清理外层
            if (_tableHLines.Count > 2 || _tableVLines.Count > 2)
            {
                if (_tableHLines[0].CrossPointCount <= 2 &&
                    _tableHLines.Last().CrossPointCount <= 2 &&
                    _tableVLines[0].CrossPointCount <= 2 &&
                    _tableVLines.Last().CrossPointCount <= 2)
                {
                    _tableHLines.RemoveAt(0);
                    _tableHLines.RemoveAt(_tableHLines.Count - 1);
                    _tableVLines.RemoveAt(0);
                    _tableVLines.RemoveAt(_tableVLines.Count - 1);
                }
            }

            //清理只有2个交点并且不等于表格宽和高的格线
            double tableWidth = _tableHLines.Max(line => line.Length);

            foreach (AcTableLine hLine in _tableHLines.ToArray())
            {
                if (hLine.CrossPointCount <= 2 && CommandUtils.Compare(hLine.Length, tableWidth) < 0)
                {
                    //System.Windows.Forms.MessageBox.Show(hLine.Length.ToString());
                    _tableHLines.Remove(hLine);
                }
            }
            double tableHeight = _tableVLines.Max(line => line.Length);

            foreach (AcTableLine vLine in _tableVLines.ToArray())
            {
                if (vLine.CrossPointCount <= 2 && CommandUtils.Compare(vLine.Length, tableHeight) < 0)
                {
                    _tableVLines.Remove(vLine);
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// 向格线中添加一段
        /// 应提前调用Accept方法判断是否应该属于该格线,本方法中不再判断
        /// </summary>
        /// <param name="pt1"></param>
        /// <param name="pt2"></param>
        public void AddSegment(Point2d pt1, Point2d pt2)
        {
            Point2d start, end;

            if (CommandUtils.Compare(pt1.Y, pt2.Y) > 0 || CommandUtils.Compare(pt1.X, pt2.X) < 0)
            {
                start = pt1;
                end   = pt2;
            }
            else
            {
                start = pt2;
                end   = pt1;
            }

            if (_direction == AcTableLineDirection.H)
            {
                if (_segments.Count == 0)
                {
                    _xory = start.Y;
                    _segments.Add(new AcLineSegment(start, end));
                }
                bool add = false;
                for (int i = 0; i < _segments.Count; i++)
                {
                    if (start.X < _segments[i].Start.X)
                    {
                        _segments.Insert(i, new AcLineSegment(start, end));
                        add = true;
                        break;
                    }
                }
                if (!add)
                {
                    _segments.Add(new AcLineSegment(start, end));
                }
                if (_start.X > start.X)
                {
                    _start = start;
                }
                if (_end.X < end.X)
                {
                    _end = end;
                }
            }
            else
            {
                if (_segments.Count == 0)
                {
                    _xory = start.X;
                    _segments.Add(new AcLineSegment(start, end));
                }
                bool add = false;
                for (int i = 0; i < _segments.Count; i++)
                {
                    if (start.Y > _segments[i].Start.Y)
                    {
                        _segments.Insert(i, new AcLineSegment(start, end));
                        add = true;
                        break;
                    }
                }
                if (!add)
                {
                    _segments.Add(new AcLineSegment(start, end));
                }
                if (_start.Y < start.Y)
                {
                    _start = start;
                }
                if (_end.Y > end.Y)
                {
                    _end = end;
                }
            }
        }