FoxPro Club Главная

Конференция Решения Фотоальбом Сайт М.Дроздова Статьи Файловый архив Книга Visual FoxPro 9.0 Русский Help для Visual FoxPro
Пользователей: 9212
Вход

Более глубокая интеграция приложений Visual FoxPro и ГИС MapInfo Professional.



В статье рассмотрены особенности механизма взаимодействия приложения Visual FoxPro с пространственными данными в среде MapInfo Professional.

После размещения статьи «Создание ГИС на Visual FoxPro средствами MapInfo Professional», мне часто приходилось отвечать на вопросы о возможности более тесной интеграции приложений Visual FoxPro c ГИС MapInfo Professional и связанных с этим особенностях реализации COM модели MapInfo Professional. По этому, прежде всего – приношу извинения тем коллегам, на вопросы которых отвечал с опозданием, излишне кратко, или не отвечал вовсе.

Не смотря на то что, в принципе, среда MapInfo Professional содержит всё необходимое для организации связи геопространственных данных с семантическими данными как во внутреннем формате MapInfo, так и во внешних БД, на практике оказывается, что возможностей MapInfo для построения эффективного рабочего места бывает не всегда достаточно. А, принимая во внимание, непревзойденную продуктивность VFP в работе с данными, решение использовать для разработки Visual FoxPro было бы оптимальным выбором!

Первое что, как правило, требуется при разработке информационной системы с географической составляющей – это показать «ГДЕ». То есть, [Москва, Красная площадь, д.1] – это где? При этом, во-первых, в окне карты должно произойти перемещение видимой части окна, так чтобы объект [Москва, Красная площадь, д.1] находился в области отображения окна карты. Во-вторых, масштаб отображения должен быть подобран таким образом, чтобы объект был, различим в окне карты, видимыми должно оказаться достаточное количество соседних объектов, составляющих окружение искомого объекта.

Второе – при выборе объекта на карте, необходимо представить информацию, из БД имеющую отношение к выделенному на карте объекту.

Надо заметить, что второе требование невозможно выполнить располагая только MapInfo Professional. Потребуется среда программирования MapBasic, где необходимо написать и откомпилировать процедуру вызова переопределения системного события [SelChangedHandler], например такую:

Declare Sub SelChangedHandler  
     
  call SelChangedHandler()  
     
  Sub SelChangedHandler   
    If SelectionInfo(3) > 0 Then   
      Run Menu Command ID 1001  
    End If   
  End Sub

Здесь находится уже откомпилированная, готовая к выполнению в среде MapInfo Professional, программа: [hook_selection.mbx]. В этой процедуре каждый раз при срабатывании события [SelChangedHandler] выполняется команда, назначенная кнопке с идентификатором [1001].

Важно! В среде MapInfo Professional не могут выполняться программы, откомпилированные в среде MapBasic с большим номером версии, чем MapInfo Professional. Файл [hook_selection.mbx] создан в среде MapBasic 9.5, которую можно скачать на сайте www.mapinfo.com: www.mapinfo.com.

Теперь рассмотрим код класса на Visual FoxPro, реализующий интересующие нас возможности.

