Геоинформация(GIS и просто карты) в программах на Лазарус

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Геоинформация(GIS и просто карты) в программах на Лазарус

Сообщение Alex2013 » 05.11.2025 16:49:55

Вообщем по случаю нового проекта понадобилось мне сделать хоть какой-то доступ к картографической информации .
Вначале попытался сделать "ход конем" использовать встроенный в программу браузер и веб-сервер и прикрутить JS-клиент .
Кое-что даже получилось ... но кривизны немеренной. ( Но если учесть, что в JS я практически "не в зуб ногой" то и это почти "подвиг")
Изображение
Изображение
Вообщем решил "идти другим путем" ....
Но помня свои ранние попытки "парсить гугл напрямую" решил поискать готовый фреймворк или демку.
Вначале нашёл "OSM MapControl"
https://github.com/Fr0sT-Brutal/Delphi_OSMMap

Все-бы хорошо (есть все что мне нужно ) но собрано это каких-то диких транках (Lazarus 2.1.0 trunk & FPC 3.3.1 trunk, )
И хотя я все-же скомпилировал (подправив в меру своего понимания ) демку но в ней ничего не загрузилось или не показалось .
(собирал в Lazarus 4.0 FPC 3.2.2 )
Изображение
В общем "едим дальше".
А дальше я нашёл не побоюсь этого слова шикарный LazMapViewer !
https://github.com/andreaspeters/LazMapViewer
(Кстати он доступен и в сетевом менеджере пакетов )
Изображение
(собирал в Lazarus 4.0 FPC 3.2.2 демка пока не сильно модифицирована но же внедрена в мой проект )

Зы
Но все-же интересно что там с Delphi_OSMMap ("OSM MapControl") ? Кто-нибудь собирал демку в "нормальном Лазарусе " ?
(Еще меня есть "Дельфи 10 мини" там демка тоже не собирается )
Последний раз редактировалось Alex2013 06.11.2025 00:18:04, всего редактировалось 3 раз(а).
Alex2013
долгожитель
 
Сообщения: 3186
Зарегистрирован: 03.04.2013 11:59:44

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Снег Север » 05.11.2025 17:02:00

В Тайфуне есть уже встроенный пакет ГИС.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3065
Зарегистрирован: 27.11.2007 16:14:47

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Alex2013 » 05.11.2025 19:04:29

Снег Север писал(а):В Тайфуне есть уже встроенный пакет ГИС.

Поскольку LazMapViewer доступен в сетевом менеджере пакетов Лазарус в качестве надежного и проверенного то скорее всего в Тайфуне установлен именно он. (пока единственное что я НЕ нашёл в LazMapViewer в удобной форме и сразу "из коробки " это простого метода выделения произвольных регионов на карте и то не факт, что я просто еще не добрался или не разобрался ) .
Alex2013
долгожитель
 
Сообщения: 3186
Зарегистрирован: 03.04.2013 11:59:44

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Lucifer » 06.11.2025 10:12:43

Ну, например, вот так. Рисуем на карте шестиугольники. Мне нужно было для построения тепловой карты заказов. Вот я и игрался. Координаты шестиугольников вычисляются в базе, да и не важны они, собственно.
Код: Выделить всё
procedure TForm1.Button2Click(Sender: TObject);
var
  APointsString: Array of String;
  APoints: Array of Double;
  n: Integer;
  Layer: TMapLayer;
  Area: TMapArea;
  Point: TGPSPoint;
  RealArea: TRealArea;
  CLayer: TMapLayer;
  procedure AddArea(AColor: TColor; AOpacity: Single; ALatLons: array of Double);
  var
    I: Integer;
  begin
    Area := Layer.Areas.Add as TMapArea;
    Area.LineColor := clNone;
    Area.FillColor := AColor;
    Area.Opacity := AOpacity;
    I := 0;
    while I < High(ALatLons) do
      with Area.Points.Add as TMapAreaPoint do
      begin
        Latitude := ALatLons[Succ(I)];
        Longitude := ALatLons[I];
        Inc(I, 2);
      end;
    Area.Visible := True;
  end;

