Skip to content

Commit

Permalink
Implemented a simple heat risk list model
Browse files Browse the repository at this point in the history
  • Loading branch information
esride-jts committed Nov 22, 2024
1 parent 1821105 commit 117d428
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ set(SOURCE_FILES
main.cpp
UrbanHeatAnalyzer.cpp
UrbanHeatAnalyzer.h
HeatRiskListModel.cpp
HeatRiskListModel.h
qml/qml.qrc
Resources/Resources.qrc
$<$<BOOL:${WIN32}>:Win/Resources.rc>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// "Urban Heat Analyzer"
// Copyright (C) 2024 Esri Deutschland GmbH
// Jan Tschada (j.tschada@esri.de)
//
// SPDX-License-Identifier: GPL-3.0-only
//
// Additional permission under GNU GPL version 3 section 7
//
// If you modify this Program, or any covered work, by linking or combining
// it with ArcGIS Maps SDK for Qt (or a modified version of that library),
// containing parts covered by the terms of ArcGIS Maps SDK for Qt,
// the licensors of this Program grant you additional permission to convey the resulting work.
// See <https://developers.arcgis.com/qt/> for further information.

#include "HeatRiskListModel.h"

#include "AttributeListModel.h"
#include "Feature.h"

using namespace Esri::ArcGISRuntime;


HeatRiskAnalysisGroup::HeatRiskAnalysisGroup(double heatRiskIndex)
: m_heatRiskIndex(heatRiskIndex)
{

}

QString HeatRiskAnalysisGroup::name() const
{
if (m_heatRiskFeatures.empty())
{
return "Unknown";
}

auto heatRiskFeatureAttributes = m_heatRiskFeatures.first()->attributes();
return heatRiskFeatureAttributes->attributeValue("GRID_ID").toString();
}

double HeatRiskAnalysisGroup::heatRiskIndex() const
{
return m_heatRiskIndex;
}

void HeatRiskAnalysisGroup::addFeature(Feature *heatRiskFeature)
{
m_heatRiskFeatures.append(heatRiskFeature);
}


HeatRiskListModel::HeatRiskListModel(QObject *parent)
: QAbstractListModel{parent}
{

}

void HeatRiskListModel::loadAnalysisGroups(const QList<HeatRiskAnalysisGroup> &analysisGroups)
{
beginResetModel();
m_analysisGroups = analysisGroups;
endResetModel();

// Emit that the full data has changed
emit dataChanged(index(0,0), index(rowCount() - 1));
}

int HeatRiskListModel::rowCount(const QModelIndex & parent) const {
Q_UNUSED(parent);
return m_analysisGroups.count();
}

QVariant HeatRiskListModel::data(const QModelIndex & index, int role) const {
if (index.row() < 0 || index.row() >= m_analysisGroups.count())
return QVariant();

const HeatRiskAnalysisGroup &analysisGroup = m_analysisGroups[index.row()];
if (role == NameRole)
return analysisGroup.name();
else if (role == RiskRole)
return analysisGroup.heatRiskIndex();
return QVariant();
}

QHash<int, QByteArray> HeatRiskListModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[RiskRole] = "risk";
return roles;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// "Urban Heat Analyzer"
// Copyright (C) 2024 Esri Deutschland GmbH
// Jan Tschada (j.tschada@esri.de)
//
// SPDX-License-Identifier: GPL-3.0-only
//
// Additional permission under GNU GPL version 3 section 7
//
// If you modify this Program, or any covered work, by linking or combining
// it with ArcGIS Maps SDK for Qt (or a modified version of that library),
// containing parts covered by the terms of ArcGIS Maps SDK for Qt,
// the licensors of this Program grant you additional permission to convey the resulting work.
// See <https://developers.arcgis.com/qt/> for further information.

#ifndef HEATRISKLISTMODEL_H
#define HEATRISKLISTMODEL_H

#include <QAbstractListModel>
#include <QObject>

namespace Esri::ArcGISRuntime {
class Feature;
} // namespace Esri::ArcGISRuntime


class HeatRiskAnalysisGroup
{
public:
HeatRiskAnalysisGroup(double heatRiskIndex);

QString name() const;
double heatRiskIndex() const;

void addFeature(Esri::ArcGISRuntime::Feature *heatRiskFeature);

private:
double m_heatRiskIndex;
QList<Esri::ArcGISRuntime::Feature*> m_heatRiskFeatures;
};


class HeatRiskListModel : public QAbstractListModel
{
Q_OBJECT
public:
enum HeatRiskRoles {
NameRole = Qt::UserRole + 1,
RiskRole
};

explicit HeatRiskListModel(QObject *parent = nullptr);

void loadAnalysisGroups(const QList<HeatRiskAnalysisGroup> &analysisGroups);

int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;

protected:
QHash<int, QByteArray> roleNames() const;

private:
QList<HeatRiskAnalysisGroup> m_analysisGroups;
};

#endif // HEATRISKLISTMODEL_H
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// See <https://developers.arcgis.com/qt/> for further information.
//

#include "HeatRiskListModel.h"
#include "UrbanHeatAnalyzer.h"

#include "ArcGISSceneLayer.h"
Expand Down Expand Up @@ -106,7 +107,7 @@ UrbanHeatAnalyzer::UrbanHeatAnalyzer(QObject *parent /* = nullptr */)
m_sceneView->setViewpointAsync(targetViewpoint, 10);
}