*!*  
 *!*   организация связи приложения VFP и карты MapInfo  
 *!*  
 *!*  
 *!*   организация связи приложения VFP и карты MapInfo  
 *!*  
 *!*   пример использования:  

 *!*   Public oForm As Form  
 *!*   m.oForm=Createobject([demo_form],[C:\callback_map\map01.tab])  
 *!*   m.oForm.Show()  
 *!*  
  Define Class demo_form As Form  
        Top=0  
        Left=0  
        Height=200  
        Width=450  
        ShowWindow=2  
        DoCreate=.T.  
        BorderStyle=2  
        Caption=[DEMO: callback and managment by map from MapInfo]  
        MaxButton=.F.  
        MinButton=.F.  
        Name=[Form1]  
        cMap=[]  
        Enabled_ChangedHandler=[ON]  
     
        Add Object list1 As ListBox With ;  
              Height=150,;  
              Left=1,;  
              Top=1,;  
              Width=450,;  
              Name=[List1]  
     
        Add Object command1 As CommandButton With ;  
              Top=171,;  
              Left=360,;  
              Height=25,;  
              Width=85,;  
              Caption=[Закрыть],;  
              Name=[Command1]  
     
        Procedure Init(cMap As Character) As VOID  
        This.cMap=m.cMap  
        Public pomi As Object  
        Try  
              m.poMI=Getobject(,[MapInfo.Application])  
        Catch  
              m.poMI=Createobject([MapInfo.Application])  
        Endtry  
        If Type([m.poMI.Name])#[C]  
              Messagebox([Ошибка при попытке обратиться к "MapInfo.Application"],;  
                    16+4096,[Внимание],15000)  
              Return .F.  
        Endif  
        m.poMI.Visible=.T.  
        m.poMI.SetCallback(This)  
        m.poMI.Do([Alter ButtonPad ID 4 ]+;  
              [Add PushButton Calling OLE "DEMO_ChangedHandler" ID 1001])  
        m.poMI.Do([Run application "C:\callback_map\hook_selection.mbx"])  
        m.poMI.Do([Open Table "]+This.cMap+;  
              [" Interactive Map From "]+Juststem(This.cMap)+["])  
        Endproc && Init  

     
        Procedure DEMO_changedhandler(lcParam As Character) As VOID  
        If Thisform.Enabled_ChangedHandler=[ON] And ;  
              Val(m.poMI.Eval([SelectionInfo(3)]))>0  
                
              Local lc_MI_query As Character  
              m.lc_MI_query=m.poMI.Eval([SelectionInfo(2)])  
              Local lcValueFromMap As Character  
              m.lcValueFromMap=m.poMI.Eval(m.lc_MI_query+[.txt])  
              Thisform.list1.AddItem(m.lcValueFromMap)  
              Thisform.list1.Value=Thisform.list1.ListCount  
        Endif  
        Endproc && demo_changedhandler  

     
        Procedure Destroy  
        If Type([m.poMI.Name])=[C]  
              m.poMI.Do([Alter ButtonPad ID 4 Show])  
              m.poMI.Do([Alter ButtonPad ID 4 Remove ID 1001])  
              m.poMI.Do([Close All Interactive])  
        Endif  
        m.poMI=Null  
        Release pomi  
        Endproc && Destroy  

     
        Procedure list1.Click  
        Thisform.Enabled_ChangedHandler=[OFF]  
        m.poMI.Do([select obj from Map01 where txt="]+;  
              This.ListItem(This.Value)+[" into _tmp])  
        m.poMI.Do(;  
              [set map center ]+;  
              [(CentroidX(_tmp.obj),]+;  
              [CentroidY(_tmp.obj))]+Chr(13)+Chr(10)+;  
              [zoom Distance( ]+;  
              [ObjectGeography(_tmp.obj,1),]+;  
              [ObjectGeography(_tmp.obj,2),]+;  
              [ObjectGeography(_tmp.obj,3),]+;  
              [ObjectGeography(_tmp.obj,4),"m")*8 Units "m"])  
        Thisform.Enabled_ChangedHandler=[ON]  
        Endproc && list1.Click  

     
        Procedure command1.Click  
        Thisform.Release  
        Endproc && command1.Click  
     
  Enddefine && demo_form



Здесь, в методе [Init] реализовано переопределение системного события MapInfo [SelChangedHandler] – срабатывающего каждый раз, когда происходит смена выделенного объекта на карте. Для этого в метод [SetCallback] COM экземпляра MapInfo передаётся ссылка на объект, содержащий метод [DEMO_ChangedHandler], т.е. наша форма. Следующая команда: [Alter ButtonPad…] создаёт кнопку в панели инструментов «Команды», связывает её с вызовом метода [DEMO_ChangedHandler], назначает идентификатор кнопки [1001]. После чего в среде MapInfo запускается программа [hook_selection.mbx], которая и будет при срабатывании системного события [SelChangedHandler] выполнять команду, назначенную кнопке c идентификатором [1001]. Затем, командой [Open Table…], открывается карта.

Это обеспечивает выполнение второго требования, т.е. – при выборе объекта на карте, представить информацию, из БД имеющую отношение к выделенному на карте объекту. Осталось только написать код метода [DEMO_ChangedHandler]. В рассматриваемом классе, метод [DEMO_ChangedHandler] добавляет в ListBox на форме атрибут выбранного на карте объекта (поле [txt]).

Надо признать, что механизм переопределения событий MapInfo – является яркой особенностью этого, во всех отношениях замечательного продукта.

Первое требование – показать «ГДЕ», реализовано в событии [List1.Click]. Здесь, командой [select obj from Map01 …] выбираем искомый объект на карте. Затем последовательным выполнением команд [set map center…] и [zoom…] устанавливаем центр окна отображения карты по координатам центроида выбранного объекта и назначаем размер фрагмента, показанного в окне карты большим в 8 раз прямоугольника описанного вокруг выделенного объекта.

Обратите внимание, что с целью избежать срабатывания системного события [SelChangedHandler], при программном выборе объекта на карте, событие [List1.Click] начинается с установки значения [OFF] флага [Enabled_ChangedHandler], который проверяется в методе [DEMO_ChangedHandler], и заканчивается возвращением флага [Enabled_ChangedHandler] в значение [ON].




Маставичус Владас
alpha2omega@mail.ru


Вернуться к списку статей






© 2000-2017 Fox Club 
При размещении любых материалов с сайта на других ресурсах- прямая ссылка на www.foxclub.ru обязательна
Яндекс.Метрика