Отображение символов антенны на карте: точечные символы или элементы (полигоны)

12

Я хочу показать сотовую сеть на карте. Входные данные - это файл .csv, где каждая строка представляет собой сотовый сектор. Атрибутами являются: идентификатор сектора, его координаты, его азимут и угол ширины луча антенны.

Значения ширины луча антенны находятся в диапазоне от 30 до 360 градусов. Ширина луча антенны 360 означает, что он должен быть показан на карте в виде круга. Антенны с другой шириной луча должны быть показаны в виде секторов с соответствующими углами апертуры.

введите описание изображения здесь

Можно ли показывать антенны, используя только символы? Я знаю, как создать свой собственный символ SVG, и надеюсь найти способ его поворота в соответствии с азимутом. Но есть ли способ применить переменную ширину луча антенны в соответствии со значением атрибута от 30 до 360 градусов?

Я думаю, что символы - лучший способ нарисовать антенны из-за динамической визуализации на карте в соответствии с масштабом обзора, если это возможно в QGIS.

Конечно, эту задачу можно решить, нарисовав соответствующие полигоны в качестве элемента слоя, но это было бы обходным решением.

Е Бобров
источник
Таким образом, вам нужно нарисовать дугу в правильном направлении, которое отличается для каждого сайта?
Натан В.
Вовсе нет, если я правильно понимаю. Это должен быть сектор круга (или весь круг в случае ширины луча = 360), как показано на рисунке.
E Бобров
Да, это то, что я имею в виду.
Натан В.
Хорошо, я вижу. Вообще говоря, символ дуги не нужен строго. Основными атрибутами являются азимут и ширина луча. Я могу использовать любой символ, чтобы нарисовать антенны, а не только дугу.
E Бобров
Возможно, я нашел пример, который может помочь: Создание пользовательских типов слоев символов . Но я не уверен. Итак, кто-нибудь пытался создать свой собственный класс слоя символов, который рисует, например, направление каждого элемента слоя в зависимости от его атрибута (то есть азимута антенны в словах на картинке выше)?
E Бобров

Ответы:

7

Несколько дней назад в QGIS был добавлен новый плагин под названием Wedge Buffer Processing Algorithm . Это выглядит так, как будто это может представлять интерес.

Как следует из названия, это алгоритм обработки, поэтому вам нужно будет запустить его из набора инструментов обработки. Пока не было возможности попробовать это.

Он создает секторы окружностей - как обычный круговой буфер, но угол клина и радиус могут быть установлены с использованием значений поля.

Документацию и скриншоты можно увидеть на странице GitHub

Стивен Кей
источник
10

Если вы хотите использовать только символы, я предлагаю решение, основанное на ответе на аналогичный вопрос: Создание секторных источников света в QGIS? ,


Следуя аналогичному подходу и предполагая, что вы работаете с Projected CRS (вместо этого, если вы используете географическую систему координат, см. Примечание в конце ответа), я хочу подчеркнуть, что я сосредоточу внимание на объяснении. из минимальных действий, которые необходимо выполнить для воспроизведения желаемого результата: это означает, что некоторые другие второстепенные параметры (такие как размеры, ширина и т. д.) должны быть легко настроены вами для лучшего соответствия вашим потребностям.

Кроме того, я предполагаю, что "AZIMUTH"это поле, в котором хранятся значения азимута, и "BEAMWIDTH"поле, в котором хранятся ширины луча антенны.

Решение

Мы будем отображать точки с помощью a Single symbolи возвращаясь к одному Simple Markerи двум Geometry generatorслоям символов:

введите описание изображения здесь

В дальнейшем объяснении я буду следовать тому же порядку символов на изображении выше.

1) Простой маркер

Я выбрал по умолчанию символ красного круга (это самая простая часть этого урока), размер которого составляет 3 мм, а ширина - 0,4 мм.

2) Генератор геометрии № 1

Добавьте новый слой символов и выберите Geometry generatorи те LineString / MultiLineStringтип:

