using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using GrxCAD.Geometry;
using GrxCAD.DatabaseServices;
using GrxCAD.ApplicationServices;
using GrxCAD.EditorInput;
namespace HCTools
{
public struct CPoint
{
public double x;
public double y;
public double z;
public object objID;
}
///
/// 判断点和线是否重叠
///
class CheckPLOverlay
{
public static int blc;//比例尺
public static string sqx;//首曲线
public static string jqx;//计曲线
public const int looptimes = 15;//循环查找次数
public static string EleLayerName;//高程点图层名
public int windowwidth;//当前可视范围
public int windowheight;
public double radius;//半径
public double length;//搜索半径
//存放所有高程点数组
public List pointarrlist = new List();
//存放有问题的高程点数组
public List errorpointarrlist = new List();
///
/// 检测点线矛盾,并画圆标记出错误点
///
public void contourch()
{
Editor editor = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
//清空各数组
pointarrlist.Clear();
errorpointarrlist.Clear();
double flagradius = 4.0 * blc / 1000;//画圆标记半径
windowwidth = 30 * 4 * blc / 1000;//确定可视范围
windowheight = 30 * 4 * blc / 1000;
if (blc == 500)
{
radius = 0.125;
}
else if (blc == 1000)
{
radius = 0.25;
}
else if (blc == 2000)
{
radius = 0.5;
}
else if (blc == 5000)
{
radius = 1.25;
}
//外切圆半径
length = radius * Math.Pow(2, 0.5);
selectcontourpoint(EleLayerName);//选出高程点
if (pointarrlist.Count == 0)
{
return;
}
//开始计时
Stopwatch watch = new Stopwatch();
watch.Start();
LayerControl layerscontrol = new LayerControl();
string layname = "点线重叠标记符号";
if (!layerscontrol.haslayername(layname))
{
colorgb col = new colorgb(255, 0, 255);
layerscontrol.creatlayer(layname, col);
layerscontrol.movelayertofront(layname);
}
else
layerscontrol.movelayertofront(layname);
layname = "点线重叠高程点";
if (layerscontrol.haslayername(layname) == false)
{
colorgb col = new colorgb(255, 0, 255);
layerscontrol.creatlayer(layname, col);
}
for (int i = 0; i < pointarrlist.Count; i++)
{
CPoint p = pointarrlist[i];
bool flag = check(p.x, p.y, p.z);
if (flag == false)
{
errorpointarrlist.Add(p);
}
}
Database database = HostApplicationServices.WorkingDatabase;
using (Transaction traction = database.TransactionManager.StartTransaction())
{
DocumentLock documentlock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
BlockTable blocktable = traction.GetObject(database.BlockTableId,
OpenMode.ForWrite) as BlockTable;
string decimals = "";
if (blc == 2000 || blc == 5000)
{
decimals = "F1";
}
else
{
decimals = "F2";
}
for (int i = 0; i < errorpointarrlist.Count; i++)
{
CPoint p = errorpointarrlist[i];
BasicFunction functions = new BasicFunction();
functions.makeflag(p.x, p.y, 0, flagradius, "点线重叠标记符号");
ObjectId id = (ObjectId)p.objID;
Entity entity = (Entity)traction.GetObject(id, OpenMode.ForWrite);
entity.Layer = "点线重叠高程点";
double z = p.z;
string ele = z.ToString(decimals);
Point3d p1 = new Point3d(p.x, p.y - 2.5, 0);
Point3d p2 = new Point3d(p.x + 10, p.y + 2.5, 0);
TypedValue[] typedvalue = new TypedValue[2];
typedvalue.SetValue(new TypedValue((int)DxfCode.Start, "Text"), 0);
typedvalue.SetValue(new TypedValue((int)DxfCode.LayerName, EleLayerName), 1);
SelectionFilter filter = new SelectionFilter(typedvalue);
PromptSelectionResult psr = editor.SelectCrossingWindow(p1, p2, filter);
if (psr.Status == PromptStatus.OK)
{
SelectionSet set = psr.Value;
ObjectId[] objs = new ObjectId[set.Count];
objs = set.GetObjectIds();
for (int ii = 0; ii < objs.Length; ii++)
{
Entity Text = (Entity)traction.GetObject(objs[ii], OpenMode.ForWrite);
DBText T = (DBText)Text;
if (T.TextString == ele)
{
T.Layer = "点线重叠高程点";
T.Color = GrxCAD.Colors.Color.FromRgb(255, 0, 255);
}
}
}
}
traction.Commit();
documentlock.Dispose();
traction.Dispose();
}
//耗时
watch.Stop();
long times = watch.ElapsedMilliseconds;
//editor.Regen();
//editor.UpdateScreen();
editor.WriteMessage("\n" + "耗时:" + times.ToString() + "毫秒");
editor.WriteMessage("\n" + "检测到压线高程点" + errorpointarrlist.Count.ToString());
editor.WriteMessage("\n");
}
///
/// 选出所有高程点,并取出其x,y,z坐标
///
/// 高程点图层名
private void selectcontourpoint(string layername)
{
Document document = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database database = HostApplicationServices.WorkingDatabase;
using (Transaction traction = database.TransactionManager.StartTransaction())
{
// 获得当前文档的编辑器
Editor editor = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
// 创建一个 TypedValue 数组,用于定义过滤条件
TypedValue[] typedvalue = new TypedValue[1];
typedvalue.SetValue(new TypedValue((int)DxfCode.LayerName, layername), 0);
// 赋值过滤条件给 SelectionFilter 对象
SelectionFilter selectionfilter = new SelectionFilter(typedvalue);
// 要求在图形区域中手动选择对象
PromptSelectionResult psr = editor.GetSelection(selectionfilter);
//自动选择图像区域全部对象
//PromptSelectionResult psr = editor.SelectAll(selectionfilter);
if (psr.Status == PromptStatus.OK)
{
SelectionSet selectionset = psr.Value;
ObjectId[] obj = new ObjectId[selectionset.Count];
obj = selectionset.GetObjectIds();
for (int i = 0; i < obj.Length; i++)
{
ObjectId objid = obj[i];
//找到实体,取出高程点的x,y,z
Entity entity = (Entity)traction.GetObject(objid, OpenMode.ForRead);
if (entity is BlockReference)
{
BlockReference blockreference = (BlockReference)entity;
CPoint cp = new CPoint();
cp.x = blockreference.Position.X;
cp.y = blockreference.Position.Y;
cp.z = blockreference.Position.Z;
cp.objID = objid;
pointarrlist.Add(cp);
}
}
editor.WriteMessage("\n" + "选中高程点数量:" + pointarrlist.Count.ToString());
}
traction.Commit();
traction.Dispose();
}
}
///
/// 检查是否压线
///
/// 高程点x坐标
/// 高程点y坐标
/// 高程点z坐标
private bool check(double x, double y, double z)
{
Database database = HostApplicationServices.WorkingDatabase;
Editor editor = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
using (Transaction acTrans = database.TransactionManager.StartTransaction())
{
ViewTableRecord currview = editor.GetCurrentView();
currview.CenterPoint = new Point2d(x, y);
currview.ViewDirection = new Vector3d(0, 0, 1);
currview.Width = windowwidth;
currview.Height = windowheight;
editor.SetCurrentView(currview);
acTrans.Commit();
}
Transaction traction = database.TransactionManager.StartTransaction();
List elevation = new List();
try
{
BlockTable blocktable = traction.GetObject(database.BlockTableId,
OpenMode.ForWrite) as BlockTable;
BlockTableRecord blocktablerecord = traction.GetObject(blocktable[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
//ViewTableRecord currview = editor.GetCurrentView();
//currview.CenterPoint = new Point2d(x, y);
//currview.ViewDirection = new Vector3d(0, 0, 1);
//currview.Width = windowwidth;
//currview.Height = windowheight;
//editor.SetCurrentView(currview);
string filttext = sqx + "," + jqx;
TypedValue[] filterlist = new TypedValue[1]
{
new TypedValue((int)DxfCode.LayerName,filttext)
};
//filterelist.SetValue(new TypedValue((int)DxfCode.LayerName, "8110,8120"),0);
// 赋值过滤条件给 SelectionFilter 对象
SelectionFilter filter = new SelectionFilter(filterlist);
Point3d p1 = new Point3d(x - length, y - length, 0);
Point3d p2 = new Point3d(x + length, y + length, 0);
PromptSelectionResult pselectresult;
pselectresult = editor.SelectCrossingWindow(p1, p2, filter);
if (pselectresult.Status == PromptStatus.OK)
{
SelectionSet selectionset = pselectresult.Value;
ObjectId[] obj = new ObjectId[selectionset.Count];
obj = selectionset.GetObjectIds();
for (int i = 0; i < obj.Length; i++)
{
ObjectId objid = obj[i];
Entity entity = (Entity)traction.GetObject(objid, OpenMode.ForRead);
if (entity is Polyline)
{
Polyline pline = (Polyline)entity;
Point3d p = pline.GetClosestPointTo(new Point3d(x, y, z), new Vector3d(0, 0, 1), false);
double distance = System.Math.Sqrt((p.X - x) * (p.X - x) + (p.Y - y) * (p.Y - y));
if (distance < radius)
{
if ((distance == 0 || pline.Elevation != z) == true)
{
return false;
//cpoint cp = new cpoint();
//cp.x = x;
//cp.y = y;
//cp.z = z;
//errorpointarrlist.Add(cp);
}
}
}
else if (entity is Polyline2d)
{
Polyline2d pline2d = (Polyline2d)entity;
Point3d p = pline2d.GetClosestPointTo(new Point3d(x, y, z), new Vector3d(0, 0, 1), false);
double distance = System.Math.Sqrt((p.X - x) * (p.X - x) + (p.Y - y) * (p.Y - y));
if (distance < radius)
{
if ((distance == 0 && pline2d.Elevation == z) == false)
{
return false;
//cpoint cp = new cpoint();
//cp.x = x;
//cp.y = y;
//cp.z = z;
//errorpointarrlist.Add(cp);
}
}
}
}
}
}
catch (GrxCAD.Runtime.Exception ex)
{
string str = ex.ToString();
Application.ShowAlertDialog(str);
}
finally
{
doclock.Dispose();
traction.Dispose();
}
return true;
}
}
}