数据:界址点图层、宗地图层
要求:找出宗地对应的所有界址点号,对这些界址点号以J1开始按顺序排列
要找出宗地所对应的所有界址点号,这里只要执行一个标识 即可得到这样得到的结果。
难点在于对界址点的编号,经过检查,这些界址点存在明显的乱序,比如这样:132564
图形复杂,太复杂了,这种图形,用arcgis无论怎么排序、编号,它编号都得乱哇。
不得已只能动用C#的神秘力量
第一步做一个标识的操作,让所有的界址点有了归属,标记了每一个界址点属于哪一个宗地。
接下来的任务就是对宗地的界址点进行编号,每个宗地的界址点都从J1 开始编号。
宗地内遍历每一个界址点,找到距离这个界址点最近的宗地点,然后给这个界址点赋予这个宗地点的这个序号。遍历完界址点之后,对这个界址点进行排序就会得到我们想要的结果了。
cs
public void aaaa222(IFeatureClass fc_jzd, IFeatureClass fc_zd,string fieldname)
{
string txtfile = "";
SaveFileDialog save = new SaveFileDialog();
save.Filter = "文本|*.txt";
if (save.ShowDialog() != DialogResult.OK) return;
txtfile = save.FileName;
int jaindex = fc_jzd.FindField(fieldname);
if (jaindex < 0)
{
MessageBox.Show("界址点图层不包含"+ fieldname+"字段,请先做标识操作。");
return;
}
jaindex = fc_zd.FindField(fieldname);
if (jaindex < 0)
{
MessageBox.Show("宗地图层不包含" + fieldname + "字段,修改输入字段名称。");
return;
}
List<string> vsdata = GetUniqueValue(fc_jzd, fieldname);
ISpatialFilter spatialFilter = new SpatialFilterClass();
List<string> dataitem_result = new List<string>();
dataitem_result.Add("序号,"+fieldname+",界址点编号,X,Y");//+ "\r\n";
int index = 1;
//spatialFilter.WhereClause = fieldname + " = ";
foreach (string str in vsdata)
{
spatialFilter = new SpatialFilterClass();
spatialFilter.WhereClause = fieldname + " = '" + str + "'";
IFeatureCursor fcur_zd = fc_zd.Search(spatialFilter, false);
IFeatureCursor fcur_jzd = fc_jzd.Search(spatialFilter, false);
List<mPoint> jzd_ps = new List<mPoint>();
List<mPoint> presult = new List<mPoint>();
IFeature feature_zd = null;
IFeature feature_jzd = null;
mPoint mp = null;
List<mPoint> zd_points = new List<mPoint>();
while ((feature_zd = fcur_zd.NextFeature()) != null)
{
IGeometryCollection geoCol = feature_zd.Shape as IGeometryCollection;
while ((feature_jzd = fcur_jzd.NextFeature()) != null)
{
mp = new mPoint();
mp.X = (feature_jzd.Shape as IPoint).X;
mp.Y = (feature_jzd.Shape as IPoint).Y;
jzd_ps.Add(mp);
}
IPoint pp = null;
IPointCollection h1 = geoCol.Geometry[0] as IPointCollection;
for (int a = 0; a < h1.PointCount; a++)
{
pp = h1.get_Point(a);
mp = new mPoint();
mp.X = pp.X;
mp.Y = pp.Y;
mp.index = a;
zd_points.Add(mp);
}
IPolygon4 p4 = feature_zd.Shape as IPolygon4;
IGeometryBag interbag = p4.get_InteriorRingBag(geoCol.Geometry[0] as IRing);
IGeometryCollection interCol = interbag as IGeometryCollection;
int neihuan = 1;
for (int c = 0; c < interCol.GeometryCount; c++)
{
IPointCollection inth = interCol.get_Geometry(c) as IPointCollection;
for (int a = 0; a < inth.PointCount; a++)
{
pp = inth.get_Point(a);
mp = new mPoint();
mp.X = pp.X;
mp.Y = pp.Y;
mp.index = h1.PointCount+ neihuan;
zd_points.Add(mp);
neihuan++;
}
}
List<mPoint> temppp = new List<mPoint>();
foreach(mPoint ppitem in jzd_ps)
{
mPoint pi = GetDirect2(ppitem, zd_points);
//zd_points.Where(x => GetDirect(ppitem, x));
//mPoint pi= zd_points.FirstOrDefault(x => GetDirect(ppitem, x) == true);
if(pi!=null)
temppp.Add(pi);
}
temppp = temppp.OrderBy(x=>x.index).ToList();
int reallyjzd = 1;
temppp.ForEach(x=>
{
if(x!=null)
dataitem_result.Add((index++) + "," + str + ",J" +( reallyjzd++) + "," + x.X + "," + x.Y);//+ "\r\n";
});
}
}
File.WriteAllLines(txtfile, dataitem_result);
MessageBox.Show("执行完成!");
}
这一个方法需要界址点、宗地图层有一个相同的字段,也就是先必须进行标识操作。
后来想了想,如果直接用代码执行按位置进行选择,也能得到和宗地对应的界址点。于是就能把标识这一个步骤省略掉了。 勾选上 "按位置进行编号" 即可。
cs
public void aaaa_position(IFeatureClass fc_jzd, IFeatureClass fc_zd, string fieldname)
{
string txtfile = "";
SaveFileDialog save = new SaveFileDialog();
save.Filter = "文本|*.txt";
if (save.ShowDialog() != DialogResult.OK) return;
txtfile = save.FileName;
int jaindex = fc_zd.FindField(fieldname);
if (jaindex < 0)
{
MessageBox.Show("宗地图层不包含" + fieldname + "字段,修改输入字段名称。");
return;
}
List<string> dataitem_result = new List<string>();
dataitem_result.Add("序号," + fieldname + ",界址点编号,X,Y");
int index = 1;
IFeature feature_zd = null;
IFeatureCursor fcur = fc_zd.Search(null,false);
while ((feature_zd = fcur.NextFeature())!=null)
{
IGeometryCollection geoCol = feature_zd.Shape as IGeometryCollection;
string strJAvalue = feature_zd.get_Value(jaindex).ToString();
ISpatialFilter spatialFilter2 = new SpatialFilterClass
{
Geometry = feature_zd.Shape as IGeometry, //
SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects, //相接
};
IPoint point1 = (feature_zd.Shape as IArea).LabelPoint;
IFeatureCursor featureCursor2 = fc_jzd.Search(spatialFilter2, true);
IFeature feature_jzd = null;//
List<mPoint> jzd_ps = new List<mPoint>();//界址点点集存放
List<mPoint> zd_ps = new List<mPoint>();//宗地点集存放
mPoint mp = new mPoint();
while ((feature_jzd = featureCursor2.NextFeature()) != null)
{
mp = new mPoint();
mp.X = (feature_jzd.Shape as IPoint).X;
mp.Y = (feature_jzd.Shape as IPoint).Y;
jzd_ps.Add(mp);
}
#region 获取宗地的点集
IPoint pp = null;
IPointCollection h1 = geoCol.Geometry[0] as IPointCollection;
for (int a = 0; a < h1.PointCount; a++)
{
pp = h1.get_Point(a);
mp = new mPoint();
mp.X = pp.X;
mp.Y = pp.Y;
mp.index = a;
zd_ps.Add(mp);
}
IPolygon4 p4 = feature_zd.Shape as IPolygon4;
IGeometryBag interbag = p4.get_InteriorRingBag(geoCol.Geometry[0] as IRing);
IGeometryCollection interCol = interbag as IGeometryCollection;
int neihuan = 1;
for (int c = 0; c < interCol.GeometryCount; c++)
{
IPointCollection inth = interCol.get_Geometry(c) as IPointCollection;
for (int a = 0; a < inth.PointCount; a++)
{
pp = inth.get_Point(a);
mp = new mPoint();
mp.X = pp.X;
mp.Y = pp.Y;
mp.index = h1.PointCount + neihuan;
zd_ps.Add(mp);
neihuan++;
}
}
#endregion
List<mPoint> temppp = new List<mPoint>();
foreach (mPoint ppitem in jzd_ps)//遍历每一个界址点
{
mPoint pi = GetDirect2(ppitem, zd_ps);
//zd_points.Where(x => GetDirect(ppitem, x));
//mPoint pi= zd_points.FirstOrDefault(x => GetDirect(ppitem, x) == true);
if (pi != null)
temppp.Add(pi);
}
temppp = temppp.OrderBy(x => x.index).ToList();//从新排序
int reallyjzd = 1;
temppp.ForEach(x =>
{
if (x != null)
dataitem_result.Add((index++) + "," + strJAvalue + ",J" + (reallyjzd++) + "," + x.X + "," + x.Y);//+ "\r\n";
});
}
File.WriteAllLines(txtfile, dataitem_result);//输出TXT文件
MessageBox.Show("执行完成!");
}
结果
为了程序执行的效率以及稳定性,不生成图层、不存储字段信息,插件把处理的结果按
"序号,宗地代码,界址点编号,X,Y"
把所有信息输出到TXT。
直接把TXT文件拖到arcgis里边,展点,就是我们想要的结果了。
插件获取: