FoxPro Club Главная

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

Создание ГИС на Visual FoxPro средствами MapInfo Professional

Цель статьи: продемонстрировать основные приёмы работы при создании геоинформационной системы на VFP, с применением MapInfo Professional. Материал ориентирован на IT-специалистов, работающих в земельных комитетах, геодезических или землеустроительных организациях.

  1. Введение
  2. Запуск экземпляра MapInfo
  3. Создание карт
  4. Окно карты MapInfo в вашем приложении
  5. «Знать ГДЕ – это только начало!»

1.Введение

Земля и объекты недвижимости – надёжный и, к тому же, стабильно растущий актив в большинстве государств. Как и всякий ресурс, земельные участки и другие объекты недвижимости необходимо учитывать. Инвентаризация земельных участков, расположенных на них объектов недвижимости, оценка, а в последующем, переоценка земли и строений осложняется интенсивно меняющимися окружающими условиями, общегосударственным и муниципальным законотворчеством. Расчётные операции, проводимые при оценке земли и объектов недвижимости, используют большое количество параметров имеющих географическую смысловую составляющую. Что, вызывает потребность в информационных системах, позволяющих аналитически обрабатывать географическую информацию.

Продукт MapInfo Professional американской компании MapInfo Corporation, предоставляет возможность включать в ваше приложение на VFP векторные карты совместно с инструментами анализа географической информации. MapInfo Professional позволяет выполнять программы MapBaisic – языке программирования, входящем в интегрированную среду разработки MapInfo. Разработчику предоставляется COM интерфейс MapInfo, позволяющий управлять отображением карт, а так же выполнять отдельные команды и программы MapBaisic.

 

2. Запуск экземпляра MapInfo

После установки MapInfo Professional в реестре OC Windows регистрируется класс «MapInfo.Application», если вы используете MapInfo Runtime, то класс «MapInfo.Runtime». Таким образом, запуск MapInfo:

Public poMI As Object
  m.poMI=CreateObject([MapInfo.Application])

Так, как метода [.Quit] COM модель MapInfo не предусматривает, завершение работы экземпляра MapInfo реализуется следующим образом:

m.poMI=Null
  Release poMI

 

3.Создание карт

Для включения векторной карты в ваше приложение, вы должны располагать такой картой. В некоторые дистрибутивы MapInfo Professional включены карты большинства стран и крупных городов Европы, Азии и Северной Америки. Но что делать, если вам нужна межевая карта садово-дачных участков в пригороде какого-нибудь Смоленска или Стамбула. Не знаю как в Турции, но качество материалов, которые вам по умеренной цене может предоставить земельный комитет администрации какого-нибудь Смоленска, вас не устроит. (Может быть, вы даже работаете в этом земельном комитете?) А карта нужна! Но, вы узнаёте, что некая землеустроительная контора проводила геодезическую съёмку и межевание той самой местности, карта которой вам так нужна! (А может, вы работаете в этой землеустроительной конторе?)

Итак, рассмотрим создание карты по координатным данным, полученным геодезической съёмкой. Не вдаваясь в подробности, можно считать что, карта в MapInfo это таблица, каждой строке которой может соответствовать графический объект. С помощью метода [.Do()] COM объекта MapInfo, выполним следующую последовательность команд MapBasic:

Local lcCommandMapBaisic As Character
  Text To m.lcCommandMapBaisic TextMerge Noshow

  Create Table "myMap" (c1 Integer,c2 Char(100))
  File "c:\gis\myMap.TAB"
  Type NATIVE
  Charset "WindowsCyrillic"

  Create Map For "myMap"
  CoordSys NonEarth Units "m" Bounds (0,0) (10000,10000)

  Browse * From "myMap"
  Map From "myMap"

  EndText

  m.poMI.Do(m.lcCommandMapBaisic)
  Release lcCommandMapBaisic

Здесь, первая команда [Create Table …] создаёт таблицу [myMap] с столбцами [c1] типа Integer и [c2] типа Char(100), файл таблицы размещается в каталоге [c:\gis\], тип таблицы – внутренний формат MapInfo, кодовая страница таблицы [WindowsCyrillic]. Следующая команда [Create Map …], создаёт в таблице [myMap] столбец [obj], имеющий специальный тип MapInfo, позволяющий создавать и хранить графические объекты, составляющие карту. Система координат карты задаётся фразой [CoordSys NonEarth], что соответствует декартовой системе координат и подходит для картографирования плана местности. Параметр [Units] задаёт единицу измерения 1 метр, а параметр [Bounds] границы карты. Оставшиеся две команды MapBasic [Browse …] и [Map From …] открывают окна таблицы и карты соответственно и имеют интуитивно понятный синтаксис.

