Skip to content
Permalink
Browse files

[feature] [mesh] Mesh Calculator

Similarly to raster calculator, mesh calculator can take dataset groups from current mesh layer and
combine them with various aritmentic/logical operators to new dataset group.
  • Loading branch information
PeterPetrik committed Dec 18, 2018
1 parent e163caf commit cd9a84e11c2649f3af9b4cee08652bdfcd340134
Showing with 4,761 additions and 76 deletions.
  1. +1 −0 doc/CMakeLists.txt
  2. +1 −0 images/images.qrc
  3. BIN images/themes/default/mActionShowMeshCalculator.png
  4. +2 −0 python/CMakeLists.txt
  5. +1 −0 python/analysis/analysis_auto.sip
  6. +109 −0 python/analysis/auto_generated/mesh/qgsmeshcalculator.sip.in
  7. +24 −0 python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in
  8. +2 −0 python/core/auto_generated/mesh/qgsmeshlayer.sip.in
  9. +14 −0 src/analysis/CMakeLists.txt
  10. +92 −0 src/analysis/mesh/qgsmeshcalclexer.ll
  11. +234 −0 src/analysis/mesh/qgsmeshcalcnode.cpp
  12. +164 −0 src/analysis/mesh/qgsmeshcalcnode.h
  13. +168 −0 src/analysis/mesh/qgsmeshcalcparser.yy
  14. +195 −0 src/analysis/mesh/qgsmeshcalculator.cpp
  15. +126 −0 src/analysis/mesh/qgsmeshcalculator.h
  16. +1,114 −0 src/analysis/mesh/qgsmeshcalcutils.cpp
  17. +281 −0 src/analysis/mesh/qgsmeshcalcutils.h
  18. +4 −1 src/app/CMakeLists.txt
  19. +557 −0 src/app/mesh/qgsmeshcalculatordialog.cpp
  20. +129 −0 src/app/mesh/qgsmeshcalculatordialog.h
  21. +13 −5 src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp
  22. +7 −1 src/app/mesh/qgsmeshrendereractivedatasetwidget.h
  23. +71 −0 src/app/qgisapp.cpp
  24. +2 −0 src/app/qgisapp.h
  25. +23 −0 src/core/mesh/qgsmeshdataprovider.h
  26. +12 −3 src/core/mesh/qgsmeshlayer.cpp
  27. +29 −6 src/core/mesh/qgsmeshlayer.h
  28. +147 −43 src/core/mesh/qgsmeshmemorydataprovider.cpp
  29. +28 −8 src/core/mesh/qgsmeshmemorydataprovider.h
  30. +2 −2 src/core/mesh/qgstriangularmesh.h
  31. +70 −0 src/providers/mdal/qgsmdalprovider.cpp
  32. +7 −0 src/providers/mdal/qgsmdalprovider.h
  33. +649 −0 src/ui/mesh/qgsmeshcalculatordialogbase.ui
  34. +49 −2 src/ui/qgisapp.ui
  35. +3 −3 src/ui/qgsrastercalcdialogbase.ui
  36. +4 −2 tests/src/analysis/CMakeLists.txt
  37. +240 −0 tests/src/analysis/testqgsmeshcalculator.cpp
  38. +6 −0 tests/src/app/CMakeLists.txt
  39. +109 −0 tests/src/app/testqgsmeshcalculatordialog.cpp
  40. +21 −0 tests/testdata/mesh/quad_and_triangle_vertex_scalar2.dat
  41. +15 −0 tests/testdata/mesh/quad_and_triangle_vertex_scalar_max.dat
  42. +21 −0 tests/testdata/mesh/quad_and_triangle_vertex_vector2.dat
  43. +15 −0 tests/testdata/mesh/quad_and_triangle_vertex_vector_max.dat