//loadHeatRiskFeatures();
loadHeatRiskFeatures();
});
m_scene->operationalLayers()->append(tiledLayer);
}
Expand All @@ -121,7 +122,8 @@ SceneQuickView *UrbanHeatAnalyzer::sceneView() const
// Set the view (created in QML)
void UrbanHeatAnalyzer::setSceneView(SceneQuickView *sceneView)
{
if (!sceneView || sceneView == m_sceneView) {
if (!sceneView || sceneView == m_sceneView)
{
return;
}

Expand All @@ -131,6 +133,16 @@ void UrbanHeatAnalyzer::setSceneView(SceneQuickView *sceneView)
emit sceneViewChanged();
}

void UrbanHeatAnalyzer::setHeatRiskListModel(HeatRiskListModel *heatRiskListModel)
{
if (!heatRiskListModel)
{
return;
}

m_heatRiskListModel = heatRiskListModel;
}

void UrbanHeatAnalyzer::loadHeatRiskFeatures()
{
// add the features
Expand Down Expand Up @@ -162,8 +174,8 @@ void UrbanHeatAnalyzer::loadHeatRiskFeatures()
return;
}

QMap<double, QList<Feature*>> analysisGroups;
QList<Feature*> currentGroup;
QList<HeatRiskAnalysisGroup> analysisGroups;
HeatRiskAnalysisGroup *currentGroup = nullptr;

// iterate over the result object
double lastValue = 9999;
Expand All @@ -176,22 +188,26 @@ void UrbanHeatAnalyzer::loadHeatRiskFeatures()
if (lastValue == heatRiskIndexValue)
{
// add to the last group
currentGroup.append(feature);
if (currentGroup)
{
currentGroup->addFeature(feature);
}
}
else if (heatRiskIndexValue < lastValue)
{
// create a new group
analysisGroups.insert(heatRiskIndexValue, QList(currentGroup));
currentGroup.clear();
currentGroup.append(feature);
HeatRiskAnalysisGroup newGroup(heatRiskIndexValue);
newGroup.addFeature(feature);
analysisGroups.append(newGroup);
currentGroup = &analysisGroups.last();
}
lastValue = heatRiskIndexValue;
}

for (auto groupIt = analysisGroups.keyValueBegin(); groupIt != analysisGroups.keyValueEnd(); ++groupIt)
// Load the features into the model
if (m_heatRiskListModel)
{
qDebug() << groupIt->first;
qDebug() << groupIt->second.size();
m_heatRiskListModel->loadAnalysisGroups(analysisGroups);
}
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#ifndef URBANHEATANALYZER_H
#define URBANHEATANALYZER_H