Поле карты создано. Следующий шаг – добавление графических примитивов на карту. Пример:

Local lcCommandMapBaisic As Character
  Text To m.lcCommandMapBaisic TextMerge Noshow

  Set CoordSys NonEarth Units "m" Bounds (0,0)(10000,10000)

  Dim loRegion As Object
  Create Region Into Variable loRegion 3
  6 (10,100)(100,100)(100,90)(20,90)(20,70)(10,70)
  6 (110,100)(120,100)(120,50)(80,50)(80,60)(110,60)
  4 (10,50)(70,50)(70,60)(10,60)

  Insert Into "myMap" (c1,obj) Values (1,loRegion)
  UnDim loRegion

  Set Map Zoom Entire

  EndText

  m.poMI.Do(m.lcCommandMapBaisic)
  Release lcCommandMapBaisic

Обратите внимание – первой командой MapBasic [Set CoordSys …] мы устанавливаем соответствие координат создаваемых графических объектов координатному полю карты. Затем, объявляем переменную [loRegion] типа [Object]. Командой [Create Region …] создаём графический объект, сохраняя результат в ранее объявленную переменную. После чего, командой [Insert Into …] вставляем в таблицу [myMap] новую строку, используя 1, как значение для поля [c1] и переменную [loRegion], как значение для поля [obj]. Команда [UnDim …] удаляет переменную [loRegion]. Последняя команда MapBasic [Set Map Zoom Entire] – масштабирует изображение в рабочей области окна карты.

Вот вид окна MapInfo Professional, демонстрирующий результат нашей работы:

 

Таким образом, располагая координатными данными геодезических работ, не составляет труда программно формировать команды создания графических объектов, подставляя координатные данные геодезических замеров и тем самым, создавать векторные карты и планы местности.

Одно важное замечание. Вы, конечно, обратили внимание, на то обстоятельство, что создавая карту, мы не использовали масштаб. Ничего странного – в векторном картографировании очень удобно создавать карты именно в масштабе 1:1, как мы и сделали, для просмотра карты на экране можно выбрать произвольный масштаб. При печати твёрдых копий карт или планов, принято придерживаться стандартных масштабов 1:200, 1:500, 1:1000, 1:2000 и т.д.

 

4.Окно карты MapInfo в вашем приложении

Код класса VFP, демонстрирующий приёмы работы с картой MapInfo:

 * пример использования  
 *Public poFM As Form  
 *m.poFM=Createobject([form4map],[c:\gis\myMap.tab])  
 *m.poFM.Show()  
 *-----------------------------------------------------------------------  
  Define Class form4map As Form
  map_hwnd=0 && указатель окна карты  

  Procedure Init
  Lparameters lcFileMap
  This.AddProperty([Map],Createobject([Mapinfo.Application]))
 * окно следующего документа MapInfo   
 * будет дочерним окном этой формы  
  This.Map.Do([Set Next Document Parent ]+;
  Transform(This.HWnd)+[ Style 1])
 * открытие карты  
  This.Map.Do([Open Table "]+m.lcFileMap+[" ]+;
  [Map From "]+Juststem(m.lcFileMap)+["])
 * определение указателя окна карты  
  This.map_hwnd=Val(This.Map.Eval([WindowInfo(FrontWindow(),12)]))
 * объявление функции для управления размером окна карты  
  Declare Integer MoveWindow In user32 ;
  Integer HWnd,;
  Integer x,;
  Integer y,;
  Integer nWidth,;
  Integer nHeight,;
  Integer bRepaint
  Endproc

  Procedure Resize
 * изменение размеров окна карты до размеров, включающей её формы  
  MoveWindow(This.map_hwnd,0,0,This.Width,This.Height,0)
  Endproc

  Procedure Destroy
 * завершение работы COM объекта MapInfo  
  This.Map=Null
  Clear Dlls MoveWindow
  Endproc

  Enddefine

В результате, форма VFP содержит план (карту), см. рис.

Благодаря применению api-функции [MoveWindow] в методе [Resize] формы, при изменении размеров формы карта, находящаяся в окне MapInfo, автоматически масштабируется к размерам родительской формы.

 

5.«Знать ГДЕ – это только начало!»

Пусть, мы располагаем планом (картой) некоторого населённого пункта, см. рис.:

Предположим, что требуется смоделировать чрезвычайную ситуацию: в результате прорыва плотины на реке Хауки, произойдёт затопление территории до 700 метров от береговой линии. Требуется определить, сколько всего, и какие именно городские строения могут попасть в зону затопления.

Построим 700 метровую буферную зону от правого берега реки Хауки:

Local lcCommandMapBaisic As Character
  Text To m.lcCommandMapBaisic TextMerge Noshow

  Dim loFlooding_zone as Object

  Create Object As Buffer From Selection
  Into Variable loFlooding_zone
  Width 700 Units "m"

  Select c1,c2 From "myMap"
  Where myMap.obj WithIn loFlooding_zone
  Group By c1,c2
  Order by c1

  UnDim loFlooding_zone

  EndText

 * SelectionInfo() – функция MapBasic,  
 * в зависимости от передаваемого параметра возвращает информацию  
 * о выделенной области на текущей карте, в данном случае  
 * количество выделенных объектов  
  If Val(m.poMI.Eval([SelectionInfo(3)]))>0
  m.poMI.Do(m.lcCommandMapBaisic)
  Else
  Messagebox([Для построения буферной зоны ;
  необходимо выбрать объект на карте.],48,[Внимание],10000)
  Endif
  Release lcCommandMapBaisic

Рассмотрим приведённый код. Команда [Create Object As Buffer …] – создаёт требуемую буферную зону, сохраняя результат в переменной [loFlooding_zone]. Следующая команда – SQL-запрос, где фразу [Where …] следует понимать так: объекты карты [myMap] внутри (WithIn) буферной зоны [loFlooding_zone]. Если на момент выполнения этого скрипта на карте нет выделенных объектов, MapInfo сгенерирует ошибку, по этому, перед отправкой на выполнение, с помощью метода [.Eval(…)] COM модели MapInfo, мы выполняем функцию SelectionInfo() для проверки наличия на карте выделенных объектов.

В результате MapInfo формирует специальный объект [Selection], в котором содержатся все графические объекты карты, попадающие в 700 метровую буферную зону от береговой линии реки Хауки. На рисунке эти объекты помечены красными насечками.

 

MapInfo поддерживает следующие пространственные операторы над географическими объектами:

Contains

«Содержит»
Объект A содержит объект Б, если центроид Б лежит в границах A.

Contains Entire

«Полностью содержит».
Объект A полностью содержит объект Б, если граница Б полностью лежит внутри границ A.

WithIn

«Внутри».
Объект A лежит внутри объекта Б, если его центроид лежит в границах Б.

Entirely WithIn

«Полностью внутри».
Объект A лежит полностью внутри объекта Б, если его граница полностью лежит внутри границ Б.

Intersects

«Пересекает».
Объект A пересекается с объектом Б, если они имеют хотя бы одну общую точку.

Различие между [Contains] и [WithIn], с одной стороны, и [Contains Entire] и [Entirely WithIn], с другой, состоит в том, что [Contains] и [WithIn] основаны на анализе центроида объекта, а [Contains Entirely] и [Entirely WithIn] - на анализе всего объекта.

Географические функции:

Area(…)

Возвращает площадь объекта

Distance(…)

Возвращает расстояние между двумя точками

ObjectLen(…)

Возвращает длину объекта

Perimeter(…)

Возвращает периметр объекта

 

Применение в пространственных SQL-запросах MapInfo таких инструментов позволяет проводить географический анализ карты. Девиз разработчиков MapInfo: «Знать ГДЕ – это только начало!»

В завершение, код позволяющий получить данные о выделенных объектах, составляющих буферную зону.

Create Cursor Flooding_obj (id_obj Integer, name_obj Character(70))

  Local lnNRows As Integer
  m.lnNRows=Val(m.poMI.Eval([SelectionInfo(3)]))

  If m.lnNRows>0
   For m.i=1 To m.lnNRows
    m.poMI.Do([Fetch Rec ]+Transform(m.i)+[ From "Selection"])
    Insert Into Flooding_obj (id_obj, name_obj) ;
    Values (Val(m.poMI.Eval([Selection.c1])),;
    m.poMI.Eval([Selection.c2]))

   Endfor
  Endif

В данном примере организован перебор всех строк специальной таблицы MapInfo: [Selection], в которую MapInfo помещает все выделенные объекты карты.

 

На этом всё. Спасибо за внимание.
Замечания принимаются.

 

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



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






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