Попробовал все-таки додавить идею с громоздкими вычислениями на сфере (т.к. вопрос важный сам по себе). В результате получилось как-то:
Код: Выделить всё
define PI 3.1415926535897932384626433832795
define SQRT2 1.4142135623730950488016887242097
'Средний радиус Земли в м
define RZ 6371000
sub DrowSector_menu_func
Dim azimut, SectorWidth, r , LAT0, LON0 as float
' Данные для примера
azimut = 120 'направление центра сектора в градусах
SectorWidth = 60 'ширина сектора в градусах
r = 300 'длина сектора на местности в метрах
LON0 = 35.976
LAT0 = 56.514
'Call DrowSector(0, 60, 300 ,56.514,35.976)
Call DrowSector(azimut, SectorWidth, r , LAT0, LON0)
End Sub
sub DrowSector( ByVal azimut as float, ByVal SectorWidth as float, ByVal r as float, ByVal LAT0 as float, ByVal LON0 as float )
' система координат устанавливается по таблице
' в которой выполняется построение (WGS84)
'Set CoordSys table input_table
Set Distance Units "m"
Set Resolution 1.8*SectorWidth 'определяет точность отрисовки дуги, чем больше тем выше точность
' Для использования Create Arc потребуются дополнительные вычисления. Нужно определить
' координаты концов одной диагонали квадрата, в который может быть вписана воображаемая
' окружность того же радиуса, что и у наша дуги
dim ArcLat1, ArcLon1 as float 'координаты левого верхнего угла квадрата (azimut = 315)
dim ArcLon2, ArcLat2 as float 'координаты правого нижненго угла квадрата (azimut = 135)
' и вычислить начальный и конечный угол дуги относительно 0° (направление на восток),
' отсчитываемые против часовой стрелки
dim ArcAngleStart, ArcAngleEnd as float 'углы начала и конца дуги отсчитанные от востока
'Вычисляем координаты диагонали
Call calc_coordinats(ArcLat1, ArcLon1, r*SQRT2, 315, LAT0, LON0)
Call calc_coordinats(ArcLat2, ArcLon2, r*SQRT2, 135, LAT0, LON0)
'Вычисляем углы
ArcAngleStart = Arc_angle_convert(azimut + SectorWidth/2)
ArcAngleEnd = Arc_angle_convert(azimut - SectorWidth/2)
' -------------------------------------------------
dim idMap,n as integer
idMap = frontWindow()
dim curArc as object
dim x1,y1, x2,y2 as float
' выполняем построение на редактируемом слое (ss)
Create Point Into Window idMap (LON0,LAT0)
'рисуем дугу
Create Arc Into Window idMap (ArcLon2,ArcLat2) (ArcLon1,ArcLat1) ArcAngleStart ArcAngleEnd
'число строк в открытой таблице
n = TableInfo(input_table,TAB_INFO_NROWS)
'выбираем последние добавленные записи Point и Arc
Select * From input_table Where rowid > n-2
Run Menu Command M_OBJECTS_CONVEX_HULL
' -------------------------------------------------
' руками рисуем линии левой и правой границ сектора
dim latP1,lonP1, azimut_left as float
dim latP2,lonP2, azimut_rigth as float
azimut_left = calc_Azimut_left(azimut, SectorWidth)
Call calc_coordinats(latP1, lonP1, r, azimut_left, LAT0, LON0)
azimut_rigth = calc_Azimut_rigth(azimut, SectorWidth)
Call calc_coordinats(latP2, lonP2, r, azimut_rigth, LAT0, LON0)
Create Line Into Window idMap (LON0,LAT0) (lonP1,latP1)
Create Line Into Window idMap (LON0,LAT0) (lonP2,latP2)
End Sub
'--------------------------------------------------------------------------------------
' Пересчет азимутов для оператора Create Arc
'--------------------------------------------------------------------------------------
Function Arc_angle_convert(ByVAL azimut as float) as float
dim az as float
az = 90 - azimut
If az < 0 Then
Arc_angle_convert = 360 + az
Else
Arc_angle_convert = az
End If
End Function
'--------------------------------------------------------------------------------------
' Вычисление координаты точки расположенной на расстоянии r в направлении azimut
'--------------------------------------------------------------------------------------
Sub calc_coordinats(lat as float, lon as float, ByVal r as float, ByVal azimut as float, ByVal lat0 as float, ByVal lon0 as float )
'dim PI,RZ as float
'PI = 3.1415926535897932384626433832795
'RZ = 6371000 'Средний радиус Земли в м
lat = lat0 + r*cos(azimut*PI/180)/(RZ*PI/180)
lon = lon0 + r*sin(azimut*PI/180)/cos(lat0*PI/180)/(RZ*PI/180)
End Sub
'--------------------------------------------------------------------------------------
' Вычисление азимута левой границы сектора
'--------------------------------------------------------------------------------------
Function calc_Azimut_left(Azimut as float, SectorWidth as float) as float
Dim SectorWidth_div2 as Float
SectorWidth_div2 = SectorWidth/2
If (Azimut - SectorWidth_div2) < 0 Then
calc_Azimut_left = 360 - (SectorWidth_div2 - Azimut )
Else
calc_Azimut_left = Azimut - SectorWidth_div2
End If
End Function
'--------------------------------------------------------------------------------------
' Вычисление азимута правой границы сектора
'--------------------------------------------------------------------------------------
Function calc_Azimut_rigth(Azimut as float, SectorWidth as float) as float
Dim SectorWidth_div2 as Float
SectorWidth_div2 = SectorWidth/2
If (Azimut + SectorWidth_div2) > 360 Then
calc_Azimut_rigth = SectorWidth_div2 - (360 - Azimut )
Else
calc_Azimut_rigth = Azimut + SectorWidth_div2
End If
End Function
Осталось нерешенным несколько проблем:
1)
вызывает меню где требуется ручное вмешательство. Если нужно нарисовать 1000 секторов - это становиться неприемлемым. Можно-ли это как-то побороть или обойти?
2) После создания сектора остается дуга. По идеи ее необходимо удалить. Вопрос как?
3)Руками нарисованные линии-границы секторов немного, но не совпадают с дугой... В рамках данного подхода, если отталкиваться от необходимости руками замкнуть контур, требуется как-то их свести друг с другом. Непонятно как... (Повысить точность вычислений на сфере?? Воспользоваться какими-нибудь процедурами проверки??) Лучше бы данной процедуры избежать совсем...
В свете вышеизложенного гораздо более перспективным выглядит предложенный выше подход:
1. Построить круг
2. Средствами MapBasic получить координаты минимального описывающего прямоугольника
3. По этим координатам построить дугу
4. Превратить дугу в полилинию
5. Средствами MapBasic получить координаты концов дуги (точные!!!)
... далее пока не понятно...
6. Нарисовать две линии из центра ТОЧНО в концы дуги
7. Замкнуть контур и превратить его в область
...или
6. Добавить к полилинии дуги еще одну точку ЦЕНТР и как-то суметь превратить все это сектор???
Сейчас занимаюсь реализацией второго сценария. В общем пока вопросов больше чем ответов. Актуален вопрос с быстродействием. Непонятно, что, где и когда быстрее работает? Оператор, функция? с переменными, с таблицами, с картами и т.д.