using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices.Styles;
using Autodesk.AutoCAD.EditorInput;
namespace ForCivilTest
{
public class Class1
{
public void MyCommand() // This method can have any name
{
// Put your command code here
CivilDocument doc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument;
ObjectIdCollection alignments = doc.GetAlignmentIds();
ObjectIdCollection sites = doc.GetSiteIds();
String docInfo = String.Format("This document has {0} alignments and {1} sites.\n", alignments.Count, sites.Count);
// Можно где-то тут объявить:
Document adoc = Application.DocumentManager.MdiActiveDocument;
Database db = adoc.Database;
Editor ed = adoc.Editor;
// И подставлять переменные, чтобы не было таких громоздких конструкций
//Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(docInfo);
ed.WriteMessage(docInfo);
//berem vse alignment
foreach (ObjectId oId in alignments)
{
//using (Transaction tr = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction())
using (Transaction tr = db.TransactionManager.StartTransaction())
{
try
{
// Получаем текущую трассу
Alignment al = (Alignment)oId.GetObject(OpenMode.ForRead);
// Выводим о ней информацию
String txt = String.Format("\nAlignName:!{0}\n", al.Name);
//Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(txt);
ed.WriteMessage(txt); // Ну и так далее
//dostaem vse tikety
// Точки геометрии
Station[] statGeom = al.GetStationSet(StationTypes.GeometryPoint);
// Точки основных пикетов - da tex 4to idut u menia kazdyje 100m dopustim
Station[] statMajo = al.GetStationSet(StationTypes.Major);
// Точки чего? eto Station Equation, nepravelnyje pikety, t.e. pikety sdvinutyje ot pravlenyx (kotoryje kazdyje 100m). iz Civil dostupny po Alignment Priperties->station control.
Station[] statEqua = al.GetStationSet(StationTypes.Equation);
// Вывод данных о точках геометрии
foreach (Station st in statGeom)
{
String st_coord = String.Format("Station: {0}, {1}\n", st.StationType, st.RawStation);
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(st_coord);
}
// Вывод данных о точках основных пикетов
foreach (Station st in statMajo)
{
String st_coord = String.Format("Station: {0}, {1}\n", st.StationType, st.RawStation);
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(st_coord);
}
// Вывод данных о точках чего? nepravel'nyje/rublenyje pikety
foreach (Station st in statEqua)
{
String st_coord = String.Format("Station: {0}, {1}\n", st.StationType, st.RawStation);
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(st_coord);
}
// Получение данных о группах меток для трассы
ObjectIdCollection alLabGr = al.GetAlignmentLabelGroupIds();
// Лишнее? lishnee :)
int i = 1;
// Проходим по группам меток
foreach (ObjectId alLabGroId in alLabGr)
{
// Хм, подозреваю, что тут лучше использовать не LabelBase, а LabelGroup, vozmozno, no poka nzn kak ispolzovat', po4itaju dokumentaciju
// чтобы понимать, что мы имеем дело не с отдельной меткой а с группой меток
LabelBase label = alLabGroId.GetObject(OpenMode.ForWrite) as LabelBase;
// Проходим по каждой группе меток, задаем текст
_SetLabelTextOverride(label, al, statMajo, statEqua, statGeom);
}
}
catch (Autodesk.Civil.CivilException ex)
{
// А куда потом эту строку? et dlia debbugera poka 4to tol'ko
string msg = ex.Message;
}
tr.Commit();
}
}
}
// Очень сложный для моего понимания метод...
private string _getNearestPoint(double pt, Dictionary<double, double> station_map)
{
double dist = pt; // rasstojanije piketa ot naciala
foreach (KeyValuePair<double, double> entry in station_map)
{
if
(entry.Value - pt < dist
&& entry.Value > pt)
dist = Math.Abs(pt - entry.Value); // popytka najti blizajshuju to4ku kotoraja nam podxodit. tak kak osnovnyj(Major) to4ek bolse 4em nepravelnyx(equation) ni4ego umnee ne pridumal,
// no javno ne pravel'mo, potomu 4to rabotaet tolko dlia sdvinutyx pikov kotoryje mense 100, 4to ne vsegda pravda.
}
return String.Format("{0:0.00}", dist);
}
private void _SetLabelTextOverride(LabelBase baseLabel, Alignment al, Station[] statMajo, Station[] statEqua, Station[] statGeom)
{
StationEquationCollection stc = al.StationEquations;
Dictionary<double, double> station_map = new Dictionary<double, double>();
//dostaem zna4enije rublennogo piketa dlia ... чего? :) zapolniaetsia map po kliu4iam osnovnyx piketov
foreach (Station st in statMajo)
{
// Что-то очень хитрое. Словарь из ключа и равного ключу значения. Зачем?
station_map[st.RawStation] = st.RawStation;
}
// К сожалению, не понимаю, что это за Equation. Поэтому, не понимаю этого цикла - a vot zdes meniaem zna4enije osnovnogo pikata na rublenyj,
// po kliu4iu osnovnogo, potomu 4to rublenyj beretsia kak otstup ot osnovnogo
foreach (Station st in statEqua)
{
StationEquation se = stc.GetStationEquation(st.RawStation);
station_map[se.StationAhead] = se.StationBack;
}
// Если в метод передавать сразу LabelGroup, то вот этого не нужно будет - bylo by zame4iatel'no, po4itaju API kak sdelat', eto variant skopirovanyj o kuda to.
switch (baseLabel.GetRXClass().DxfName)
{
case "AECC_ALIGNMENT_GEOMPOINT_LABEL_GROUP":
LabelGroup group = (LabelGroup)baseLabel;
// Где-то я это уже встречал... :)
int i = 1;
// Проходим по всем примитивам внутри LabelGroup
foreach (LabelGroupSubEntity subEntity in group.SubEntities)
{
// Получаем их коллекцию текстовых компонентов
ObjectIdCollection textComponentIds = subEntity.GetTextComponentIds();
// ... дважды
textComponentIds = subEntity.GetTextComponentIds();
// Если компоненты есть
if (textComponentIds.Count > 0)
{
double st = 0;
double off = 0;
al.StationOffset(subEntity.LabelLocation.X, subEntity.LabelLocation.Y, 0.01, ref st, ref off);
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(st + " " + al.GetStationStringWithEquations(st) + "\n");
// Проходим по ним
foreach (ObjectId id in textComponentIds)
{
// Получаем объект текстового компонента метки
LabelStyleTextComponent lsc = (LabelStyleTextComponent)id.GetObject(OpenMode.ForWrite);
// Если его имя нам подходит
if (lsc.Name == "добавкаНАЧАЛОкривой" || lsc.Name == "ДобавкаНачалаКонца")
{
// следующие строки можно вынести за цикл 'foreach (ObjectId id in textComponentIds)'
//meniajem zna4enije "dobavki"
//double st = 0;
//double off = 0;
//al.StationOffset(subEntity.LabelLocation.X, subEntity.LabelLocation.Y, 0.01, ref st, ref off);
//Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(st + " " + al.GetStationStringWithEquations(st) + "\n");
// Вычисляем и задаем ему значение. Это я проверить не могу, т.к. не понимаю какие данные обрабатываются
// Double.Parse(al.GetStationStringWithEquations(st).Replace("+", "")) - eto preobrazovanije pikate iz vida 196+00, v normalnyj double dlia vyshislenij.
// vozmozno eto vsio ne pravel'no i nuzno po drugomu, na kak i napisal ja ne znaju poka drugogo varianta kak pos4itat rasstojanije mezdu geometri4eskoj to4noj i rublenym piketom :)
subEntity.SetTextComponentOverride(id, _getNearestPoint(Double.Parse(al.GetStationStringWithEquations(st).Replace("+", "")), station_map));
}
}
}
else
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Label: "
+ subEntity.Parent.GetRXClass().DxfName + " doesn't have any text component to override! "
+ "This label will be ignored for the current action.\n");
// А это вроде как серьезная ошибка. Если нам попадается какая-то метка без текстовых компонентов,
// цикл 'foreach (LabelGroupSubEntity subEntity in group.SubEntities)' прерывается.
// Хотя, может в этом есть какая-то логика?
// poka ne znaju ese kak budet ralizovana logika, poka ostavil tak
break;
}
}
// Это мы из case выходим
break;
default:
break;
}
}
}
}