|
|
|
|
using ESRI.ArcGIS.Carto;
|
|
|
|
|
using ESRI.ArcGIS.Geodatabase;
|
|
|
|
|
using ESRI.ArcGIS.Geometry;
|
|
|
|
|
using KGIS.Framework.AE;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Kingo.Plugin.DataCheck
|
|
|
|
|
{
|
|
|
|
|
public static class GeometryAPI
|
|
|
|
|
{
|
|
|
|
|
#region 计算两条线段(包含延长线)的交点
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计算两条线段(包含延长线)的交点
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pLine1"></param>
|
|
|
|
|
/// <param name="pLine2"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static IPoint GetIntersectPoint(IPolyline pLine1, IPolyline pLine2)
|
|
|
|
|
{
|
|
|
|
|
IPoint result = null;
|
|
|
|
|
var x1 = pLine1.FromPoint.X;
|
|
|
|
|
var x2 = pLine1.ToPoint.X;
|
|
|
|
|
var y1 = pLine1.FromPoint.Y;
|
|
|
|
|
var y2 = pLine1.ToPoint.Y;
|
|
|
|
|
|
|
|
|
|
var x3 = pLine2.FromPoint.X;
|
|
|
|
|
var x4 = pLine2.ToPoint.X;
|
|
|
|
|
var y3 = pLine2.FromPoint.Y;
|
|
|
|
|
var y4 = pLine2.ToPoint.Y;
|
|
|
|
|
|
|
|
|
|
var b1 = (y2 - y1) * x1 + (x1 - x2) * y1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var b2 = (y4 - y3) * x3 + (x3 - x4) * y3;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var D = (x2 - x1) * (y4 - y3) - (x4 - x3) * (y2 - y1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var D1 = b2 * (x2 - x1) - b1 * (x4 - x3);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var D2 = b2 * (y2 - y1) - b1 * (y4 - y3);
|
|
|
|
|
var x0 = D1 / D;
|
|
|
|
|
var y0 = D2 / D;
|
|
|
|
|
result = new PointClass() { X = x0, Y = y0 };
|
|
|
|
|
//}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计算两点连线和另一条线段的交点(待验证)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pointStart"></param>
|
|
|
|
|
/// <param name="pointEnd"></param>
|
|
|
|
|
/// <param name="targetGeo"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static IPoint GetIntersectPoint3(IPoint pointStart, IPoint pointEnd, IPolyline targetGeo)
|
|
|
|
|
{
|
|
|
|
|
//要返回的延长线终点
|
|
|
|
|
IPoint returnPoint = null;
|
|
|
|
|
IPoint ans, v1, v2;
|
|
|
|
|
//延长线的长度:用来判断取延长线长度短的点
|
|
|
|
|
double distance = double.MaxValue;
|
|
|
|
|
if (targetGeo != null)
|
|
|
|
|
{
|
|
|
|
|
IGeometryCollection geoCollection = targetGeo as IGeometryCollection;
|
|
|
|
|
for (int i = 0; i < geoCollection.GeometryCount; i++)
|
|
|
|
|
{
|
|
|
|
|
IPointCollection points = geoCollection.get_Geometry(i) as IPointCollection;
|
|
|
|
|
for (int j = 0; j < points.PointCount - 1; j++)
|
|
|
|
|
{
|
|
|
|
|
v1 = points.get_Point(j);
|
|
|
|
|
v2 = points.get_Point(j + 1);
|
|
|
|
|
if (parallel(pointStart, pointEnd, v1, v2) || !intersect_in(pointStart, pointEnd, v1, v2))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ans = intersection(pointStart, pointEnd, v1, v2);
|
|
|
|
|
IPolyline polylineOld = new PolylineClass();
|
|
|
|
|
polylineOld.FromPoint = pointStart;
|
|
|
|
|
polylineOld.ToPoint = pointEnd;
|
|
|
|
|
polylineOld.SpatialReference = targetGeo.SpatialReference;
|
|
|
|
|
IPolyline polylineNew = new PolylineClass();
|
|
|
|
|
polylineNew.FromPoint = pointEnd;
|
|
|
|
|
polylineNew.ToPoint = ans;
|
|
|
|
|
polylineNew.SpatialReference = targetGeo.SpatialReference;
|
|
|
|
|
if (FeatureAPI.IsInterSect(polylineOld as IPolyline, polylineNew as IPolyline))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
//延长线的长度:取延长线长度短的点
|
|
|
|
|
if (polylineNew.Length < distance)
|
|
|
|
|
{
|
|
|
|
|
distance = polylineNew.Length;
|
|
|
|
|
returnPoint = ans;
|
|
|
|
|
returnPoint.SpatialReference = targetGeo.SpatialReference;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return returnPoint;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计算来给你调线段的交点(不包含延长线上的点)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pLine1"></param>
|
|
|
|
|
/// <param name="pLine2"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static IPoint GetIntersectPoint2(IPolyline pLine1, IPolyline pLine2)
|
|
|
|
|
{
|
|
|
|
|
IPoint result = new PointClass();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ITopologicalOperator pTopo = pLine1 as ITopologicalOperator;
|
|
|
|
|
result = pTopo.Intersect(pLine2, esriGeometryDimension.esriGeometry0Dimension) as IPoint;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判两线段相交,包括端点和部分重合
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="u1"></param>
|
|
|
|
|
/// <param name="u2"></param>
|
|
|
|
|
/// <param name="v1"></param>
|
|
|
|
|
/// <param name="v2"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static bool intersect_in(IPoint u1, IPoint u2, IPoint v1, IPoint v2)
|
|
|
|
|
{
|
|
|
|
|
if (!dots_inline(u1, u2, v1) || !dots_inline(u1, u2, v2))
|
|
|
|
|
{
|
|
|
|
|
return !same_side(u1, u2, v1, v2) || !same_side(v1, v2, u1, u2);
|
|
|
|
|
}
|
|
|
|
|
return dot_online_in(u1, v1, v2) || dot_online_in(u2, v1, v2) || dot_online_in(v1, u1, u2) || dot_online_in(v2, u1, u2);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计算两线段交点,请判线段是否相交(同时还是要判断是否平行!)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="u1"></param>
|
|
|
|
|
/// <param name="u2"></param>
|
|
|
|
|
/// <param name="v1"></param>
|
|
|
|
|
/// <param name="v2"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static IPoint intersection(IPoint u1, IPoint u2, IPoint v1, IPoint v2)
|
|
|
|
|
{
|
|
|
|
|
IPoint ret = new PointClass();
|
|
|
|
|
ret.X = u1.X;
|
|
|
|
|
ret.Y = u1.Y;
|
|
|
|
|
ret.SpatialReference = u1.SpatialReference;
|
|
|
|
|
double t = ((u1.X - v1.X) * (v1.Y - v2.Y) - (u1.Y - v1.Y) * (v1.X - v2.X)) / ((u1.X - u2.X) * (v1.Y - v2.Y) - (u1.Y - u2.Y) * (v1.X - v2.X));
|
|
|
|
|
ret.X += (u2.X - u1.X) * t;
|
|
|
|
|
ret.Y += (u2.Y - u1.Y) * t;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计算交叉乘积(P1-P0)x(P2-P0)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="p1"></param>
|
|
|
|
|
/// <param name="p2"></param>
|
|
|
|
|
/// <param name="p0"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static double xmult(IPoint p1, IPoint p2, IPoint p0)
|
|
|
|
|
{
|
|
|
|
|
return (p1.X - p0.X) * (p2.Y - p0.Y) - (p2.X - p0.X) * (p1.Y - p0.Y);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判点是否在线段上,包括端点
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="p"></param>
|
|
|
|
|
/// <param name="l1"></param>
|
|
|
|
|
/// <param name="l2"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static bool dot_online_in(IPoint p, IPoint l1, IPoint l2)
|
|
|
|
|
{
|
|
|
|
|
double d_xmult = xmult(p, l1, l2);
|
|
|
|
|
if (((d_xmult > 0 && d_xmult < 1e-8) || (d_xmult < 0 && -d_xmult < 1e-8)) && (l1.X - p.X) * (l2.X - p.X) == 0 && (l1.Y - p.Y) * (l2.Y - p.Y) == 0)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判两点在线段同侧,点在线段上返回0
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="p1"></param>
|
|
|
|
|
/// <param name="p2"></param>
|
|
|
|
|
/// <param name="l1"></param>
|
|
|
|
|
/// <param name="l2"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static bool same_side(IPoint p1, IPoint p2, IPoint l1, IPoint l2)
|
|
|
|
|
{
|
|
|
|
|
return xmult(l1, p1, l2) * xmult(l1, p2, l2) > 1e-8 ? true : false;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判两直线平行
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="u1"></param>
|
|
|
|
|
/// <param name="u2"></param>
|
|
|
|
|
/// <param name="v1"></param>
|
|
|
|
|
/// <param name="v2"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static bool parallel(IPoint u1, IPoint u2, IPoint v1, IPoint v2)
|
|
|
|
|
{
|
|
|
|
|
return (u1.X - u2.X) * (v1.Y - v2.Y) - (v1.X - v2.X) * (u1.Y - u2.Y) == 0 ? true : false;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判三点共线
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="p1"></param>
|
|
|
|
|
/// <param name="p2"></param>
|
|
|
|
|
/// <param name="p3"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static bool dots_inline(IPoint p1, IPoint p2, IPoint p3)
|
|
|
|
|
{
|
|
|
|
|
double d_xmult = xmult(p1, p2, p3);
|
|
|
|
|
if ((d_xmult > 0 && d_xmult < 1e-8) || (d_xmult < 0 && -d_xmult < 1e-8))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 计算两点间距离
|
|
|
|
|
public static double TwoPointDistance(IPoint p1, IPoint p2)
|
|
|
|
|
{
|
|
|
|
|
double result = -1;
|
|
|
|
|
result = Math.Abs(Math.Sqrt(Math.Pow((p1.X - p2.X), 2) + Math.Pow((p1.Y - p2.Y), 2)));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取线段延长线上的点
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pLine"></param>
|
|
|
|
|
/// <param name="pLength"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static IPoint GetExtendedLinePoint(IPolyline pLine, double pLength)
|
|
|
|
|
{
|
|
|
|
|
IPoint result = null;
|
|
|
|
|
double relativeX = pLine.ToPoint.X - pLine.FromPoint.X;
|
|
|
|
|
double relativeY = pLine.ToPoint.Y - pLine.FromPoint.Y;
|
|
|
|
|
double hypotenuse = Math.Sqrt(Math.Pow(relativeX, 2) + Math.Pow(relativeY, 2));
|
|
|
|
|
double x = relativeX / hypotenuse * pLength;
|
|
|
|
|
double y = relativeY / hypotenuse * pLength;
|
|
|
|
|
result = new PointClass() { X = pLine.ToPoint.X + x, Y = pLine.ToPoint.Y + y };
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
public static IGeometry UnionGeometry(IGeometry geo1, IGeometry geo2)
|
|
|
|
|
{
|
|
|
|
|
IGeometry result = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ITopologicalOperator topo = geo2 as ITopologicalOperator;
|
|
|
|
|
topo.Simplify();
|
|
|
|
|
topo = geo1 as ITopologicalOperator;
|
|
|
|
|
topo.Simplify();
|
|
|
|
|
result = topo.Union(geo2);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
public static bool IsEqualGeo(IGeometry geo1, IGeometry geo2)
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IRelationalOperator relat = geo1 as IRelationalOperator;
|
|
|
|
|
result = relat.Equals(geo2);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IPolyline GetSegment(IGeometry pGeo, IPoint pPoint, int position = 0)
|
|
|
|
|
{
|
|
|
|
|
IPolyline result = new PolylineClass();
|
|
|
|
|
if (pGeo == null)
|
|
|
|
|
return result;
|
|
|
|
|
if (pGeo.IsEmpty)
|
|
|
|
|
return result;
|
|
|
|
|
object o = Type.Missing;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IHitTest tempLine = null;
|
|
|
|
|
if (pGeo.GeometryType == esriGeometryType.esriGeometryPolygon)
|
|
|
|
|
{
|
|
|
|
|
tempLine = (pGeo as ITopologicalOperator).Boundary as IHitTest;
|
|
|
|
|
}
|
|
|
|
|
else if (pGeo.GeometryType == esriGeometryType.esriGeometryPolyline)
|
|
|
|
|
{
|
|
|
|
|
tempLine = pGeo as IHitTest;
|
|
|
|
|
}
|
|
|
|
|
if (tempLine == null) return result;
|
|
|
|
|
|
|
|
|
|
double DbHitDis = 0;
|
|
|
|
|
var ptDelete = new PointClass();
|
|
|
|
|
int LngPrtIdx = 0;
|
|
|
|
|
int segIndex = 0;
|
|
|
|
|
bool BoolHitRt = false;
|
|
|
|
|
bool Hittest = tempLine.HitTest(pPoint, 1, esriGeometryHitPartType.esriGeometryPartBoundary, ptDelete, ref DbHitDis, ref LngPrtIdx, ref segIndex, ref BoolHitRt);
|
|
|
|
|
if (Hittest)
|
|
|
|
|
{
|
|
|
|
|
ISegmentCollection newSegCol = (ISegmentCollection)result;
|
|
|
|
|
|
|
|
|
|
IGeometryCollection pGeocoll = tempLine as IGeometryCollection;
|
|
|
|
|
|
|
|
|
|
ISegmentCollection lineSegCol = (ISegmentCollection)pGeocoll.Geometry[LngPrtIdx];
|
|
|
|
|
ISegment segment = lineSegCol.Segment[segIndex];
|
|
|
|
|
if (position == 1)
|
|
|
|
|
{
|
|
|
|
|
if (lineSegCol.SegmentCount > segIndex + 1)
|
|
|
|
|
{
|
|
|
|
|
segment = lineSegCol.Segment[segIndex + 1];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
segment = lineSegCol.Segment[lineSegCol.SegmentCount - 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (position == -1)
|
|
|
|
|
{
|
|
|
|
|
if (segIndex == 0)
|
|
|
|
|
{
|
|
|
|
|
segment = lineSegCol.Segment[lineSegCol.SegmentCount - 1];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
segment = lineSegCol.Segment[segIndex - 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
newSegCol.AddSegment(segment, ref o, ref o);
|
|
|
|
|
newSegCol.SegmentsChanged();
|
|
|
|
|
result = newSegCol as IPolyline;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int GetSegmentIndex(IGeometry pGeo, IPoint pPoint, int position = 0)
|
|
|
|
|
{
|
|
|
|
|
int result = -1;
|
|
|
|
|
if (pGeo == null)
|
|
|
|
|
return result;
|
|
|
|
|
if (pGeo.IsEmpty)
|
|
|
|
|
return result;
|
|
|
|
|
object o = Type.Missing;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IHitTest tempLine = null;
|
|
|
|
|
if (pGeo.GeometryType == esriGeometryType.esriGeometryPolygon)
|
|
|
|
|
{
|
|
|
|
|
tempLine = (pGeo as ITopologicalOperator).Boundary as IHitTest;
|
|
|
|
|
}
|
|
|
|
|
else if (pGeo.GeometryType == esriGeometryType.esriGeometryPolyline)
|
|
|
|
|
{
|
|
|
|
|
tempLine = pGeo as IHitTest;
|
|
|
|
|
}
|
|
|
|
|
if (tempLine == null) return result;
|
|
|
|
|
|
|
|
|
|
double DbHitDis = 0;
|
|
|
|
|
var ptDelete = new PointClass();
|
|
|
|
|
int LngPrtIdx = 0;
|
|
|
|
|
int segIndex = 0;
|
|
|
|
|
bool BoolHitRt = false;
|
|
|
|
|
bool Hittest = tempLine.HitTest(pPoint, 1, esriGeometryHitPartType.esriGeometryPartBoundary, ptDelete, ref DbHitDis, ref LngPrtIdx, ref segIndex, ref BoolHitRt);
|
|
|
|
|
if (Hittest)
|
|
|
|
|
{
|
|
|
|
|
result = segIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取一条直线上的所有连续的线段
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pPoint"></param>
|
|
|
|
|
/// <param name="pLayer"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static List<IPolyline> GetSegmentsOfStraightLine(IPolyline pLine, IFeatureLayer pLayer)
|
|
|
|
|
{
|
|
|
|
|
List<IPolyline> result = new List<IPolyline>();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//result.Add(pLine);
|
|
|
|
|
IPoint centerPoint = new PointClass()
|
|
|
|
|
{
|
|
|
|
|
X = (pLine.FromPoint.X + pLine.ToPoint.X) / 2,
|
|
|
|
|
Y = (pLine.FromPoint.Y + pLine.ToPoint.Y) / 2
|
|
|
|
|
};
|
|
|
|
|
double angle = getAngle360(pLine.FromPoint, pLine.ToPoint);
|
|
|
|
|
List<IFeature> features = FeatureAPI.Identify(centerPoint, pLayer);
|
|
|
|
|
GetSegmentsOfStraightLine2(angle, centerPoint, pLayer, features, ref result);
|
|
|
|
|
|
|
|
|
|
IPolyline temp = new PolylineClass() { FromPoint = result[0].ToPoint, ToPoint = result[0].FromPoint };
|
|
|
|
|
centerPoint = GetExtendedLinePoint(temp, 0.1);
|
|
|
|
|
//centerPoint=
|
|
|
|
|
features = FeatureAPI.Identify(centerPoint, pLayer);
|
|
|
|
|
angle = getAngle360(temp.FromPoint, temp.ToPoint);
|
|
|
|
|
GetSegmentsOfStraightLine2(angle, centerPoint, pLayer, features, ref result);
|
|
|
|
|
//GetSegmentsOfStraightLine(angle, pLine.ToPoint, pLayer, ref result, 1);
|
|
|
|
|
//GetSegmentsOfStraightLine(angle, pLine.FromPoint, pLayer, ref result, -1);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
private static void GetSegmentsOfStraightLine2(double pAngle, IPoint pPoint, IFeatureLayer pLayer, List<IFeature> pFeatures, ref List<IPolyline> pReturnLines, int position = 0)
|
|
|
|
|
{
|
|
|
|
|
int num = pReturnLines.Count;
|
|
|
|
|
while (pFeatures.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
IGeometry geo = pFeatures[0].ShapeCopy;
|
|
|
|
|
pFeatures.Remove(pFeatures[0]);
|
|
|
|
|
|
|
|
|
|
IPolyline line = GetSegment(geo, pPoint);
|
|
|
|
|
if (line.Length == 0)
|
|
|
|
|
break;
|
|
|
|
|
double tempAngle = getAngle360(line.FromPoint, line.ToPoint);
|
|
|
|
|
while (Math.Abs(pAngle - tempAngle) < 3)
|
|
|
|
|
{
|
|
|
|
|
pFeatures.Clear();
|
|
|
|
|
if (pReturnLines.FirstOrDefault(f => f.Length == line.Length) != null)
|
|
|
|
|
break;
|
|
|
|
|
pReturnLines.Add(line);
|
|
|
|
|
pPoint = GetExtendedLinePoint(line, 0.1);
|
|
|
|
|
IPolyline tempLine = GetSegment(geo, pPoint);
|
|
|
|
|
if (tempLine.Length == 0)
|
|
|
|
|
break;
|
|
|
|
|
tempAngle = getAngle360(tempLine.FromPoint, tempLine.ToPoint);
|
|
|
|
|
if (Math.Abs(pAngle - tempAngle) > 0.1)
|
|
|
|
|
{
|
|
|
|
|
pPoint = GetExtendedLinePoint(line, 0.1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
line = tempLine;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (Math.Abs(Math.Abs(pAngle - tempAngle) - 180) < 3)
|
|
|
|
|
{
|
|
|
|
|
pFeatures.Clear();
|
|
|
|
|
if (pReturnLines.FirstOrDefault(f => f.Length == line.Length) != null)
|
|
|
|
|
break;
|
|
|
|
|
pReturnLines.Add(line);
|
|
|
|
|
IPolyline temp = new PolylineClass() { FromPoint = line.ToPoint, ToPoint = line.FromPoint };
|
|
|
|
|
pPoint = GetExtendedLinePoint(temp, 0.1);
|
|
|
|
|
IPolyline tempLine = GetSegment(geo, pPoint, -1);
|
|
|
|
|
if (tempLine.Length == 0)
|
|
|
|
|
break;
|
|
|
|
|
tempAngle = getAngle360(tempLine.FromPoint, tempLine.ToPoint);
|
|
|
|
|
if (Math.Abs(Math.Abs(pAngle - tempAngle) - 180) > 0.1)
|
|
|
|
|
{
|
|
|
|
|
pPoint = GetExtendedLinePoint(temp, 0.1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
line = tempLine;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (num != pReturnLines.Count)
|
|
|
|
|
{
|
|
|
|
|
List<IFeature> features = FeatureAPI.Identify(pPoint, pLayer);
|
|
|
|
|
GetSegmentsOfStraightLine2(pAngle, pPoint, pLayer, features, ref pReturnLines);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IPolyline GetLineByAngle(IPoint pPoint, double pAngle, IFeatureLayer pLayer)
|
|
|
|
|
{
|
|
|
|
|
IPolyline line = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
List<IFeature> features = FeatureAPI.Identify(pPoint, pLayer);
|
|
|
|
|
double referAngle = 360;
|
|
|
|
|
foreach (var item in features)
|
|
|
|
|
{
|
|
|
|
|
IPolyline tempLine = GetSegment(item.ShapeCopy, pPoint);
|
|
|
|
|
double tempAngle = getAngle360(tempLine.FromPoint, tempLine.ToPoint);
|
|
|
|
|
|
|
|
|
|
double angleDiff = Math.Round(Math.Abs(Math.Abs(tempAngle - pAngle) - 90), 2);
|
|
|
|
|
double angleDiff2 = Math.Round(Math.Abs(Math.Abs(Math.Abs(tempAngle - pAngle) - 180) - 90), 2);
|
|
|
|
|
bool pointOnSegment = IsPointOnSegment(pPoint, tempLine, 0.01);
|
|
|
|
|
if (referAngle > angleDiff && pointOnSegment)
|
|
|
|
|
{
|
|
|
|
|
referAngle = angleDiff;
|
|
|
|
|
line = tempLine;
|
|
|
|
|
}
|
|
|
|
|
if (referAngle > angleDiff2 && pointOnSegment)
|
|
|
|
|
{
|
|
|
|
|
referAngle = angleDiff2;
|
|
|
|
|
line = tempLine;
|
|
|
|
|
}
|
|
|
|
|
if (Math.Abs(pAngle - tempAngle) < 1 || Math.Abs(Math.Abs(pAngle - tempAngle) - 180) < 1)
|
|
|
|
|
{
|
|
|
|
|
tempLine = GetSegment(item.ShapeCopy, pPoint, 1);
|
|
|
|
|
pointOnSegment = IsPointOnSegment(pPoint, tempLine, 0.01);
|
|
|
|
|
double tempAngle2 = getAngle360(tempLine.FromPoint, tempLine.ToPoint);
|
|
|
|
|
angleDiff = Math.Abs(Math.Abs(tempAngle2 - pAngle) - 90);
|
|
|
|
|
angleDiff2 = Math.Abs(Math.Abs(Math.Abs(tempAngle2 - pAngle) - 180) - 90);
|
|
|
|
|
if (referAngle > angleDiff && pointOnSegment)
|
|
|
|
|
{
|
|
|
|
|
referAngle = angleDiff;
|
|
|
|
|
line = tempLine;
|
|
|
|
|
}
|
|
|
|
|
if (referAngle > angleDiff2 && pointOnSegment)
|
|
|
|
|
{
|
|
|
|
|
referAngle = angleDiff2;
|
|
|
|
|
line = tempLine;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (Math.Abs(pAngle - tempAngle) < 1 || Math.Abs(Math.Abs(pAngle - tempAngle) - 180) < 1)
|
|
|
|
|
{
|
|
|
|
|
tempLine = GetSegment(item.ShapeCopy, pPoint, -1);
|
|
|
|
|
pointOnSegment = IsPointOnSegment(pPoint, tempLine, 0.01);
|
|
|
|
|
double tempAngle2 = getAngle360(tempLine.FromPoint, tempLine.ToPoint);
|
|
|
|
|
angleDiff = Math.Abs(Math.Abs(tempAngle2 - pAngle) - 90);
|
|
|
|
|
angleDiff2 = Math.Abs(Math.Abs(Math.Abs(tempAngle2 - pAngle) - 180) - 90);
|
|
|
|
|
if (referAngle > angleDiff && pointOnSegment)
|
|
|
|
|
{
|
|
|
|
|
referAngle = angleDiff;
|
|
|
|
|
line = tempLine;
|
|
|
|
|
}
|
|
|
|
|
if (referAngle > angleDiff2 && pointOnSegment)
|
|
|
|
|
{
|
|
|
|
|
referAngle = angleDiff2;
|
|
|
|
|
line = tempLine;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
return line;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判断点pPoint,是否和pLine在同一条直线上
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pPoint"></param>
|
|
|
|
|
/// <param name="pLine"></param>
|
|
|
|
|
/// <param name="delta"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static bool IsPointOnLine(IPoint pPoint, IPolyline pLine, double delta)
|
|
|
|
|
{
|
|
|
|
|
double xa = pLine.FromPoint.X - pLine.ToPoint.X;
|
|
|
|
|
double ya = pLine.FromPoint.Y - pLine.ToPoint.Y;
|
|
|
|
|
double xb = pPoint.X - pLine.ToPoint.X;
|
|
|
|
|
double yb = pPoint.Y - pLine.ToPoint.Y;
|
|
|
|
|
return (Math.Abs(yb / xb - ya / xa) <= delta);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判断点pPoint,是否在pLine上
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pPoint"></param>
|
|
|
|
|
/// <param name="pLine"></param>
|
|
|
|
|
/// <param name="delta"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static bool IsPointOnSegment(IPoint pPoint, IPolyline pLine, double delta)
|
|
|
|
|
{
|
|
|
|
|
double xa = Math.Round(pLine.FromPoint.X - pLine.ToPoint.X, 5);
|
|
|
|
|
double ya = Math.Round(pLine.FromPoint.Y - pLine.ToPoint.Y, 5);
|
|
|
|
|
double xb = Math.Round(pPoint.X - pLine.ToPoint.X, 5);
|
|
|
|
|
double yb = Math.Round(pPoint.Y - pLine.ToPoint.Y, 5);
|
|
|
|
|
if (xb == 0 && yb == 0)
|
|
|
|
|
return true;
|
|
|
|
|
return (Math.Abs(yb / xb - ya / xa) < delta
|
|
|
|
|
&& Math.Round(Math.Min(pLine.ToPoint.X, pLine.FromPoint.X), 5) <= Math.Round(pPoint.X, 5)
|
|
|
|
|
&& Math.Round(Math.Max(pLine.ToPoint.X, pLine.FromPoint.X), 5) >= Math.Round(pPoint.X, 5)
|
|
|
|
|
&& Math.Round(Math.Min(pLine.ToPoint.Y, pLine.FromPoint.Y), 5) <= Math.Round(pPoint.Y, 5)
|
|
|
|
|
&& Math.Round(Math.Max(pLine.ToPoint.Y, pLine.FromPoint.Y), 5) >= Math.Round(pPoint.Y, 5));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//判断点是否在线上,在返回1,不在返回0
|
|
|
|
|
public static bool IsPointOnSegment(ICurve pSegment, IPoint Q)
|
|
|
|
|
{
|
|
|
|
|
double maxx, minx, maxy, miny;
|
|
|
|
|
|
|
|
|
|
maxx = pSegment.FromPoint.X > pSegment.ToPoint.X ? pSegment.FromPoint.X : pSegment.ToPoint.X; //矩形的右边长
|
|
|
|
|
minx = pSegment.FromPoint.X > pSegment.ToPoint.X ? pSegment.ToPoint.X : pSegment.FromPoint.X; //矩形的左边长
|
|
|
|
|
maxy = pSegment.FromPoint.Y > pSegment.ToPoint.Y ? pSegment.FromPoint.Y : pSegment.ToPoint.Y; //矩形的上边长
|
|
|
|
|
miny = pSegment.FromPoint.Y > pSegment.ToPoint.Y ? pSegment.ToPoint.Y : pSegment.FromPoint.Y; //矩形的下边长
|
|
|
|
|
|
|
|
|
|
if (((Q.X - pSegment.FromPoint.X) * (pSegment.ToPoint.Y - pSegment.FromPoint.Y) == (pSegment.ToPoint.X - pSegment.FromPoint.X) * (Q.Y - pSegment.FromPoint.Y)) && (Q.X >= minx && Q.X <= maxx) && (Q.Y >= miny && Q.Y <= maxy))
|
|
|
|
|
return true;
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
public static double getAngle(IPoint p1, IPoint p2)
|
|
|
|
|
{
|
|
|
|
|
//两点的x、y值
|
|
|
|
|
double x = p2.X - p1.X;
|
|
|
|
|
double y = p2.Y - p1.Y;
|
|
|
|
|
double hypotenuse = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
|
|
|
|
|
//斜边长度
|
|
|
|
|
double cos = x / hypotenuse;
|
|
|
|
|
double radian = Math.Acos(cos);
|
|
|
|
|
//求出弧度
|
|
|
|
|
double angle = 180 / (Math.PI / radian);
|
|
|
|
|
//用弧度算出角度
|
|
|
|
|
if (y < 0)
|
|
|
|
|
{
|
|
|
|
|
angle = -angle;
|
|
|
|
|
}
|
|
|
|
|
else if ((y == 0) && (x < 0))
|
|
|
|
|
{
|
|
|
|
|
angle = 180;
|
|
|
|
|
}
|
|
|
|
|
return angle;
|
|
|
|
|
}
|
|
|
|
|
public static double getAngle360(IPoint p1, IPoint p2)
|
|
|
|
|
{
|
|
|
|
|
//两点的x、y值
|
|
|
|
|
double x = p2.X - p1.X;
|
|
|
|
|
double y = p2.Y - p1.Y;
|
|
|
|
|
double hypotenuse = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
|
|
|
|
|
//斜边长度
|
|
|
|
|
double cos = y / hypotenuse;
|
|
|
|
|
double radian = Math.Acos(cos);
|
|
|
|
|
//求出弧度
|
|
|
|
|
double angle = 180 / (Math.PI / radian);
|
|
|
|
|
//用弧度算出角度
|
|
|
|
|
if (x < 0)
|
|
|
|
|
{
|
|
|
|
|
//angle = -angle;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (x > 0)
|
|
|
|
|
{
|
|
|
|
|
angle = 360 - angle;
|
|
|
|
|
}
|
|
|
|
|
return angle;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 垂足
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="line"></param>
|
|
|
|
|
/// <param name="pnt"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static IPoint GetCrossPnt(ICurve line, IPoint pnt)
|
|
|
|
|
{
|
|
|
|
|
double dAngle360 = getAngle360(line.FromPoint, line.ToPoint);
|
|
|
|
|
IPoint pt1 = line.FromPoint;
|
|
|
|
|
IPoint pt2 = line.ToPoint;
|
|
|
|
|
if (line.Length == 0)
|
|
|
|
|
return null;
|
|
|
|
|
if (pt1.X == pt2.X || dAngle360 == 180 || dAngle360 == 0)
|
|
|
|
|
{
|
|
|
|
|
IPoint ptCross = new PointClass();
|
|
|
|
|
ptCross.X = pt1.X;
|
|
|
|
|
ptCross.Y = pnt.Y;
|
|
|
|
|
return ptCross;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
double A = (pt1.Y - pt2.Y) / (pt1.X - pt2.X);
|
|
|
|
|
double B = (pt1.Y - A * pt1.X);
|
|
|
|
|
/// > 0 = ax +b -y; 对应垂线方程为 -x -ay + m = 0;(m为系数)
|
|
|
|
|
/// > A = a; B = b;
|
|
|
|
|
double m = pnt.X + A * pnt.Y;
|
|
|
|
|
/// 求两直线交点坐标
|
|
|
|
|
IPoint ptCross = new PointClass();
|
|
|
|
|
ptCross.X = ((m - A * B) / (A * A + 1));
|
|
|
|
|
ptCross.Y = (A * ptCross.X + B);
|
|
|
|
|
return ptCross;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IPolyline UnionLine(List<IPolyline> pGeometry)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (pGeometry == null || pGeometry.Count == 0)
|
|
|
|
|
return null;
|
|
|
|
|
if (pGeometry.Count == 1)
|
|
|
|
|
return pGeometry[0];
|
|
|
|
|
|
|
|
|
|
IPolyline baseGeo = pGeometry[0];
|
|
|
|
|
double angle1 = getAngle360(baseGeo.FromPoint, baseGeo.ToPoint);
|
|
|
|
|
//IGeometry target = FeatureCopy(baseFeature);
|
|
|
|
|
ITopologicalOperator2 topo = baseGeo as ITopologicalOperator2;
|
|
|
|
|
foreach (IPolyline f in pGeometry)
|
|
|
|
|
{
|
|
|
|
|
IPolyline tempLine = new PolylineClass();
|
|
|
|
|
if (f != baseGeo)
|
|
|
|
|
{
|
|
|
|
|
double angle2 = getAngle360(f.FromPoint, f.ToPoint);
|
|
|
|
|
if (Math.Abs(Math.Abs(angle1 - angle2) - 180) < 1)
|
|
|
|
|
{
|
|
|
|
|
tempLine.FromPoint = f.ToPoint;
|
|
|
|
|
tempLine.ToPoint = f.FromPoint;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tempLine = f;
|
|
|
|
|
}
|
|
|
|
|
ITopologicalOperator2 topolog = tempLine as ITopologicalOperator2;
|
|
|
|
|
topolog.Simplify();
|
|
|
|
|
topo.Simplify();
|
|
|
|
|
topo = topo.Union(tempLine) as ITopologicalOperator2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!topo.IsSimple)
|
|
|
|
|
{
|
|
|
|
|
topo.Simplify();
|
|
|
|
|
}
|
|
|
|
|
//target.Shape = topo as IGeometry;
|
|
|
|
|
return topo as IPolyline;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double GetPointOnLineLeftOrRight(IPolyline line, IPoint pnt)
|
|
|
|
|
{
|
|
|
|
|
return (line.FromPoint.X - pnt.X) * (line.ToPoint.Y - pnt.Y) - (line.FromPoint.Y - pnt.Y) * (line.ToPoint.X - pnt.X);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 重构Geometry
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pGeometry">原始Geometry</param>
|
|
|
|
|
/// <returns>重构后的Geometry</returns>
|
|
|
|
|
public static IGeometry ResetGeometry(IGeometry pGeometry, Point pPoint = null)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (pGeometry == null) return null;
|
|
|
|
|
//外接矩形左上角的点
|
|
|
|
|
Point UpperLeft = pPoint;
|
|
|
|
|
if (UpperLeft == null)
|
|
|
|
|
{
|
|
|
|
|
UpperLeft = new Point();
|
|
|
|
|
UpperLeft.X = pGeometry.Envelope.XMin;
|
|
|
|
|
UpperLeft.Y = pGeometry.Envelope.YMax;
|
|
|
|
|
UpperLeft.SpatialReference = pGeometry.SpatialReference;
|
|
|
|
|
}
|
|
|
|
|
ITopologicalOperator topologicalOperator = pGeometry as ITopologicalOperator;
|
|
|
|
|
if (topologicalOperator == null) return null;
|
|
|
|
|
topologicalOperator.Simplify();
|
|
|
|
|
//外环图形
|
|
|
|
|
GeometryBag ExterGeometryBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).ExteriorRingBag as GeometryBag;
|
|
|
|
|
if (ExterGeometryBag == null) return null;
|
|
|
|
|
IGeometryCollection ExterRingGeometryCollection = ExterGeometryBag as IGeometryCollection;
|
|
|
|
|
IGeometryCollection geometry = new ESRI.ArcGIS.Geometry.PolygonClass() as IGeometryCollection;
|
|
|
|
|
//List<IGeometry> geometry = new List<IGeometry>();
|
|
|
|
|
for (int g = 0; g < ExterRingGeometryCollection.GeometryCount; g++)
|
|
|
|
|
{
|
|
|
|
|
IGeometry ExterGeometry = ExterRingGeometryCollection.get_Geometry(g);
|
|
|
|
|
IGeometry newGeo = ResetPointCollection(ExterGeometry, UpperLeft) as IGeometry;
|
|
|
|
|
if (newGeo == null) continue;
|
|
|
|
|
geometry.AddGeometry(newGeo);
|
|
|
|
|
|
|
|
|
|
//内环图形
|
|
|
|
|
IGeometryBag InteriorBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).get_InteriorRingBag(ExterGeometry as IRing);
|
|
|
|
|
if (InteriorBag == null) continue;
|
|
|
|
|
IGeometryCollection InteriorRingGeometryCollection = InteriorBag as IGeometryCollection;
|
|
|
|
|
if (InteriorRingGeometryCollection == null) continue;
|
|
|
|
|
for (int IG = 0; IG < InteriorRingGeometryCollection.GeometryCount; IG++)
|
|
|
|
|
{
|
|
|
|
|
IGeometry interiorGeo = InteriorRingGeometryCollection.get_Geometry(IG);
|
|
|
|
|
if (interiorGeo == null) continue;
|
|
|
|
|
IGeometry newInteriorGeo = ResetPointCollection(interiorGeo, UpperLeft) as IGeometry;
|
|
|
|
|
if (newInteriorGeo == null) continue;
|
|
|
|
|
geometry.AddGeometry(newInteriorGeo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//ITopologicalOperator iTopological = geometry as ITopologicalOperator;
|
|
|
|
|
//if (iTopological == null) return null;
|
|
|
|
|
//iTopological.Simplify();
|
|
|
|
|
return geometry as IGeometry;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 界址点重新排列
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pGeo">原始图形</param>
|
|
|
|
|
/// <param name="pUpperLeftPoint">原始Geometry外接矩形左上角的点</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static IPointCollection ResetPointCollection(IGeometry pGeo, Point pUpperLeftPoint)
|
|
|
|
|
{
|
|
|
|
|
if (pGeo == null) return null;
|
|
|
|
|
IPointCollection pointCollection = pGeo as IPointCollection;
|
|
|
|
|
if (pointCollection == null) return null;
|
|
|
|
|
//图形的起始点
|
|
|
|
|
IPoint startPoint = null;
|
|
|
|
|
//图形的起始点在原图形中的顺序号
|
|
|
|
|
int index = 0;
|
|
|
|
|
double length = double.MaxValue;
|
|
|
|
|
#region 获取图形的起始点
|
|
|
|
|
for (int p = 0; p < pointCollection.PointCount; p++)
|
|
|
|
|
{
|
|
|
|
|
IPoint tempPoint = pointCollection.get_Point(p);
|
|
|
|
|
Polyline line = new PolylineClass();
|
|
|
|
|
line.AddPoint(pUpperLeftPoint);
|
|
|
|
|
line.AddPoint(tempPoint);
|
|
|
|
|
|
|
|
|
|
if (length > (line as IPolyline).Length)
|
|
|
|
|
{
|
|
|
|
|
length = (line as IPolyline).Length;
|
|
|
|
|
startPoint = tempPoint;
|
|
|
|
|
index = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
ESRI.ArcGIS.Geometry.IPointCollection poins = new ESRI.ArcGIS.Geometry.Ring() as ESRI.ArcGIS.Geometry.IPointCollection;
|
|
|
|
|
#region 按照新的起始点重新排列图形
|
|
|
|
|
for (int i = 0; i < pointCollection.PointCount; i++)
|
|
|
|
|
{
|
|
|
|
|
IPoint point = null;
|
|
|
|
|
if (index + i < pointCollection.PointCount)
|
|
|
|
|
{
|
|
|
|
|
point = pointCollection.get_Point(index + i);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (index + i == pointCollection.PointCount)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
point = pointCollection.get_Point(Math.Abs(pointCollection.PointCount - (index + i)));
|
|
|
|
|
}
|
|
|
|
|
point.SpatialReference = pGeo.SpatialReference;
|
|
|
|
|
poins.AddPoint(point);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
startPoint.SpatialReference = pGeo.SpatialReference;
|
|
|
|
|
if (index != 0)
|
|
|
|
|
poins.AddPoint(startPoint);
|
|
|
|
|
return poins;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|