/// <summary> /// 计算绕射路径长度 /// </summary> /// <param name="buildingLayer">建筑物图层</param> /// <param name="sourcePoint">声源点</param> /// <param name="receivePoint">接收点</param> /// <param name="line">直达路径</param> /// <returns>绕射路径长度</returns> private List <Geometry> diffractionLine2(Layer buildingLayer, Geometry sourcePoint, Geometry receivePoint, Geometry line) { List <Geometry> diffLineList = new List <Geometry>(); //绕射声线 Geometry[] diffractionLine = new Geometry[3]; Feature bFeature = null; //直达声线上的建筑物,并选取最高建筑物 List <Geometry> buildingList = new List <Geometry>(); double buildingheigh = 0; Geometry buildingtop = null; while ((bFeature = buildingLayer.GetNextFeature()) != null) { if (buildingheigh < bFeature.GetFieldAsDouble("HEIGHT_BU")) { buildingtop = bFeature.GetGeometryRef(); } buildingList.Add(bFeature.GetGeometryRef()); } if (buildingList.Count > 0) { Geometry upLinePoint = new Geometry(wkbGeometryType.wkbMultiPoint); Geometry belowLinePoint = new Geometry(wkbGeometryType.wkbMultiPoint); double k = (sourcePoint.GetY(0) - receivePoint.GetY(0)) / (sourcePoint.GetX(0) - receivePoint.GetX(0)); double b = sourcePoint.GetY(0) - k * sourcePoint.GetX(0); Geometry upLine = new Geometry(wkbGeometryType.wkbLinearRing); Geometry belowLine = new Geometry(wkbGeometryType.wkbLinearRing); foreach (Geometry item in buildingList) { Geometry buildingring = item.Boundary(); for (int i = 0; i < buildingring.GetPointCount() - 1; i++) { Geometry pointb = GeometryCreate.createPoint3D(buildingring.GetX(i), buildingring.GetY(i), buildingring.GetZ(i)); if (pointb.GetY(0) < k * pointb.GetX(0) + b) { belowLinePoint.AddGeometry(pointb); } else if (buildingring.GetY(i) > k * buildingring.GetX(i) + b) { upLinePoint.AddGeometry(pointb); } } SortedList <double, Geometry> sList = new SortedList <double, Geometry>(); if (upLinePoint.GetGeometryCount() > 0) { upLine.AddPoint(sourcePoint.GetX(0), sourcePoint.GetY(0), sourcePoint.GetZ(0)); sList.Clear(); for (int i = 0; i < upLinePoint.GetGeometryCount(); i++) { sList.Add(sourcePoint.Distance(upLinePoint.GetGeometryRef(i)), upLinePoint.GetGeometryRef(i)); } foreach (KeyValuePair <double, Geometry> items in sList) { upLine.AddPoint(items.Value.GetX(0), items.Value.GetY(0), items.Value.GetZ(0)); } upLine.AddPoint(receivePoint.GetX(0), receivePoint.GetY(0), receivePoint.GetZ(0)); upLine.CloseRings(); } if (belowLinePoint.GetGeometryCount() > 0) { belowLine.AddPoint(sourcePoint.GetX(0), sourcePoint.GetY(0), sourcePoint.GetZ(0)); sList.Clear(); for (int i = 0; i < belowLinePoint.GetGeometryCount(); i++) { sList.Add(sourcePoint.Distance(belowLinePoint.GetGeometryRef(i)), belowLinePoint.GetGeometryRef(i)); } foreach (KeyValuePair <double, Geometry> items in sList) { belowLine.AddPoint(items.Value.GetX(0), items.Value.GetY(0), items.Value.GetZ(0)); } belowLine.AddPoint(receivePoint.GetX(0), receivePoint.GetY(0), receivePoint.GetZ(0)); belowLine.CloseRings(); } } Geometry area; Geometry diffline; Geometry convexHull; if (upLine.GetPointCount() > 3) { diffline = new Geometry(wkbGeometryType.wkbLineString); area = new Geometry(wkbGeometryType.wkbPolygon); area.AddGeometry(upLine); convexHull = area.ConvexHull().Boundary(); for (int i = 0; i < convexHull.GetPointCount(); i++) { diffline.AddPoint(convexHull.GetX(i), convexHull.GetY(i), convexHull.GetZ(i)); } diffLineList.Add(diffline.Difference(line)); } if (belowLine.GetPointCount() > 3) { area = new Geometry(wkbGeometryType.wkbPolygon); area.AddGeometry(belowLine); convexHull = area.ConvexHull().Boundary(); diffline = new Geometry(wkbGeometryType.wkbLineString); for (int i = 0; i < convexHull.GetPointCount(); i++) { diffline.AddPoint(convexHull.GetX(i), convexHull.GetY(i), convexHull.GetZ(i)); } diffLineList.Add(diffline.Difference(line)); } } return(diffLineList); }
/// <summary> /// 绕射声线 /// </summary> /// <param name="buildingLayer">建筑物图层</param> /// <param name="sourcePoint">声源点</param> /// <param name="receivePoint">接收点</param> /// <param name="line">直达声线</param> /// <returns>绕射声线</returns> private Geometry[] diffractionLine(Layer buildingLayer, Geometry sourcePoint, Geometry receivePoint, Geometry line) { //左绕射路径点集 SortedList <double, Geometry> leftPoints = new SortedList <double, Geometry>(); //右绕射路径点集 SortedList <double, Geometry> rightPoints = new SortedList <double, Geometry>(); //直达路径方程参数 double k = (sourcePoint.GetY(0) - receivePoint.GetY(0)) / (sourcePoint.GetX(0) - receivePoint.GetX(0)); double b = sourcePoint.GetY(0) - k * sourcePoint.GetX(0); //最高建筑物 double heighttemp = 0; Geometry building = null; Feature bFeature = null; try { //加入起始点 rightPoints.Add(0, sourcePoint); leftPoints.Add(0, sourcePoint); while ((bFeature = buildingLayer.GetNextFeature()) != null) { Geometry buildingring = bFeature.GetGeometryRef().ConvexHull().GetGeometryRef(0); double height = bFeature.GetFieldAsDouble("HEIGHT_BU"); //选择最高的建筑物 if (heighttemp < height) { building = bFeature.GetGeometryRef(); } //构建左右绕射点集 for (int i = 0; i < buildingring.GetPointCount() - 1; i++) { Geometry point = GeometryCreate.createPoint3D(buildingring.GetX(i), buildingring.GetY(i), height); if (point.GetY(0) < k * point.GetX(0) + b) { rightPoints.Add(sourcePoint.Distance(point), point); } else if (buildingring.GetY(i) > k * buildingring.GetX(i) + b) { leftPoints.Add(sourcePoint.Distance(point), point); } } } //加入终点 rightPoints.Add(sourcePoint.Distance(receivePoint), receivePoint); leftPoints.Add(sourcePoint.Distance(receivePoint), receivePoint); } catch (Exception e) { Console.WriteLine(e.Message); } Geometry[] diffLine = new Geometry[3]; if (heighttemp <= receivePoint.GetZ(0) || heighttemp <= sourcePoint.GetZ(0)) { diffLine[0] = null; diffLine[1] = null; diffLine[2] = null; } else { diffLine[0] = getUpdiffLine(building, line, heighttemp); diffLine[1] = flankdiffLine(leftPoints, line); diffLine[2] = flankdiffLine(rightPoints, line); } return(diffLine); }
private List <Geometry> getWidth(Layer buildingLayer, Geometry sourcePoint, Geometry receivePoint, Geometry line) { topBuilding st = new topBuilding(); st.width = 0; st.high = 0; st.tophigh = null; st.topwidth = null; // buildingLayer.ResetReading(); Feature bFeature = null; OSGeo.OGR.Envelope env = new OSGeo.OGR.Envelope(); while ((bFeature = buildingLayer.GetNextFeature()) != null) { bFeature.GetGeometryRef().GetEnvelope(env); double width = Math.Sqrt((env.MaxX - env.MinX) * (env.MaxX - env.MinX) + (env.MaxY - env.MinY) * (env.MaxY - env.MinY)); if (st.width < width) { st.width = width; st.topwidth = bFeature.GetGeometryRef(); } if (st.high < bFeature.GetFieldAsDouble("HEIGHT_G")) { st.high = bFeature.GetFieldAsDouble("HEIGHT_G"); st.tophigh = bFeature.GetGeometryRef(); } } List <Geometry> list = null; //list.Add(line); if (st.topwidth != null) { list = new List <Geometry>(); SortedDictionary <double, Geometry> upLinePoint = new SortedDictionary <double, Geometry>(); SortedDictionary <double, Geometry> belowLinePoint = new SortedDictionary <double, Geometry>(); double k = (sourcePoint.GetY(0) - receivePoint.GetY(0)) / (sourcePoint.GetX(0) - receivePoint.GetX(0)); double b = sourcePoint.GetY(0) - k * sourcePoint.GetX(0); Geometry buildingring = new Geometry(wkbGeometryType.wkbLinearRing); st.topwidth.GetEnvelope(env); buildingring.AddPoint(env.MinX, env.MinY, 0); buildingring.AddPoint(env.MaxX, env.MinY, 0); buildingring.AddPoint(env.MaxX, env.MaxY, 0); buildingring.AddPoint(env.MinX, env.MaxY, 0); for (int i = 0; i < buildingring.GetPointCount(); i++) { Geometry point = GeometryCreate.createPoint3D(buildingring.GetX(i), buildingring.GetY(i), buildingring.GetZ(i)); if (point.GetY(0) < k * point.GetX(0) + b) { belowLinePoint.Add(sourcePoint.Distance(point), point); } else if (buildingring.GetY(i) > k * buildingring.GetX(i) + b) { upLinePoint.Add(sourcePoint.Distance(point), point); } } Geometry uoLine = new Geometry(wkbGeometryType.wkbLineString); Geometry belowLine = new Geometry(wkbGeometryType.wkbLineString); if (upLinePoint.Count > 0) { uoLine.AddPoint(sourcePoint.GetX(0), sourcePoint.GetY(0), sourcePoint.GetZ(0)); foreach (KeyValuePair <double, Geometry> item in upLinePoint) { uoLine.AddPoint(item.Value.GetX(0), item.Value.GetY(0), item.Value.GetZ(0)); } uoLine.AddPoint(receivePoint.GetX(0), receivePoint.GetY(0), receivePoint.GetZ(0)); } if (belowLinePoint.Count > 0) { belowLine.AddPoint(sourcePoint.GetX(0), sourcePoint.GetY(0), sourcePoint.GetZ(0)); foreach (KeyValuePair <double, Geometry> item in belowLinePoint) { belowLine.AddPoint(item.Value.GetX(0), item.Value.GetY(0), item.Value.GetZ(0)); } belowLine.AddPoint(receivePoint.GetX(0), receivePoint.GetY(0), receivePoint.GetZ(0)); } list.Add(uoLine); list.Add(belowLine); } return(list); }