Вот наконец-то, я добрался и до MapWindow GIS, давненько, я про него ничего не писал, но это не просто так, так как уже почти большую часть, я про него рассказал, и Вы уже спокойно можете начинать делать свою небольшую ГИС. Осталось рассмотреть совсем не большие темы, а на этот раз мы рассмотрим, как можно из своего проекта создать сам слой карты, то есть shp-файл.
Хотя, на самом деле, созданием одного слоя мы не обойдемся. Я надеюсь, Вы помните, какие файлы еще должны находиться, в одной папке с shape-файлом, если нет, то я напоминаю:
- *.shp
- *.dbf
- *.shx
Это тот минимум, который необходим, чтобы можно было загружать данные в свой проект.
Ну, так что, мы также не ограничимся созданием одного shp-файла, так как нам в любом случае придется хранить координаты объектов нашего слоя, в каких-то либо файлах, в данном случае — это dbf (в данном файле храниться название наших объектов, координаты и так далее, можно записывать любую информацию, обычно его называют таблицей атрибутов).
Ну что, приступим к созданию нашего проекта. Давайте установим следующие компоненты на форму:
- TMap
- TButton
Ну сам компонент, TMap, нам понадобится для того, чтобы отобразить то, что мы создадим, то есть отобразить наш слой, а по нажатию на кнопку, мы будем создавать слой и его отображать в компоненте TMap.
Давайте разберем те функции, которые нам потребуются для создания shape-файла. Все функции, что рассмотрим, относятся к интерфейсу IShapeFile:
-
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
- StartEditingShapes(StartEditTable:Boolean;cBack:iCallBack):Boolean — функция, которая разрешает редактировать shape-объект, в том числе, таблица атрибутов, также должна быть в режиме редактирования.
- EditInsertField(NewField:Field;ByRef:Ineger;cBack:iCallback):Boolean — функция, которая разрешает ввод/редактирования параметров таблицы атрибутов, в параметрах требуется указать объект интерфейса IField, который необходимо редактировать или добавить в него что-то, а также номер столбца.
- EditInsertShape(Shape:Shape;ByRef:Integer):Boolean — функция, которая вставляет фигуру на наш слой (точка, полигон, линия и т.д), в параметрах указывается объект интерфейса IShape и номер фигуры, которую необходимо отредактировать или вставить.
- EditCellValue(FieldIndex:Integer;ShapeIndex:Integer;NewVal:OleVariant):Boolean — функция, которая редактирует данные таблицы атрибутов, с параметрами все понятно должно быть тут.
- 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, MapWindow GIS в Delphi, MapWindowGIS, Shape, TMap
https://zaokomtek.ru/?p=207#comment-736
Андрей, зайди сюда.
зашел и отписал Вам
Ну наконец то новая статья! Очень интересно. Я уж думал вы забыли уже про эту рубрику
Ждем продолжения!
по мере возможности буду в нее писать
Если два раза запустить ваш пример, то второй раз не отображаются точки.
помогает выполнения shp.Save(nil); и последующее удаление сохраненных файлов
спасибо, будем иметь ввиду
А можно пример где используется процедура 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
К сожалению у меня также были проблемы именно с DrawPolygon, спрашивал на официальном сайте, но ответа так и не получил, так как там в основном подсказывают для C#
почему линии не отображаются на shape file ????
Добрый день!
Подскажите как получить корректную площадь и периметр (в м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;
Получаемые значения трудно понять в каких они единицах измерения.
Заранее спасибо!