/*! * 功能 过线外一点的发现与已知线交点 * 版本号 1.0 * 作者 樊晓剑 * 创建时间 2016年7月5日 * 参数 * 修改时间 */ public static Geometry getPoint(Geometry line, Geometry point) { int count = line.GetPointCount() - 1; double k = (line.GetY(count) - line.GetY(0)) / (line.GetX(count) - line.GetX(0)); double b = line.GetY(0) - k * line.GetX(0); double k1 = -1 / k; double b1 = point.GetY(0) - k1 * point.GetX(0); double x = (b1 - b) / (k - k1); double y = k * x + b; return(GeometryCreate.createPoint(x, y)); }
private List <Geometry> direct(Layer buildings, Layer sources, Geometry receivePoint, double distance) { sources.ResetReading(); double length = 0; Geometry receiveBuffer = receivePoint.Buffer(distance, 30); sources.SetSpatialFilter(receiveBuffer); Feature sFeature = null; Geometry sourcePoint = null; Geometry line = null; Queue <Feature> diffbuildings = new Queue <Feature>(); List <Geometry> geos = new List <Geometry>(); while ((sFeature = sources.GetNextFeature()) != null) { sourcePoint = sFeature.GetGeometryRef(); line = GeometryCreate.createLineString3D(sourcePoint.GetX(0), sourcePoint.GetY(0), sourcePoint.GetZ(0), receivePoint.GetX(0), receivePoint.GetY(0), receivePoint.GetZ(0)); buildings.SetSpatialFilter(line); // List<Geometry> a = getWidth(buildings, sourcePoint, receivePoint, line); List <Geometry> a = diffractionLine2(buildings, sourcePoint, receivePoint, line); if (a != null) // if (buildings.GetFeaturesRead()>0) { // geos.AddRange(getWidth(buildings, sourcePoint, receivePoint, line)); geos.AddRange(a); } else { //计算绕射 // geos.Add(line); // length += line.Length(); // break; } } //Console.WriteLine(length); return(geos); // return length; }
/// <summary> /// 寻找一组声线 /// </summary> /// <param name="buildings">建筑物图层</param> /// <param name="sourcesPoint">声源点</param> /// <param name="receivePoint">接收点</param> /// <param name="range">影响范围</param> /// <returns>一组声线</returns> public Geometry[] getPath(Layer buildings, Geometry sourcesPoint, Geometry receivePoint, float range) { //构建传播路程的数组,分别为两点直射、上绕射、左绕射、右绕射、反射 Geometry[] pathLength = new Geometry[5]; //构建直达声线 Geometry line = GeometryCreate.createLineString3D(sourcesPoint.GetX(0), sourcesPoint.GetY(0), sourcesPoint.GetZ(0), receivePoint.GetX(0), receivePoint.GetY(0), receivePoint.GetZ(0)); //直达声线长度 // double distance = Distance3D.getPointDistance(sourcesPoint, receivePoint); //直达声线 pathLength[0] = line; buildings.SetSpatialFilter(line);//直达声线上受影响的建筑物 //判断是否有直射路径,如果没有,求绕射路径 if (buildings.GetFeatureCount(0) <= 0) { //存在直射则不存在绕射 pathLength[1] = null; pathLength[2] = null; pathLength[3] = null; //计算反射 pathLength[4] = line; } else { Geometry[] diffLine = diffractionLine(buildings, sourcesPoint, receivePoint, line); pathLength[1] = diffLine[0]; pathLength[2] = diffLine[0]; pathLength[3] = diffLine[0]; //忽略反射 pathLength[4] = null; } //计算反射路径 return(pathLength); }
/// <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); }
/// <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); }
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); }