Ну что, любитель MapWindow GIS, пора возвращаться к нашей теме. Давненько мы ничего интересного не рассматривали. Долго искал тему, чтобы такое новое и интересное написать про MapWindow GIS, в итоге нашел и решился. Помните нашу статью о том, когда мы выделяли и получали данные отдельных областей слоя, так вот данную статью я решил модернизировать и сделать это намного проще. То есть, я теперь вывожу данные об отдельной области слоя в виде всплывающей подсказки – смотрится очень эффективно и красиво.
Вообще, я думал это организовать стандартными свойствами и методами Delphi, то есть при помощи подсказок Hint, но мне не удалось достичь такого эффекта, чтобы она появлялась именно на нужной области. После того, как я достиг именно данного эффекта, у меня возникли другие проблемы: подсказка все время моргала и в это время не выделялась область, на которую был наведен курсор мыши.
Данную проблему я решил при помощи стандартных методов MapWindow GIS, как сказал выше, получилось очень эффектно и красиво, можете полюбоваться сами:
То есть, я подвел мышкой к нужной мне области, в итоге у меня появляется такая всплывающая подсказка, на которой я вывожу все поля из dbf-файла нашей карты. Можно выводить любое количество полей, я решил выводить именно все.
Данные всплывающие подсказки (метки) легко настраиваются: шрифт, цвет, фон, обрамление и так далее, а также вид формы метки (ромб, закругленная, прямоугольник).
Давайте теперь разбираться, как можно создать такие всплывающие подсказки для каждой отдельной области нашего слоя. Не забываем, что все это делаем мы на основе прошлой статьи. За все наши всплывающие подсказки отвечает интерфейс ILabels. Поэтому необходимо объявить переменную Lab:ILabels, а также переменную DrawLabels:Integer для того, чтобы знать, на каком слое нам выводить подсказки. Затем, на событие, где у нас открывается наш shape-файл, необходимо создать эти самые метки, это делается при помощи следующего кода:
DrawLabels:=Map1.NewDrawing(dlScreenReferencedList);
Lab:=CoLabels.Create;
Lab.FrameVisible:=True;
Lab.FontOutlineVisible:=true;
Задаем новый метод рисования на компоненте TMap, а также сразу получаем идентификатор слоя, на который мы открываем shape-файл, который будет содержаться в переменной DrawLabels. После этого мы создаем метки, делаем их видимыми. Все на этом, дальше нам необходимо продумать, чтобы они появлялись именно на той области, на которую мы подвели указателем мыши, а также та, которая будет выделена. Для этого нам понадобится событие OnMouseMove компонента TMap, а также не забывайте, что у Вас свойство SendMouseMove все того же компонента, должно быть установлено в True.
Ну что, переходим в свойство OnMouseMove компонента TMap и пишем следующий код (я представлю весь, с учетом прошлой статьи, а разбирать мы будем только тот кусок, который интересует нас в данной статье):
procedure TForm1.Map1MouseMove(ASender: TObject; Button, Shift: Smallint;
x, y: Integer);
var
projx,projy:double;
ShID:OleVariant;
ext:Extents;
i,j,k,count:integer;
array_of_word:array of integer;
CaptionLabels:String;
sheme:IColorScheme;
begin
count:=TreeView1.Selected.Index;
Lab:=Map1.DrawingLabels[DrawLabels];
Lab.Clear;
Map1.PixelToProj(x,y,projx,projy);
ext:=CoExtents.Create;
ext.SetBounds(projx,projy,0.0,projx,projy,0.0);
ShapeLayer[count].shp.SelectNone;
ShapeLayer[count].shp.SelectionTransparency:=127;
ShapeLayer[count].shp.SelectionColor:=clRed;
if ShapeLayer[count].shp.SelectShapes(ext,0.0,INTERSECTION,ShID)=True then
begin
j:=VarArrayHighBound(ShID, VarArrayDimCount(ShID));
CaptionLabels:='';
for k:=0 to ShapeLayer[count].shp.NumFields-1 do
begin
CaptionLabels:=CaptionLabels+ShapeLayer[count].shp.Field[k].Name+':'+String(ShapeLayer[count].shp.CellValue[k,ShpID])+#13#10;
end;
Lab.AddLabel(CaptionLabels,x+80,y,0.0,-1);
Lab.FrameVisible:=true;
Lab.FrameType:=lfPointedRectangle;
Lab.FrameOutlineColor:=clBlack;
Lab.FrameOutlineWidth:=2;
if j=1 then
begin
for i:=1 to j do
begin
ShapeLayer[count].shp.ShapeSelected[ShID[i]]:=True;
ShpID:=Integer(ShID[i]);
end;
end;
if j=0 then
begin
for i:=0 to j do
begin
ShapeLayer[count].shp.ShapeSelected[ShID[i]]:=True;
ShpID:=Integer(ShID[i]);
end;
end;
end;
Map1.Redraw;
end;
Данный код, как Вы поняли, делает: выделяет нужную область, а также выводит всплывающую подсказку, нам, для нашей статьи, необходим следующий кусок кода:
CaptionLabels:='';
for k:=0 to ShapeLayer[count].shp.NumFields-1 do
begin
CaptionLabels:=CaptionLabels+ShapeLayer[count].shp.Field[k].Name+':'+String(ShapeLayer[count].shp.CellValue[k,ShpID])+#13#10;
end;
Lab.AddLabel(CaptionLabels,x+80,y,0.0,-1);
Lab.FrameVisible:=true;
Lab.FrameType:=lfPointedRectangle;
Lab.FrameOutlineColor:=clBlack;
Lab.FrameOutlineWidth:=2;
Переменная CaptionLabels имеет тип String, в ней мы будем хранить текст, который необходимо выводить в нашей метке. Поэтому в цикле мы заполняем всеми полями данную переменную, после каждой строчки мы ставим символов #13#10, чтобы не лепило все в одну строку, а делало перенос на новую строку.
Далее мы с помощью процедуры AddLabel добавляем нашу метку, задаем координаты и текст, а затем уже выставляем настройки для нашей метки: цвет, обрамление и так далее.
Существуют следующие типы (свойство FrameType):
- lfPointedRectangle – в виде ромба
- lfRectangle – в виде прямоугольника
- lfRoundedRectangle – в виде овала (закругленные углы)
Цветовую схемы выбираете Вы сами, а также цвет и толщину линий обрамления. В самом начале мы делали еще:
Lab:=Map1.DrawingLabels[DrawLabels];
Lab.Clear;
То есть, задавали идентификатор слоя, на котором будет отображать метки, а также очищали их каждый раз, то есть при каждом перемещении мыши. Вот примерно и все, мы сделали отличные, эффективные и качественные всплывающие подсказки для нашего проекта MapWindow GIS.