Работа с картами в Windows Form с использованием GMap.NET. Часть 2.

      Данная инструкция является продолжением обзора компонента по работе с картами - «GMap.NET». По завершению работы с данной инструкцией в вашем проекте будет реализован функционал загрузки карты по определенным координатам, установка маркера и получение его координат, а так же замена стандартного маркера, который предоставляет компонент, на любое другое изображение в формате «*.png».
      Для данной инструкции будет использован пример из первой части (Работа с картами в Windows Form с использованием GMap.NET) обзора данного компонента. Вы можете воспользоваться как тестовым примером или полностью выполнить первую инструкцию самостоятельно и плавно перейти к выполнению этой. Если вы воспользовались исходником из первой части обзора компонента «GMap.NET», метод загрузки главной формы «Form1_Load» будет содержать код установки двух маркеров (красный и зеленый) по координатам Красной площади в Москве, удалите данный код. У вас останется только часть инициализации карты по заданным координатам.
//Настройки для компонента GMap.
gMapControl1.Bearing = 0;

//CanDragMap - Если параметр установлен в True,
//пользователь может перетаскивать карту 
///с помощью правой кнопки мыши. 
gMapControl1.CanDragMap = true;

//Указываем, что перетаскивание карты осуществляется 
//с использованием левой клавишей мыши.
//По умолчанию - правая.
gMapControl1.DragButton = MouseButtons.Left;

gMapControl1.GrayScaleMode = true;

//MarkersEnabled - Если параметр установлен в True,
//любые маркеры, заданные вручную будет показаны.
//Если нет, они не появятся.
gMapControl1.MarkersEnabled = true;

//Указываем значение максимального приближения.
gMapControl1.MaxZoom = 18;

//Указываем значение минимального приближения.
gMapControl1.MinZoom = 2;

//Устанавливаем центр приближения/удаления
//курсор мыши.
gMapControl1.MouseWheelZoomType =
    GMap.NET.MouseWheelZoomType.MousePositionAndCenter;

//Отказываемся от негативного режима.
gMapControl1.NegativeMode = false;

//Разрешаем полигоны.
gMapControl1.PolygonsEnabled = true;

//Разрешаем маршруты
gMapControl1.RoutesEnabled = true;

//Скрываем внешнюю сетку карты
//с заголовками.
gMapControl1.ShowTileGridLines = false;

//Указываем, что при загрузке карты будет использоваться 
//18ти кратное приближение.
gMapControl1.Zoom = 15;

//Указываем что все края элемента управления
//закрепляются у краев содержащего его элемента
//управления(главной формы), а их размеры изменяются 
//соответствующим образом.
gMapControl1.Dock = DockStyle.Fill;

//Указываем что будем использовать карты Google.
gMapControl1.MapProvider =
    GMap.NET.MapProviders.GMapProviders.GoogleMap;
GMap.NET.GMaps.Instance.Mode =
    GMap.NET.AccessMode.ServerOnly;

//Если вы используете интернет через прокси сервер,
//указываем свои учетные данные.
GMap.NET.MapProviders.GMapProvider.WebProxy =
    System.Net.WebRequest.GetSystemWebProxy();
GMap.NET.MapProviders.GMapProvider.WebProxy.Credentials =
    System.Net.CredentialCache.DefaultCredentials;

//Устанавливаем координаты центра карты для загрузки.
gMapControl1.Position = new GMap.NET.PointLatLng(55.75393, 37.620795);
      Далее необходимо добавить в проект класс, отвечающий за создание рамки при наведении на маркер и подстановки выбранного вами изображения в качестве маркера. Перейдите в Обозреватель решений и сделайте клик правой клавишей мыши по заголовку вашего проекта. В открывшемся контекстном меню перейдите в меню «Добавить -> Класс…» или выполните сочетание клавиш «Shift+Alt+C».
      У вас откроется диалоговое окно «Добавление нового элемента» в котором вам будет предложено ввести имя создаваемого класса, введите имя «GMapMarkerImage» и нажмите кнопку «Добавить» расположенную в нижней части формы.
      После выполнения этих действий, у вас автоматически откроется новая вкладка с только что созданным классом, так же класс появится в Обозревателе решений.
      Приведите листинг данного класса в соответствии с полным кодом, который представлен ниже.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using GMap.NET;
using GMap.NET.WindowsForms;
using System.Drawing;
namespace Gmap_Markers
{
    class GMapMarkerImage : GMapMarker
    {
        private Image image;
        public Image Image
        {
            get
            {
                return image;
            }
            set
            {
                image = value;
                if (image != null)
                {
                    this.Size = 
                        new Size(image.Width,
                            image.Height);
                }
            }
        }

        public Pen Pen
        {
            get;
            set;
        }

        public Pen OutPen
        {
            get;
            set;
        }

