public static void drawSector(LTE.Geometric.Point p, double fromAngle, double toAngle, double radius) { IPoint centralPoint = GeometryUtilities.ConstructPoint2D(p.X, p.Y); double arithmeticToAngle = GeometricUtilities.GetRadians(GeometricUtilities.ConvertGeometricArithmeticAngle(toAngle)); double angle = (toAngle - fromAngle) % 360; bool isCCW = true; if (angle > 180) { angle = 360 - angle; isCCW = false; } if (angle == 0) { angle = 360; } double arcDistance = radius * GeometricUtilities.GetRadians(angle); IPoint fromPoint = GeometryUtilities.ConstructPoint_AngleDistance(centralPoint, arithmeticToAngle, radius); ICircularArc circularArc = GeometryUtilities.ConstructCircularArc(centralPoint, fromPoint, isCCW, arcDistance); IPoint toPoint = circularArc.ToPoint; ISegment fromSegment = GeometryUtilities.ConstructLine(centralPoint, fromPoint) as ISegment; ISegment toSegment = GeometryUtilities.ConstructLine(toPoint, centralPoint) as ISegment; ISegment[] segmentArray = new ISegment[] { fromSegment, circularArc as ISegment, toSegment }; IGeometryCollection polygon = GeometryUtilities.ConstructPolygon(segmentArray); //画扇形 IGraphicsContainer3D graphicsContainer3D = GISMapApplication.Instance.GetLayer(LayerNames.Rays) as IGraphicsContainer3D; IPolygonElement polygonElement = new PolygonElementClass(); IElement element = polygonElement as IElement; element.Geometry = polygon as IGeometry; graphicsContainer3D.AddElement(element); }
//MessageBox.Show(this, "入库完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); /// <summary> /// 用目标干扰源计算方位角 /// </summary> /// <param name="dtinfo"></param> /// <returns></returns> private Boolean CompleteAzimuthVir(DataTable dtinfo) { Hashtable ht = new Hashtable(); ht["BtsName"] = this.virname; DataTable tbcell = IbatisHelper.ExecuteQueryForDataTable("GettbSource", ht); if (tbcell.Rows[0]["x"] == DBNull.Value || tbcell.Rows[0]["y"] == DBNull.Value) { Debug.WriteLine("未找到对应的小区地理信息"); return(false); } double endx = Convert.ToDouble(tbcell.Rows[0]["x"]); double endy = Convert.ToDouble(tbcell.Rows[0]["y"]); Point end = new Point(endx, endy, 0); tb.Clear(); for (int i = 0; i < dtinfo.Rows.Count; i++) { Debug.WriteLine(i); double x = Convert.ToInt32(dtinfo.Rows[i]["x"]); double y = Convert.ToInt32(dtinfo.Rows[i]["y"]); Point start = new Point(x, y, 0); double azimuth = GeometricUtilities.getPolarCoord(start, end).theta / Math.PI * 180; azimuth = GeometricUtilities.ConvertGeometricArithmeticAngle(azimuth + 1); DataRow thisrow = tb.NewRow(); thisrow["fromName"] = this.virname; thisrow["x"] = x; thisrow["y"] = y; thisrow["ReceivePW"] = dtinfo.Rows[i]["ReceivePW"]; thisrow["CI"] = dtinfo.Rows[i]["CI"]; thisrow["Azimuth"] = azimuth; thisrow["Distance"] = distanceXY(start.X, start.Y, end.X, end.Y) + 300; tb.Rows.Add(thisrow); } return(true); }
public double calcDirectRayStrength(double fromX, double fromY, double fromZ, double toX, double toY, double toZ, double EIRP, double nata) { double rayAzimuth, rayInclination; LTE.Geometric.Point SourcePoint = new Point(fromX, fromY, fromZ); LTE.Geometric.Point crossWithGround = new Point(toX, toY, toZ); double distance = Math.Sqrt(Math.Pow(fromX - toX, 2) + Math.Pow(fromY - toY, 2) + Math.Pow(fromZ - toZ, 2)); //double L = 32.45 + 20 * Math.Log(nata) + 20 * Math.Log(distance/1000.0); //return EIRP - L; GeometricUtilities.getAzimuth_Inclination(SourcePoint, crossWithGround, out rayAzimuth, out rayInclination); double amendCoeDis = 0.3; //直射校正系数 double dbmPt1 = dbmPt(EIRP, 0, Math.Abs(rayInclination)); //double dbmPt1 = EIRP; double wPt = convertdbm2w(dbmPt1); nata = 300.0 / (1085 + 0.2 * (nata - 511)); double receivePwr = Math.Pow(nata / (4 * Math.PI), 2) * (wPt / Math.Pow(distance, (2 + amendCoeDis))); double ReceivedPower_dbm = convertw2dbm(receivePwr); return(ReceivedPower_dbm); }
public NodeInfo(Point PointOfIncidence, Point CrossPoint, RayType rayType, double angle) { this.distance = GeometricUtilities.GetDistanceOf3DPoints(PointOfIncidence, CrossPoint); this.rayType = rayType; this.Angle = angle; }
/// <summary> /// 获取扇形与地面网格相交的网格中心点 /// </summary> /// <param name="p"></param> /// <param name="fromAngle"></param> /// <param name="toAngle"></param> /// <param name="radius"></param> /// <returns></returns> public static List <LTE.Geometric.Point> getSelectedGridsCenterPoints(LTE.Geometric.Point p, double fromAngle, double toAngle, double radius) { IPoint centralPoint = GeometryUtilities.ConstructPoint2D(p.X, p.Y); double arithmeticToAngle = GeometricUtilities.GetRadians(GeometricUtilities.ConvertGeometricArithmeticAngle(toAngle)); double angle = (toAngle - fromAngle) % 360; bool isCCW = true; if (angle > 180) { angle = 360 - angle; isCCW = false; } if (angle == 0) { angle = 360; } double arcDistance = radius * GeometricUtilities.GetRadians(angle); IPoint fromPoint = GeometryUtilities.ConstructPoint_AngleDistance(centralPoint, arithmeticToAngle, radius); ICircularArc circularArc = GeometryUtilities.ConstructCircularArc(centralPoint, fromPoint, isCCW, arcDistance); IPoint toPoint = circularArc.ToPoint; ISegment fromSegment = GeometryUtilities.ConstructLine(centralPoint, fromPoint) as ISegment; ISegment toSegment = GeometryUtilities.ConstructLine(toPoint, centralPoint) as ISegment; ISegment[] segmentArray = new ISegment[] { fromSegment, circularArc as ISegment, toSegment }; IGeometryCollection polygon = GeometryUtilities.ConstructPolygon(segmentArray); //画扇形 //IGraphicsContainer3D graphicsContainer3D = GISMapApplication.Instance.GetLayer(LayerNames.Rays) as IGraphicsContainer3D; //IPolygonElement polygonElement = new PolygonElementClass(); //IElement element = polygonElement as IElement; //element.Geometry = polygon as IGeometry; //graphicsContainer3D.AddElement(element); IGeometry pGeometry = GeometryUtilities.ConvertProjToGeo(polygon as IGeometry); //地面网格图层是经纬度 IFeatureLayer groundFeatureLayer = GISMapApplication.Instance.GetLayer(LayerNames.GroundGrids) as IFeatureLayer; IFeatureClass groundFeatureClass = groundFeatureLayer.FeatureClass; ISpatialFilter spatialFilter = new SpatialFilterClass(); spatialFilter.Geometry = pGeometry; //spatialFilter.Geometry = pPolygon as IGeometry; spatialFilter.GeometryField = groundFeatureClass.ShapeFieldName; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; IFeatureCursor featureCursor = groundFeatureClass.Search(spatialFilter, false); int CenterXIndex = groundFeatureClass.Fields.FindField("CenterX"); int CenterYIndex = groundFeatureClass.Fields.FindField("CenterY"); int xindex = groundFeatureClass.Fields.FindField("GXID"); int yindex = groundFeatureClass.Fields.FindField("GYID"); IFeature pFeature; List <LTE.Geometric.Point> centerPoints = new List <LTE.Geometric.Point>(); while ((pFeature = featureCursor.NextFeature()) != null) { int gxid = (int)pFeature.get_Value(xindex); int gyid = (int)pFeature.get_Value(yindex); double centerX = double.Parse(pFeature.get_Value(CenterXIndex).ToString()); double centerY = double.Parse(pFeature.get_Value(CenterYIndex).ToString()); IPoint crossWithGround = GeometryUtilities.ConstructPoint3D(centerX, centerY, 0); double lng = crossWithGround.X, lat = crossWithGround.Y; crossWithGround = (IPoint)GeometryUtilities.ConvertGeoToProj(crossWithGround as IGeometry); centerPoints.Add(new LTE.Geometric.Point(crossWithGround.X, crossWithGround.Y, crossWithGround.Z)); } System.Runtime.InteropServices.Marshal.ReleaseComObject(featureCursor); System.Runtime.InteropServices.Marshal.ReleaseComObject(groundFeatureLayer); System.Runtime.InteropServices.Marshal.ReleaseComObject(groundFeatureClass); System.Runtime.InteropServices.Marshal.ReleaseComObject(spatialFilter); System.Runtime.InteropServices.Marshal.ReleaseThreadCache(); return(centerPoints); }
/// <summary> /// 相对原点的多边形边界 /// </summary> /// <param name="source"></param> /// <param name="vertex"></param> /// <param name="mintheta"></param> /// <param name="maxtheta"></param> /// <param name="distance"></param> /// <returns></returns> public static bool getBoundPointIndex(Point source, List <Point> vertex, ref TriangleBound tb) { bool isEdge; int startIndex = 0; //原点是否在多边形内部 if (GeometricUtilities.PointInPolygon(vertex.ToArray(), source, out isEdge, ref startIndex)) { return(false); } tb.maxIndex = -1; tb.maxTheta = -1; tb.minIndex = int.MaxValue - 500; tb.minTheta = 1000; tb.totalVertex = vertex.Count; double theta; Dictionary <int, Polar> tmp = new Dictionary <int, Polar>(); int cnt = vertex.Count; Polar p; //求相对原点的极坐标,根据theta角判断边界 for (int i = 0; i < cnt; i++) { p = GeometricUtilities.getPolarCoord(source, vertex[i]); theta = p.theta; tmp.Add(i, p); if (theta < tb.minTheta) { tb.minIndex = i; tb.minTheta = theta; } if (theta > tb.maxTheta) { tb.maxIndex = i; tb.maxTheta = theta; } } //说明多边形与x轴相交 if (tb.maxTheta - tb.minTheta > Math.PI) { double th; tb.maxIndex = -1; tb.maxTheta = -1; tb.minIndex = int.MaxValue - 500; tb.minTheta = 1000; foreach (var kv in tmp) { th = kv.Value.theta; if (th < Math.PI) { if (th > tb.maxTheta) { tb.maxIndex = kv.Key; tb.maxTheta = th; } } else if (th < tb.minTheta) { tb.minIndex = kv.Key; tb.minTheta = th; } } } tb.stob = tmp[tb.minIndex].r > tmp[(tb.minIndex + 1) % cnt].r; return(true); }
/// <summary> /// 求比基准高度高的建筑物遮挡距离和角度范围 /// </summary> /// <param name="source"></param> /// <param name="buildingids"></param> /// <param name="baseHeight"></param> /// <returns></returns> /// /// <summary> /// 建筑物遮挡关系(极坐标系) /// </summary> /* * public struct TriangleBound * { * //建筑物id * public int buildingid; * public int totalVertex; * //角度最小的边界点的索引 * public int minIndex; * public double minTheta; * //角度最大的边界点的索引 * public int maxIndex; * public double maxTheta; * //离原点较近的边是否是从minIndex到maxIndex * public bool stob; * //原点与建筑物的距离(近似值) * public double distance; * //违背遮挡高度 * public double baseHeight; * //建筑物高度 * public double height; * } */ public static List <TriangleBound> getShelterDisAndAngle(Point source, List <int> buildingids, double baseHeight) { Dictionary <int, TriangleBound> bdis = new Dictionary <int, TriangleBound>(); TriangleBound tb = new TriangleBound(); double height, sz = baseHeight, altitude; int bid; for (int i = 0, cnt = buildingids.Count; i < cnt; i++) { bid = buildingids[i]; height = buildingHeight[bid]; altitude = buildingAltitude[bid]; // 地形 if (height > sz) { tb = new TriangleBound(); tb.height = height; tb.baseHeight = altitude; // 地形 tb.distance = GeometricUtilities.GetDistanceOf2DPoints(source, buildingCenter[bid]); bdis[bid] = tb; } } List <KeyValuePair <int, TriangleBound> > bdisOrder = bdis.OrderBy(c => c.Value.distance).ToList(); List <TriangleBound> ret = new List <TriangleBound>(); foreach (var kv in bdisOrder) { bid = kv.Key; tb = bdis[bid]; // 得到每个建筑物相对于原点的最小、最大角度 if (getBoundPointIndex(source, buildingVertex[bid], ref tb)) { tb.buildingid = bid; ret.Add(tb); } } //去掉一些遮挡的 double min1, max1, min2, max2; for (int i = ret.Count - 1; i > 0; i--) { for (int j = i - 1; j >= 0; j--) { min1 = ret[j].minTheta; max1 = ret[j].maxTheta; min2 = ret[i].minTheta; max2 = ret[i].maxTheta; // j比i范围广,且在i前面 if (max2 < max1 && min2 > min1) { if (ret[j].height >= ret[i].height) // j完全挡住了i { ret.RemoveAt(i); break; } else if (ret[j].height > ret[i].baseHeight) // j部分遮住了i { TriangleBound tt = ret[i]; // 更新i的可见度 tt.baseHeight = Math.Max(ret[j].height, tt.baseHeight); // 地形 ret[i] = tt; } } } } return(ret); }
private Boolean CompleteAzimuth(DataTable dtinfo) { tb.Clear(); double avgx = 0, avgy = 0; for (int i = 0; i < dtinfo.Rows.Count; i++) { double x = Convert.ToDouble(dtinfo.Rows[i]["x"]); double y = Convert.ToDouble(dtinfo.Rows[i]["y"]); avgx += x; avgy += y; } avgx /= dtinfo.Rows.Count; avgy /= dtinfo.Rows.Count; Debug.WriteLine("路测中点:x" + avgx + "路测中点:x" + avgy); Geometric.Point endavg = new Geometric.Point(avgx, avgy, 0); double minx = double.MaxValue, miny = double.MaxValue, maxx = double.MinValue, maxy = double.MinValue; for (int i = 0; i < dtinfo.Rows.Count; i++) { //Debug.WriteLine(i); double x = Convert.ToDouble(dtinfo.Rows[i]["x"]); double y = Convert.ToDouble(dtinfo.Rows[i]["y"]); if (x < minx) { minx = x; } if (x > maxx) { maxx = x; } if (y < miny) { miny = y; } if (y > maxy) { maxy = y; } Geometric.Point start = new Geometric.Point(x, y, 0); double aziavg = LTE.Geometric.GeometricUtilities.getPolarCoord(start, endavg).theta / Math.PI * 180; aziavg = GeometricUtilities.ConvertGeometricArithmeticAngle(aziavg + 1); Debug.WriteLine("路测中点计算角度:" + aziavg); DataRow thisrow = tb.NewRow(); thisrow["fromName"] = this.virname; thisrow["x"] = x; thisrow["y"] = y; thisrow["ReceivePW"] = dtinfo.Rows[i]["ReceivePW"]; thisrow["CI"] = dtinfo.Rows[i]["CI"]; thisrow["Azimuth"] = aziavg; thisrow["Distance"] = distanceXY(start.X, start.Y, endavg.X, endavg.Y) + 300; tb.Rows.Add(thisrow); } if (maxx - minx < 100 || maxy - maxx < 100) { tb.Clear(); return(false); } return(true); }