Всем привет, как и обещал, сразу же возвращаюсь к написанию статей. Первая статья, после недельного перерыва, посвящена MapWindow GIS. А, рассмотрим мы, в этой статье: как работать со слоями компонента TMap, а точнее, как придать очертание краям карты; как разукрасить области в нужный нам цвет; как разместить на слоях надписи, линии и другое. Немного затронем работу с dbf-файлами, но об этом подробнее будет в следующих статьях. Хочу сказать, что тут ничего сложного нету, должно все у всех получиться и быть понятно. У меня на форме следующие компоненты

  • TButton — 3 шт
  • TMap
  • TColorBox

При загрузке shp-файла, мы сразу будем разукрашивать в нужный нам цвет области нашего слоя. При выборе конкретного значения цвета из компонента TColorBox, мы будем менять цвет контура всей карты.

На событие кнопки OnClick, по нажатию, на которую, мы загружаем наш shp-файл, я написал следующий код:

procedure TForm1.Button1Click(Sender: TObject);
var
 i:integer;
 shp:Shapefile;
begin
   try
    if OpenDialog1.Execute then
     begin
      shp:=CoShapefile.Create;
      shp.Open(OpenDialog1.FileName,nil);
      Map1.Focused;
      idLayer:=Map1.AddLayer(shp,True);
      Map1.ZoomToMaxExtents;
      for i:=0 to shp.NumShapes-1 do
       begin
        Map1.ShapeFillColor[idLayer,i]:=RGB(RandomRange(0,255),RandomRange(0,255),RandomRange(0,255));
       end;
     end
    else
     exit;
   except
    on e:Exception do
     //-//-//-//-//-//
   end;
end;

Переменная idLayer у меня объявлена типа integer. Как видите, у меня здесь есть цикл, который каждую область слоя окрашивает в случайный цвет, что определено функцией RandomRange. Свойство ShapeFillColor, определяет заливку конкретной области слоя, а свойство NumShapes - общее количество.

Для того, чтобы сразу залить весь слой в один цвет, необходимо написать следующий код:

procedure TForm1.Button4Click(Sender: TObject);
begin
   Map1.ShapeLayerFillColor[idLayer]:=clred;
end;

Теперь перейдем к цвету самого контура карты. Для этого, на событие OnChange компонента TColorBox, я написал следующий код:

procedure TForm1.ColorBox1Change(Sender: TObject);
begin
   Map1.ShapeLayerLineColor[idLayer]:=ColorToRGB(ColorBox1.Colors[ColorBox1.ItemIndex]);
end;

Для того, чтобы каждую область нашего слоя, обвести разным цветом, то воспользуемся следующим кодом:

procedure TForm1.Button4Click(Sender: TObject);
var
 i:integer;
begin
   for i:=0 to shp.NumShapes-1 do
    begin
     Map1.ShapeLineColor[idLayer,i]:=RGB(RandomRange(0,255),RandomRange(0,255),RandomRange(0,255));
    end;
end;

Теперь приступим к нанесению на слой точек, линий, надписей. Начнем с точек. Нанесем, на каждый областной центр (область), по одной точке, для этого нам понадобится тот же цикл, что и при раскрашивании областей.

Код, который расставляет точки:

procedure TForm1.Button3Click(Sender: TObject);
var
 i:integer;
begin
   Map1.NewDrawing(dlSpatiallyReferencedList);
   for i:=0 to shp.NumShapes-1 do
    begin
     Map1.DrawCircle(shp.Shape[i].Point[0].x,shp.Shape[i].Point[0].y,4,clRed,True);
    end;
end;

Функция NewDrawing определяет то, что мы начинаем рисовать на нашем слое, параметром которой выступает тип рисования.

Далее с помощью процедуры DrawCircle мы размещаем круг, нужных нам размеров, думаю с параметрами тут все ясно. Также есть процедура DrawCircleEx, которая определяет, на каком слое рисовать круги (идентификатор слоя). Остальные геометрические фигуры рисуются аналогичным образом, я только лишь перечислю названия процедур:

  • DrawPolygon - рисование области
  • DrawPoint - рисование точки
  • DrawLine - рисование линии

И все теже процедуры, но с добавление Ex, которое означает, что необходимо еще указывать: на каком конкретном слое рисовать.

Ну и напоследок, нанесем метки на наш слой, а точнее какой-нибудь текст. В данном случае, текст, я буду брать из файла dbf, там находятся названия областей, городов и так далее, но глубоко объяснять я по-этому поводу не буду, так как данной теме будет посвящена целая статья.

Итак, следующий код, который расставляет:

procedure TForm1.Button2Click(Sender: TObject);
var
 i:integer;
 text:WideString;
begin
   for i:=0 to shp.NumShapes-1 do
    begin
     text:=shp.CellValue[1,i];
     Map1.AddLabel(idLayer,text,clRed,shp.Shape[i].Point[0].x,shp.Shape[i].Point[0].y,hjCenter);
    end;
end;

С помощью CellValue мы получаем значение из dbf-файла, где первым параметром является номер колонки, из которой получать значение, Вы должны его знать заранее.

