Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map theme integration (#17) #27

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
Loading