Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
developers:tutorial:sfcedit [2022/04/09 15:14] proxor |
developers:tutorial:sfcedit [2022/04/09 18:54] (текущий) proxor [Редактирование элементов поверхности] |
||
---|---|---|---|
Строка 18: | Строка 18: | ||
<note>[[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|Структурная линия]] всегда опирается на [[developers:references:topomatic.sfc.surfacepoint|точки поверхности]] и не может существовать без них.</note> | <note>[[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|Структурная линия]] всегда опирается на [[developers:references:topomatic.sfc.surfacepoint|точки поверхности]] и не может существовать без них.</note> | ||
- | Прежде чем приступить к рассмотрению примеров по созданию и редактированию элементов поверхности, следует изучить предыдущий урок, в котором рассматривается процесс [[developers:tutorial:sfcselection|выделения элементов поверхности]]. | ||
==== Настройка проекта Visual Studio ==== | ==== Настройка проекта Visual Studio ==== | ||
Строка 32: | Строка 31: | ||
* [[developers:references:topomatic.foundationclasses|Topomatic.FoundationClasses]] - базовые классы программного комплекса [[http://www.topomatic.ru|Топоматик Робур]]. | * [[developers:references:topomatic.foundationclasses|Topomatic.FoundationClasses]] - базовые классы программного комплекса [[http://www.topomatic.ru|Топоматик Робур]]. | ||
* [[developers:references:topomatic.smt|Topomatic.Smt]] - семантика | * [[developers:references:topomatic.smt|Topomatic.Smt]] - семантика | ||
+ | |||
+ | В следующих примерах используются классы и методы предыдущего урока, в котором рассматривается процесс [[developers:tutorial:sfcselection|выделения элементов поверхности]]. | ||
===== Добавление элементов поверхности ===== | ===== Добавление элементов поверхности ===== | ||
- | В этом примере мы выберем замкнутую [[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|структурную линию]] и на указанном расстоянии от неё построим новую с учётом приращения высоты. Результатом действия станет сооружение насыпи или оврага в зависимости от значений указанных пользователем. | + | В этом примере мы выберем замкнутую [[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|структурную линию]] и на указанном расстоянии от неё построим новую с учётом приращения высоты. |
+ | |||
+ | Для этого нам потребуются координаты точек эквидистанты существующей [[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|структурной линии]]. Далее мы рассчитаем новое значение высоты этих точек и на основе полученных координат создадим новые [[developers:references:topomatic.sfc.surfacepoint|точки поверхности]]. Вновь созданные [[developers:references:topomatic.sfc.surfacepoint|точки поверхности]] станут основой для создания новой [[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|структурной линии]]. | ||
- | Для этого нам потребуются координаты точек эквидистанты от существующей [[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|структурной линии]]. Далее мы рассчитаем новое значение высоты этих точек и на основе полученных координат создадим новые [[developers:references:topomatic.sfc.surfacepoint|точки поверхности]]. Вновь созданные [[developers:references:topomatic.sfc.surfacepoint|точки поверхности]] станут основой для создания новой [[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|структурной линии]]. | + | Эквидистанта для новой [[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|структурной линии]] должна рассчитываться относительно удалённости курсора от выбранной [[road:work_with_cmm:create_and_edit_surface_new:notion_structural_lines_new|структурной линии]]. Чтобы получить это значение, необходимо воспользоваться методом [[developers:references:b91330957111b48e6dd7fd9cf6e05eba|CadLibrary.PosToPolylineStaOffset()]]. В качестве аргументов, метод принимает список координат полилинии типа [[developers:references:topomatic.cad.foundation.vector2d|Vector2D]], координаты курсора типа [[developers:references:topomatic.cad.foundation.vector2d|Vector2D]] и записывает рассчитанные значения в принимаемые переменные ''offset'' и ''station'' типа [[https://docs.microsoft.com/ru-ru/dotnet/api/system.double?view=net-6.0|double]] с модификатором [[https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/keywords/out-parameter-modifier|out]]. ''offset'' - кратчайшее расстояние от курсора до полилинии, а ''station'' - длина части полилинии от её первой точки до точки в которой был определён ''offset''. |
Для наглядности будущего положения новой структурной линии мы воспользуемся [[developers:tutorial:dynamicrender|динамической отрисовкой]] примитива. | Для наглядности будущего положения новой структурной линии мы воспользуемся [[developers:tutorial:dynamicrender|динамической отрисовкой]] примитива. | ||
- | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «create_hill_or_pit» предложит пользователю выбрать замкнутую структурную линию и приращение высоты. | + | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «create_hill_or_pit» предложит пользователю выбрать замкнутую структурную линию и приращение высоты. Результатом действия станет сооружение насыпи или котлована в зависимости от значений указанных пользователем. |
<code csharp> | <code csharp> | ||
Строка 68: | Строка 71: | ||
DrawCursorEvent ondraw = delegate (CadPen pen, Vector3D vertex) | DrawCursorEvent ondraw = delegate (CadPen pen, Vector3D vertex) | ||
{ | { | ||
- | int i; | ||
double s, o; | double s, o; | ||
//находим смещение точки по линии | //находим смещение точки по линии | ||
- | if (CadLibrary.PosToPolylineStaOffset(poly2d, vertex.Pos, out i, out o, out s)) | + | if (CadLibrary.PosToPolylineStaOffset(poly2d, vertex.Pos, out o, out s)) |
{ | { | ||
var offs_line = new List<Vector3D>(); | var offs_line = new List<Vector3D>(); | ||
Строка 108: | Строка 110: | ||
- | int ind; | ||
double sta; | double sta; | ||
var off = 0.0; | var off = 0.0; | ||
if (res == GetPointResult.Accept) | if (res == GetPointResult.Accept) | ||
{ | { | ||
- | CadLibrary.PosToPolylineStaOffset(poly2d, point.Pos, out ind, out off, out sta); | + | CadLibrary.PosToPolylineStaOffset(poly2d, point.Pos, out off, out sta); |
} | } | ||
else if (res == GetPointResult.UserCmd) | else if (res == GetPointResult.UserCmd) | ||
Строка 176: | Строка 177: | ||
</code> | </code> | ||
- | {{ :developers:tutorial:surfaceelementsedit:tutcreatestrline.gif?nolink&600 |}} | + | {{ :developers:tutorial:surfaceelementsedit:tutcreatestrline.png?nolink&600 |}} |
+ | |||
+ | |||
+ | ===== Редактирование элементов поверхности ===== | ||
+ | В этом примере мы рассмотрим процесс замены [[road:commons_tasks:purpose_objects_semantics:start|объекта семантики]] у [[road:work_with_cmm:create_and_edit_surface_new:notion_dots_new|точки поверхности]] и изменение значений его свойств. | ||
+ | |||
+ | Изменение семантики точки осуществляется через специальный класс [[developers:references:topomatic.sfc.surfacepointextensiveinformation|SurfacePointExtensiveInformation]], который хранит в себе подробную информацию о точке поверхности. Получить эту информацию можно с помощью метода [[developers:references:topomatic.sfc.surfacepointarray.getextensiveinformation_ref_topomatic.sfc.surfacepoint|SurfacePointArray.GetExtensiveInformation()]]. В качестве аргумента метод принимает [[road:work_with_cmm:create_and_edit_surface_new:notion_dots_new|точку поверхности]] или её индекс в [[developers:references:topomatic.sfc.surfacepointarray|массиве точек поверхности]]. | ||
+ | |||
+ | Чтобы поменять [[road:commons_tasks:purpose_objects_semantics:start|семантический объект]] [[road:work_with_cmm:create_and_edit_surface_new:notion_dots_new|точки поверхности]], следует изменить значение свойства [[developers:references:topomatic.sfc.surfacepointextensiveinformation.code|SurfacePointExtensiveInformation.Code]]. В этом примере мы назначим точке объект ''Пункт государственной геодезической сети'', который имеет код ''1000''. | ||
+ | |||
+ | Состояние [[road:commons_tasks:purpose_objects_semantics:start|семантического объекта]] описывается его [[road:commons_tasks:edit_objects:start|семантическими свойствами]] и хранится в классе [[developers:references:topomatic.smt.semanticdataset|SemanticDataSet]]. Это состояние можно получить через свойство [[developers:references:topomatic.sfc.surfacepointextensiveinformation.semantic|SurfacePointExtensiveInformation.Semantic]]. | ||
+ | |||
+ | [[road:commons_tasks:edit_objects:start|Семантические свойства]] являются подтипами [[developers:references:topomatic.smt.semanticpropertynode|SemanticPropertyNode]]. Среди них: | ||
+ | * [[developers:references:topomatic.smt.semanticdoublenode|Topomatic.Smt.SemanticDoubleNode]] - ствойство с плавающей точкой | ||
+ | * [[developers:references:topomatic.smt.semanticintegernode|Topomatic.Smt.SemanticIntegerNode]] - целочисленное свойство | ||
+ | * [[developers:references:topomatic.smt.semanticjumper|Topomatic.Smt.SemanticJumper]] - условный переключатель | ||
+ | * [[developers:references:topomatic.smt.semanticstringnode|Topomatic.Smt.SemanticStringNode]] - строковое свойство | ||
+ | |||
+ | Необходимое [[road:commons_tasks:edit_objects:start|семантическое свойство]] можно получить по значению его свойства [[developers:references:topomatic.smt.semanticnode.tag|SemanticNode.Tag]]. Далее, зная его тип можно присвоить ему соответствующее значение. В этом примере мы будем менять значение свойства с плавающей точкой со значением тега ''CENTER''. | ||
+ | |||
+ | {{ :developers:tutorial:surfaceelementsedit:tutsemprop.png?nolink&600 |}} | ||
+ | |||
+ | Список [[road:commons_tasks:edit_objects:start|семантических свойств]] объекта можно получить с помощью метода [[developers:references:topomatic.smt.semanticdataset.gettags_system.collections.generic.idictionary_2|SemanticDataSet.GetTags()]]. В качестве аргумента метод принимает словарь [[https://docs.microsoft.com/ru-ru/dotnet/api/system.collections.generic.dictionary-2?view=net-6.0|Dictionary<string,string>]], который будет заполнен доступными значениями. | ||
+ | |||
+ | После назначения [[road:commons_tasks:purpose_objects_semantics:start|объекта семантики]] у [[road:work_with_cmm:create_and_edit_surface_new:notion_dots_new|точки поверхности]], следует вызвать метод [[developers:references:topomatic.sfc.layer.surfaceextentions.refreshpointsign|Surface.RefreshPointSign()]] для перерисовки отображения условного знака объекта. | ||
+ | |||
+ | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «change_point_semantic_code» предложит пользователю выбрать [[road:work_with_cmm:create_and_edit_surface_new:notion_dots_new|точку поверхности]] и задать значение отметки центра. Результатом действия станет изменение [[road:commons_tasks:purpose_objects_semantics:start|семантического объекта]] [[road:work_with_cmm:create_and_edit_surface_new:notion_dots_new|точки поверхности]] и заполнение свойства ''Отметка центра'' значением указанным пользователем. | ||
+ | |||
+ | <code csharp> | ||
+ | { | ||
+ | ... | ||
+ | [cmd("change_point_semantic_code")] | ||
+ | private void ChangePointSemanticCode() | ||
+ | { | ||
+ | //Находим активный SurfaceLayer | ||
+ | var cadview = CadView; | ||
+ | if (cadview == null) return; | ||
+ | |||
+ | var layer = SurfaceLayer.GetSurfaceLayer(cadview); | ||
+ | if (layer == null) return; | ||
+ | |||
+ | //Выбираем точку поверхности | ||
+ | int ind; | ||
+ | var res = layer.PickOnePoint(null, out ind, "Выберите точку поверхности:"); | ||
+ | if (res == GetPointResult.Cancel) return; | ||
+ | |||
+ | //Задаём отметку | ||
+ | var elev = 0.0; | ||
+ | res = CadCursors.GetDouble(cadview, ref elev, "Задайте отметку центра:"); | ||
+ | if (res == GetPointResult.Cancel) return; | ||
+ | |||
+ | //Фиксируем момент начала внесения изменений в поверхность | ||
+ | var sfc = layer.Surface; | ||
+ | sfc.BeginUpdate("Преобразование точки поверхности в пункт гос. геод. сети"); | ||
+ | |||
+ | try | ||
+ | { | ||
+ | //Задаём точке код объекта и присваиваем значение свойству | ||
+ | var info = sfc.Points.GetExtensiveInformation(ind); | ||
+ | info.Code = 1000; | ||
+ | |||
+ | var tags = new Dictionary<string, string>(); | ||
+ | info.Semantic.GetStringTags(tags); | ||
+ | if (tags.ContainsKey("CENTER")) info.Semantic["CENTER"] = elev; | ||
+ | |||
+ | sfc.RefreshPointSign(info); | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | //Фиксируем окончание внесения изменений в поверхность | ||
+ | sfc.EndUpdate(); | ||
+ | } | ||
+ | |||
+ | //Очищаем список выбранных элементов поверхности | ||
+ | //и сообщаем CadView о необходиомсти обновить отображение его содержимого | ||
+ | layer.SelectionSet.Clear(); | ||
+ | cadview.Unlock(); | ||
+ | cadview.Invalidate(); | ||
+ | } | ||
+ | ... | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | {{ :developers:tutorial:surfaceelementsedit:tutchangepointsemantic.png?nolink&600 |}} | ||
+ | |||
+ | Теперь необходимо сформировать наш файл .plugin. Заполните его следующим образом. | ||
+ | |||
+ | <code javascript> | ||
+ | { | ||
+ | "assemblies": { | ||
+ | "TutorialEditSurfaceElements": { | ||
+ | "assembly": "TutorialEditSurfaceElements.dll, TutorialEditSurfaceElements.ModulePluginHost" | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | "actions": { | ||
+ | "id_create_hill_or_pit": { | ||
+ | "cmd": "create_hill_or_pit", | ||
+ | "title": "Построить насыпь или котлован" | ||
+ | }, | ||
+ | "id_change_point_semantic_code": { | ||
+ | "cmd": "change_point_semantic_code", | ||
+ | "title": "Преобразование точки поверхности в пункт гос. геод. сети" | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | "menubars": { | ||
+ | "rbproj": { | ||
+ | "items": [ | ||
+ | { | ||
+ | "id": "tutorial_menu", | ||
+ | "title": "Tutorial", | ||
+ | "items": [ | ||
+ | "id_create_hill_or_pit", | ||
+ | "id_change_point_semantic_code" | ||
+ | ] | ||
+ | } | ||
+ | ] | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Результатом запуска проекта будет появление в главном меню пункта «Tutorial», с подпунктами, которые будут работать в соответствии с описанными выше алгоритмами. | ||
+ | |||
+ | <note>[[developers:tutorial:tutorialcode|Исходный код]] примера расположен в проекте **"TutorialEditSurfaceElements"**.</note> |