С помощью AddLabel, мы, размещаем текст (метку) на нашем слое. С параметрами, думаю, тут все ясно. Скажу, только, насчет последнего параметра — он определяет расположение текста, относительно координат. Вот, что у меня получилось:


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

procedure TForm1.Button2Click(Sender: TObject);
var
 i:integer;
 text:WideString;
begin
   for i:=0 to shp.NumShapes-1 do
    begin
     text:=shp.CellValue[1,i];
     Map1.AddLabelEx(idLayer,text,clRed,shp.Shape[i].Point[0].x,shp.Shape[i].Point[0].y,hjCenter,45);
    end;
end;

У меня текст, относительно координат, расположен, по данному примеру, под 45 градусов, вот, что у меня получилось:

Если слой состоит из множество областей (например, около 500 и больше), то во время нанесение на него меток, линий, точек (в цикле имеется ввиду), может происходить зависание программы, что нейтрализуется путем введения потоков.

Исходник программы, как всегда прилаживаю, скачиваем его тут


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


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

  1. Работа с MapWindow GIS. Обзор
  2. Работа с MapWindow GIS. Загрузка карт
  3. Работа с MapWindow GIS. Проекция карт
  4. Работа с MapWindow GIS. Настройки TMap
  5. Работа с MapWindow GIS. Конвертация Яндекс.Карт в Shape-файл
  6. Работа с MapWindow GIS. Работа со слоями

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




К записи “Работа с MapWindow GIS. Работа со слоями” оставлено комментариев: 26.

  1. [...] подразумевается с помощью переменной типа ShapeFile, в прошлой статье, мы немного затрагивали данную тему. Данный код это [...]

  2. Maringo:

    Названия административных центров отображаются, но в какой-то странной кодировке. Нечитаемо) Можно как-нибудь кодировку поменять выводимого текста или считываемого через CellValue?

  3. Maringo:

    http://rapidshare.com/files/45.....kir_1_.rar
    Вот тут целая карта. Я грузила слой admin)

    • Andrey53:

      там проблемы с самой кодировка БД Paradox, посмотрите статьи на такие темы, как программно установить кодировки на БД Paradox

  4. NULL:

    Спасибо большое, очень интерсный цикл статей, давно искал информацию по работе с картами в delphi. Хотелось бы узнать можно ли сохранить изменения в слое? Можно ли в delphi создать свой собственный слой?

  5. NULL:

    А примеры будут :-))? А вот еще такой вопрос возник: в QGIS можно в свойствах точеного слоя поставить, что-бы вместо точки грузился рисунок, например дорожный знак. Если ливозможность реализовать такое с помощью Mapwindow GIS?

  6. Aleks:

    Как добавить легенду к карте!

  7. Максим:

    Вопрос можно ли сделать так:
    Создать слой как SapeFile
    Включить режим редактирования и добавить полигон
    Сохранить шейп!

    Что то это у меня не получается! :)

    • Andrey53:

      создать слой можно, ну а дальше рисовать на нем можно, указывать только необходимо номер слоя, на котором рисуете, сохраняется с помощью функции Save

  8. Максим:

    А можно какой нить пример!?

  9. Prot_XT:

    А есть возможность в MapWinGIS создавать подписи динамически перемещающиеся на полилиниях при сдвиге карты?

    • Andrey53:

      Какие именно надписи, насколько я знаю GIS не предоставляет такую возможность, зачем перемещать надписи, если карта все равно за пределы уходит

  10. Prot_XT:

    Все очень просто, практически все GIS системы (MapInfo, ArcGIS или допустим тот же TatukGIS для разработчиков)имеют возможность удержания подписи в центре экрана (только для линий, не для полигонов), не смотря на то что линия может быть сколько угодно длинная и выходить за пределы экрана. Где это применяется? Улицы города… при перемещении карты у нас названия улиц постоянно находятся перед нами, скользя вдоль линии, причем в случае их возможного пересечения с другими перпендикулярными улицами (линиями) еще и «умно» разъезжаются друг от друга. Я давненько как-то пробовал MapWinGIS, но при знакомстве с продуктом так и не нашел как это сделать и забросил возможность работы с ним. Но продукт бесплатен… и развивается потихоньку, поэтому снова смотрю на него… Ну вроде все подробно описал.

  11. Prot_XT:

    И еще… есть ли опыт применения стилей для окраски объектов по каким либо значениям? То есть типа как в OpenStreets — нарисовал дорогу, допустим, применил к ней параметры, что это дорога республиканского значения и вуаля — она сразу же окрасилась в желтый цвет, с коричневой окантовкой и стала определенной толщины. Скачал полную версию (не только ActivX) последней MapWinGIS, там в комплекте идет редактор, где представлены возможности продукта. Там что-то подобное присутствует… Вот разобраться бы, да статеечку на эту тему… :-)

  12. Chek:

    А есть ли возможность добавлять плагины в свой проект?

  13. Ігор:

    как задать масштаб 1:10000 програмно

  14. bers25:

    А как можно копировать слой?

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

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

*