Создание произвольной точки заливки полигонов в QGIS?

9

Используя QGIS 2.18.3, я хотел бы применить шаблон случайных точек к моей символике многоугольника. Менеджер стилей по умолчанию имеет точечный шаблон с регулярными интервалами , который называется Cemetery-25-50k (см. Изображение ниже). Это хорошая отправная точка, но, очевидно, не случайно.

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

Кроме того, я рассмотрел параметры заливки точечного рисунка в свойствах слоя (ниже), но не появляется ничего, что могло бы генерировать случайный узор.

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

Мне нужно воссоздать символику случайных точек ESRI Arcmap, показанную здесь:

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

Стю Смит
источник
Одна из возможностей (которая позволяет лучше контролировать случайность, а также использовать произвольные символы, такие как деревья) - это использовать inkscape для создания SVG (используя мозаичные клоны со случайностью) и использовать заполнение SVG.
Стивен Кей

Ответы:

12

Вы можете добавить символы случайных точек, используя следующие шаги:

  1. Добавьте новый слой символов с помощью кнопки «+»:

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

  1. Измените тип слоя «Символ» на «Точка заливки»
  2. Выделите «Точка заливки» в левой части дерева.
  3. Измените горизонтальные и вертикальные расстояния до разумных значений. В этом примере я выбрал одно и то же значение для обоих расстояний2.0
  4. Под горизонтальным смещением и вертикальным смещением используйте следующие функции:

    5.1 Для горизонтального смещения:

    randf(3,5) 

    5.2 Для вертикального смещения

    randf(2,4) 
  5. Дублируйте точечный слой и измените горизонтальное и вертикальное расстояния на 6 и 3 соответственно. Под горизонтальным смещением и вертикальным смещением используйте следующие функции:

    6.1 Для горизонтального смещения:

    randf(0,1) 

    6.2 Для вертикального смещения

    randf(1,2) 
  6. Вам нужно уменьшить размер символа до 2 Pixels

Вы можете увидеть результат на следующем изображении:

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

В композиторе легенда будет выглядеть так:

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

ahmadhanb
источник
2
Это не совсем дублирует случайность встроенных символов Arc, но это хорошее решение. Чтобы увеличить случайность, используйте функцию randf () на горизонтальном и вертикальном расстояниях, а также дублируйте заливку несколько раз.
Эд
1
@EdRollason Спасибо за ваш комментарий. Также неплохо добавить несколько слоев с помощью функции randf ().
Ахмадханб
1
@ahmadhanb Интересное решение, в закладки!
Мгри
2

другой метод включает использование InkScape для создания SVG и использование слоя заполнения SVG в QGIS.

Это позволяет лучше контролировать символы (например, вы можете рисовать случайно разбросанные деревья, а не только точки) и больше контролировать интервалы

  • В Inkscape нарисуйте круг / дерево и выберите объект
  • Правка> Клон> Плиточные клоны
  • Создайте (скажем) 5 x 5 или 10x10 плиточных клонов. Рекомендуется сохранять размер сетки небольшим, так как QGIS будет бороться, если у вас слишком много символов.
  • На вкладке «Сдвиг» выберите что-то вроде этого ... используйте настройки по умолчанию, но измените параметр Randomise, чтобы добавить «джиттер».

Поэкспериментируйте с настройками, вы всегда можете нажать, Removeесли результат не очень хороший.

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

  • Нажмите Create.
  • Выберите все плиточные клоны, используя CtrlA
  • CtrlShiftD вызвать свойства документа
  • Выберите Изменить размер страницы для рисования или выделения
  • Сохранить как SVG, но убедитесь, что вы используете простой формат SVG
  • Теперь внесите в QGIS символ SVG.

Вот тот, где я сделал случайную сетку 5 х 5 копий одного из встроенных деревьев QGIS. Экспериментируя с интервалом и джиттером, вы можете получить разные образы. Вы также можете поэкспериментировать с горизонтальным смещением QGIS . Устанавливая это на половину горизонтального расстояния, он разбивает «плиточный» вид (давая рисунок, похожий на кирпичи в стене).

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

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

Только что нашел онлайн скрипт, который с некоторыми настройками работает с qgis 3.5.x

Я потерял оригинальное сообщение, поэтому не могу отдать должное автору.

Что вы делаете, это:

  • создать слой заливки изменить его на "генератор геометрии"
  • изменить "тип геометрии" на точки
  • для выражения нажмите кнопку «сигма» прямо к текстовому полю
  • в окне «диалог выражений» перейдите на вкладку «Редактор функций» и вставьте туда код
  • Теперь вернемся к «диалогу выражений» и вставим вызов функции следующим образом: fillGrid (0.001,0.001,1) (первые 2 значения - случайный размер)
  • Сохраните изменения и обновите представление.
  • Потрясающие случайные точки есть.

Спасибо оригинальному автору сценария.

from qgis.core import *
from qgis.gui import *
import math
import random

"""
Define a grid based on the interval and the bounding box of
the feature. Grid will minimally cover the feature and be centre aligned

Create a multi-point geometry at the grid intersections where
the grid is enclosed by the feature - i.e. apply a clipping mask

Random value determines amount of randomness in X/Y within its
grid square a particular feature is allowed to have
"""
@qgsfunction(args='auto', group='Custom')
def fillGrid(xInterval, yInterval, rand, feature, parent):
  box = feature.geometry().boundingBox()

  #Create a grid that minimally covers the boundary
  #using the supplied intervals and centre it
  countX = math.ceil(box.width() / xInterval)
  countY = math.ceil(box.height() / yInterval)

  #Align the grid
  gridX = countX * xInterval
  gridY = countY * yInterval
  dX= gridX - box.width()
  dY= gridY - box.height()
  xMin = box.xMinimum() - (dX/2)
  yMin = box.yMinimum() - (dY/2)

  points = []
  #+1 to draw a symbol on the n+1th grid element
  for xOff in range(countX+1):
    for yOff in range(countY+1):

      ptX = xMin + xOff*(xInterval) + rand * random.uniform(0,xInterval)
      ptY = yMin + yOff*(yInterval) + rand * random.uniform(0,xInterval)

      pt = QgsPointXY(ptX,ptY)
      point = QgsGeometry.fromPointXY(pt)
      if feature.geometry().contains(point):
        points.append(pt)

  return QgsGeometry.fromMultiPointXY(points)
MichałKraków
источник