Вот наконец-то, я добрался и до MapWindow GIS, давненько, я про него ничего не писал, но это не просто так, так как уже почти большую часть, я про него рассказал, и Вы уже спокойно можете начинать делать свою небольшую ГИС. Осталось рассмотреть совсем не большие темы, а на этот раз мы рассмотрим, как можно из своего проекта создать сам слой карты, то есть shp-файл.

Хотя, на самом деле, созданием одного слоя мы не обойдемся. Я надеюсь, Вы помните, какие файлы еще должны находиться, в одной папке с shape-файлом, если нет, то я напоминаю:

  • *.shp
  • *.dbf
  • *.shx

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

Ну, так что, мы также не ограничимся созданием одного shp-файла, так как нам в любом случае придется хранить координаты объектов нашего слоя, в каких-то либо файлах, в данном случае — это dbf (в данном файле храниться название наших объектов, координаты и так далее, можно записывать любую информацию, обычно его называют таблицей атрибутов).

Ну что, приступим к созданию нашего проекта. Давайте установим следующие компоненты на форму:

  • TMap
  • TButton

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

Давайте разберем те функции, которые нам потребуются для создания shape-файла. Все функции, что рассмотрим, относятся к интерфейсу IShapeFile:

  1. CreateNew(ShapeFileName:String; ShapeFileType:ShpFileType):Boolean — функция, которая создает shape-файл, в параметрах необходимо указать имя shape-файла, а также тип создаваемого слоя, он может принимать следующие значения:
    • SHP_NULLSHAPE
    • SHP_POINT
    • SHP_POLYLINE
    • SHP_POLYGON
    • SHP_MULTIPOINT
    • SHP_POINTZ
    • SHP_POLYLINEZ
    • SHP_POLYGONZ
    • SHP_MULTIPOINTZ
    • SHP_POINTM
    • SHP_POLYLINEM
    • SHP_POLYGONM
    • SHP_MULTIPOINTM
    • SHP_MULTIPATCH
  2. StartEditingShapes(StartEditTable:Boolean;cBack:iCallBack):Boolean — функция, которая разрешает редактировать shape-объект, в том числе, таблица атрибутов, также должна быть в режиме редактирования.
  3. EditInsertField(NewField:Field;ByRef:Ineger;cBack:iCallback):Boolean — функция, которая разрешает ввод/редактирования параметров таблицы атрибутов, в параметрах требуется указать объект интерфейса IField, который необходимо редактировать или добавить в него что-то, а также номер столбца.
  4. EditInsertShape(Shape:Shape;ByRef:Integer):Boolean — функция, которая вставляет фигуру на наш слой (точка, полигон, линия и т.д), в параметрах указывается объект интерфейса IShape и номер фигуры, которую необходимо отредактировать или вставить.
  5. EditCellValue(FieldIndex:Integer;ShapeIndex:Integer;NewVal:OleVariant):Boolean — функция, которая редактирует данные таблицы атрибутов, с параметрами все понятно должно быть тут.
  6. StopEditingShapes(ApplyChanges:Boolean;StopEditTable:Boolean;cBack:ICallback):Boolean — функция, которая запрещает редактировать наш shape - файл.

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

procedure TForm1.btn1Click(Sender: TObject);
var
  shp:IShapefile;
  Layer,fld_index,i,pnt:Integer;
  fld:IField;
  pt:IPoint;
  sh:IShape;
  Result:Boolean;
begin
   shp:=CoShapefile.Create;
   shp.CreateNew('C:\newlayer.shp',SHP_POLYLINE);
   Result:=shp.StartEditingShapes(True,nil);
   fld:=CoField.Create;
   fld.type_:=STRING_FIELD;
   fld.Name:='NewFieldString';
   fld.Width:=20;
   fld_index:=0;
   Result:=shp.EditInsertField(fld,fld_index,nil);
   fld:=CoField.Create;
   fld.type_:=INTEGER_FIELD;
   fld.Name:='NewFieldInteger';
   inc(fld_index);
   Result:=shp.EditInsertField(fld,fld_index,nil);
   fld:=CoField.Create;
   fld.type_:=DOUBLE_FIELD;
   fld.Name:='NewFieldDoouble';
   fld.Precision:=8;
   inc(fld_index);
   Result:=shp.EditInsertField(fld,fld_index,nil);
   for i:=0 to 10 do
    begin
      sh:=CoShape.Create;
      sh.ShapeType:=SHP_POLYLINE;
      for pnt:=0 to 4 do
       begin
         pt:=CoPoint.Create;
         pt.x:=Cos(RandomRange(1,1000)*100);
         pt.y:=Sin(RandomRange(1,1000)*10);
         sh.InsertPoint(pt,pnt);
       end;
      shp.EditInsertShape(sh,i);
      shp.EditCellValue(0,i,'Shape '+IntToStr(i));
      shp.EditCellValue(1,i,i);
      shp.EditCellValue(2,i,pt.x*pt.y);
    end;
   Result:=shp.StopEditingShapes(True,True,nil);
   mp1.AddLayer(shp,True);
   mp1.SetFocus;
   mp1.ZoomToMaxExtents;
   for i:=0 to shp.NumShapes-1 do
    begin
      mp1.ShapeLineColor[0,i]:=clBlue;
    end;
