Has anyone added GitHub - walkermatt/ol-layerswitcher: Layer control for OpenLayers to Jmix Map yet?
How do I do that?
Has anyone added GitHub - walkermatt/ol-layerswitcher: Layer control for OpenLayers to Jmix Map yet?
How do I do that?
Hi Benoît!
Could you clarify which features you need from the Layer Switcher? To integrate it with GeoMap, you’ll need to extend the GeoMap component and run some JavaScript code to update the added layers.
I’ve prepared a demo project that uses the Layer Switcher. In this project, I imported BaseObjectMap to detect added layers and set the correct labels. This import comes from generated/jar-resource/... , which may change in future Vaadin releases. Therefore, I wouldn’t recommend using it in production.
I think you can implement a similar popup using Jmix components. For example, you could create a button with popup content, like this:
<layout classNames="relative">
<button id="jmixLayerSwitcherButton"
icon="CHEVRON_CIRCLE_DOWN_O"
themeNames="tertiary-inline"
classNames="jmix-button-layer-switcher"/>
<maps:geoMap id="map" height="100%" width="100%">
<maps:layers>
<maps:tile id="osmLayer">
<maps:osmSource/>
</maps:tile>
<maps:vector id="vectorLayer">
<maps:vectorSource/>
</maps:vector>
</maps:layers>
</maps:geoMap>
</layout>
@ViewComponent
private GeoMap map;
@ViewComponent
private MessageBundle messageBundle;
@Subscribe
public void onInit(final InitEvent event) {
createLayersPopover();
}
protected void createLayersPopover() {
Popover popover = new Popover();
popover.setFor("jmixLayerSwitcherButton");
CheckboxGroup<Layer<?>> layersCheckboxGroup = new CheckboxGroup<>();
layersCheckboxGroup.addThemeVariants(CheckboxGroupVariant.LUMO_VERTICAL);
layersCheckboxGroup.setItems(new ListDataProvider<>(map.getLayers()));
layersCheckboxGroup.setValue(new HashSet<>(map.getLayers()));
layersCheckboxGroup.setItemLabelGenerator(layer -> messageBundle.getMessage("map.layer." + layer.getId()));
layersCheckboxGroup.addValueChangeListener(event -> {
map.getLayers().forEach(layer ->
layer.setVisible(event.getValue().contains(layer)));
});
popover.add(layersCheckboxGroup);
getContent().add(popover);
}

Demo project: layer-switcher.zip (198.4 KB)
Thanks,
I adapted your code to inject the layers switch button from the controller, so I could use it in any screen with a map
fun createLayersPopover(map: GeoMap, origin: View<*>) {
val view = origin.content as ViewLayout
if (view.findComponent("jmixLayerSwitcherButton").getOrNull() == null) {
val parentMap = map.parent.get()
val button = uiComponents.create(JmixButton::class.java).apply {
icon = Icon(VaadinIcon.CHEVRON_CIRCLE_DOWN_O)
addClassNames("z-10", "absolute", "top-s", "end-s", "bg-base", "text-xl")
addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE) // Use tertiary style for icon buttons
setId("jmixLayerSwitcherButton")
}
val children = (parentMap as HasOrderedComponents).children
parentMap.removeAll()
children.forEach {
if (it == map) {
val mapBox = uiComponents.create(HorizontalLayout::class.java).apply {
addClassNames("relative", "w-full", "h-full")
}
mapBox.add(it)
mapBox.add(button)
parentMap.add(mapBox)
}
else
parentMap.add(it)
}
}
val popover = Popover()
popover.setFor("jmixLayerSwitcherButton");
val layersCheckboxGroup = CheckboxGroup<Layer<*>>()
layersCheckboxGroup.addThemeVariants(CheckboxGroupVariant.LUMO_VERTICAL)
layersCheckboxGroup.setItems(ListDataProvider(map.layers.sortedBy { it.zIndex }))
layersCheckboxGroup.value = HashSet(map.layers.filter { it.visible != false })
layersCheckboxGroup.setItemLabelGenerator { layer ->
when (layer) {
is TileLayer -> {
try {
//
dataManger.find from my app WMS table with layer.id
} catch (e: IllegalArgumentException) {
null
}?.name
?: messages.getMessage(origin.javaClass.name, "tile.layer.${layer.id}")
}
is VectorLayer -> {
messages.getMessage(origin.javaClass.name, "vector.layer.${layer.id}")
}
else -> messages.getMessage(origin.javaClass.name, "other.layer.${layer.id}")
}
}
layersCheckboxGroup.addValueChangeListener { event ->
map.layers.forEach { layer ->
layer.visible = event.getValue().contains(layer)
}
}
popover.add(layersCheckboxGroup);
view.add(popover)
}