void _ReadTunnelAxes( DGObjects objs, string tableNameSQL, string conditionSQL, string orderSQL) { ReadRawData(objs, tableNameSQL, orderSQL, conditionSQL); DataTable table = objs.rawDataSet.Tables[_dbContext.TableNamePrefix + "TunnelAxes"]; if( table != null) { foreach (DataRow row in table.Rows) { if (IsDbNull(row, "ID")) continue; TunnelAxis ta = new TunnelAxis(row); ta.name = ReadString(row, "Name"); ta.id = ReadInt(row, "ID").Value; ta.LineNo = ReadInt(row, "LineNo").Value; ta.shape = ReadShape(row); objs[ta.key] = ta; } DataTable table2 = objs.rawDataSet.Tables[_dbContext.TableNamePrefix + "TunnelAxesPoints"]; Dictionary<int, TunnelAxis> dictAxes = new Dictionary<int, TunnelAxis>(); if (table2 != null) { TunnelAxis axis = null; foreach (DataRow reader in table2.Rows) { if (IsDbNull(reader, "LineNo")) continue; int lineNo = ReadInt(reader, "LineNo").Value; if (dictAxes.ContainsKey(lineNo)) axis = dictAxes[lineNo]; else { axis = new TunnelAxis(); axis.LineNo = lineNo; axis.id = lineNo; axis.name = lineNo.ToString(); dictAxes[lineNo] = axis; } TunnelAxisPoint tap = new TunnelAxisPoint(); tap.Mileage = ReadDouble(reader, "Milage").Value; tap.X = ReadDouble(reader, "X").Value; tap.Y = ReadDouble(reader, "Y").Value; tap.Z = ReadDouble(reader, "Z").Value; axis.AxisPoints.Add(tap); } } foreach (TunnelAxis ta in objs.values) { if (dictAxes.ContainsKey(ta.id)) ta.AxisPoints = dictAxes[ta.id].AxisPoints; } } }
/* // Convert axis points in map coordinates to TunnelAxis format // Note: A new TunneAxis will be returned and the result is still in map coordinates. // public static TunnelAxis ConvertMapPointsToAxis( ESRI.ArcGIS.Client.Geometry.PointCollection axisPts, double startMileage, double endMileage) { double axisLen = ArcGISMappingUtility.Length(axisPts); double mapScale = axisLen / (endMileage - startMileage); TunnelAxis mapAxis = new TunnelAxis(); List<TunnelAxisPoint> pts = new List<TunnelAxisPoint>(); mapAxis.AxisPoints = pts; double m = startMileage; TunnelAxisPoint pt = new TunnelAxisPoint(); MapPoint p1 = axisPts[0]; pt.X = p1.X; pt.Y = p1.Y; pt.Mileage = startMileage; mapAxis.AxisPoints.Add(pt); for (int i = 1; i < axisPts.Count; ++i) { pt = new TunnelAxisPoint(); MapPoint p2 = axisPts[i]; pt.X = p2.X; pt.Y = p2.Y; m += ArcGISMappingUtility.Distance(p1, p2) / mapScale; pt.Mileage = m; mapAxis.AxisPoints.Add(pt); p1 = p2; } return mapAxis; } public enum CoordinateType { XY, Z }; // Interpolate the coordinates of one axis using the data of another axis based on the mileage. // For example, you can evaluate the z coordinates of a map axis based on the z coordinate of real axis. // public static void InterpolateAxis(TunnelAxis axis, TunnelAxis axisRef, CoordinateType evType) { TunnelAxisPoint p1, p2; p1 = axisRef.AxisPoints[0]; p2 = axisRef.AxisPoints[1]; double m1, m2; // mileage -> m m1 = p1.Mileage; m2 = p2.Mileage; int i = 0, j = 0; for (; i < axis.AxisPoints.Count; ++i) { TunnelAxisPoint p = axis.AxisPoints[i]; double m = p.Mileage; if (m < m1) { // if m<m1, p1,p2,m1,m2 is ready to approximate p.X,p.Y,p.Z // don't need to do anything ; } else { while (!(m >= m1 && m < m2) && j < axisRef.AxisPoints.Count - 1) { p1 = axisRef.AxisPoints[j]; p2 = axisRef.AxisPoints[j + 1]; m1 = p1.Mileage; m2 = p2.Mileage; j++; } } double scale = (m - m1) / (m2 - m1); if (evType == CoordinateType.Z) { double z1, z2; z1 = p1.Z; z2 = p2.Z; p.Z = z1 + (z2 - z1) * scale; } else { double x1, x2, y1, y2; x1 = p1.X; y1 = p1.Y; x2 = p2.X; y2 = p2.Y; p.X = x1 + (x2 - x1) * scale; p.Y = y1 + (y2 - y1) * scale; } } } // Interpolate/Extrapolate the axis according to the given start and end mileage. // public static void InterpolateAxis( ESRI.ArcGIS.Client.Geometry.PointCollection axisPts, double axisStartMileage, double axisEndMileage, double startMileage, double endMileage) { if (startMileage > endMileage) { double t = startMileage; startMileage = endMileage; endMileage = t; } #region Code for fast processing if (Math.Abs(startMileage - axisStartMileage) < GeometryAlgorithms.Zero && Math.Abs(endMileage - axisEndMileage) < GeometryAlgorithms.Zero) return; if (endMileage < axisStartMileage || startMileage > axisEndMileage) { MapPoint pt1, pt2; pt1 = MileageToAxisPoint(startMileage, axisPts, axisStartMileage, axisEndMileage); pt2 = MileageToAxisPoint(endMileage, axisPts, axisStartMileage, axisEndMileage); axisPts.Clear(); axisPts.Add(pt1); axisPts.Add(pt2); return; } #endregion TunnelAxis axis = ConvertMapPointsToAxis(axisPts, axisStartMileage, axisEndMileage); TunnelAxisPoint p1, p2; p1 = MileageToAxisPoint(startMileage, axis); p2 = MileageToAxisPoint(endMileage, axis); int index; int count = 0; if (Math.Abs(startMileage - axisStartMileage) < GeometryAlgorithms.Zero) { // do nothing } else if (startMileage < axisStartMileage) { axis.AxisPoints.Insert(0, p1); } else { for (index = 0; index < axis.AxisPoints.Count - 1; ++index) { count++; double m1 = axis.AxisPoints[index].Mileage; double m2 = axis.AxisPoints[index + 1].Mileage; if ((startMileage >= m1 && startMileage < m2)) break; } axis.AxisPoints.RemoveRange(0, count); axis.AxisPoints.Insert(0, p1); } if (Math.Abs(endMileage - axisEndMileage) < GeometryAlgorithms.Zero) { // do nothing } else if (endMileage > axisEndMileage) { axis.AxisPoints.Add(p2); } else { for (index = 0; index < axis.AxisPoints.Count - 1; ++index) { double m1 = axis.AxisPoints[index].Mileage; double m2 = axis.AxisPoints[index + 1].Mileage; if ((endMileage > m1 && endMileage <= m2)) break; } count = axis.AxisPoints.Count - index - 1; if (count > 0) { axis.AxisPoints.RemoveRange(index + 1, count); axis.AxisPoints.Add(p2); } } SpatialReference sr = axisPts[0].SpatialReference; axisPts.Clear(); for (int i = 0; i < axis.AxisPoints.Count; ++i) { MapPoint pt = new MapPoint(); pt.SpatialReference = sr; pt.X = axis.AxisPoints[i].X; pt.Y = axis.AxisPoints[i].Y; axisPts.Add(pt); } } // Merge two axes according to the mileage of axis points // public static TunnelAxis MergeAxis(TunnelAxis axis1, TunnelAxis axis2) { TunnelAxis axis = new TunnelAxis(); List<TunnelAxisPoint> pts = new List<TunnelAxisPoint>(); axis.AxisPoints = pts; axis.LineNo = axis1.LineNo; axis.AxisPoints.AddRange(axis1.AxisPoints); axis.AxisPoints.AddRange(axis2.AxisPoints); axis.AxisPoints.Sort(CompareAxisPoints); return axis; } */ /* static int CompareAxisPoints(TunnelAxisPoint p1, TunnelAxisPoint p2) { return p1.Mileage.CompareTo(p2.Mileage); } // Evaluate the axis points of a tunnel, give its geometry. // The geometry can only be a Polygon with 4 corner points and 4 sides. // The points on one side should be the same with the points on the opposite side. // Otherwise, the function will fail and a NULL value will be returned. // public static ESRI.ArcGIS.Client.Geometry.PointCollection EvaluateTunnelAxisPoints(ESRI.ArcGIS.Client.Geometry.Geometry geom) { ESRI.ArcGIS.Client.Geometry.Polygon polygon = geom as ESRI.ArcGIS.Client.Geometry.Polygon; if (polygon == null) return null; ESRI.ArcGIS.Client.Geometry.PointCollection result = new ESRI.ArcGIS.Client.Geometry.PointCollection(); ESRI.ArcGIS.Client.Geometry.PointCollection pts = polygon.Rings[0]; List<int> corners = new List<int>(); // corner points index corners.Add(0); for (int i = 1; i < pts.Count - 1; ++i) { MapPoint p0 = pts[i - 1]; MapPoint p1 = pts[i]; MapPoint p2 = pts[i + 1]; double angle = GeometryAlgorithms.AngleBetweenLines(p0.X, p0.Y, p1.X, p1.Y, p1.X, p1.Y, p2.X, p2.Y); if (Math.Abs(angle) > 30.0 * Math.PI / 180.0) { corners.Add(i); } } if (corners.Count == 4) { int pts1 = corners[1] - corners[0] + 1; // points on line1 int pts2 = corners[2] - corners[1] + 1; // points on line2 int pts3 = corners[3] - corners[2] + 1; // points on line3 int pts4 = pts.Count - corners[3]; // points on line4 if (pts1 > pts2) // use long lines: line1,line3 { int min = pts1 < pts3 ? pts1 : pts3; int index1, index2; MapPoint p; for (int i = 0; i < min - 1; ++i) { index1 = i; index2 = corners[3] - i; p = ArcGISMappingUtility.MidPoint(pts[index1], pts[index2]); result.Add(p); } index1 = corners[1]; index2 = corners[2]; p = ArcGISMappingUtility.MidPoint(pts[index1], pts[index2]); result.Add(p); } else { int min = pts2 < pts4 ? pts2 : pts4; int index1, index2; MapPoint p; for (int i = 0; i < min - 1; ++i) // use long lines: line2,line4 { index1 = corners[1] + i; index2 = pts.Count - 1 - i; p = ArcGISMappingUtility.MidPoint(pts[index1], pts[index2]); result.Add(p); } index1 = corners[2]; index2 = corners[3]; p = ArcGISMappingUtility.MidPoint(pts[index1], pts[index2]); result.Add(p); } return result; } else return null; } public class LineSegment { public MapPoint StartPt; public MapPoint EndPt; public LineSegment() { StartPt = new MapPoint(); EndPt = new MapPoint(); } } public class AxisSegment : LineSegment { public double StartMileage; public double EndMileage; } */ // Translate a point represented by mileage to map coordinate. // Input mileage: (mileage) // Tunnel axis is given by (axisPts, startMileage, endMileage). // return value: (1) a MapPoint // (2) (outSegment), the segment that contains the map point. // /* public static MapPoint MileageToAxisPoint(double mileage, ESRI.ArcGIS.Client.Geometry.PointCollection axisPts, double startMileage, double endMileage, AxisSegment outSegment = null) { double axisLen = ArcGISMappingUtility.Length(axisPts); // this is map length (often greater) double len = endMileage - startMileage; // this is real length double mapScale = axisLen / len; MapPoint p; // case 1: mileage < startMileage MapPoint p1 = axisPts[0]; MapPoint p2 = axisPts[1]; double m1 = startMileage; double m2 = m1 + ArcGISMappingUtility.Distance(p1, p2) / mapScale; double scale = 0.0; if (mileage < m1) { scale = (mileage - m1) / (m2 - m1); p = ArcGISMappingUtility.InterpolatePointOnLine(p1, p2, scale); if (outSegment != null) { outSegment.StartPt = p1; outSegment.EndPt = p2; outSegment.StartMileage = m1; outSegment.EndMileage = m2; } return p; } // case 2: startMileage <= mileage <= endMileage m1 = startMileage; m2 = startMileage; for (int i = 0; i < axisPts.Count - 1; ++i) { p1 = axisPts[i]; p2 = axisPts[i + 1]; m1 = m2; m2 = m1 + ArcGISMappingUtility.Distance(p1, p2) / mapScale; if (mileage >= m1 && mileage <= m2) { scale = (mileage - m1) / (m2 - m1); p = ArcGISMappingUtility.InterpolatePointOnLine(p1, p2, scale); if (outSegment != null) { outSegment.StartPt = p1; outSegment.EndPt = p2; outSegment.StartMileage = m1; outSegment.EndMileage = m2; } return p; } } // case 3: mileage > endMileage scale = (mileage - m1) / (m2 - m1); p = ArcGISMappingUtility.InterpolatePointOnLine(p1, p2, scale); if (outSegment != null) { outSegment.StartPt = p1; outSegment.EndPt = p2; outSegment.StartMileage = m1; outSegment.EndMileage = m2; } return p; } */ // Translate a point represented by mileage to engineering coordinate: (x,y,z,m) // public static TunnelAxisPoint MileageToAxisPoint(double mileage, TunnelAxis axis) { TunnelAxisPoint p = new TunnelAxisPoint(); double x = 0.0, y = 0.0, z = 0.0; // case 1: mileage < startMileage TunnelAxisPoint p1 = axis.AxisPoints[0]; TunnelAxisPoint p2 = axis.AxisPoints[1]; double m1 = p1.Mileage; double m2 = p2.Mileage; double scale = 0.0; if (mileage < m1) { scale = (mileage - m1) / (m2 - m1); GeometryAlgorithms.InterpolatePointOnLine(p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z, scale, ref x, ref y, ref z); p.X = x; p.Y = y; p.Z = z; p.Mileage = mileage; return p; } // case 2: startMileage <= mileage <= endMileage for (int i = 0; i < axis.AxisPoints.Count - 1; ++i) { p1 = axis.AxisPoints[i]; p2 = axis.AxisPoints[i + 1]; m1 = p1.Mileage; m2 = p2.Mileage; if (mileage >= m1 && mileage <= m2) { scale = (mileage - m1) / (m2 - m1); GeometryAlgorithms.InterpolatePointOnLine(p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z, scale, ref x, ref y, ref z); p.X = x; p.Y = y; p.Z = z; p.Mileage = mileage; return p; } } // case 3: mileage > endMileage scale = (mileage - m1) / (m2 - m1); GeometryAlgorithms.InterpolatePointOnLine(p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z, scale, ref x, ref y, ref z); p.X = x; p.Y = y; p.Z = z; p.Mileage = mileage; return p; }
public static LPResult ProjectTunnel_LS(EngineeringMap targetEMap, DGObject obj, ISpatialReference sp, DrawTunnelsSettings lsSettings) { IPolyline projLine = targetEMap.profileLine; if (projLine == null) return null; Tunnel tunnel = obj as Tunnel; if (tunnel.LineNo == null) return null; int lineNo = tunnel.LineNo.Value; double mapScale = targetEMap.Scale; Domain domain = Globals.project.getDomain(DomainType.Structure); DGObjectsCollection allAxes = domain.getObjects("TunnelAxis"); TunnelAxis axis = allAxes[tunnel.id] as TunnelAxis; if (axis == null) return null; double distance = 0; IMapPoint pt = Runtime.geometryEngine.newMapPoint(0, 0, sp); IMapPoint prjPt = Runtime.geometryEngine.newMapPoint(0, 0,sp); List<IMapPoint> upperPnts = new List<IMapPoint>(); List<IMapPoint> lowerPnts = new List<IMapPoint>(); int num = axis.AxisPoints.Count; double height = 0.0; if (tunnel.Height != null) height = tunnel.Height.Value; TunnelAxis profileAxis = new TunnelAxis(); List<TunnelAxisPoint> pts = new List<TunnelAxisPoint>(); profileAxis.AxisPoints = pts; profileAxis.LineNo = lineNo; for (int i = 0; i < num; ++i) { TunnelAxisPoint axisPt = axis.AxisPoints[i]; pt = Runtime.geometryEngine.newMapPoint(axisPt.X, axisPt.Y, sp); GeomUtil.ProjectPointToPolyline(pt, projLine.GetPoints(), ref distance, ref prjPt); distance /= mapScale; distance += lsSettings.xOffset; double X = distance; double Y = (axisPt.Z + height / 2.0) * lsSettings.zScale; IMapPoint upperPnt = Runtime.geometryEngine.newMapPoint(X, Y, sp); upperPnts.Add(upperPnt); X = distance; Y = (axisPt.Z - height / 2.0) * lsSettings.zScale; IMapPoint lowerPnt = Runtime.geometryEngine.newMapPoint(X, Y, sp); lowerPnts.Add(lowerPnt); TunnelAxisPoint newPt = new TunnelAxisPoint(); newPt.X = distance; newPt.Z = axisPt.Z * lsSettings.zScale; newPt.Mileage = axisPt.Mileage; profileAxis.AxisPoints.Add(newPt); } lowerPnts.Reverse(); upperPnts.AddRange(lowerPnts); upperPnts.Add(upperPnts[0]); IPointCollection tunnelPnts = Runtime.geometryEngine.newPointCollection(); foreach (IMapPoint mp in upperPnts) tunnelPnts.Add(mp); IGraphic g = Runtime.graphicEngine.newPolygon(tunnelPnts); ISimpleLineSymbol linesymbol = Runtime.graphicEngine.newSimpleLineSymbol( Colors.Black, Core.Graphics.SimpleLineStyle.Solid, 0.5); ISymbol symbol = Runtime.graphicEngine.newSimpleFillSymbol( Colors.Red, SimpleFillStyle.Solid, linesymbol); g.Symbol = symbol; LPResult result = new LPResult(); result.id = obj.id; result.name = obj.id.ToString() + targetEMap.MapID; result.Obj = obj; result.Graphic = g; result.PlanAxis = axis; result.ProfileAxis = profileAxis; result.Setting = lsSettings; return result; }
void StartAnalysis() { string mapID = _inputView.eMap.MapID; _settings.mapID = mapID; _spatialRef = _inputView.spatialReference; // check all needed data is set up correctly if (_selectedTunnelsDict == null || _selectedTunnelsDict.Count() == 0) return; foreach (string tunnelLayerID in _selectedTunnelsDict.Keys) { IGraphicsLayer gLayer = _inputView.getLayer("DES_AXL"); if (gLayer == null) continue; IEnumerable<DGObject> tunnels = _selectedTunnelsDict[tunnelLayerID]; foreach (var obj in tunnels) { Tunnel tunnel = obj as Tunnel; if (tunnel.StartMileage == null || tunnel.EndMileage == null || tunnel.LineNo == null) continue; _allAxes = _structureDomain.getObjects("TunnelAxis"); TunnelAxis ta = _allAxes[tunnel.id] as TunnelAxis; if (ta == null) continue; //analysis the axis, change the engineering coordinate to map coordinate TunnelAxis engineeringAxis = ta; int count = engineeringAxis.AxisPoints.Count; IGraphicCollection gc = gLayer.getGraphics(ta); if (gc.Count == 0) continue; IGraphic g = gc[0]; IPolyline pline = g.Geometry as IPolyline; if (pline == null) continue; IPointCollection pc = pline.GetPoints(); if (pc.Count != count) { return; } TunnelAxis mapAxis = new TunnelAxis(); mapAxis.AxisPoints = new System.Collections.Generic.List<TunnelAxisPoint>(); for (int i = 0; i < count; i++) { TunnelAxisPoint p1 = engineeringAxis.AxisPoints[i]; TunnelAxisPoint p2 = new TunnelAxisPoint(); p2.Mileage = p1.Mileage; p2.X = pc[i].X; p2.Y = pc[i].Y; p2.Z = p1.Z; mapAxis.AxisPoints.Add(p2); } mapAxis = TunnelMappingUtility.ClipAxis(mapAxis, (double)tunnel.StartMileage, (double)tunnel.EndMileage); if (mapAxis.AxisPoints[0].Mileage != tunnel.StartMileage) { TunnelAxisPoint pt = TunnelMappingUtility.MileageToAxisPoint((double)tunnel.StartMileage, mapAxis); mapAxis.AxisPoints.Insert(0, pt); } count = mapAxis.AxisPoints.Count; if (mapAxis.AxisPoints[count - 1].Mileage != tunnel.EndMileage) { TunnelAxisPoint pt = TunnelMappingUtility.MileageToAxisPoint((double)tunnel.EndMileage, mapAxis); mapAxis.AxisPoints.Add(pt); } mapAxis.LineNo = ta.LineNo; mapAxis.id = ta.id; mapAxis.name = ta.name; _results.Add(mapAxis); } } }