Ответы:
Да, выполнимо. Обычно я бы предложил частично прозрачный буфер, но я понимаю, почему вы хотите сделать это картографически.
Это может быть медленным, и вам нужно вручную решить, куда вы хотите поместить метки - но с точки зрения картографии, это не плохо!
Вот скриншот ...
Как видите, буферов нет. Растр внизу не изменяется. Я включил более тонкие промежуточные контурные линии и создал их таким образом, чтобы они отображались только при ELEV% 50 <> 0
Я сделал это в QGIS 2.12 ... ваш пробег может отличаться от предыдущих версий.
Я предполагаю, что здесь у вас есть поле "ELEV" на каждой линии контура.
Сегментируйте контурные линии
Используйте обработку и алгоритм GRASS v.split.length, чтобы разделить ваши контуры на сегменты равной длины. Вам нужно выбрать длину, которая будет близка к размеру вашей метки в единицах карты, если вы используете метры. Здесь я использовал 200м.
Будьте осторожны с этим, так как это сделает ваш файл намного, намного больше (обратите внимание на количество функций на скриншоте).
Чтобы обойти это, вам может потребоваться создать только те линии контуров, которые вы хотите стилизовать (например, каждые 50 или 100 метров), чтобы избежать обработки всех промежуточных линий контура.
К этому слою добавьте однозначное целое поле с именем showLabel . По умолчанию 0 или NULL.
Измените метку, чтобы она отображалась только в сегменте, где это поле установлено в 1. Используйте это для выражения текста метки ...
if ( "showlabel" is not null, "ELEV", "")
Я думаю, что if (выражение, истинное значение, ложное значение) является довольно новым; если вы используете более старую версию, вы можете использовать CASE-ELSE
Измените стиль линии так, чтобы все сегменты фиксированной длины рисовались, кроме тех сегментов, где отображается метка. Поэтому используйте рендеринг на основе правил с двумя правилами
Rule 1: "showLabel" is null
Black, 0% transparent
Rule 2: "showLabel" is not null
Any colour, 100% transparent
Теперь все контуры будут отображаться по умолчанию, но без меток.
Вручную отредактируйте сегменты, в которых вы хотите показывать метки
Перейдите в режим редактирования и вручную выберите сегменты, в которых вы хотите отобразить значения контуров, и установите значение showLabel
1 для выбранных объектов. Вы можете использовать Ctrl+ select (в Ubuntu / Win, Cmd+ Ctrl+ Click / на Mac?), Чтобы выбрать несколько сегментов, чтобы ускорить процесс.
Теперь это должно «обрезать» контуры там, где вы хотите, чтобы метки отображались, и метки будут отображаться в промежутках.
В этом случае мои настройки ярлыка были:
CRS: EPSG 27700 (Local UTM for UK, in meters)
Text size: 50 map units
Placement: Parallel, On Line
Надеюсь, это поможет!
Я использую опцию «Буфер» на вкладке «Настройка метки». (Использование кнопки надписей, а не старой опции надписей в диалоговом окне свойств слоя.) Это не стирает контурную линию, как я полагаю, вы хотите, но она делает разметку разборчивой.
Я думаю, что самое близкое, что можно получить с текущими возможностями QGIS, - это использовать эффект ореола (или фона) с цветом, полученным из таблицы, который будет основан на значении высоты и цветовой схеме, которые используются для базовой сетки. Конечно, это не будет учитывать склоны и все остальное ниже ореола на карте. Пример случайного цвета: с небольшим количеством кода это можно переписать как функцию для отображения цвета сетки.
Теоретически должно быть возможно использовать собственный шаблон линии и метку repeat + offset . К сожалению, нет настройки смещения метки.
Недавно, столкнувшись с той же проблемой, я собрал скрипт Python QGIS для выполнения тяжелой работы. Сценарий, включающий некоторые (британские) тестовые данные, Readme (Руководство) и используемые таблицы стилей, можно найти по адресу https://github.com/pjgeng/Contour-Labels.
Короче говоря, скрипт использует два векторных слоя в качестве входных данных - аннотированный контурный слой и слой «направляющих». Последний состоит из полилиний, пересекающих контуры в нужных местах меток.
Затем сценарий работает на основе расстояния между контурами и интервала контура индекса, который должен применяться метками, добавляет значение поворота к точкам меток и, в конечном итоге, обрезает исходный слой контура для создания промежутков.
Подход работает особенно хорошо, если пользователю необходимо создавать контурные карты с разными интервалами в одной и той же области (т. Е. Направляющие не меняются). Недостатком является невозможность изменить положение метки после завершения сценария. Для этого пользователь должен будет отрегулировать направляющие линии и повторно запустить сценарий в соответствии с исходным вводом. Ранее я много работал с буферами вокруг меток, чтобы создать эффект прерывания, но это оказалось эстетически неприятным на картах, управляемых векторными данными.
К сожалению, я не могу добавить больше картинок, чтобы документировать или проиллюстрировать процесс дальше.
PS: при использовании слоев стилей, представленных в репозитории, пользователям может понадобиться «активировать» настраиваемые поля для «Поворот», «Показать метку» и «Всегда показывать» в меню меток. На некоторых установках QGIS они применяются автоматически из таблицы стилей - я пока не выяснил, чем это вызвано.
Вот еще одно решение проблемы маскирования контурных меток QGIS, где я использую функциональность QGIS Spatialite (в настоящее время QGIS 3.x) вместе с генератором геометрии для размещения меток.
Это очень динамичное решение позволяет нам немедленно изменять все размеры текста и положение этикеток, и даже выдерживает экспорт в PDF-вектор!
Для этого нам понадобятся следующие части:
Виртуальный слой, называемый то есть «contours_with_labels» со стилем на основе правил:
Правило 2: ЕЩЕ ... простая линия
и текст условной метки для правила 1:
СЛУЧАЙ, КОГДА этикетка = 1, ТОГДА ЭЛЕМЕНТ '' END
make_line (начальная точка ($ геометрия), конечная точка ($ геометрия))
атрибут (get_feature ('settings', 'variable', 'contourlabel_size'), 'value')
и наконец, что не менее важно, здесь идет запрос SQL для виртуального уровня:
------------------------------------------------------------------------
-- select all contour lines that do not intersect any scratch lines
------------------------------------------------------------------------
select c.geometry,c.elev,0 as label
from contours c,
(select st_union(geometry) as geom from scratch_lines) as scr
where not st_intersects(c.geometry,scr.geom)
------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all scratch lines (bufferwidth = length(elevation_text) * txtsize/3),
-- get st_difference between contour lines and buffers
-- and set attribute "label" to 0
--------------------------------------------------------------------------------------------------------
select st_difference(c.geometry,buf.geom) as geom,c.elev,0 as label
from
(select c.fid,st_union(st_buffer(scr.geometry,length(c.elev) * txtsize.value / 3)) as geom
from scratch_lines scr,
contours c,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(scr.geometry,c.geometry)
group by c.fid) as buf,
contours c
where c.fid = buf.fid
group by c.fid
--------------------------------------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all scratch lines (bufferwidth = length(elevation_text) * txtsize/3),
-- get st_intersection between contour lines and buffers
-- and set attribute "label" to 1
--------------------------------------------------------------------------------------------------------
select st_intersection(st_buffer(scr.geometry,length(c.elev) * txtsize.value / 3),c.geometry) as geom,c.elev,1 as label
from scratch_lines scr,
contours c,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
Вот и все.
Большое спасибо всем этим увлеченным людям, которые делают это возможным!
Ты помнишь эту тему, Мартин? Единственный способ приблизиться к решению вашей проблемы - это наложить слой контура на слой обрезанного контура, использовать его для маркировки и изменить цвет линии на нейтральный, маскирующий контуры под метками, каждый надеется, не будучи слишком навязчивым. Н.
Добавлено позже: возможно, стоит посмотреть и эту ветку , второй ответ. Возможно, ответом будет разрыв линий контура, возможно, используя буферный слой, используемый для обрезания контуров?
Чтобы сделать метки более совершенными, я изменил SQL-запрос виртуального слоя так, чтобы он соответствовал скретч-линиям, проходящим параллельно контурным линиям (см. Решение ниже):
А вот новый SQL для виртуального слоя:
------------------------------------------------------------------------
-- select all contour lines that do not intersect any scratch lines
------------------------------------------------------------------------
select c.geometry,c.elev,0 as label
from contours c,
(select st_union(geometry) as geom from scratch_lines) as scr
where not st_intersects(c.geometry,scr.geom)
------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all intersection points (bufferwidth = length(elevation_text) * txtsize/2.5),
-- get st_difference between contour lines and buffers
-- and set attribute "label" to 0
--------------------------------------------------------------------------------------------------------
select st_difference(c.geometry,buf.geom) as geom,c.elev,0 as label
from contours c,
(select c.fid,st_union(st_buffer(st_intersection(c.geometry,scr.geometry),length(c.elev) * txtsize.value / 3)) as geom
from contours c, scratch_lines scr, (select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
group by c.fid) as buf
where c.fid = buf.fid
--------------------------------------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all intersection points (bufferwidth = length(elevation_text) * txtsize/2.5),
-- get st_intersection between contour lines and buffers
-- and set attribute "label" to 1
--------------------------------------------------------------------------------------------------------
select st_intersection(c.geometry,st_buffer(st_intersection(c.geometry,scr.geometry),length(c.elev) * txtsize.value / 3)) as geom,c.elev,1 as label
from contours c,
scratch_lines scr,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
Запись в блоге ESRI: http://blogs.esri.com/esri/arcgis/2011/11/28/variable-depth-masking-contour-label-example/
Маскирование переменной глубины для контурных меток включает три этапа:
1создание аннотации на основе меток, 2 использование инструмента «Маски контура объекта» для создания масок и 3 использование параметров «Дополнительные параметры рисования»> «Маскировка», чтобы указать, какие слои маскируются.