@@ -94,6 +94,7 @@ IF(WITH_APIDOC)
${CMAKE_SOURCE_DIR}/src/gui/raster
${CMAKE_SOURCE_DIR}/src/gui/symbology
${CMAKE_SOURCE_DIR}/src/analysis
${CMAKE_SOURCE_DIR}/src/analysis/mesh
${CMAKE_SOURCE_DIR}/src/analysis/interpolation
${CMAKE_SOURCE_DIR}/src/analysis/network
${CMAKE_SOURCE_DIR}/src/analysis/processing
@@ -379,6 +379,7 @@
<file>themes/default/mActionShowPinnedLabels.svg</file>
<file>themes/default/mActionShowPluginManager.svg</file>
<file>themes/default/mActionShowRasterCalculator.png</file>
<file>themes/default/mActionShowMeshCalculator.png</file>
<file>themes/default/mActionShowSelectedLayers.svg</file>
<file>themes/default/mActionSimplify.svg</file>
<file>themes/default/mActionSplitFeatures.svg</file>
Binary file not shown.
@@ -274,13 +274,15 @@ INCLUDE_DIRECTORIES(BEFORE
${CMAKE_SOURCE_DIR}/src/analysis/processing
${CMAKE_SOURCE_DIR}/src/analysis/vector
${CMAKE_SOURCE_DIR}/src/analysis/vector/geometry_checker
${CMAKE_SOURCE_DIR}/src/analysis/mesh
${CMAKE_SOURCE_DIR}/src/analysis/raster
${CMAKE_SOURCE_DIR}/src/analysis/network
${CMAKE_SOURCE_DIR}/src/analysis/interpolation
${CMAKE_SOURCE_DIR}/src/analysis/openstreetmap

${CMAKE_BINARY_DIR}/src/analysis/processing
${CMAKE_BINARY_DIR}/src/analysis/vector
${CMAKE_BINARY_DIR}/src/analysis/mesh
${CMAKE_BINARY_DIR}/src/analysis/raster
${CMAKE_BINARY_DIR}/src/analysis/network
${CMAKE_BINARY_DIR}/src/analysis/interpolation
@@ -14,6 +14,7 @@
%Include auto_generated/raster/qgsrastermatrix.sip
%Include auto_generated/raster/qgsrastercalcnode.sip
%Include auto_generated/raster/qgstotalcurvaturefilter.sip
%Include auto_generated/mesh/qgsmeshcalculator.sip
%Include auto_generated/vector/qgsgeometrysnapper.sip
%Include auto_generated/vector/qgsgeometrysnappersinglesource.sip
%Include auto_generated/vector/qgszonalstatistics.sip
@@ -0,0 +1,109 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/analysis/mesh/qgsmeshcalculator.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/






class QgsMeshCalculator
{
%Docstring
Performs mesh layer calculations.

Mesh calculator can do various mathematical operations
between dataset groups from a single mesh layer.
Resulting dataset group is added to the mesh layer.
Result can be filtered by extent or a vector layer mask
spatially and by selection of times.

Note: only dataset groups defined on vertices are
implemented and supported

.. versionadded:: 3.6
%End

%TypeHeaderCode
#include "qgsmeshcalculator.h"
%End
public:

enum Result
{
Success,
Canceled,
CreateOutputError,
InputLayerError,
ParserError,
InvalidDatasets,
EvaluateError,
MemoryError,
};

QgsMeshCalculator( const QString &formulaString,
const QString &outputFile,
const QgsRectangle &outputExtent,
double startTime,
double endTime,
QgsMeshLayer *layer );
%Docstring
Creates calculator with bounding box (rectangular) mask

:param formulaString: formula/expression to evaluate. Consists of dataset group names, operators and numbers
:param outputFile: file to store the resulting dataset group data
:param outputExtent: spatial filter defined by rectangle
:param startTime: time filter defining the starting dataset
:param endTime: time filter defining the ending dataset
:param layer: mesh layer with dataset groups references in formulaString
%End

QgsMeshCalculator( const QString &formulaString,
const QString &outputFile,
const QgsGeometry &outputMask,
double startTime,
double endTime,
QgsMeshLayer *layer );
%Docstring
Creates calculator with geometry mask

:param formulaString: formula/expression to evaluate. Consists of dataset group names, operators and numbers
:param outputFile: file to store the resulting dataset group data
:param outputMask: spatial filter defined by geometry
:param startTime: time filter defining the starting dataset
:param endTime: time filter defining the ending dataset
:param layer: mesh layer with dataset groups references in formulaString
%End

Result processCalculation( QgsFeedback *feedback = 0 );
%Docstring
Starts the calculation, writes new dataset group to file and adds it to the mesh layer

:param feedback: The optional feedback argument for progress reporting and cancelation support

:return: QgsMeshCalculator.Success in case of success
%End

static Result expression_valid( const QString &formulaString, QgsMeshLayer *layer );
%Docstring
Returns whether formula is valid for particular mesh layer

:param formulaString: formula/expression to evaluate. Consists of dataset group names, operators and numbers
:param layer: mesh layer with dataset groups references in formulaString

:return: QgsMeshCalculator.Success in case of success
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/analysis/mesh/qgsmeshcalculator.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -509,6 +509,30 @@ V3 ---- V4 ---- V6-----V8
%Docstring
Returns whether the faces are active for particular dataset

.. versionadded:: 3.6
%End

virtual bool persistDatasetGroup( const QString &path,
const QgsMeshDatasetGroupMetadata &meta,
const QVector<QgsMeshDataBlock> &datasetValues,
const QVector<QgsMeshDataBlock> &datasetActive,
const QVector<double> &times
) = 0;
%Docstring
Creates a new dataset group from a data and
persists it into a destination path

On success, the mesh's dataset group count is changed

:param path: destination path of the stored file
:param meta: new group's metadata
:param datasetValues: scalar/vector values for all datasets and all faces/vertices in the group
:param datasetActive: active flag values for all datasets in the group. Empty array represents can be used
when all faces are active
:param times: times in hours for all datasets in the group

:return: true on failure, false on success

.. versionadded:: 3.6
%End
};
@@ -130,6 +130,8 @@ Returns the provider type for this layer





QgsMeshRendererSettings rendererSettings() const;
%Docstring
Returns renderer settings
@@ -137,6 +137,10 @@ SET(QGIS_ANALYSIS_SRCS
vector/qgsgeometrysnappersinglesource.cpp
vector/qgszonalstatistics.cpp

mesh/qgsmeshcalcnode.cpp
mesh/qgsmeshcalculator.cpp
mesh/qgsmeshcalcutils.cpp

network/qgsgraph.cpp
network/qgsgraphbuilder.cpp
network/qgsgraphbuilderinterface.cpp
@@ -204,14 +208,18 @@ FIND_PACKAGE(EXIV2 REQUIRED)
INCLUDE_DIRECTORIES(SYSTEM ${SPATIALITE_INCLUDE_DIR})
INCLUDE_DIRECTORIES(SYSTEM ${SQLITE3_INCLUDE_DIR})
INCLUDE_DIRECTORIES(BEFORE raster)
INCLUDE_DIRECTORIES(BEFORE mesh)

ADD_FLEX_FILES_PREFIX(QGIS_ANALYSIS_SRCS raster raster/qgsrastercalclexer.ll)
ADD_FLEX_FILES_PREFIX(QGIS_ANALYSIS_SRCS mesh mesh/qgsmeshcalclexer.ll)

ADD_BISON_FILES_PREFIX(QGIS_ANALYSIS_SRCS raster raster/qgsrastercalcparser.yy)
ADD_BISON_FILES_PREFIX(QGIS_ANALYSIS_SRCS mesh mesh/qgsmeshcalcparser.yy)

IF(NOT MSVC)
SET_SOURCE_FILES_PROPERTIES(
${CMAKE_BINARY_DIR}/src/analysis/qgsrastercalcparser.cpp
${CMAKE_BINARY_DIR}/src/analysis/qgsmeshcalcparser.cpp
PROPERTIES COMPILE_FLAGS "-w"
)
ELSE(NOT MSVC)
@@ -220,6 +228,7 @@ ELSE(NOT MSVC)
# 4702 unreachable code
SET_SOURCE_FILES_PROPERTIES(
${CMAKE_BINARY_DIR}/src/analysis/qgsrastercalcparser.cpp
${CMAKE_BINARY_DIR}/src/analysis/qgsmeshcalcparser.cpp
PROPERTIES COMPILE_FLAGS "-wd4127 -wd4702"
)
ENDIF(PEDANTIC)
@@ -258,6 +267,10 @@ SET(QGIS_ANALYSIS_HDRS
raster/qgsrastermatrix.h
raster/qgsrastercalcnode.h
raster/qgstotalcurvaturefilter.h

mesh/qgsmeshcalcnode.h
mesh/qgsmeshcalculator.h
mesh/qgsmeshcalcutils.h

vector/mersenne-twister.h
vector/qgsgeometrysnapper.h
@@ -329,6 +342,7 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/src/core/geometry
${CMAKE_SOURCE_DIR}/src/core/processing
${CMAKE_SOURCE_DIR}/src/core/raster
${CMAKE_SOURCE_DIR}/src/core/mesh
${CMAKE_SOURCE_DIR}/src/core/symbology
${CMAKE_SOURCE_DIR}/src/core/metadata
${CMAKE_SOURCE_DIR}/src/core/expression
@@ -0,0 +1,92 @@
/***************************************************************************
qgsmeshcalclexer.ll
-------------------
begin : December 19th, 2018
copyright : (C) 2018 by Peter Petrik
email : zilolv at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

%option noyywrap
%option nounput
%option case-insensitive
%option never-interactive

// ensure that lexer will be 8-bit (and not just 7-bit)
%option 8bit

%{
//directly included in the output program
#include "qgsmeshcalcnode.h"
#include "qgsmeshcalcparser.hpp"

// if not defined, searches for isatty()
// which doesn't in MSVC compiler
#define YY_NEVER_INTERACTIVE 1

#ifdef _MSC_VER
#define YY_NO_UNISTD_H
#endif

#ifndef _MSC_VER
#pragma GCC diagnostic ignored "-Wsign-compare"
#endif
%}

white [ \t\r\n]+

dig [0-9]
num1 {dig}+\.?([eE][-+]?{dig}+)?
num2 {dig}*\.{dig}+([eE][-+]?{dig}+)?
number {num1}|{num2}

non_ascii [\x80-\xFF]
dataset_ref_char [A-Za-z0-9_./:]|{non_ascii}|[-]
dataset_ref ({dataset_ref_char}+)
dataset_ref_quoted \"(\\.|[^"])*\"
%%
"sum_aggr" { meshlval.op = QgsMeshCalcNode::opSUM_AGGR; return FUNCTION; }
"max_aggr" { meshlval.op = QgsMeshCalcNode::opMAX_AGGR; return FUNCTION; }
"min_aggr" { meshlval.op = QgsMeshCalcNode::opMIN_AGGR; return FUNCTION; }
"average_aggr" { meshlval.op = QgsMeshCalcNode::opAVG_AGGR; return FUNCTION; }
"abs" { meshlval.op = QgsMeshCalcNode::opABS; return FUNCTION; }
"max" { meshlval.op = QgsMeshCalcNode::opMAX; return FUNCTION2; }
"min" { meshlval.op = QgsMeshCalcNode::opMIN; return FUNCTION2; }
"IF" { return IF; }
"AND" { return AND; }
"OR" { return OR; }
"NOT" { return NOT; }
"!=" { return NE; }
"<=" { return LE; }
">=" { return GE; }
"NODATA" {return NODATA;}
[=><+-/*^] { return yytext[0]; }
[()] { return yytext[0]; }
{number} { meshlval.number = atof(meshtext); return NUMBER; }
{dataset_ref} { return DATASET_REF; }
{dataset_ref_quoted} { return DATASET_REF; }
{white} /* skip blanks and tabs */
%%
void set_mesh_input_buffer(const char* buffer)
{
mesh_scan_string(buffer);
}

0 comments on commit cd9a84e

Please sign in to comment.
You can’t perform that action at this time.