using System; using System.Drawing; using GeoScene.Data; using GeoScene.Engine; using GeoScene.Globe; namespace WorldGIS { public class LineBuilder : ModelBuilder { public LineBuilder(GSODataSource ds) : base(ds) { } public override bool validate(GSOLayer layer) { return true; } /// <summary> /// /// </summary> /// <param name="updateMode">追加或修改</param> /// <param name="buildMode">高程入库或埋深入库</param> /// <param name="param"></param> public override bool doBuild(EnumUpdateMode updateMode, EnumBuildMode buildMode, BaseParam param) { LineParam lineParam = param as LineParam; GSOFeatureDataset newFeatureSet = ds.GetDatasetByName(lineParam.layerName) as GSOFeatureDataset; if (newFeatureSet == null) { newFeatureSet = CreateDBFeatureDataset(layer, lineParam.layerName); } newFeatureSet.Open(); GSOFeatures features = layer.GetAllFeatures(true); for (int i = 0; i < features.Length; i++) { GSOFeature f = features[i]; GSOGeoPolyline3D lineeee = f.Geometry as GSOGeoPolyline3D; if (lineeee == null || lineeee.GetSpaceLength(true, 6378137) == 0) { LogHelper.Error("出现数据无法入库:" + f.ID); continue; } GSOFeature newFeature = newFeatureSet.CreateFeature(); double radius = getRadius(lineParam, f); newFeature.Geometry = updateGemotry(f, lineParam, radius, buildMode); // f.Geometry; //TODO LIST: newFeature.Geometry.Style = getPipeLineStyle(lineParam, f, radius); newFeature.Name = f.GetFieldAsString(lineParam.uniqueIdFieldName); setFeatureValueByShapeFeature(f, newFeature); // newFeatureSet if (newFeatureSet.GetFeatureByName(newFeature.Name, true).Length > 0) { //存在 if (updateMode.Equals(EnumUpdateMode.Append)) { continue; } GSOFeature delFeature = newFeatureSet.GetFeatureByName(newFeature.Name, true)[0]; delFeature.Delete(); } newFeatureSet.AddFeature(newFeature); } newFeatureSet.Save(); newFeatureSet.Close(); return true; } private double getRadius(LineParam lineParam, GSOFeature f) { double radius = 0; GSOFieldDefn field = f.GetFieldDefn(lineParam.diameterFieldName); if (field.Type == EnumFieldType.Text) { string temp = f.GetFieldAsString(lineParam.diameterFieldName); double outNum = 0; bool num = double.TryParse(temp, out outNum); if (num) radius = outNum / 2000; } else if (field.Type == EnumFieldType.Double || field.Type == EnumFieldType.INT32) radius = f.GetFieldAsDouble(lineParam.diameterFieldName) / 2000;// 探测数据的单位一般是毫米,需换算为米; 管径一般是 直径, 这个需要半径, 所有除以2000 return radius; } /** * 获取管线style **/ private GSOLineStyle3D getPipeLineStyle(LineParam lineParam, GSOFeature f, double radius) { if (lineParam.channelHeight == "") { GSOPipeLineStyle3D style0 = new GSOPipeLineStyle3D(); style0.LineColor = Color.FromArgb(lineParam.transparency, lineParam.lineColor); style0.Slice = lineParam.sliceNum; style0.CornerSliceAngle = lineParam.cornerSliceAngle; style0.Radius = radius; return style0; } double width = f.GetFieldAsDouble(lineParam.channelWidth)/1000;//管沟宽、高单位转换成米 double height = f.GetFieldAsDouble(lineParam.channelHeight)/1000; GSOExtendSectionLineStyle3D style1 = new GSOExtendSectionLineStyle3D(); style1.LineColor = Color.FromArgb(Convert.ToByte(lineParam.transparency), lineParam.lineColor); GSOPoint3ds sectionpts = new GSOPoint3ds(); sectionpts.Add(new GSOPoint3d(width / -2, height / 2, 0)); sectionpts.Add(new GSOPoint3d(width / -2, height / -2, 0)); sectionpts.Add(new GSOPoint3d(width / 2, height / -2, 0)); sectionpts.Add(new GSOPoint3d(width / 2, height / 2, 0)); style1.SetSectionPoints(sectionpts); style1.IsClosed = true; style1.SetAnchorByAlign(EnumAlign.MiddleCenter); return style1; } private GSOGeometry updateGemotry(GSOFeature f, LineParam lineParam, double radius, EnumBuildMode buildMode) { f.Geometry.AltitudeMode = (buildMode.Equals(EnumBuildMode.Alititude)) ? EnumAltitudeMode.RelativeToGround : EnumAltitudeMode.Absolute; GSOGeoPolyline3D line = f.Geometry as GSOGeoPolyline3D; if (line == null) { return null; //log4net 记录错误处理 } double deep1 = f.GetFieldAsDouble(lineParam.startDepthFieldName); double deep2 = f.GetFieldAsDouble(lineParam.endDepthFieldName); deep1 = lineParam.isRevert ? -deep1 : deep1; deep2 = lineParam.isRevert ? -deep2 : deep2; //根据相对模式进行深度修改 deep1 = lineParam.relativeMode == 1 ? deep1 + radius * 2 : deep1 - radius * 2; deep2 = lineParam.relativeMode == 1 ? deep2 + radius * 2 : deep2 - radius * 2; GSOPoint3ds pt3ds = new GSOPoint3ds(); for (int n = 0; n < line[0].Count; n++) { GSOPoint3d pt3d = line[0][n]; int pointcount = line[0].Count; //TODO LIST:BUG double totalLength = Math.Sqrt(Math.Pow(line[0][pointcount - 1].Y - line[0][0].Y, 2) + Math.Pow(line[0][pointcount - 1].X - line[0][0].X, 2)); if (totalLength == 0) { //TODOLIST:ERROR log4net pt3d.Z = deep1; } else { double radio = Math.Sqrt(Math.Pow(pt3d.Y - line[0][0].Y, 2) + Math.Pow(pt3d.X - line[0][0].X, 2)) / totalLength; pt3d.Z = deep1 + (deep2 - deep1) * radio; } if (double.IsInfinity(pt3d.Z)) { pt3d.Z = deep2; } pt3ds.Add(pt3d); } line[0] = pt3ds; return line; } } }