begin
  if not ZQuery1.Active then
    ZQuery1.Open
  else
  begin
    ZQuery1.Close;
    ZQuery1.Open;
  end;
  ZQuery1.First;
  for n := 0 to MapView1.Layers.Count - 1 do
  begin
    CLayer := MapView1.Layers.Items[n];
    if (CLayer <> nil) and (CLayer.Tag = 1) then
    begin
      CLayer.Free;
    end;
  end;
  Layer := MapView1.Layers.Add as TMapLayer;
  Layer.Tag := 1;
  while not ZQuery1.EOF do
  begin
    APointsString := ZQuery1.FieldByName('coordinates_string').AsString.Split([';']);
    SetLength(APoints, 0);
    SetLength(APoints, Length(APointsString));
    for n := Low(APointsString) to High(APointsString) do
    begin
      APoints[n] := APointsString[n].ToDouble;
    end;
    AddArea(ColorToRGB(StringToColor(StringReplace(ZQuery1.FieldByName('color_code_bgr').AsString, '#', '$', []))), 0.3, APoints);
    ZQuery1.Next;
  end;
end;   
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Lucifer
постоялец
 
Сообщения: 130
Зарегистрирован: 05.01.2014 21:39:03
Откуда: Новороссийск

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Alex2013 » 06.11.2025 11:33:50

Lucifer писал(а):Ну, например, вот так. Рисуем на карте шестиугольники. Мне нужно было для построения тепловой карты заказов. Вот я и игрался. Координаты шестиугольников вычисляются в базе, да и не важны они, собственно.

Спасибо, попробую ! ( Мне нужен произвольный контур, но думаю с этим я как нибудь разберусь)
Alex2013
долгожитель
 
Сообщения: 3186
Зарегистрирован: 03.04.2013 11:59:44

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Lucifer » 06.11.2025 12:01:32

Спасибо, попробую ! ( Мне нужен произвольный контур, но думаю с этим я как нибудь разберусь)

Собственно, рисуешь координаты, которые тебе нужно. Только не забывай, что контур должен быть замкнутым, иначе ты полигон не построишь.
Код: Выделить всё
procedure TForm1.Button3Click(Sender: TObject);
const
  _POI_ = 10;
var
  pt: TRealPoint;
  P: TMapPointOfInterest;
  L: TMapLayer;
  ptName: String;
  Area: TRealArea;
begin
  L := MapView1.Layers.Add as TMapLayer;
  L.Tag := 1;
  P := TMapPointOfInterest.Create(L.PointsOfInterest);
  P.RealPoint := RealPoint(68, 111);
  P.ImageIndex := 0;
  P.ImageAnchorX := 0;
  P.ImageAnchorY := 100;
  P.TextPositionHor := tphLeft;
  P.Caption := 'Tilted Pin';
  pt.Lon := 34.102411;
  pt.Lat := 44.951846;
  ptName := 'City cetnter';
  P := TMapPointOfInterest.Create(L.PointsOfInterest);
  Area := MapView1.GetVisibleArea;
  P.ImageIndex := 1;
  P.RealPoint := pt;
  P.Caption := ptName;
  P.TextPositionHor := tphRight;
  P.Visible := True;
  L.Visible := True;
end;

Это как поставить на карту точку интереса. ImageIndex - просто номер картинки из ImageList.
Могу еще дать код, который рисует трек по произвольным координатам. Просто в примерах, что к компоненту идут, это совсем неочевидно. Там на основе готовых наборов, которые еще нужно как-то получить и сохранить. А я сделал, что на вход прилетает строка-массив координат, и она рисуется в виде линии на карте.
Lucifer
постоялец
 
Сообщения: 130
Зарегистрирован: 05.01.2014 21:39:03
Откуда: Новороссийск

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Alex2013 » 06.11.2025 13:28:00

Ок. Снова спасибо! :idea: Как точку ставить, есть пример в основной демке, мне нужно «рисование на карте» (с привязкой к координатам) — просто нарисовать контур, если он полностью помещается в окне , а если нет, то могут быть проблемы, и нужно или пользоваться встроенным механизмом, или делать «отсечение контура» самостоятельно.
Ps
"Могу еще дать код, который рисует трек по произвольным координатам. "

