Skip to content

Commit

Permalink
Map theme integration (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
boardend committed Feb 16, 2024
1 parent 57b4baf commit 4aee2f8
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 6 deletions.
9 changes: 9 additions & 0 deletions packages/qgis-js/src/QgisApiAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ export class QgisApiAdapterImplementation implements QgisApiAdapter {
}
return result;
}

mapThemes(): readonly string[] {
const mapLayersRaw = this._api.mapThemes();
const result = new Array<string>(mapLayersRaw.size());
for (let i = 0; i < mapLayersRaw.size(); i++) {
result[i] = mapLayersRaw.get(i);
}
return result;
}
}

export function getQgisApiProxy(api: InternalQgisApi): QgisApi {
Expand Down
16 changes: 14 additions & 2 deletions sites/dev/src/demo.css
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,31 @@ a.source {
right: 2em;
}

#layers-control .layers {
#layers-control .layers,
.themes {
width: 25em;
padding: 1em 0.5em;
border: 1px solid #ccc;
border-bottom: none;
background-color: #ffffff;
}

#layers-control .layers::before {
#layers-control .layers::before,
.themes::before {
margin: 1em 0.5em;
font-weight: bold;
content: "Layers:";
}

#layers-control .themes::before {
content: "Map Theme:";
}

#layers-control .themes select {
float: right;
width: 18em;
}

#layers-control .layers :first-child {
margin-top: 0.5em;
}
Expand Down
1 change: 1 addition & 0 deletions sites/dev/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ async function initDemo() {
if (timer) console.time("project");
api.loadProject(project);
if (timer) console.timeEnd("project");

// update all demos
setTimeout(() => {
updateCallbacks.forEach((update) => update());
Expand Down
45 changes: 41 additions & 4 deletions sites/dev/src/layers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export function layersControl(
const update = () => {
target.innerHTML = "";

const container = document.createElement("div");
container.className = "layers";
target.appendChild(container);
const layerContainer = document.createElement("div");
layerContainer.className = "layers";
target.appendChild(layerContainer);

const layers = api.mapLayers();
for (const layer of layers) {
Expand All @@ -26,6 +26,7 @@ export function layersControl(
checkbox.addEventListener("change", () => {
layer.visible = checkbox.checked;
redraw();
update();
});
node.appendChild(checkbox);

Expand All @@ -49,7 +50,43 @@ export function layersControl(
});

node.appendChild(slider);
container.appendChild(node);
layerContainer.appendChild(node);
}

if (api.mapThemes().length > 0) {
const themeContainer = document.createElement("div");
themeContainer.className = "themes";
target.appendChild(themeContainer);

const select = document.createElement("select");
select.addEventListener("change", () => {
if (select.value) {
api.setMapTheme(select.value);
redraw();
update();
}
});
themeContainer.appendChild(select);

const currentTheme = api.getMapTheme();

const option = document.createElement("option");
option.value = "";
option.text = "";
if (!currentTheme) {
option.selected = true;
}
select.appendChild(option);

for (const theme of api.mapThemes()) {
const option = document.createElement("option");
option.value = theme;
option.text = theme;
if (theme === currentTheme) {
option.selected = true;
}
select.appendChild(option);
}
}
};

Expand Down
38 changes: 38 additions & 0 deletions src/api/QgisApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,40 @@ const std::vector<MapLayer *> QgisApi_mapLayers() {
return result;
}

const std::vector<std::string> QgisApi_mapThemes() {
std::vector<std::string> result = {};
for (const QString &theme : QgsProject::instance()->mapThemeCollection()->mapThemes()) {
result.push_back(theme.toStdString());
}
return result;
}

const std::string QgisApi_getMapTheme() {
QgsLayerTree *layerTreeRoot = QgsProject::instance()->layerTreeRoot();
QgsMapThemeCollection *collection = QgsProject::instance()->mapThemeCollection();
QgsLayerTreeModel model(layerTreeRoot);
auto currentState = QgsMapThemeCollection::createThemeFromCurrentState(layerTreeRoot, &model);
for (const QString &theme : QgsProject::instance()->mapThemeCollection()->mapThemes()) {
if (currentState == QgsProject::instance()->mapThemeCollection()->mapThemeState(theme)) {
return theme.toStdString();
}
}
return "";
}

const bool QgisApi_setMapTheme(std::string themeName) {
QString qThemeName = QString::fromStdString(themeName);
if (!QgsProject::instance()->mapThemeCollection()->hasMapTheme(qThemeName)) {
return false;
} else {
QgsLayerTree *layerTreeRoot = QgsProject::instance()->layerTreeRoot();
QgsMapThemeCollection *collection = QgsProject::instance()->mapThemeCollection();
QgsLayerTreeModel model(layerTreeRoot);
collection->applyTheme(qThemeName, layerTreeRoot, &model);
return true;
}
}

EMSCRIPTEN_BINDINGS(QgisApi) {
emscripten::function("loadProject", &QgisApi_loadProject);
emscripten::function("fullExtent", &QgisApi_fullExtent);
Expand All @@ -151,4 +185,8 @@ EMSCRIPTEN_BINDINGS(QgisApi) {
emscripten::function("transformRectangle", &QgisApi_transformRectangle);
emscripten::function("mapLayers", &QgisApi_mapLayers, emscripten::allow_raw_pointers());
emscripten::register_vector<MapLayer *>("vector<MapLayer *>");
emscripten::function("mapThemes", &QgisApi_mapThemes, emscripten::allow_raw_pointers());
emscripten::function("getMapTheme", &QgisApi_getMapTheme);
emscripten::function("setMapTheme", &QgisApi_setMapTheme);
emscripten::register_vector<std::string>("vector<std::string>");
}
23 changes: 23 additions & 0 deletions src/api/QgisApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ export interface CommonQgisApi extends QgisModelConstructors {
inputSrid: string,
outputSrid: string,
): Rectangle;

/**
* Gets the current map theme of the current project.
*
* @returns The name of the current map theme. An empty string if no map theme is set.
*/
setMapTheme(mapTheme: string): boolean;

/**
* Sets a map theme of the current project.
*
* @param
* @returns true if the map theme was loaded successfully, false otherwise.
*/
setMapTheme(mapTheme: string): boolean;
}

/**
Expand Down Expand Up @@ -89,6 +104,13 @@ export interface QgisApiAdapter {
* @returns The map layers of the loaded project.
*/
mapLayers(): readonly MapLayer[];

/**
* Returns the map themes of the loaded project.
*
* @returns The map themes of the loaded project.
*/
mapThemes(): readonly string[];
}

/**
Expand Down Expand Up @@ -120,4 +142,5 @@ export interface InternalQgisApi extends CommonQgisApi {
callback: (tileData: ArrayBufferLike) => void,
): number;
mapLayers(): any;
mapThemes(): any;
}

0 comments on commit 4aee2f8

Please sign in to comment.