MapBasic - Нарисовать сектор на карте. Как?

MapInfo, MapBasic
tems-ya
Интересующийся
Сообщения: 39
Зарегистрирован: 28 янв 2015, 22:07
Репутация: 1
Откуда: Воронеж

Re: MapBasic - Нарисовать сектор на карте. Как?

Сообщение tems-ya » 29 мар 2015, 22:19

По старой доброй традиции, неоднократно проверенной временем, сохраним достигнутые результаты в надежном месте, т.е. здесь. Функция рисует сектор или часть сектора между двух радиусов для любых углов от 0 до 359.(9)

Код: Выделить всё

'=========================================================================================================================================================================================================
'           Функция рисования универсального сектора ( в том числе и куска сектора между r_start и r_end)
'
'   azimut      - азимут
'   SectorWidth - ширина сектора
'   r_start     - ближняя граница куска сектора, если 0 - то полный сектор
'   r_end       - дальняя граница куска сектора
'   LAT0,LON0   - координаты центра
'   STYPE       - тип сектра ('1'- область, '0'- только контур (линия)) 
'
'   вызываем CreateUSector(azimut, 60,  0,  300, LAT, LON, 1) "полигон" сектор
'   вызываем CreateUSector(azimut, 60, 150, 300, LAT, LON, 0) "контур" полусектор - кусок сетора от 150м до 300м
'
'=========================================================================================================================================================================================================
Function CreateUSector( ByVal azimut as float, ByVal SectorWidth as float, ByVal r_start as float, ByVal r_end as float, ByVal LAT0 as float, ByVal LON0 as float, ByVal STYPE as Logical) as object

    dim tmpCircle_start, tmpCircle_end, tmpArc_start, tmpArc_end, plArc_start, plArc_end, line1, line2, plPartSector as object 
    dim x1,y1, x2,y2 as float
    dim xx1,yy1, xx2,yy2 as float
	
'	Для использования Create Arc необходимы дополнительные манипуляции. Необходимо знать
'   координаты концов одной диагонали квадрата, в который может быть вписана воображаемая 
'   окружность того же радиуса, что и у нашей дуги. Для построения необходимо указать
'   координаты левого верхнего угла квадрата  (azimut = 315), координаты правого нижненго 
'   угла квадрата (azimut = 135), а также начальный и конечный угол дуги относительно 0° 
'   за который в процедуре Create Arc принято направление НА ВОСТОК !!!, а отсчет ведется
'   ПРОТИВ часовой стрелки !!!
 	
	dim ArcAngleStart, ArcAngleEnd as float  'углы начала и конца дуги отсчитанные от востока