введите описание изображения здесь

Вставьте это выражение в Expressionполе:

make_line(
 $geometry,
 make_point($x + 300*cos(radians(90 -  "AZIMUTH" )), $y + 300*sin(radians((90 - "AZIMUTH" ))))
)

Мы только что определили стрелку, которая указывает на набор азимута (для создания стрелки не забудьте выбрать Arrowтип слоя символов под Lineопцией в главном меню символов). Обратите внимание, что 300это расстояние в метрах и это произвольное значение, поэтому не стесняйтесь изменять его в соответствии с вашими потребностями.

3) Генератор геометрии № 2

Добавьте новый слой символов и выберите Geometry generatorтип и Polygon / MultiPolygonтипы:

введите описание изображения здесь

Вставьте это выражение в Expressionполе:

CASE
WHEN ("BEAMWIDTH") <= 180
THEN
intersection(
  buffer(
   $geometry, 200),
  make_polygon(
   geom_from_wkt(
    geom_to_wkt(
     make_line(
      $geometry,
      make_point($x + 2000*cos(radians(90 -  "AZIMUTH" - "BEAMWIDTH"/2 )), $y + 2000*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
      make_point($x + 2000*cos(radians(90 -  "AZIMUTH" )), $y + 2000*sin(radians((90 - "AZIMUTH" )))),
      make_point($x + 2000*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + 2000*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
      $geometry)
     )
    )
   )
  )

WHEN ("BEAMWIDTH") > 180
THEN
difference(
  buffer(
   $geometry, 200),
   make_polygon(
    geom_from_wkt(
     geom_to_wkt(
      make_line(
       $geometry,
       make_point($x + 2000*cos(radians(90 -  "AZIMUTH" - "BEAMWIDTH"/2 )), $y + 2000*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
       make_point($x - 2000*cos(radians(90 -  "AZIMUTH" )), $y - 2000*sin(radians((90 - "AZIMUTH" )))),
       make_point($x + 2000*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + 2000*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
       $geometry)
      )
     )
    )
   )

END

Мы только что определили сектор. Обратите внимание, что 200и 2000представляют расстояния в метрах, и они являются произвольными значениями, потому что я пытаюсь создать многоугольник, который будет пересекаться с окружностью радиусом 200 м, поэтому смело меняйте их в соответствии с вашими потребностями.

Конечный результат

Если вы правильно выполняете предыдущие задачи, вы сможете получить результаты, подобные этим (метки добавляются отдельно от этого решения, и они должны только лучше объяснять контекст):

введите описание изображения здесь

Запись

Если вы используете географическую систему координат , то есть если вы имеете дело с градусами, а не с расстояниями, этого должно быть достаточно, используя правильные значения, когда я использовал расстояние в предыдущих формулах. Расстояния, которые я использовал:

  • 300 м (см. Генератор геометрии № 1);
  • 200 м (см. Генератор геометрии № 2);
  • 2000 м (см. Генератор геометрии № 2);

поэтому вы можете заменить его другими произвольными значениями, выраженными в градусах (например 0.0002, 0.002и т. д.).

бонус

Я прикрепил стиль здесь : вы можете открыть этот код в любом текстовом редакторе и сохранить его как файл стиля слоя QGIS (т.е. с .qmlрасширением).

Приведенный выше стиль был создан с использованием QGIS 2.18.4 (он должен иметь то же имя используемого вами шейп- файла ).

МГРИ
источник
Вы искали это решение? Это работает?
МГРИТЕ
Ваш солутон полностью решит дело, описанное в теме! Я реализовал это и понял, что мой реальный случай немного отличается. Извините, это моя вина.
E Бобров
1) Плотность моих секторов на карте является различной, то есть в случае коротких расстояний между секторами определенное расстояние в коде приведет к наложению большого количества секторов, изменение масштаба карты не поможет, так что это будет довольно сложно читать карту. Но в случае больших расстояний между секторами показанные секторы будут очень маленькими и, возможно, будут трудно читать карту. Использование отдельных символов избавляет от этой проблемы, их масштабы изменяются с увеличением масштаба карты.
E Бобров
2) И есть искажения ширины луча: ширина луча 360 градусов похожа на эллипсы, сектора с разными азимутами, но одинаковой ширины луча не похожи на секторы с эквивалентной шириной луча. Это потому, что я использую географическую систему координат? У вас теперь разные углы долготы / широты представляют разные расстояния между точками на земле. Таким образом, решение необходимо было локализовать на земных участках, где расположены сектора.
E Бобров
В любом случае, ваше решение и ссылка на аналогичный ответ "Создание сектора освещения в QGIS?" помог мне увидеть некоторые полезные функции. Еще раз спасибо.
E Бобров
4

Большой респект MGRI.

В нашем тестовом слое все работало гладко. На производственном уровне через два-три часа мне удалось отследить проблему с $ geometry . Экспортировал точечный слой с платформы, не заметил, но это был MultiPoint . Казалось, это вызывает проблемы: стрелка не была нарисована; и как ни странно, только вычисленные точки сделали многоугольник из кругов.

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

Вот то, что я сейчас использую, со слоем типа геометрии MultiPoints (хотя на самом деле все объекты являются одной точкой), и это работает для меня в QGis 2.18.3

Выражение стрелки Нет стрелки, если 360 °.

CASE

WHEN ("BEAMWIDTH") = 360
THEN 
make_line(
 make_point($x, $y),
 make_point($x + "RADIUS"*cos(radians(90 -  "AZIMUTH" )), $y + "RADIUS"*sin(radians((90 - "AZIMUTH" ))))
)

END

Выражение полигонов

CASE

WHEN ("BEAMWIDTH") <= 180
THEN
intersection(
  buffer(
   make_point($x,$y), "RADIUS"),
  make_polygon(
   geom_from_wkt(
    geom_to_wkt(
     make_line(
      make_point($x,$y),
      make_point($x + "RADIUS"*2*cos(radians(90 -  "AZIMUTH" - "BEAMWIDTH"/2 )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
      make_point($x + "RADIUS"*2*cos(radians(90 -  "AZIMUTH" )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" )))),
      make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
      make_point($x,$y))
     )
    )
   )
  )

WHEN ("BEAMWIDTH") > 180
THEN
difference(
  buffer(
   make_point($x,$y), "RADIUS"),
   make_polygon(
    geom_from_wkt(
     geom_to_wkt(
      make_line(
       make_point($x,$y),
       make_point($x + "RADIUS"*2*cos(radians(90 -  "AZIMUTH" - "BEAMWIDTH"/2 )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
       make_point($x - "RADIUS"*2*cos(radians(90 -  "AZIMUTH" )), $y - "RADIUS"*2*sin(radians((90 - "AZIMUTH" )))),
       make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
       make_point($x,$y))
      )
     )
    )
   )

END
jbostoen
источник
В моем ответе был предложен общий подход: поскольку в этом вопросе было много переменных, было совершенно невозможно создать уникальную процедуру для решения любой ситуации. Так что, спасибо за указание на это и предложение подхода с функциями MultiPoint, он наверняка кому-то поможет в будущем.
МГРИТЕ
1

Я был одарен частичным решением в сети без каких-либо дополнительных плагинов, просто qgis из коробки. Она не показывает ширину луча антенны, просто поверните простой маркер в правильном направлении: используйте простой маркер и поверните его с азимутом антенны + 180 градусов (Свойства слоя> Одиночный символ-> Маркер-> Простой маркер-> Треугольник-> Вращение-> Редактировать -> введите <180 + "азимут антенны"> в поле выражения. А также установите Top в поле точки привязки маркера). Использование <180 + «азимут антенны»> необходимо из-за неправильного направления встроенного простого треугольного маркера. В противном случае он покажет неправильное направление антенны.

Е Бобров
источник