Настройка стиля отображения вершин и виртуальных узлов редактируемого объекта в OpenLayers: различия между версиями
Нет описания правки |
Нет описания правки |
||
(не показано 7 промежуточных версий 2 участников) | |||
Строка 1: | Строка 1: | ||
{{Статья| | {{Статья|Опубликована|openlayers-modify-style}} | ||
{{Аннотация|В статье рассмотрен вопрос решения проблемы, связанной с устранением дублирующихся подписей объектов в режиме редактирования.}} | {{Аннотация|В статье рассмотрен вопрос решения проблемы, связанной с устранением дублирующихся подписей объектов в режиме редактирования.}} | ||
Строка 8: | Строка 8: | ||
[[Файл:Modify-01.png|700px|thumb|center|<center>Объект в режиме редактирования</center>]] | [[Файл:Modify-01.png|700px|thumb|center|<center>Объект в режиме редактирования</center>]] | ||
Полупрозрачные круги - это так называемые виртуальные узлы, располагающиеся | Полупрозрачные круги - это так называемые виртуальные узлы, располагающиеся в центре рёбер и доступные для перетягивания. На первый взгляд всё хорошо, всё работает. А теперь давайте попробуем включить на редактирование какой-нибудь объект, в стиле отображения слоя которого используется подпись. В этом случае редактируемый объект приобретает вот такой вид и редактировать его становится практически невозможно: | ||
в центре рёбер и доступные для перетягивания. На первый взгляд всё хорошо, всё работает. А теперь давайте попробуем включить на редактирование какой-нибудь объект, в стиле отображения слоя которого используется подпись. В этом случае редактируемый объект приобретает вот такой вид и редактировать его становится практически невозможно: | |||
[[Файл:Modify-02.png|700px|thumb|center|<center>Дублирующиеся подписи объектов в режиме редактирования</center>]] | [[Файл:Modify-02.png|700px|thumb|center|<center>Дублирующиеся подписи объектов в режиме редактирования</center>]] | ||
Это происходит потому что и виртуальные узлы и сами вершины отрисовываются | Это происходит потому что и виртуальные узлы и сами вершины отрисовываются стилем самого слоя. Очевидным решением данной проблемы является определение отдельного стиля для отрисовки вершин и виртуальных узлов. | ||
стилем самого слоя. Очевидным решением данной проблемы является определение | |||
отдельного стиля для отрисовки вершин и виртуальных узлов. | |||
Посмотрим, что нам в этом направлении предлагает API | Посмотрим, что нам в этом направлении предлагает API OpenLayers. Согласно документации у ModifyFeature есть 2 свойства, позволяющих управлять внешним видом вершин и виртуальных узлов: [http://dev.openlayers.org/releases/OpenLayers-2.12/doc/devdocs/files/OpenLayers/Control/ModifyFeature-js.html#OpenLayers.Control.ModifyFeature.virtualStyle virtualStyle] и [http://dev.openlayers.org/releases/OpenLayers-2.12/doc/devdocs/files/OpenLayers/Control/ModifyFeature-js.html#OpenLayers.Control.ModifyFeature.vertexRenderIntent vertexRenderIntent]. | ||
видом вершин и виртуальных узлов: [http://dev.openlayers.org/releases/OpenLayers-2.12/doc/devdocs/files/OpenLayers/Control/ModifyFeature-js.html#OpenLayers.Control.ModifyFeature.virtualStyle virtualStyle] и [http://dev.openlayers.org/releases/OpenLayers-2.12/doc/devdocs/files/OpenLayers/Control/ModifyFeature-js.html#OpenLayers.Control.ModifyFeature.vertexRenderIntent vertexRenderIntent]. | |||
Фактически, vertexRenderIntent - это ключ, по которому доступно описание стиля (внутри карты стилей (styleMap) слоя), которым будут отрисовываться вершины. По умолчанию в OpenLayers векторный слой создаётся с картой стилей, содержащей описание 4-х предустановленных стилей: | Фактически, vertexRenderIntent - это ключ, по которому доступно описание стиля (внутри карты стилей (styleMap) слоя), которым будут отрисовываться вершины. По умолчанию в OpenLayers векторный слой создаётся с картой стилей, содержащей описание 4-х предустановленных стилей: | ||
Строка 29: | Строка 25: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
При создании слоя мы можем переопределить значение styleMap, указав только нужные стили и сконфигурировав их соответствующим образом (например, добавив вывод подписей). Предположим, наш слой содержит 4 вышеописанных предустановленных стиля, причём стиль "default" переопределён и содержит | При создании слоя мы можем переопределить значение styleMap, указав только нужные стили и сконфигурировав их соответствующим образом (например, добавив вывод подписей). Предположим, наш слой содержит 4 вышеописанных предустановленных стиля, причём стиль "default" переопределён и содержит вывод подписей. Таким образом, чтобы при редактировании объекта его узлы не подписывались - их нужно отрисовывать любым из стилей, в описание которого | ||
вывод подписей. Таким образом, чтобы при редактировании объекта его узлы | отсутствует вывод подписей. Например, их можно отрисовать стилем "temporary", указав его при создании контрола: | ||
не подписывались - их нужно | |||
указав его при создании контрола: | |||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
new OpenLayers.Control.ModifyFeature(layer, {vertexRenderIntent: "temporary"}) | new OpenLayers.Control.ModifyFeature(layer, {vertexRenderIntent: "temporary"}); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[Файл:Modify-03.png|700px|thumb|center|<center>Объект в режиме редактирования, свойство vertexRenderIntent контрола ModifyFeature равно " | [[Файл:Modify-03.png|700px|thumb|center|<center>Объект в режиме редактирования, свойство vertexRenderIntent контрола ModifyFeature установлено в значение "temporary"</center>]] | ||
Если нас не устраивает стиль "temporary", мы можем использовать любой другой, указанный в styleMap слоя: | |||
<syntaxhighlight lang="javascript"> | |||
var vertexStyle = { | |||
strokeColor: "#ff0000", | |||
fillColor: "#ff0000", | |||
strokeOpacity: 1, | |||
strokeWidth: 2, | |||
pointRadius: 3, | |||
graphicName: "cross" | |||
} | |||
var styleMap = new OpenLayers.StyleMap({ | |||
"default": OpenLayers.Feature.Vector.style['default'], | |||
"vertex": vertexStyle | |||
}, {extendDefault: false}); | |||
var layer = new OpenLayers.Layer.Vector('features', {styleMap: styleMap}); | |||
map.addControl(new OpenLayers.Control.ModifyFeature(layer, {vertexRenderIntent: "vertex"})); | |||
</syntaxhighlight> | |||
[[Файл:Modify-04.png|700px|thumb|center|<center>Использование собственного vertexRenderIntent</center>]] | |||
Опция [http://dev.openlayers.org/releases/OpenLayers-2.12/doc/devdocs/files/OpenLayers/StyleMap-js.html#OpenLayers.StyleMap.extendDefault extendDefault] очень важна, если значение extendDefault равно true (по умолчанию), то во время рендеринга используемый стиль будет расширять стиль "default", если false - то | |||
использоваться как независимый стиль. | |||
Как можно увидеть из рисунка виртуальные узлы отрисовываются в этом случае случае точно таким же стилем, что и вершины, только с другой прозрачностью заливки и обводки. | |||
Если же мы хотим чтобы стиль отрисовки виртуальных узлов не базировался на стиле вершин, мы можем задать его отдельно: | |||
<syntaxhighlight lang="javascript"> | |||
var virtual = { | |||
strokeColor: "#00ff00", | |||
fillColor: "#00ff00", | |||
strokeOpacity: 1, | |||
strokeWidth: 2, | |||
pointRadius: 5, | |||
graphicName: "triangle" | |||
}; | |||
map.addControl(new OpenLayers.Control.ModifyFeature(vectors, {vertexRenderIntent: "vertex", virtualStyle: virtual})); | |||
</syntaxhighlight> | |||
[[Файл:Modify-05.png|700px|thumb|center|<center>Совместное использование vertexRenderIntent и virtualStyle</center>]] | |||
Конечно, существуют и другие решения описанной проблемы, [http://gis.stackexchange.com/a/20136/3420 например], однако предложенный выше подход видится более общим и поэтому правильным. |
Текущая версия от 13:16, 29 июня 2012
по адресу http://gis-lab.info/qa/openlayers-modify-style.html
В статье рассмотрен вопрос решения проблемы, связанной с устранением дублирующихся подписей объектов в режиме редактирования.
Контрол OpenLayers.Control.ModifyFeature предназначен для изменения геометрий векторных объектов. По умолчанию данный контрол работает в режиме RESHAPE, который позволяет изменять положение вершин редактируемого объекта. Выглядит это следующим образом:
Полупрозрачные круги - это так называемые виртуальные узлы, располагающиеся в центре рёбер и доступные для перетягивания. На первый взгляд всё хорошо, всё работает. А теперь давайте попробуем включить на редактирование какой-нибудь объект, в стиле отображения слоя которого используется подпись. В этом случае редактируемый объект приобретает вот такой вид и редактировать его становится практически невозможно:
Это происходит потому что и виртуальные узлы и сами вершины отрисовываются стилем самого слоя. Очевидным решением данной проблемы является определение отдельного стиля для отрисовки вершин и виртуальных узлов.
Посмотрим, что нам в этом направлении предлагает API OpenLayers. Согласно документации у ModifyFeature есть 2 свойства, позволяющих управлять внешним видом вершин и виртуальных узлов: virtualStyle и vertexRenderIntent.
Фактически, vertexRenderIntent - это ключ, по которому доступно описание стиля (внутри карты стилей (styleMap) слоя), которым будут отрисовываться вершины. По умолчанию в OpenLayers векторный слой создаётся с картой стилей, содержащей описание 4-х предустановленных стилей:
layer.styleMap.styles["default"]
layer.styleMap.styles["delete"]
layer.styleMap.styles["select"]
layer.styleMap.styles["temporary"]
При создании слоя мы можем переопределить значение styleMap, указав только нужные стили и сконфигурировав их соответствующим образом (например, добавив вывод подписей). Предположим, наш слой содержит 4 вышеописанных предустановленных стиля, причём стиль "default" переопределён и содержит вывод подписей. Таким образом, чтобы при редактировании объекта его узлы не подписывались - их нужно отрисовывать любым из стилей, в описание которого отсутствует вывод подписей. Например, их можно отрисовать стилем "temporary", указав его при создании контрола:
new OpenLayers.Control.ModifyFeature(layer, {vertexRenderIntent: "temporary"});
Если нас не устраивает стиль "temporary", мы можем использовать любой другой, указанный в styleMap слоя:
var vertexStyle = {
strokeColor: "#ff0000",
fillColor: "#ff0000",
strokeOpacity: 1,
strokeWidth: 2,
pointRadius: 3,
graphicName: "cross"
}
var styleMap = new OpenLayers.StyleMap({
"default": OpenLayers.Feature.Vector.style['default'],
"vertex": vertexStyle
}, {extendDefault: false});
var layer = new OpenLayers.Layer.Vector('features', {styleMap: styleMap});
map.addControl(new OpenLayers.Control.ModifyFeature(layer, {vertexRenderIntent: "vertex"}));
Опция extendDefault очень важна, если значение extendDefault равно true (по умолчанию), то во время рендеринга используемый стиль будет расширять стиль "default", если false - то использоваться как независимый стиль.
Как можно увидеть из рисунка виртуальные узлы отрисовываются в этом случае случае точно таким же стилем, что и вершины, только с другой прозрачностью заливки и обводки.
Если же мы хотим чтобы стиль отрисовки виртуальных узлов не базировался на стиле вершин, мы можем задать его отдельно:
var virtual = {
strokeColor: "#00ff00",
fillColor: "#00ff00",
strokeOpacity: 1,
strokeWidth: 2,
pointRadius: 5,
graphicName: "triangle"
};
map.addControl(new OpenLayers.Control.ModifyFeature(vectors, {vertexRenderIntent: "vertex", virtualStyle: virtual}));
Конечно, существуют и другие решения описанной проблемы, например, однако предложенный выше подход видится более общим и поэтому правильным.