class HeatRiskListModel;

namespace Esri::ArcGISRuntime {
class Scene;
class SceneQuickView;
Expand All @@ -32,12 +34,16 @@ class SceneQuickView;

Q_MOC_INCLUDE("SceneQuickView.h")


class UrbanHeatAnalyzer : public QObject
{
Q_OBJECT

Q_PROPERTY(Esri::ArcGISRuntime::SceneQuickView *sceneView READ sceneView WRITE setSceneView
Q_PROPERTY(Esri::ArcGISRuntime::SceneQuickView *sceneView
READ sceneView WRITE setSceneView
NOTIFY sceneViewChanged)
Q_PROPERTY(HeatRiskListModel *heatRiskListModel
WRITE setHeatRiskListModel)

public:
explicit UrbanHeatAnalyzer(QObject *parent = nullptr);
Expand All @@ -54,8 +60,11 @@ class UrbanHeatAnalyzer : public QObject
Esri::ArcGISRuntime::SceneQuickView *sceneView() const;
void setSceneView(Esri::ArcGISRuntime::SceneQuickView *sceneView);

void setHeatRiskListModel(HeatRiskListModel *heatRiskListModel);

Esri::ArcGISRuntime::Scene *m_scene = nullptr;
Esri::ArcGISRuntime::SceneQuickView *m_sceneView = nullptr;
HeatRiskListModel *m_heatRiskListModel = nullptr;
};

#endif // URBANHEATANALYZER_H
4 changes: 4 additions & 0 deletions native-apps/urban-heat-analyzer/UrbanHeatAnalyzer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// See <https://developers.arcgis.com/qt/> for further information.
//

#include "HeatRiskListModel.h"
#include "UrbanHeatAnalyzer.h"

#include "ArcGISRuntimeEnvironment.h"
Expand Down Expand Up @@ -91,6 +92,9 @@ int main(int argc, char *argv[])
// Register the UrbanHeatAnalyzer (QQuickItem) for QML
qmlRegisterType<UrbanHeatAnalyzer>("Esri.UrbanHeatAnalyzer", 1, 0, "UrbanHeatAnalyzer");

// Register the HeatRiskListModel for QML
qmlRegisterType<HeatRiskListModel>("Esri.UrbanHeatAnalyzer", 1, 0, "HeatRiskListModel");

// Initialize application view
QQmlApplicationEngine engine;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,18 @@ import Esri.UrbanHeatAnalyzer

Item {

// Define a property for HeatRiskListModel
property HeatRiskListModel heatRiskListModel: riskModel

function printCamera() {
model.printCamera();
}

// Create HeatRiskListModel here
HeatRiskListModel {
id: riskModel
}

// Create SceneQuickView here, and create its Scene etc. in C++ code
SceneView {
id: view
Expand All @@ -40,5 +48,6 @@ Item {
UrbanHeatAnalyzer {
id: model
sceneView: view
heatRiskListModel: riskModel
}
}
19 changes: 1 addition & 18 deletions native-apps/urban-heat-analyzer/UrbanHeatAnalyzer/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,6 @@ ApplicationWindow {
RowLayout {
anchors.fill: parent

ListModel {
id: riskModel

ListElement {
name: "Place 1"
risk: 12
}
ListElement {
name: "Place 2"
risk: 11
}
ListElement {
name: "Place 3"
risk: 10
}
}

Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
Expand Down Expand Up @@ -107,7 +90,7 @@ ApplicationWindow {
anchors.fill: parent
orientation: Qt.Horizontal

model: riskModel
model: mapForm.heatRiskListModel
delegate: riskDelegate
highlight: Rectangle { color: Material.primary; radius: 5 }
focus: false
Expand Down

0 comments on commit 117d428

Please sign in to comment.