Да это было бы замечательно !
Alex2013
долгожитель
 
Сообщения: 3186
Зарегистрирован: 03.04.2013 11:59:44

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Lucifer » 06.11.2025 14:00:11

Контур рисуется по координатам, при чем тут окно и видимая часть карты? Даже если полигон не поместится, то все равно будет отрисовано все. Проверено уже.
Ну и код отрисовки треков:
Код: Выделить всё
procedure TfmOrderCard.DrawTrack(sLineKey, sPoints: String);
var
  F: TfmOrderCard;
  SL: TStringList;
  n: Integer;
  APoint: TStringArray;
  sNormPoint: String;
  RedTrack: TGPSTrack;
  GreenTrack: TGPSTrack;
  BlackTrack: TGPSTrack;
  Area: TRealArea;
  fTrack: TGPSPolyLine;
  P: TGPSPoint;
  fPoints: TGPSPointList;
  TrackPoints: array of TMapPoint;
  RealArea: TRealArea;
begin
  if sPoints = '' then
    Exit;
  F := dmMain.AForm[FormIndex];
  if F = nil then
    Exit;
  APoint := sPoints.Split([';']);
  RedTrack := TGPSTrack.Create;
  GreenTrack := TGPSTrack.Create;
  BlackTrack := TGPSTrack.Create;
  for n := Low(APoint) to High(APoint) do
  begin
    P := TGPSPoint.Create((APoint[n].Split([','])[0]).ToDouble, (APoint[n].Split([','])[1]).ToDouble, NO_ELE, Now());
    P.Visible := True;
    if sLineKey.Contains('calc') then
      RedTrack.Points.Add(P)
    else if sLineKey.Contains('goes') then
      GreenTrack.Points.Add(P)
    else
      BlackTrack.Points.Add(P);
  end;
  RedTrack.LineWidth := 0.5;
  GreenTrack.LineWidth := 0.5;
  BlackTrack.LineWidth := 0.5;
  if sLineKey.Contains('calc') then
  begin
    F.MapV.GPSItems.Add(RedTrack, 1);
    RedTrack.LineColor := clRed;
    F.MapV.DrawTrack(F.MapV.GetVisibleArea, RedTrack);
  end
  else if sLineKey.Contains('goes') then
  begin
    F.MapV.GPSItems.Add(GreenTrack, 3);
    GreenTrack.LineColor := clGreen;
    F.MapV.DrawTrack(F.MapV.GetVisibleArea, GreenTrack);
  end
  else
  begin
    F.MapV.GPSItems.Add(BlackTrack, 2);
    BlackTrack.LineColor := clBlack;
    F.MapV.DrawTrack(F.MapV.GetVisibleArea, BlackTrack);
  end;
  F.MapV.Engine.Redraw;
end;   

sLineKey - просто идентификатор трека, по которому я потом определяю цвет отрисовки. sPoints - массив координат точек трека. На F можешь внимания не обращать, это просто нужная в данном контексте форма карточки заказа. Их может быть несколько открыто у оператора. Ну и я в лоб использую три трека. Можно, конечно, это тоже динамически реализовать, но мне больше трех не нужно. Поэтому для скорости сделал так. Массив координат передается в виде XX.XXXX,YY.YYYY;XX.XXXX,YY.YYYY
Впрочем, это в коде видно, как оно делится.
Lucifer
постоялец
 
Сообщения: 130
Зарегистрирован: 05.01.2014 21:39:03
Откуда: Новороссийск

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Alex2013 » 06.11.2025 15:02:12

Lucifer писал(а):Контур рисуется по координатам, при чем тут окно и видимая часть карты? Даже если полигон не поместится, то все равно будет отрисовано все.