        public GMapMarkerImage(
            GMap.NET.PointLatLng p,
            Image image)
            : base(p)
        {
            Size = 
                new System.Drawing.Size(
                    image.Width,
                    image.Height);
            Offset =
                new System.Drawing.Point(
                    -Size.Width / 2,
                    -Size.Height / 2);
            this.image = image;
            Pen = null;
            OutPen = null;
        }

        public override void OnRender(Graphics g)
        {
            if (image == null)
                return;

            Rectangle rect =
                new Rectangle(LocalPosition.X, 
                              LocalPosition.Y, 
                              Size.Width, 
                              Size.Height);
            g.DrawImage(image, rect);

            if (Pen != null)
            {
                g.DrawRectangle(Pen, rect);
            }

            if (OutPen != null)
            {
                g.DrawEllipse(OutPen, rect);
            }
        }
    }
}
      Данный класс расширяет функциональные возможности существующего класса «GMapMarker», путем создания нового класса, производного от существующего. Производный класс «GMapMarkerImage» наследует все свойства базового класса «GMapMarker», и добавляет новые методы и свойства в зависимости от необходимости.
В языке C# как наследование, так и реализация интерфейса определяются оператором «:». Базовый класс должен всегда занимать крайнее левое положение в объявлении класса. Так же обратите внимание, что в начале листинга добавлены ссылки на необходимые для работы библиотеки.
      Перейдите в листинг главной формы и перед методом загрузки главной формы «Form1_Load», объявите приведенные ниже переменные.
//Переменная отвечающая за состояние нажатия 
//левой клавиши мыши.
private bool isLeftButtonDown = false;

//Таймер для вывода
private Timer blinkTimer = new Timer();

//Переменная нового класса,
//для замены стандартного маркера.
private Gmap_Markers.GMapMarkerImage currentMarker;

//Список маркеров.
private GMap.NET.WindowsForms.GMapOverlay markersOverlay;
      Так же добавьте в конец метода следующий код, установки своих методов на различные события элемента управления «gMapControl1».
//Создаем новый список маркеров, с указанием компонента 
//в котором они будут использоваться и названием списка.
markersOverlay =
    new GMap.NET.WindowsForms.GMapOverlay(gMapControl1, "marker");

//Устанавливаем свои методы на события.
gMapControl1.OnMapZoomChanged += 
    new MapZoomChanged(mapControl_OnMapZoomChanged);
gMapControl1.MouseClick += 
    new MouseEventHandler(mapControl_MouseClick);
gMapControl1.MouseDown += 
    new MouseEventHandler(mapControl_MouseDown);
gMapControl1.MouseUp += 
    new MouseEventHandler(mapControl_MouseUp);
gMapControl1.MouseMove += 
    new MouseEventHandler(mapControl_MouseMove);
gMapControl1.OnMarkerClick +=
    new MarkerClick(mapControl_OnMarkerClick);
gMapControl1.OnMarkerEnter += 
    new MarkerEnter(mapControl_OnMarkerEnter);
gMapControl1.OnMarkerLeave += 
    new MarkerLeave(mapControl_OnMarkerLeave);

//Добавляем в элемент управления карты
//список маркеров.
gMapControl1.Overlays.Add(markersOverlay);
     Далее необходимо добавить сами методы отображения изображения, координат и рамки маркера.
//Метод, отвечающий за перемещение
//маркера левой клавишей мыши
//по карте и отображения подсказки с 
//текущими координатами маркера.
void mapControl_MouseMove(object sender, MouseEventArgs e)
{
    //Проверка, что нажата левая клавиша мыши.
    if (e.Button == System.Windows.Forms.MouseButtons.Left && isLeftButtonDown)
    {
        if (currentMarker != null)
        {
            PointLatLng point = 
                gMapControl1.FromLocalToLatLng(e.X, e.Y);
            //Получение координат маркера.
            currentMarker.Position = point;
            //Вывод координат маркера в подсказке.
            currentMarker.ToolTipText = 
                string.Format("{0},{1}", point.Lat, point.Lng);
        }
    }
}

void mapControl_MouseUp(object sender, MouseEventArgs e)
{
    //Выполняем проверку, какая клавиша мыши была отпущена,
    //если левая то устанавливаем переменной значение false.
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        isLeftButtonDown = false;
    }
}

void mapControl_MouseDown(object sender, MouseEventArgs e)
{
    //Выполняем проверку, какая клавиша мыши была нажата,
    //если левая, то устанавливаем переменной значение true.
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        isLeftButtonDown = true;
    }
}

//Убираем квадрат выделения маркера
//если нет действий с маркером.
void mapControl_OnMarkerLeave(GMapMarker item)
{
    if (item is GMapMarkerImage)
    {
        currentMarker = null;
        GMapMarkerImage m = item as GMapMarkerImage;
        m.Pen.Dispose();
        m.Pen = null;
    }
}

