vct输出思想
-----------------------------------------
vp:hsg
create date:2010-10-14
概述:
重点说一说输出vct topo1的面对象的思想。
//输出Vct文件
public override bool OutPut(string outVctFilePath)
{
bool rbc = false;
if (System.IO.File.Exists(outVctFilePath) == true)
{
System.IO.File.Delete(outVctFilePath);
}
//输出 xxx.vct 文件....
this.sw = new StreamWriter(outVctFilePath, true, Encoding.Default);
//输出Vct文件头
this.OutVctHeadBeginEnd();
//输出要素代码
this.OutVctFeatureCodeBeginEnd();
//输出表结构
this.OutVctTableStructureBeginEnd();
//输出点要素类
this.OutVctPointBeginEnd();
//输出线要素类
this.OutVctLineBeginEnd();
//输出面要素类
this.OutVctPolygonBeginEnd();
//输出注记要素类
this.OutVctAnnotationBeginEnd();
//输出拓扑数据
this.OutVctTopologyBeginEnd();
//输出属性值
this.OutVctAttributeBeginEnd();
//输出图形表现数据
this.OutVctStyleBeginEnd();
//ends
if (sw != null)
{ //保存数据到Vct文件
sw.Flush();
sw.Close();
sw.Dispose();
sw = null;
}
rbc = true;
return rbc;
}
输出点图层:
输出线图层:
输出注记图层:
这此图层按照标准输出都很简单,这里重点说一说输出vct(topo1)面图层的情况:
输出面图层:
(一)把面图层转为线图层:采用PolgyonToPolyline功能生成mdb中的Polygon_Line图层,这样会得到左右多边形编号,
left_fid,right_fid字段,
然后在线图层添加两个字段
vct_nums_xp/Vct线对象标识码
points_xp/线的点集合
vct_nums_xp用来保存线对象的编号,points_xp用来保存线对象的坐标串;
(二)对Polygon_Line图层的right_fid,left_fid创建索引,加快筛选速度;
//创建索引
string tabName="Polygon_Line";
string sqlIndex = "";
sqlIndex = "Create Index right_fid_Index on " + tabName + "(right_fid)";
dbConnWrap.ExecuteQuery(sqlIndex);
sqlIndex = "Create Index left_fid_Index on " + tabName + "(left_fid)";
dbConnWrap.ExecuteQuery(sqlIndex);
输出单个面要素思想:
lineNum += 1;
sw.WriteLine(lineNum.ToString()); //第一行序号(目标标识码)
sw.WriteLine(FeatureCode); //第二行要素代码
sw.WriteLine(FeatureName); //第三行要素名称
sw.WriteLine("100"); //第四行表示面的特征类型(1=表示直接坐标表示的面对象,100=表示由间接坐标表示的面对象)
centerX = 0; centerY = 0;
if (feat.ShapeCopy is IArea)
{
try
{
IArea tmpArea = feat.ShapeCopy as IArea;
if (tmpArea != null && tmpArea.Centroid != null)
{
centerX = tmpArea.Centroid.X;
centerY = tmpArea.Centroid.Y;
}
}
catch { }
}
sw.WriteLine(centerX.ToString() + "," + centerY.ToString()); //第五行几何中心点坐标(标识点坐标)
sw.WriteLine("21"); //第六行表示间接坐标面的构成类型(21=表示引用线对象构成的面,22=表示引用面对象构成的面)
int pid = ZhFeature.GetObjectID(feat);
string sqlQuerey = "select vct_nums_xp,points_xp,right_fid,left_fid from " + tabName + " ";
sqlQuerey += " where (right_fid=" + pid.ToString() + " or left_fid=" + pid.ToString() + ") and (right_fid<>left_fid)";
DataTable dt = dbConnWrap.ExecuteDataTable(sqlQuerey);
if (dt != null && dt.Rows.Count >= 0)
{
IPolygon4 p4 = feat.ShapeCopy as IPolygon4;
IGeometryCollection geoColl = p4 as IGeometryCollection;
if (geoColl is ITopologicalOperator)
{
(geoColl as ITopologicalOperator).Simplify();
}
geoCount = (geoColl as IGeometryCollection).GeometryCount;
objNums = dt.Rows.Count + geoCount - 1; //总项数
string tmpPolygon_LineID = "";
//生成面转为线的集合 并保存在LineOfPolygonList中(外环,内环)
List<CommonComboBoxItem> LineOfPolygonList = new List<CommonComboBoxItem>();
......
//对线对象编号进行排序操作
//构成面的线对象及线标识码并保存到LineList中
Dictionary<int, IPolyline> LineList = new Dictionary<int, IPolyline>();
......
//所有线段排序(构成面的线对象标识码的顺序)
Dictionary<int, IPolyline> intersetLineList = new Dictionary<int, IPolyline>();
foreach(IPolyline lOfp LineOfPolygonList)
{
IPolyline plGeo=(lOfp as ITopologicalOperator).Intersect(LineList[key] as IGeometry, esriGeometryDimension.esriGeometry1Dimension) as IPolyline;
intersetLineList.Add(key, tmpGeo);
ccb.Value += "," + key.ToString();
.......
//线段内排序(对Key,intersetLine排序)
//一条线时ccb.value就是一个key即线对象标识码
ccb.Text = ccb.Value;
//多条线时 (面线段内多条线先后顺序排序)
//获取线的方向Direction(1,-1)和线对象在面之线中的开始位置StartIndex
Direction = this.CheckAtLineByLine(lOfp, LineList[tmpkey], 0.0001 * 10, ref StartIndex);
if (Direction != 0)
{
tmpkey = tmpkey * Direction;
}
if (sortedIndex_LineID.Keys.Contains(StartIndex) == false)
sortedIndex_LineID.Add(StartIndex, tmpkey);
}
else
{
System.Diagnostics.Debug.WriteLine(tmpkey+"没在面中["+pid+"]");
}
}
//对已排序线对象标识码组合成一个字符串tmpPolygon_LineID
......
//第七行对象的项数
string[] arrayStr = tmpPolygon_LineID.Split(new char[] { ',' });
sw.WriteLine(arrayStr.Length.ToString());
#region //第八行线对象标识码 八个一行用(,)分开
vct_nums_xp = -1; string eight_line = "";
int ELIndex = 0;
for (int i = 0; i < arrayStr.Length; i++)
{
ELIndex += 1;
vct_nums_xp = -1;
if (arrayStr[i].Trim() != "")
{
vct_nums_xp = CommonClass.TInt(arrayStr[i]);
}
if (eight_line.Trim().Length <= 0)
{
eight_line = vct_nums_xp.ToString();
}
else
{
eight_line += "," + vct_nums_xp.ToString();
}
if (ELIndex % 8 == 0)
{
sw.WriteLine(eight_line);
eight_line = "";
}
}
if (eight_line.Trim().Length > 0)
{
sw.WriteLine(eight_line);
}
#endregion
}
sw.WriteLine("0"); //以0开始的单独一行表示一个要素数据结束
其中函数定义如下:
//获取和判断Line在AtLine线中的位置pos,返回方向是1,-1
private int CheckAtLineByLine(IPolyline AtLine, IPolyline Line, double tolerance,ref int pos)
{
int rbc = 0;
pos = -1;
IPointCollection pcOfP = AtLine as IPointCollection;
IPointCollection pcOfLine = Line as IPointCollection;
//计算线段先后顺序位置pos
IPoint midPoint = new PointClass();
IPoint hitPoint = new PointClass();
Line.QueryPoint(esriSegmentExtension.esriNoExtension, 0.5, true, midPoint); //获取中间点
double hitDistance = 0;
int hitPartIndex = -1;
int hitSegmentIndex = -1;
bool isRightSide = false;
esriGeometryHitPartType GeoHitPartType=esriGeometryHitPartType.esriGeometryPartBoundary;
IHitTest tmphitTest=AtLine as IHitTest;
bool IsHit = tmphitTest.HitTest(midPoint, tolerance, GeoHitPartType, hitPoint,
ref hitDistance, ref hitPartIndex, ref hitSegmentIndex, ref isRightSide);
if (IsHit == true)
{
pos = hitSegmentIndex; //记录位置
}
//计算线的方向rbc
for (int p = 0; p < pcOfP.PointCount-1; p++)
{
if (this.IsEquatePoint(pcOfP.get_Point(p), pcOfLine.get_Point(0), 0.0001) == true &&
this.IsEquatePoint(pcOfP.get_Point(p + 1), pcOfLine.get_Point(1), 0.0001) == true)
{
rbc = 1;
}
else if (this.IsEquatePoint(pcOfP.get_Point(p), pcOfLine.get_Point(pcOfLine.PointCount - 1), 0.0001) == true &&
this.IsEquatePoint(pcOfP.get_Point(p + 1), pcOfLine.get_Point(pcOfLine.PointCount - 2), 0.0001) == true)
{
rbc = -1;
}
if (rbc != 0)
{
break;
}
}
return rbc;
}
参考文献:
乡级制图规范.doc 2010
县级制图规范.doc 2010
市级制图规范.doc 2010
----------------------------
the end!