end;

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

В начале создаем наш shape-файл, размещаем его на диске C:\ и сразу же с помощью функции StartEditingShapes разрешаем его редактировать.

Дальше, мы, создаем таблицу атрибутов, указывая имя поля, тип, длину (если необходимо) и с помощью функции EditInsertField привязываем, созданное поле таблицы атрибутов к нашему shape-файлу (если достаточно много таки полей, то их проще организовать в виде функции или процедуры).

Дальше, создаем фигуру shape-файла (в нашем случае это линии), а делаем это в цикле, так как их несколько будет, ну и для каждой линии создаем точки.

Дальше все просто, с помощью функции EditCellValue, записываем значения в таблицу атрибутов, чтобы данный слой можно было использовать и другой программой, ну и запрещаем редактирование shape-файла, c помощью функции StopEditingShapes.

В самом конце, просто отображаем все наши линии в компонент TMap


Кстати, хочу сказать, что телепроект Дом2 на протяжении длительно времени, становится все популярнее и популярнее, а поклонников становится все больше и больше, так вот, если у кого-то не получилось посмотреть серию по телевизору, то ее можно будет посмотреть с помощью дом 2 онлайн трансляция, а также прочитать достаточно много информации об участниках проектов, так что не попустите.


Исходник, можно скачать тут

Метки: , , , ,




К записи “Работа с MapWindow GIS. Создание shape-файлов” оставлено комментариев: 10.

  1. ZeUs:

    Ну наконец то новая статья! Очень интересно. Я уж думал вы забыли уже про эту рубрику :)
    Ждем продолжения!

  2. Александр:

    Если два раза запустить ваш пример, то второй раз не отображаются точки.
    помогает выполнения shp.Save(nil); и последующее удаление сохраненных файлов

  3. ЙЦУКЕН:

    А можно пример где используется процедура DrawPolygon?
    сколько ни пытался его заюзать всегда вылетает ошибка Access violation, не понимаю на что он ругается, отправляет в заголовочный модуль самого компонента=(
    вот пример кода:

    procedure TForm1.BitBtn4Click(Sender: TObject);
    var
    XX, YY : OleVariant;
    begin

    XX := VarArrayCreate([0,5], varDouble);
    YY := VarArrayCreate([0,5], varDouble);

    XX[0] := 50000;
    YY[0] := 50000;

    XX[1] := 55000;
    YY[1] := 50000;

    XX[2] := 56000;
    YY[2] := 55000;

    XX[3] := 53000;
    YY[3] := 58000;

    XX[4] := 52000;
    YY[4] := 57000;

    XX[5] := 49000;
    YY[5] := 56000;

    Map1.NewDrawing(dlSpatiallyReferencedList);

    Map1.DrawPolygon(XX, YY, 6, RGB(255, 0, 0), true);
    end;

    Все остальные примитивы отлично рисует, с полигоном беда=(
    Работаю в Delphi7 MapWinGis 4.7

    • Andrey:

      К сожалению у меня также были проблемы именно с DrawPolygon, спрашивал на официальном сайте, но ответа так и не получил, так как там в основном подсказывают для C#

  4. Ziko:

    почему линии не отображаются на shape file ????

  5. Виктор:

    Добрый день!
    Подскажите как получить корректную площадь и периметр (в м2 и м) полигона в shape файле.
    Вот пример кода на Delphi 7 и MapWinGIS 4.8

    procedure TFMOOnMapOnline.BCalcAreaAndPerimetrClick(Sender: TObject);
    var
    I,HandleLayer: integer;
    Result: boolean;
    Sh: IShape;
    NameFile: string;
    begin
    NameFile := PathToShpFields + CBFields_Polygon.Hint + ‘.shp';
    Shp := CoShapefile.Create;
    Result := Shp.Open(NameFile,nil);
    Result := Shp.StartEditingShapes(true,nil);
    SBMOOnLine.Panels[2].Text := Shp.Projection;
    for I := 0 to Shp.NumShapes — 1 do begin
    Sh := Shp.Shape[I];
    Shp.EditCellValue(1,I,Sh.Area);
    Shp.EditCellValue(2,I,Sh.Perimeter);
    end;
    Result := Shp.StopEditingShapes(true,true,nil);
    Shp.Close();
    end;

    Получаемые значения трудно понять в каких они единицах измерения.
    Заранее спасибо!

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

Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*