Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Андрей Могильный
Зарегистрирован: 21.03.2006 Сообщения: 864
|
Добавлено: Вт Ноя 22, 2011 2:01 pm Заголовок сообщения: |
|
|
1. Все верно. Командой:
Set CoordSys Nonearth Units ""m"" Bounds (0.1, 0.1) ( 40000, 40000)
вы задаете проекцию, в которой работает ваша MapBasic-программа. Она может отличаться от проекций таблиц, например. Т.е. эта команда обязательна перед началом работы с координатами объектов в MapBasic-коде.
Если вы убираете предложение по координатной системе в Create Map, то карта у таблицы создается с проекцией по умолчанию в MapInfo, которой по-видимому у вас является Долгота/Широта.
2. Варианта 2.
2.1. Создавать объект не через связку Create Region + Alter Object. А сразу писать Create Region со всеми точками. Вариант трудновыполним в программировании, но все же.
2.2. В конце кода сделать полное пересоздание созданного региона, например, функцией конвертации в полилинию и обратно в полигон. Тогда центроид встанет на место у конечного полигона. |
|
Вернуться к началу |
|
|
xax_nv
Зарегистрирован: 28.10.2011 Сообщения: 43 Откуда: г. Нижневартовск
|
Добавлено: Ср Ноя 23, 2011 8:25 am Заголовок сообщения: |
|
|
Андрей, большое спасибо!
По первому пункту теперь понятно. По второму пункту решил пойти путем создания полилинии и конвертации ее в полигон. Но тут возник еще один вопрос. Задаю для полилинии Pen (2,2, 16711680), при конвертации в полигон стиль меняется на стиль по умолчанию, хотя в Справочнике по MapBasic'у сказано, что "Сохраняются все значения стилей оформления объекта." Как задать стиль оформления полигона после конвертации? Попробовал такой вариант:
mi.do "Alter Object obj_region Info obj_info_pen, MakePen (2,2, 16711680)"
Пишет, что "В этом выражении нельзя использовать неинициализированную переменную object" |
|
Вернуться к началу |
|
|
Андрей Могильный
Зарегистрирован: 21.03.2006 Сообщения: 864
|
Добавлено: Чт Ноя 24, 2011 6:16 am Заголовок сообщения: |
|
|
Конвертировать нужно функциями MapBasic - ConvertToPline, ConvertToRegion. Согласно документации - "сохраняются все значения стилей оформления объекта. Недостающие атрибуты используются по текущим значениям стилей."
Т.е. потеряется только заливка полигона. Делается тоже стандатно - перед конвертацией считываете текущее значение заливки в переменную. После конвертации восстанавливаете его у объекта. |
|
Вернуться к началу |
|
|
xax_nv
Зарегистрирован: 28.10.2011 Сообщения: 43 Откуда: г. Нижневартовск
|
Добавлено: Чт Ноя 24, 2011 8:36 am Заголовок сообщения: |
|
|
Андрей, добрый день!
Я и использую эти функции. Вот фрагмент кода:
mi.do "Create Region Into Variable obj_region 0 Pen (2,2, 16711680) Brush (1,0,16777215)"
For i = 1 To boss
mi.do "Alter Object obj_region Node Add (" & rs!obr5 & "," & rs!obr4 & ")"
nUch = rs!nUch
rs.MoveNext
Next i
mi.do "obj_pline=ConvertToPline(obj_region)"
mi.do "obj_region=ConvertToRegion(obj_pline)"
mi.do "Insert Into CurUch (Object,nUch) Values (obj_region," & Chr(34) & nUch & Chr(34) & ")"
mi.do "Commit Table CurUch Interactive"
mi.do "Map From CurUch"
Про заливку сейчас не говорю, но и стиль границы не сохраняется.
Возможно это зависит от версии MI, у меня 7.0 |
|
Вернуться к началу |
|
|
xax_nv
Зарегистрирован: 28.10.2011 Сообщения: 43 Откуда: г. Нижневартовск
|
Добавлено: Вт Мар 13, 2012 8:51 am Заголовок сообщения: |
|
|
Приветствую всех!
Решил вернуться к началу топика.
Считываю координаты выделенного объекта из MapInfo в MS Access следующим кодом:
Код: |
Public Sub fromMItoObraz1()
Dim MapInfo As Object
Dim n As Integer, objtype As Integer
Dim S As String, tablica As String
Dim objnpoly As Integer, counter As Integer, NP As Integer
Dim X As String, Y As String
Set MapInfo = GetObject(, "MapInfo.Application")
MapInfo.Do "Set CoordSys Nonearth units ""m"" Bounds (0.1,0.1) ( 40000,40000)"
MapInfo.Do "Set Distance Units ""m"""
n = Val(MapInfo.Eval("SelectionInfo(3)")) '3= SEL_INFO_NROWS
If n > 1 Or n = 0 Then Exit Sub
objnpoly = Val(MapInfo.Eval("ObjectInfo(Selection.obj, 21)")) '21 -OBJ_INFO_NPOLYGONS число ломаных компонент
For i = 1 To objnpoly
counter = Val(MapInfo.Eval("ObjectInfo(Selection.obj, 21 + " & i & ")")) 'кол-во узлов objnpoly - ной
For j = 1 To counter
NP = NP + 1
X = Val(MapInfo.Eval("ObjectNodeX(Selection.obj, " & i & ", " & j & ")")) ' Определяет координату X NumPoint -ного узла
Y = Val(MapInfo.Eval("ObjectNodeY(Selection.obj, " & i & ", " & j & ")")) ' Определяет координату Y NumPoint -ного узла
If j = counter Then
CurrentDb.Execute _
"insert into tblObraz1 (obr1, obr2, obr3, obr4,kod,nUch) " & _
"VALUES(" & NP - counter + 1 & ", " & Y & ", " & X & ", '0.1', " & Forms!frmProjects!sForm.Form!id.Value & ",'" & Forms!frmProjects!sForm.Form!numUch.Value & "')"
Forms!frmProjects!sForm.Form.sfObraz1.Requery
NP = NP - 1
Else
CurrentDb.Execute _
"insert into tblObraz1 (obr1, obr2, obr3, obr4,kod,nUch) " & _
"VALUES(" & NP & ", " & Y & ", " & X & ", '0.1', " & Forms!frmProjects!sForm.Form!id.Value & ",'" & Forms!frmProjects!sForm.Form!numUch.Value & "')"
Forms!frmProjects!sForm.Form.sfObraz1.Requery
End If
Next j
If i <> objnpoly Then CurrentDb.Execute _
"insert into tblObraz1 (kod) " & _
"VALUES(" & Forms!frmProjects!sForm.Form!id.Value & ")"
Forms!frmProjects!sForm.Form.sfObraz1.Requery
Next i
Set MapInfo = Nothing
Exit Sub
End Sub
|
Все прекрасно работает, координаты считываются и многоконтурных объектов, и объектов с "дырками". В таблице MS Access координаты контуров отделяются пустой строкой.
Вопрос в следующем: как определить, что контур является "дыркой".
Вариантов объектов может быть множество, в том числе объект может содержать несколько полигонов с "дырками", плюс ко всему в составе объекта могут быть еще и просто полигоны, без дырок. Задача получить признак, что это "дырка", даже без привязки к конкретному полигону.
Для примера "картинка" такого сложного объекта.
|
|
Вернуться к началу |
|
|
Андрей Могильный
Зарегистрирован: 21.03.2006 Сообщения: 864
|
Добавлено: Вт Мар 13, 2012 5:33 pm Заголовок сообщения: |
|
|
Используйте географические операторы:
objectA Contains Entire objectB граница объекта B полностью лежит внутри границ объекта A;
objectA Entirely Within objectB граница объекта A полностью лежит внутри границ B;
т.е. берете нужный полигон, обходите в цикле все остальные полигоны в объекте и если есть полное попадание нужного полигона внутрь хотя бы одного, то можно считать что это дырка. |
|
Вернуться к началу |
|
|
xax_nv
Зарегистрирован: 28.10.2011 Сообщения: 43 Откуда: г. Нижневартовск
|
Добавлено: Вт Мар 13, 2012 5:56 pm Заголовок сообщения: |
|
|
Андрей, а можно пример кода? Я с MapBasic'ом пока на "Вы". |
|
Вернуться к началу |
|
|
Андрей Могильный
Зарегистрирован: 21.03.2006 Сообщения: 864
|
Добавлено: Ср Мар 14, 2012 8:27 pm Заголовок сообщения: |
|
|
Не проверял:
Код: |
Function IsHole(O As Object, ByVal APolygonNum As Inetger) As Logical
Dim i As Integer
Dim SourcePolygon, CurrentPolygon As Object
' Получим проверяемый полигон из объекта
SourcePolygon = ExtractNodes(O, APolygonNum, 1, 1, true)
' Обойдем все полигоны в объекте
For i = 1 To ObjectInfo(O, OBJ_INFO_NPOLYGONS)
If i <> APolygonNum Then
' Получим очередной полигон из объекта
CurrentPolygon = ExtractNodes(O, i, 1, 1, true)
' Проверяем на вложенность
If SourcePolygon Entirely Within CurrentPolygon Then
IsHole = True
Exit Function
End If
End If
Next
IsHole = False
End Function
|
В программе MapBasic естественно должна быть установлена правильная текущая координатная система, чтобы правильно работали географические операторы. |
|
Вернуться к началу |
|
|
xax_nv
Зарегистрирован: 28.10.2011 Сообщения: 43 Откуда: г. Нижневартовск
|
Добавлено: Вт Июн 26, 2012 7:13 am Заголовок сообщения: |
|
|
Приветствую всех!
Как из MS Access объявить массив MI? На строку
Код: |
MapInfo.Do "Dim AP() As Object" |
выдает ошибку - "Синтаксическая ошибка (."
Пробовал в окне MB, та же ошибка. |
|
Вернуться к началу |
|
|
Андрей Могильный
Зарегистрирован: 21.03.2006 Сообщения: 864
|
Добавлено: Вт Июн 26, 2012 12:27 pm Заголовок сообщения: |
|
|
MapInfo.Do "Dim AP(0) As Object" |
|
Вернуться к началу |
|
|
xax_nv
Зарегистрирован: 28.10.2011 Сообщения: 43 Откуда: г. Нижневартовск
|
Добавлено: Вт Июн 26, 2012 12:42 pm Заголовок сообщения: |
|
|
Андрей Могильный писал(а): |
MapInfo.Do "Dim AP(0) As Object" |
Не помогает, та же ошибка. |
|
Вернуться к началу |
|
|
xax_nv
Зарегистрирован: 28.10.2011 Сообщения: 43 Откуда: г. Нижневартовск
|
Добавлено: Вс Июн 09, 2013 10:01 am Заголовок сообщения: |
|
|
Приветствую всех!
И вновь поднимаю свой топик.
В MS Access создаю объект Полилиния, а затем конвертирую ее в Полигон. Координаты X и Y берутся из рекордсета, порядок координат протв часовой стрелки. А в итоге, когда полилиния замыкается, направление меняется на противоположное и, соответственно, в полигоне направление тоже становится по часовой стрелке. Если все эти операции проделываю вручную, то направление сохраняется против часовой стрелки. Или у меня ошибка в коде, или это особенность MB. Вопрос собственно в следующем, как мне получить направление обхода полигона против часовой стрелки, т.е. соответствующее порядку добавления координат.
Код: |
mi.Do "Create Pline Into Variable obj_pline 0 Pen (2,2, 0)"
For k = 1 To boss3
mi.Do "Alter Object obj_pline Node Add (" & rs3!Y & "," & rs3!X & ")"
rs3.MoveNext
Next k
rs3.MoveFirst
mi.Do "Alter Object obj_pline Node Add (" & rs3!Y & "," & rs3!X & ")"
mi.Do "Insert Into " & TableName & " (Object,nUch,kontur,Note) Values (obj_pline," & Chr(34) & knUch & Chr(34) & ", " & j & ", " & Chr(34) & note & Chr(34) & ")"
mi.Do "Commit Table " & TableName
mi.Do "Select * From " & TableName & " where nUch=""" & knUch & """ And kontur=" & j
mi.Do "Objects Combine Data nUch=nUch,kontur=kontur,Note=Note"
mi.Do "Commit Table " & TableName
mi.Do "Select * From " & TableName & " Where nUch=""" & knUch & """ into tmp_tbl_sel noselect"
mi.Do "update tmp_tbl_sel set obj = ConvertToRegion(obj)"
mi.Do "close table tmp_tbl_sel"
mi.Do "Commit Table " & TableName
mi.Do "Map From " & TableName
|
|
|
Вернуться к началу |
|
|
xax_nv
Зарегистрирован: 28.10.2011 Сообщения: 43 Откуда: г. Нижневартовск
|
Добавлено: Вс Июн 09, 2013 3:54 pm Заголовок сообщения: |
|
|
Несколько упрощу вопрос:
Как программно изменить направление обхода полигона?
Забыл указать версию MI - 7.0 |
|
Вернуться к началу |
|
|
Андрей Могильный
Зарегистрирован: 21.03.2006 Сообщения: 864
|
Добавлено: Вс Июн 09, 2013 10:04 pm Заголовок сообщения: |
|
|
Программно - написать алгоритм, который пересоздаст полигон в обратном порядке. Готовой функции в MapBasic нет. |
|
Вернуться к началу |
|
|
|