QString IlwisObjectModel::rangeDefinition(bool defaultRange, bool calc, const QString& columnName) { try { IlwisTypes objectype = _ilwisobject->ilwisType(); QString rangeString; if ( hasType( objectype, itCOVERAGE|itDOMAIN)){ if ( objectype == itRASTER){ IRasterCoverage raster = _ilwisobject.as<RasterCoverage>(); if ( defaultRange){ rangeString = raster->datadef().domain()->range()->toString(); }else{ if ( calc){ raster->loadData(); raster->statistics(NumericStatistics::pBASIC); } rangeString = raster->datadef().range()->toString(); } } else if ( hasType( objectype , itFEATURE)){ IFeatureCoverage features = _ilwisobject.as<FeatureCoverage>(); ColumnDefinition coldef = features->attributeDefinitions().columndefinition(COVERAGEKEYCOLUMN); if ( coldef.isValid()){ if ( defaultRange) rangeString = coldef.datadef().domain()->range()->toString(); else{ if ( calc){ features->loadData(); std::vector<QVariant> data = features->attributeTable()->column(columnName); if ( data.size() != 0){ std::vector<double> values(data.size()); int i=0; for(auto v : data) values[i++] = v.toDouble(); NumericStatistics stats; // realy like to do this with a template specialization of the proper calculate function, but the syntax was unclear to me stats.calculate(values.begin(), values.end()); NumericRange *rng = new NumericRange(stats.prop(NumericStatistics::pMIN),stats.prop(NumericStatistics::pMAX)); features->attributeDefinitionsRef().columndefinitionRef(columnName).datadef().range(rng); } } rangeString = coldef.datadef().range()->toString(); } } } else if ( hasType( objectype , itDOMAIN)){ rangeString = _ilwisobject.as<Domain>()->range()->toString(); } } return rangeString; }catch(const ErrorObject& ){ // no exceptions may escape here } return ""; }
bool SelectionRaster::execute(ExecutionContext *ctx, SymbolTable& symTable) { if (_prepState == sNOTPREPARED) if((_prepState = prepare(ctx, symTable)) != sPREPARED) return false; IRasterCoverage outputRaster = _outputObj.as<RasterCoverage>(); IRasterCoverage inputRaster = _inputObj.as<RasterCoverage>(); std::map<Raw, quint32> raw2record; int keyColumn = _inputAttributeTable.isValid() ? _inputAttributeTable->columnIndex(inputRaster->primaryKey()) : iUNDEF; if (keyColumn != iUNDEF){ std::vector<QVariant> values = _inputAttributeTable->column(keyColumn); for(quint32 rec=0; rec < values.size(); ++rec){ Raw r = values[rec].toDouble(); if ( !isNumericalUndef(r)){ raw2record[r] = rec; } } } std::vector<int> extraAtrrib = organizeAttributes(); std::vector<QString> selectionBands = bands(inputRaster); initialize(outputRaster->size().linearSize() * selectionBands.size()); PixelIterator iterOut(outputRaster); int count = 0; bool numeric = outputRaster->datadef().domain()->ilwisType() == itNUMERICDOMAIN; for(QString band : selectionBands){ PixelIterator iterIn = inputRaster->band(band, _box); PixelIterator iterEnd = iterIn.end(); while(iterIn != iterEnd) { bool ok = true; double pixValue = *iterIn; double matchValue = pixValue; for(const auto& epart : _expressionparts){ bool partOk = epart.match(iterIn.position(), matchValue,this); if ( epart._andor != loNONE) ok = epart._andor == loAND ? ok && partOk : ok || partOk; else ok &= partOk; if (epart._type == ExpressionPart::ptATTRIBUTE && extraAtrrib.size() == 1){ if ( pixValue < 0 || pixValue >= _inputAttributeTable->recordCount()){ ok = false; continue; } // pixValue == ID; ID < zero means undef, ID's start at zero. if (pixValue >= 0) { if (keyColumn != iUNDEF){ auto iter = raw2record.find(pixValue); if ( iter != raw2record.end()){ quint32 rec = iter->second; const Record& record = _inputAttributeTable->record(rec); pixValue = record.cell(extraAtrrib[0]).toDouble(); }else pixValue = rUNDEF; } } else pixValue = rUNDEF; } } if ( ok){ *iterOut = pixValue; }else *iterOut = rUNDEF; ++iterIn; ++iterOut; updateTranquilizer(++count, 100); } // if there is an attribute table we must copy the correct attributes and records if ( keyColumn != iUNDEF && _attTable.isValid()){ for(int recIndex=0; recIndex < _inputAttributeTable->recordCount(); ++recIndex){ const Record& rec = _inputAttributeTable->record(recIndex); for(int i=0; i < extraAtrrib.size(); ++i){ _attTable->setCell(i, recIndex, rec.cell(extraAtrrib[i])); } } } } if ( numeric) outputRaster->statistics(ContainerStatistics<double>::pBASIC); outputRaster->setAttributes(_attTable); QVariant value; value.setValue<IRasterCoverage>(outputRaster); logOperation(outputRaster, _expression); ctx->setOutput(symTable, value, outputRaster->name(), itRASTER,outputRaster->resource()); return true; }