Здравствуйте все, на этот раз статья по MapWindow GIS в Delphi готовилась долго, просто времени не так уж и много, да и в принципе уже многое с MapWindow GIS разобрали, так что, приходится, что-то новое поискать и рассмотреть. В этой статье, мы рассмотрим, как можно выделять отдельные области, регионы или что-то другое на shp-слоях. Довольно очень популярный прием, который часто используется в своих приложениях. Мы, в данной статье, рассмотрим:

  • Как выделить область с помощью мыши
  • Как выделить область с помощью двойного щелчка мыши

Что касается первого вопроса, то Вы наверняка помните, стиль курсора TMapcmSelection, который принимает вид выделения, так вот, если им что-то попробовать выделить, то ничего не происходит, на этот раз, мы сделаем так, чтобы все у нас выделялось.

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

Все это нам придаст визуального восприятия того, где какая область, регион расположен на нашем слое.

Приступим, в наш проект MapWindow GIS в Delphi, исходник, которого находится на вкладке Исходники, я добавил, дополнительно, следующие компоненты:

  • TPanel
  • TListBox

Далее, на событие OnClick кнопки, которая загружает в TMap shp-слой, я дописал следующий код:

Map1.SendSelectBoxFinal:=True;

Данный код, позволит нам активировать событие, которое отвечает за выделение отдельных областей карты.

Ну а далее, на событие OnSelectBoxFinal компонента TMap, я написал следующий код:

procedure TForm1.Map1SelectBoxFinal(ASender: TObject; left, right, bottom,
  top: Integer);
var
 xmin,ymin,xmax,ymax:double;
 ex:IExtents;
 ShpID:OleVariant;
 a:integer;
begin
   if Map1.CursorMode=cmselection then
   begin
    ex:=shp.Extents;
    Map1.PixelToProj(left,bottom,xmin,ymin);
    Map1.PixelToProj(right,top,xmax,ymax);
    ex.SetBounds(xmin,ymin,0,xmax,ymax,0);
    shp.SelectShapes(ex,0,INTERSECTION,ShpID);
    Map1.ShapeLayerFillColor[HandleLayer] := Map1.ShapeLayerFillColor[HandleLayer];  //reset the color of the shapes
    Map1.ShapeLayerLineColor[HandleLayer] := Map1.ShapeLayerLineColor[HandleLayer];
    For a := 0 To VarArrayDimCount(ShpID) do
     begin
      Map1.ShapeFillColor[HandleLayer, ShpID[a]] := clYellow;
      Map1.ShapeLineColor[HandleLayer, ShpID[a]] := clRed;
     end;
    end
   else
    begin
     ex:=shp.Extents;
     Map1.PixelToProj(left,bottom,xmin,ymin);
     Map1.PixelToProj(right,top,xmax,ymax);
     ex.SetBounds(xmin,ymin,0,xmax,ymax,0);
     shp.SelectShapes(ex,0,INTERSECTION,ShpID);
     Map1.ShapeLayerFillColor[HandleLayer] := Map1.ShapeLayerFillColor[HandleLayer];
     Map1.ShapeLayerLineColor[HandleLayer] := Map1.ShapeLayerLineColor[HandleLayer];
     Map1.ShapeFillColor[HandleLayer, ListBox1.ItemIndex] := clYellow;
     Map1.ShapeLineColor[HandleLayer, ListBox1.ItemIndex] := clRed;
   end;
end;

Разберемся по-порядку. Во-первых, данный код выделяет, как с помощью курсора, так с помощью двойного щелчка мыши, по нужной области, которая находится в TListBox, это можно определить, исходя из условий в данном коде. Во-вторых, выделение с помощью двойного щелчка мыши, мы рассмотрим и без данного события.

В самом начале, мы сверяем, если курсор у нас в виде выделения, то мы переводим координаты мыши в географические координаты, и при выделении мыши, у нас области, которые охватил указатель мыши, при выделении — окрашиваются в желтый цвет, а границы задаются карсным цветом. Вот, что у меня вышло:

Хочу заметить!!! При загрузке shp-слоя, я дописал также код, который добавляет в TListBox — области данного слоя. При этом, я использовал для добавления — свойство CellValue, в котором указывал номер столбца, где хранятся названия всех областей, у меня это столбец под номером 2.

Идем дальше, чтобы выделить слой, при нажатии двойного щелчка мыши по TListBox, я на событие OnDbClick компонента TListBox, написал следующий код:

procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
   Map1SelectBoxFinal(sender,round(shp.Shape[0].Extents.xMin),round(shp.Shape[0].Extents.yMin),round(shp.Shape[0].Extents.xMax),round(shp.Shape[0].Extents.xMax));
end;

То есть, мы просто передаем значения  в нашу процедуру.

Можно было сделать просто так:

Map1.ShapeFillColor[HandleLayer, ListBox1.ItemIndex] := clYellow;
Map1.ShapeLineColor[HandleLayer, ListBox1.ItemIndex] := clRed;

Думаю статья, в дальнейшем, Вам пригодится, ну а обновленный исходник проекта MapWindow GIS в Delphi, скачивайте со страницы Исходники


Интернет безусловно грандиозное создание человечества. Но подумайте, где хранится вся информация, наверняка существует хостинг сайтов, который позволяет существовать интернет ресурсам.


Все статьи по MapWindow GIS на моем блоге:

  1. Работа с MapWindow GIS. Обзор
  2. Работа с MapWindow GIS. Загрузка карт
  3. Работа с MapWindow GIS. Проекция карт
  4. Работа с MapWindow GIS. Настройки TMap
  5. Работа с MapWindow GIS. Конвертация Яндекс.Карт в Shape-файл
  6. Работа с MapWindow GIS. Работа со слоями
  7. Работа с MapWindow GIS. Работа с таблицами атрибутов
  8. Работа с MapWindow GIS. Загрузка растровых изображений. Тип Image
  9. Работа с MapWindow GIS. Выделение отдельных областей слоя

Метки: , , , , , , , , ,




К записи “Работа с MapWindow GIS. Выделение отдельных областей слоя” оставлено комментариев: 16.

  1. Дмитрий:

    Очень-очень-очень жду примеров по работе с динамическими яндекс картами!!!!

  2. Дмитрий:

    Жду. Проект на этом стоИт… сегодня случайно нашел Ваш сайт. Очень рад, нашел много полезной для себя информации!!!

  3. Сергей:

    Очень полезные статьи. Спасибо большое.
    Хотелось бы узнать есть ли возможность рисовать на поверхности карты мышкой произвольные фигуры как в графических редакторах.
    Жду новых статьей

  4. Andrey:

    Спасибо за важную и нужную информацию.
    Поставил компоненту как положено, все компилируется и работает
    (открыввает слои, подписывает и т.д.), но Ваш исходник скачанный тут
    не работает — поишет ошибка создания ыормы и даже в среде делфи
    (Delphi 7) не открывается.
    Не предполагаете причину?

    • Andrey53:

      Если честно, то понятния не имею, у меня в моей версии Delphi 7 все отлично открывает и работает

  5. Алия:

    Обнаружилась ошибка в коде.
    Строку
    For a := 0 To VarArrayDimCount(ShpID) do
    следует заменить на
    For a := VarArrayLowBound(ShpID, 1) to VarArrayHighBound(ShpID, 1) do

    VarArrayDimCount — определяет размерность массива (1*1,2*2 и т.д.), в то время как в коде требуется получить количество элементов массива.
    VarArrayLowBound — определяет нижнюю границу массива
    VarArrayHighBound — верхнюю границу

  6. bers25:

    А как узнать на какую именно шейпу наведен курсор?

  7. […] информации о данном объекте. Мы уже рассматривали тему в MapWindow GIS 4.7, как можно выделять мышью объекты, но в отличие от версии MapWindow GIS 4.8 там есть свои нюансы […]

  8. Vlad:

    Доброго времени суток!
    Хочу пожаловаться=) у меня почему то не работает данный метод выделения областей, и в принципе не только он, а любые процедуры в которых фигурирует функция PixelToProj/ProjToPixel, если их использую, то при наведении курсора на компонент вылазит ошибка ‘List index out of bounds 0′ или что то в этом духе, дословно не помню=)
    Не подскажете в чем может быть проблема?
    ошибка вылазит всегда и в моих приложениях и в ваших исходниках,при использовании любых карт

    • Andrey:

      Исходники какие? Мой проект MapWindows GIS? может у Вас версия другая совсем самого компонента

  9. Vlad:

    И ещё, забыл сказать, у меня почему то этот компонент на отрез отказывается закрашивать области слоя по отдельности, при обращении к ним напрямую, а вот слой целиком красит нормально, что может быть не так??=)

    • Andrey:

      Исходники какие? Мой проект MapWindows GIS? может у Вас версия другая совсем самого компонента

Оставить комментарий

Вы можете использовать следующие теги:

*