![](https://habrastorage.org/getpro/habr/upload_files/764/02f/c0b/76402fc0bcfbc15f04da78201a3ca4d2.png)
На написание данной статьи меня подтолкнуло не столь большое наличие текстовой информации по работе с GMap на просторах интернета, как хотелось бы.
Стояла задача визуализировать на карте положение объектов по известным координатам для дальнейшего анализа и выявления каких-либо закономерностей расположения этих объектов.
Первое что могу порекомендовать из своего опыта – начать работать сразу с WinForm, а не с WPF т.к. проще и больше информации можно добыть именно по ней.
Краткий словарь терминов, которые встретятся в моей статье:
-
Тайловая, плиточная или знакоместная графика (от англ. tile — плитка) — метод создания больших изображений (как правило, уровней в компьютерных играх) из маленьких фрагментов одинаковых размеров
-
Тайл — элемент разбиения
-
Слой можно сравнить с прозрачной пленкой, наложенной на изображение, на который наносятся пользовательские элементы
-
Тепловая карта — графическое представление данных, где индивидуальные значения в таблице отображаются при помощи цвета. Термин «heatmap» изначально был придуман и официально зарегистрирован как товарный знак разработчиком программного обеспечения Кормаком Кинни в 1991 году.
-
Полигон — многоугольник, минимальная поверхность для визуализации в трёхмерной графике.
-
Маркер — отметка на карте
Переходим к работе с библиотекой.
Нам понадобятся GMap.NET.Core.dll и GMap.NET.WindowsForms.dll Для установки можно использовать Nuget.
![](https://habrastorage.org/getpro/habr/upload_files/6ee/e2f/0f3/6eee2f0f3ef4dbd9dfe43b415ab0c915.png)
или скачать dll из интернета и вставить ссылки
![](https://habrastorage.org/getpro/habr/upload_files/64d/99a/c6a/64d99ac6a347c83876583ccc0c1e8e79.png)
Щелкните правой кнопкой мыши панель инструментов и нажмите «Выбрать элементы…». В появившемся окне с помощью кнопки «Обзор» найдите файл GMap.NET.WindowsForms.dll:
![](https://habrastorage.org/getpro/habr/upload_files/ad2/3e2/74d/ad23e274d0f33e33696e58835f599bb6.png)
После закрытия окна новый элемент управления появится в наборе инструментов. Перетаскиваем его в форму и настраиваем положение и размеры.
Создаем эвент (событие) загрузки контрала.
![](https://habrastorage.org/getpro/habr/upload_files/000/c0e/288/000c0e2886b766a4461581f1893fd030.png)
Вставляем код:
GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerAndCache; //выбор подгрузки карты – онлайн или из ресурсов gMapControl1.MapProvider = GMap.NET.MapProviders.GoogleMapProvider.Instance; //какой провайдер карт используется (в нашем случае гугл) gMapControl1.MinZoom = 2; //минимальный зум gMapControl1.MaxZoom = 16; //максимальный зум gMapControl1.Zoom = 4; // какой используется зум при открытии gMapControl1.Position = new GMap.NET.PointLatLng(66.4169575018027, 94.25025752215694);// точка в центре карты при открытии (центр России) gMapControl1.MouseWheelZoomType = GMap.NET.MouseWheelZoomType.MousePositionAndCenter; // как приближает (просто в центр карты или по положению мыши) gMapControl1.CanDragMap = true; // перетаскивание карты мышью gMapControl1.DragButton = MouseButtons.Left; // какой кнопкой осуществляется перетаскивание gMapControl1.ShowCenter = false; //показывать или скрывать красный крестик в центре gMapControl1.ShowTileGridLines = false; //показывать или скрывать тайлы
Результат выполнения кода. Карта делится на квадраты, называемые тайлами. Тайлы и крест по центру включены.
Работа с библиотекой. Маркеры
Чтобы отобразить объект на карте мы создаем маркер с координатами объекта и выводим его на карту. Теперь создадим функцию, возвращающую тот самый маркер. В коде ниже функция принимает параметры: классы Us откуда я беру название и координаты и необязательный параметр gMarkerGoogleType – тип маркера.
private GMarkerGoogle GetMarker(Us us, GMarkerGoogleType gMarkerGoogleType= GMarkerGoogleType.red) { GMarkerGoogle mapMarker = new GMarkerGoogle(new GMap.NET.PointLatLng(us.сoordinates[0].lat, us.сoordinates[0].lon), gMarkerGoogleType);//широта, долгота, тип маркера mapMarker.ToolTip = new GMap.NET.WindowsForms.ToolTips.GMapRoundedToolTip(mapMarker);//всплывающее окно с инфой к маркеру mapMarker.ToolTipText = us.id; // текст внутри всплывающего окна mapMarker.ToolTipMode = MarkerTooltipMode.OnMouseOver; //отображение всплывающего окна (при наведении) return mapMarker; }
Необходимо сказать о GMapOverlay – это слой, похожий на слой в Photoshop, который можно описать как прозрачный холст размером с карту на который мы размещаем все маркеры.
Теперь функция возвращающая слой с маркерами. Входные параметры: список классов с именами и координатами, название слоя и все тот же необязательный параметр gMarkerGoogleType.
private GMapOverlay GetOverlayMarkers(List<Us> uss, string name, GMarkerGoogleType gMarkerGoogleType= GMarkerGoogleType.red) { GMapOverlay gMapMarkers = new GMapOverlay(name);// создание именованного слоя foreach (Us us in uss) { gMapMarkers.Markers.Add(GetMarker(us, gMarkerGoogleType));// добавление маркеров на слой } return gMapMarkers; }
Добавление слоя. Вызываем функцию создающую слой и добавляем его к слоям контрола карты:
gMapControl1.Overlays.Add(GetOverlayMarkers(groups, "GroupsMarkers"));
то же самое, но с указанием типов маркеров:
gMapControl1.Overlays.Add(GetOverlayMarkers(LUs, " GroupsMarkers", GMarkerGoogleType.blue));
Можно отображать / скрывать слои
gMapControl1.Overlays[0].IsVisibile = false;
Слой добавлен, теперь просто обновляем контрол
gMapControl1.Update();// обновить контрол
На выходе получаем карту с нанесенными на нее маркерами
![](https://habrastorage.org/getpro/habr/upload_files/f1b/e1b/c92/f1be1bc92cf71109e4945d4afa76af82.png)
Тепловая карта
Изначально хотелось сделать тепловую карту по количеству маркеров в районах разных городов, но для этого придется искать и добывать координаты границ этих районов. А это больше труда и времени, а дедлайн, как всегда, уже позавчера, поэтому было придумано составлять карту по концентрациям в тайлах. Чтобы это хорошо смотрелось, тайлы лучше брать меньшего размера, чем для нынешнего зума. И из таких соображений я делаю набор слоев для каждого зума, и при изменении зума меняю слой.
Код создания слоев с цветными полигонами:
public void GetHeatMap(List<Us> LUs, string name, bool AllCoord = true) { MercatorProjection mercatorProjection = new MercatorProjection(); // класс с функциями https://github.com/radioman/greatmaps/blob/master/GMap.NET.Core/GMap.NET.Projections/MercatorProjection.cs#L73 for (int myZoom = gMapControl1.MinZoom + 3; myZoom <= gMapControl1.MaxZoom + 3; myZoom++) { GMapOverlay gMapOverlay = new GMapOverlay(name + myZoom); // создание слоя с именем включающий зум int tileSizePx = (int)mercatorProjection.TileSize.Height; //размер тайла List<GPoint> gPoints = new List<GPoint>();//список точек foreach (Us us in LUs) { if (AllCoord) { foreach (Coordinat coordinat in us.сoordinates) { GPoint pixelCoord = mercatorProjection.FromLatLngToPixel(coordinat.lat, coordinat.lon, myZoom); gPoints.Add(new GPoint(pixelCoord.X / tileSizePx * tileSizePx, pixelCoord.Y / tileSizePx * tileSizePx)); } } else { GPoint pixelCoord = mercatorProjection.FromLatLngToPixel(us.сoordinates[0].lat, us.сoordinates[0].lon, myZoom);//из широты долготы в пиксели gPoints.Add(new GPoint(pixelCoord.X / tileSizePx * tileSizePx, pixelCoord.Y / tileSizePx * tileSizePx)); } } var group = gPoints.GroupBy(r => r).ToList(); int TileMaxCount = group.Max(r => r.Count());// максимальное содержание маркеров на тайле foreach (var item in group) { int minus = Convert.ToInt32(155 * item.Count() / TileMaxCount);//сколько вычитать из РГБ if (minus == 0) { minus++; } Color color = Color.FromArgb(200, 255, 155 - minus, 155 - minus);// задаем цвет для использования List<PointLatLng> pointLatLngs = new List<PointLatLng>() { mercatorProjection.FromPixelToLatLng(item.Key, myZoom), mercatorProjection.FromPixelToLatLng(item.Key.X+tileSizePx, item.Key.Y, myZoom), mercatorProjection.FromPixelToLatLng(item.Key.X+tileSizePx, item.Key.Y+tileSizePx, myZoom), mercatorProjection.FromPixelToLatLng(item.Key.X, item.Key.Y+tileSizePx, myZoom) }; //создаем список точек для полигона GMapPolygon gMapPolygon = new GMapPolygon(pointLatLngs, item.Key.ToString()); //создаем полигон из списка точек gMapPolygon.Fill = new SolidBrush(color);// заливка gMapPolygon.Stroke = new Pen(color, -1); // рамка gMapPolygon.IsVisible = true; // видимость gMapOverlay.Polygons.Add(gMapPolygon); // добавляем полигон } gMapControl1.Overlays.Add(gMapOverlay);// добавляем слой GC.Collect();// сбор мусора } }
Код при изменении зума:
private void gMapControl1_OnMapZoomChanged() { if (AllPolygonsToolStripMenuItem.CheckState == CheckState.Checked) { CheckHeatMap("AllPolygons"); gMapControl1.Update(); } }
Код функции:
private void CheckHeatMap(string name) { foreach (GMapOverlay gMapOverlay in gMapControl1.Overlays.Where(r => r.Id.Contains("Polygons"))) { gMapOverlay.IsVisibile = false; }// все слои содержащие слово полигон невидимы if (name != null) { name += gMapControl1.Zoom + 3; GMapOverlay gMapOverlaySearch = gMapControl1.Overlays.Where(r => r.Id == name).FirstOrDefault(); gMapControl1.Overlays.Where(r => r.Id == name).FirstOrDefault().IsVisibile = true;//видимость слоя с заданным именем } }
![](https://habrastorage.org/getpro/habr/upload_files/086/4c6/1ac/0864c61aca88dc2db67ddcf7fcf200c6.png)
При приближении размер тайлов меняется:
![](https://habrastorage.org/getpro/habr/upload_files/ba9/9b1/f4d/ba99b1f4d9be578db7146e6227c616a4.png)
Заключение
В статье показано как начать знакомство с GMap: работать со слоями, тайлами, полигонами и добавлять маркеры. Надеюсь, идеи и код, изложенные в статье, будут полезны при решении ваших задач.
Также предлагаю заглянуть:
ссылка на оригинал статьи https://habr.com/ru/articles/585734/
Добавить комментарий