完成了核心功能。

Signed-off-by: facat <facat@facat.com>
This commit is contained in:
facat 2020-05-19 21:42:45 +08:00
commit c527abf326
8 changed files with 545 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
.stfolder
bin
obj
Newtonsoft.Json*
nuget.exe
ILMerge*
example
*.sln
*.suo

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("NWEPDI")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("Copyright © NWEPDI 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("d70bd3b9-6432-4f15-8adf-c4a6fd9239d8")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.8689
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PutTowerPostion.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles />
<Settings />
</SettingsFile>

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{CA8FB7A3-CEB6-471C-BB97-76CBFA17293C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PutTowerPostion</RootNamespace>
<AssemblyName>PutTowerPostion</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<StartAction>Program</StartAction>
<StartProgram>C:\Program Files\AutoCAD 2010\acad.exe</StartProgram>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Reference Include="acdbmgd, Version=18.0.0.0, Culture=neutral, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files\AutoCAD 2010\acdbmgd.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="acmgd, Version=18.0.0.0, Culture=neutral, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files\AutoCAD 2010\acmgd.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Office.Interop.Excel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files (x86)\Microsoft Office\root\Office16\ADDINS\Microsoft Power Query for Excel Integrated\bin\Microsoft.Office.Interop.Excel.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>Newtonsoft.Json.11.0.2\lib\net35\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="cmd.cs" />
<Compile Include="Config.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="Utils.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,8 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<PropertyGroup>
<ProjectView>ProjectFiles</ProjectView>
</PropertyGroup>
</Project>

21
PutTowerPosition/Utils.cs Normal file
View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PutTowerPosition
{
class Utils
{
static public String NormDirectoryPath(String path)//把文件路径标准化为c:/abc/c的格式
{
String newPath = path.Trim();
newPath = newPath.Replace('\\', '/');
if ('/' == newPath[newPath.Length - 1])
{
newPath = newPath.Remove(newPath.Length - 1);
}
return newPath;
}
}
}

344
PutTowerPosition/cmd.cs Normal file
View File

@ -0,0 +1,344 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.IO;
using System.Reflection;
[assembly: CommandClass(typeof(PutTowerPosition.Cmd))]
namespace PutTowerPosition
{
public class Cmd
{
struct spanStruct
{
public string towerName;
public double span;
};
struct Point2D
{
public double X;
public double Y;
};
public void PutTowerPositionCmd()
{
}
[CommandMethod("ptp", CommandFlags.Session)]
public static void PutTowerPosition()
{
string excelFile = findCordinationExcel(@"d:\code\PutTowerPosition\example\S000.DAT");
Dictionary<string, double[]> cordDic = readCordExcel(excelFile);
List<spanStruct> spanList = readSSpan(@"d:\code\PutTowerPosition\example\S000.DAT");
Document acDoc;
Database acCurDb;
//acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.Open(filePath, true);
acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
using (DocumentLock acLckDoc = acDoc.LockDocument())
{
acCurDb = acDoc.Database;
GetOrCreateLayer("TW", acCurDb);
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
OpenMode.ForWrite) as BlockTable;
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
Point2D[] cordinationList = calTowerXYPostion(cordDic, spanList);
foreach (Point2D point in cordinationList)
{
DBPoint dbPoint = new DBPoint(new Point3d(point.Y, point.X, 0));
dbPoint.Layer = "TW";
acBlkTblRec.AppendEntity(dbPoint);
acTrans.AddNewlyCreatedDBObject(dbPoint, true);
acCurDb.Pdmode = 35;
acCurDb.Pdsize = 15;
//break;
}
acTrans.Commit();
}
//acBlkTblRec.Database.SaveAs(outputFilePath, false, DwgVersion.Current, acDoc.Database.SecurityParameters);
}
return;
}
private bool UnlockAllLayer(Document doc)
{
var acCurDb = doc.Database;
//var ed = doc.Editor;
LayerTableRecord ltr = null;
using (var acTrans = acCurDb.TransactionManager.StartTransaction())
{
LayerTable layerTable;
layerTable = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable;
foreach (ObjectId ltrId in layerTable)
{
// Don't try to lock/unlock either the current layer or layer 0
// (depending on whether lockZero == true for the latter)
ltr = (LayerTableRecord)acTrans.GetObject(ltrId, OpenMode.ForWrite);
ltr.IsLocked = false;
//ltr.IsOff = ltr.IsOff; // This is needed to force a graphics update
}
acTrans.Commit();
}
return true;
}
static private LayerTableRecord GetOrCreateLayer(string layerName, Database db)
{
LayerTableRecord ltr;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable lt =
(LayerTable)tr.GetObject(
db.LayerTableId,
OpenMode.ForRead
);
if (lt.Has(layerName))
{
ObjectId ltId = lt[layerName];
ltr = (LayerTableRecord)tr.GetObject(ltId, OpenMode.ForWrite);
}
else
{
ltr = new LayerTableRecord();
ltr.Name = layerName;
lt.UpgradeOpen();
ObjectId ltId = lt.Add(ltr);
tr.AddNewlyCreatedDBObject(ltr, true);
}
tr.Commit();
}
return ltr;
}
private static ObjectIdCollection GetEntitiesOnLayer(Document acDoc, string layerName)
{
//Document doc =
//Application.DocumentManager.MdiActiveDocument;
Editor ed = acDoc.Editor;
// Build a filter list so that only entities
// on the specified layer are selected
TypedValue[] tvs =
new TypedValue[1] {
new TypedValue(
(int)DxfCode.LayerName,
layerName
)
};
SelectionFilter sf =
new SelectionFilter(tvs);
PromptSelectionResult psr =
ed.SelectAll(sf);
if (psr.Status == PromptStatus.OK)
return
new ObjectIdCollection(
psr.Value.GetObjectIds()
);
else
return new ObjectIdCollection();
}
static string findCordinationExcel(string findDirOrFile)
{
string dir = findDirOrFile;
FileAttributes attr = File.GetAttributes(findDirOrFile);
if ((attr & FileAttributes.Directory) > 0)
{
}
else
{
dir = Path.GetDirectoryName(findDirOrFile);
}
string cordExcelFile = dir + "/cord.xlsx";
return cordExcelFile;
}
static private object get_value(Microsoft.Office.Interop.Excel.Worksheet sheet, string str_rang)
{
return sheet.get_Range(str_rang, Missing.Value).Value2;
}
static Dictionary<string, double[]> readCordExcel(string excelFilePath)
{
//TowerName X Y
Microsoft.Office.Interop.Excel.Application objApp;
Microsoft.Office.Interop.Excel._Workbook objBook;
Microsoft.Office.Interop.Excel.Worksheet w_sheet;
objApp = new Microsoft.Office.Interop.Excel.Application();
objBook = objApp.Application.Workbooks.Add(excelFilePath);
w_sheet = objBook.Sheets[1] as Microsoft.Office.Interop.Excel.Worksheet;
Dictionary<string, double[]> towerCordination = new Dictionary<string, double[]>();
for (int i = 1; i < 10000; i++)
{
string towerName = (string)(get_value(w_sheet, "A" + i.ToString()));
if (towerName == null || towerName.Trim() == "")
{
break;
}
double[] cordination = new double[2];
cordination[0] = (double)(get_value(w_sheet, "B" + i.ToString()));
cordination[1] = (double)(get_value(w_sheet, "C" + i.ToString()));
towerCordination.Add(towerName, cordination);
}
return towerCordination;
}
static List<spanStruct> readSSpan(string SFilePath)
{
StreamReader reader = new StreamReader(SFilePath, Encoding.GetEncoding("gb2312"));
string line;
double basicMileage = -1;
List<spanStruct> spanList = new List<spanStruct>();
Dictionary<string, char> has_tower = new Dictionary<string, char>();
while ((line = reader.ReadLine()) != null)
{
if (line.Trim().StartsWith("首端") | line.Trim().StartsWith("塔号"))
{
continue;
}
if (line.Trim() == "")
{
continue;
}
string norm_line;
norm_line = Regex.Replace(line, @"\s+", ",");
norm_line = norm_line.Substring(1);
string[] sep = norm_line.Split(',');
string towerName = sep[0];
if (has_tower.ContainsKey(towerName))
{
continue;
}
has_tower.Add(towerName, ' ');
double mileage = Double.Parse(sep[1]);
double span;
if (basicMileage == -1)
{
basicMileage = mileage;
}
span = mileage - basicMileage;
spanStruct _span;
_span.towerName = towerName;
_span.span = span;
spanList.Add(_span);
basicMileage = mileage;
}
reader.Close();
return spanList;
}
static Point2D[] calTowerXYPostion(Dictionary<string, double[]> cordDic, List<spanStruct> SSpan)
{
Point2D[] cordinationList = new Point2D[SSpan.Count];
Point2D startPoint;
int tensionStart;//耐张段第一基塔位置
tensionStart = 0;
//find next end point
Point2D endPoint;
while (true)
{
startPoint.X = cordDic[SSpan[tensionStart].towerName][0];
startPoint.Y = cordDic[SSpan[tensionStart].towerName][1];
for (int i = tensionStart+1; i < SSpan.Count; i++)
{
string towerName;
towerName = SSpan[i].towerName;
if (cordDic.ContainsKey(towerName))
{
endPoint.X = cordDic[towerName][0];
endPoint.Y = cordDic[towerName][1];
cordinationList[tensionStart] = startPoint;
double mileageInTension=0;//耐张段中的里程
for (int j = tensionStart + 1; j < i; j++)
{
Point2D suspensionTowerPostion;
double tensionLength;//耐张段长度
tensionLength = Math.Sqrt(Math.Pow(endPoint.X - startPoint.X, 2) + Math.Pow(endPoint.Y - startPoint.Y, 2));
mileageInTension += SSpan[j].span;
suspensionTowerPostion.X = startPoint.X + (endPoint.X - startPoint.X) / tensionLength * mileageInTension;
suspensionTowerPostion.Y = startPoint.Y + (endPoint.Y - startPoint.Y) / tensionLength * mileageInTension;
cordinationList[j]=suspensionTowerPostion;
}
cordinationList[i] = endPoint;
tensionStart = i;
break;
}
}
if (tensionStart >= (SSpan.Count - 1))
{
break;
}
}
return cordinationList;
}
}
}