//Устанавливаем вокруг маркера красный квадрат
//если маркер выделен клавишей Enter
void mapControl_OnMarkerEnter(GMapMarker item)
{
    if (item is GMapMarkerImage)
    {
        currentMarker = item as GMapMarkerImage;
        currentMarker.Pen = new Pen(Brushes.Red, 2);
    }
}

void mapControl_OnMarkerClick(GMapMarker item, MouseEventArgs e)
{
}

void mapControl_MouseClick(object sender, MouseEventArgs e)
{
    //Выполняем проверку, какая клавиша мыши была нажата,
    //если правая то выполняем установку маркера.
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        //Если надо установить только один маркер,
        //то выполняем очистку списка маркеров
        markersOverlay.Markers.Clear();
        PointLatLng point = gMapControl1.FromLocalToLatLng(e.X, e.Y); 

        //Инициализируем новую переменную изображения и
        //загружаем в нее изображение маркера,
        //лежащее возле исполняемого файла
        Bitmap bitmap = 
            Bitmap.FromFile(Application.StartupPath+@"\marker.png")
                 as Bitmap; 

        //Инициализируем новый маркер с использованием 
        //созданного нами маркера.
        GMapMarker marker = new GMapMarkerImage(point, bitmap);
        marker.ToolTipMode = MarkerTooltipMode.OnMouseOver;

        //В качестве подсказки к маркеру устанавливаем 
        //координаты где он устанавливается.
        //Данные о местоположении маркера, вы можете
        //вывести в любой компонент
        //который вам нужен.
        //например:
        //textBo1.Text = point.Lat;
        //textBo2.Text = point.Lng;
        marker.ToolTipText = string.Format("{0},{1}", point.Lat, point.Lng);

        //Добавляем маркер в список маркеров.
        markersOverlay.Markers.Add(marker);
    }
}
//Событие изменения масштаба
void mapControl_OnMapZoomChanged()
{
}

//Запускаем таймер при наведении на маркер
private void buttonBeginBlink_Click(object sender, EventArgs e)
{
    //Устанавливаем интервал срабатывания
    //таймера, равным одной секунде.
    blinkTimer.Interval = 1000;

    //Добавляем свое событие на каждое
    //срабатывание таймера.
    blinkTimer.Tick += new EventHandler(blinkTimer_Tick);

    //Запускаем таймер.
    blinkTimer.Start();
}

//Отрисовка красного квадрата при наведении на маркер
void blinkTimer_Tick(object sender, EventArgs e)
{
    foreach (GMapMarker m in markersOverlay.Markers)
    {
        if (m is GMapMarkerImage)
        {
            GMapMarkerImage marker = m as GMapMarkerImage;
            if (marker.OutPen == null)
                //Задаем цвет и ширину линии квадрата,
                //отображаемого вокруг маркера
                //на который наведен курсор.
                marker.OutPen = new Pen(Brushes.Red, 2);
            else
            {
                //Убираем красный квадрат.
                marker.OutPen.Dispose();
                marker.OutPen = null;
            }
        }
    }
    //Перерисовываем карту.
    gMapControl1.Refresh();
}

private void buttonStopBlink_Click(object sender, EventArgs e)
{
    //Останавливаем таймер отображения квадрата.
    blinkTimer.Stop();
    foreach (GMapMarker m in markersOverlay.Markers)
    {
        if (m is GMapMarkerImage)
        {
            GMapMarkerImage marker = 
                m as GMapMarkerImage;
            marker.OutPen.Dispose();
            marker.OutPen = null;
        }
    }
    //Перерисовываем карту.
    gMapControl1.Refresh();
}
      При инициализации элемента управления «gMapControl1», у свойства «DragButton» задано значение «MouseButtons.Left», указывающее, что перемещение карты осуществляется с использованием левой клавиши мыши. Поэтому установка маркера будет осуществляться с использованием правой клавишей мыши. Но его перемещение, как и карты, реализовано посредством левой клавиши мыши. Запустите проект, нажав на клавиатуре, клавишу «F5». Нажмите правой клавишей мыши на любом мечте карты, у вас появится маркер с заданным вами изображением, которое загружается из директории с исполняемым файлом вашего проекта.
      При наведении курсора мыши на маркер вы увидите подсказку, содержащую его координаты на карте. Так же подсказка будет отображаться при перемещении маркера по карте, левой клавишей мыши.
      Для изменения изображения маркера вам необходимо заменить изображение рядом с исполняемым файлом проекта на любое другое, соблюдая всего два критерия, изображение должно быть в формате «*.png» и названо «marker».
Изображение для маркера вы можете бесплатно скачать с сайта findicons.com по следующему адресу findicons.com.

Ссылка для скачивания примера: Яндекс.Диск


Комментариев нет:

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

Большая просьба, не писать в комментариях всякую ерунду не по теме!