Ок. Я просто пытался рисовать контур поверх карты самостоятельно (в локальных координатах окна), пока рисуешь, оставаясь в рамках окна, это отлично работает, но при попытке показа контура в «произвольном масштабе» нужно пересчитывать глобальные координаты точек (ясное дело полученные из локальных при рисовании контура) обратно в локальные, и, разумеется, если пытаться вставить полученные значения в процедуру рисования, её начинает или «плющить» (что-то рисует но неправильно), или вообще приводит к генерации исключения (ошибке выхода за диапазон доступных значений).

Так что нужно обсчитывать «отсечение» (точки пресечения линий контура и краев окна), а если контур еще нужно, например, заштриховать, то нужно ещё вычислить и то, как он помещается в окно.

Вообщем, получается много лишней мороки (пусть не сложной математически), которую, по идее, должен уметь делать сам движок LazMapViewer (часть информации на картах точно задана в векторной форме).
Зы
Вроде разобрался, спасибо за помощь!
Последний раз редактировалось Alex2013 06.11.2025 15:30:26, всего редактировалось 1 раз.
Alex2013
долгожитель
 
Сообщения: 3186
Зарегистрирован: 03.04.2013 11:59:44

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Lucifer » 06.11.2025 15:26:31

Я тоже так сначала пытался делать. Но потом плюнул. Гораздо проще поиметь реальные координаты и работать уже с ними, опираясь на возможности карты и движка. И не делать себе мозги, пытаясь вычислить коэффициенты масштабирования и прочей невнятной субстанции.
P.S. Пользуйся на здоровье. Надеюсь, хоть чем-то помог. ;-)
Lucifer
постоялец
 
Сообщения: 130
Зарегистрирован: 05.01.2014 21:39:03
Откуда: Новороссийск

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Sharfik » 06.11.2025 16:40:01

Alex2013 писал(а):...должен уметь делать сам движок LazMapViewer (часть информации на картах точно задана в векторной форме)

Никто ничего не должен. Для посадки одних систем координат в другие пересчет нужен. Я недавно разбирался с возможностями программы QGIS и тем как в нее загнать генплан промышленного объекта с правильной посадкой. Люди привыкли к географическим координатам, программа работает в плоскостных координатах, планы местности делаются в местных координатах.... :shock: :? плюнул и попросил GigaChat сделать файл WKT с пересчетом местных координат в плоскостные координаты. Благо возможность получить два варианта одной и той же точки у меня имелась. Заодно узнал, что все планы у нас не в МСК региона, а собственной фабричной системе координат....

PS: Жаль LazMapViewer не трехмерный. Мне бы рельеф и высоту зданий оценивать пригодился.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 829
Зарегистрирован: 20.07.2013 01:04:30

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение sts » 06.11.2025 17:48:46

Sharfik писал(а):попросил GigaChat сделать файл WKT

т.е. вы слили левому сервису информацию ограниченного доступа, да и еще пишете об этом в интернетах, зря это, напрасно
sts
энтузиаст
 
Сообщения: 500
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение Sharfik » 06.11.2025 18:13:38

sts писал(а):т.е. вы слили левому сервису информацию ограниченного доступа, да и еще пишете об этом в интернетах, зря это, напрасно

Две ошибки. Не левому, он в отличие от прочих сберовский. Ну и ничего я не сливал, а как было выше сказано - сказал сделать файл пересчета позволяющих из цифры А сделать цифру Б. Это все открытая информация. Просто искать документацию на WKT и разбираться какое смещение от какой точки лучше взять было не к месту. Грязный прием в плане точности, но если задача просто собрать данные для визуального анализа ситуации сойдет. Ну или протестировать какое то ПО, как тут обсуждается, тоже можно.

На тему слива: OSM в плане слива критической информации реально жесть.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 829
Зарегистрирован: 20.07.2013 01:04:30

Re: Геоинформация(GIS и просто карты) в программах на Лазару

Сообщение sts » 06.11.2025 18:33:38

Sharfik писал(а):Две ошибки.

думать что это имеет значение, в обоих случаях это не отменяет ответственности.
левость не определяется местоположением, определяется наличием разрешения передавать.
наличие информации в открытом доступе не отменяет передачи без разрешения.
sts
энтузиаст
 
Сообщения: 500
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1