'	устанавливаем систему координат, единицы измерения и точность построения сектора
	Set CoordSys Earth Projection 1, 104
	Set Distance Units "m"
	Set Resolution 1.8*SectorWidth 'определяет точность отрисовки дуги, чем больше тем выше точность


    'Для упращения программирования алгоритма инициализируем так, если r_start не 0, то значения пересчитаются
    x1 = LON0
    y1 = LAT0

    x2 = LON0
    y2 = LAT0

    'Вычисляем углы для построения дуги
    ArcAngleStart = Arc_angle_convert(azimut + SectorWidth/2)
    ArcAngleEnd   = Arc_angle_convert(azimut - SectorWidth/2)


    '-----------------------------------------------------------------------------
    If r_start <> 0 Then    'если r_start = 0, то ветка просто не будет выполняться

        'рисуем окружность меньшего радиуса
        tmpCircle_start = CreateCircle(LON0,LAT0, r_start)

            'координаты левой верхней точки меньшего радиуса- (x1,y1) 	
        x1 = ObjectGeography(tmpCircle_start,OBJ_GEO_MINX)  'lon_min
        y1 = ObjectGeography(tmpCircle_start,OBJ_GEO_MAXY)  'lat_max
            'координаты правой нижней точки меньшего радиуса - (x2,y2)
        x2 = ObjectGeography(tmpCircle_start,OBJ_GEO_MAXX)  'lon_max
        y2 = ObjectGeography(tmpCircle_start,OBJ_GEO_MINY)  'lat_min

            'рисуем дугу меньшего радиуса
        Create Arc Into Variable tmpArc_start (x2,y2) (x1,y1) ArcAngleStart ArcAngleEnd

            'превращаем ее в полилинию
        plArc_start = ConvertToPline(tmpArc_start)
    
            'определяем координаты концов меньшей полилинии
        x1 = ObjectNodeX(plArc_start, 1, 1)  'чтение долготы первой точки
        y1 = ObjectNodeY(plArc_start, 1, 1)  'чтение широты первой точки
        x2 = ObjectNodeX(plArc_start, 1, ObjectInfo(plArc_start, OBJ_INFO_NPNTS))  'чтение долготы последеней точки
        y2 = ObjectNodeY(plArc_start, 1, ObjectInfo(plArc_start, OBJ_INFO_NPNTS))  'чтение широты последеней точки

    End If
    '-----------------------------------------------------------------------------

    'рисуем окружность большего радиуса
    tmpCircle_end   = CreateCircle(LON0,LAT0,r_end)

        'координаты левой верхней точки большего радиуса- (x1,y1) 	
    xx1 = ObjectGeography(tmpCircle_end,OBJ_GEO_MINX)  'lon_min
    yy1 = ObjectGeography(tmpCircle_end,OBJ_GEO_MAXY)  'lat_max
        'координаты правой нижней точки большего радиуса - (x2,y2)
    xx2 = ObjectGeography(tmpCircle_end,OBJ_GEO_MAXX)  'lon_max
    yy2 = ObjectGeography(tmpCircle_end,OBJ_GEO_MINY)  'lat_min

	'рисуем дугу большего радиуса
	Create Arc Into Variable tmpArc_end  (xx2,yy2) (xx1,yy1) ArcAngleStart ArcAngleEnd

    'превращаем ее в полилинию
    plArc_end   = ConvertToPline(tmpArc_end)
    
            'определяем координаты концов полилинии
        xx1 = ObjectNodeX(plArc_end, 1, 1)  'чтение долготы первой точки
        yy1 = ObjectNodeY(plArc_end, 1, 1)  'чтение широты первой точки
        xx2 = ObjectNodeX(plArc_end, 1, ObjectInfo(plArc_end, OBJ_INFO_NPNTS))  'чтение долготы последеней точки
        yy2 = ObjectNodeY(plArc_end, 1, ObjectInfo(plArc_end, OBJ_INFO_NPNTS))  'чтение широты последеней точки

    '-----------------------------------------------------------------------------


    'рисуем боковые линии сектора
	line1 = CreateLine(x1,y1, xx1,yy1)
	line2 = CreateLine(x2,y2, xx2,yy2)
	
	'объединяем все линии и дуги в одну полилинию
    plPartSector = Combine(line1,line2)
    plPartSector = Combine(plArc_end,   plPartSector)
    If r_start <> 0 Then
        plPartSector = Combine(plArc_start, plPartSector)
    End If

    If STYPE = 0 Then 'возвращаем контур
        CreateUSector = plPartSector
    Else
        'преобразовываем ее в область
        CreateUSector = ConvertToRegion(plPartSector)
    End If
    
	
End Function

Код: Выделить всё

'--------------------------------------------------------------------------------------
'      Пересчет азимутов для оператора 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




Использовать в коде можно так (вставляем на косметический слой)

Код: Выделить всё

Dim curSector as Object

'......................................

      curSector = CreateUSector( AZIMUTH, 60, r_min, r_max, LAT0, LON0, 1)
      Insert Into WindowInfo(FrontWindow(), WIN_INFO_TABLE) (obj) Values (curSector)

Конструктивная критика(дополнения, улучшения) приветствуются.

Ответить

Вернуться в «MapInfo»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей