bool SetValueRange::execute(ExecutionContext *ctx, SymbolTable &symTable) { if (_prepState == sNOTPREPARED) if((_prepState = prepare(ctx, symTable)) != sPREPARED) return false; DataDefinition& datadef = _outputRaster->datadefRef(); const SPNumericRange numrange = datadef.range<NumericRange>(); const SPNumericRange rngDomain = datadef.domain()->range<NumericRange>(); double lmin = _min == rUNDEF ? numrange->min() : std::max(_min, rngDomain->min()); double lmax = _max == rUNDEF ? numrange->max() : std::min(_max, rngDomain->max()); double lstep = _step == rUNDEF ? numrange->resolution() : std::max(_step, rngDomain->resolution()); NumericRange *rng = new NumericRange(lmin, lmax,lstep); datadef.range(rng); datadef.domain()->range(rng); std::function<bool(const BoundingBox)> SetValrange = [&](const BoundingBox box ) -> bool { PixelIterator iter(_raster, box); PixelIterator iterOut(_outputRaster, box); auto end = iter.end(); while(iter != end){ double val = *iter; if ( val != rUNDEF){ double v = rng->ensure(val).value<double>(); val = v; } *iterOut = val; updateTranquilizer(iterOut.linearPosition(), 1000); ++iter; ++iterOut; }; return true; }; bool ok = OperationHelperRaster::execute(ctx, SetValrange, _outputRaster); _outputRaster->datadefRef().range<NumericRange>()->resolution(_step); for(int i=0; i < _outputRaster->size().zsize(); ++i){ _outputRaster->datadefRef(i).range<NumericRange>()->resolution(_step) ; } QVariant value; value.setValue<IRasterCoverage>(_outputRaster); _outputRaster->addDescription(_expression.toString()); ctx->setOutput(symTable,value,_outputRaster->name(), itRASTER,_outputRaster->resource() ); return ok; }
bool NumericRange::contains(SPRange rng, bool inclusive) const { if ( rng.isNull()) return false; SPNumericRange numrange = rng.staticCast<NumericRange>(); bool ok = contains(numrange->min(), inclusive); return ok && contains(numrange->max(), inclusive); }
void BaseTable::adjustRange(int index) { ColumnDefinition& coldef = columndefinitionRef(index); if (!coldef.isValid()) return; if( hasType(coldef.datadef().domain<>()->ilwisType(), itNUMERICDOMAIN)) { SPNumericRange rng = coldef.datadef().range<NumericRange>(); std::vector<QVariant> values = column(coldef.id()); if ( values.size() > 0 && !rng.isNull()) { double vmin=1e208, vmax=-1e208; bool hasfraction = true; for(const QVariant& var : values ){ double v = var.toDouble(); if ( !isNumericalUndef2(v, this)) vmin = std::min(vmin, v) ; v = var.toDouble(); if (!isNumericalUndef2(v, this)) { vmax = std::max(vmax, v) ; } hasfraction |= (v - (qint64)v != 0); } if ( vmin != 1e208 && vmax != -1e208) { //something has changed rng->min(vmin); rng->max(vmax); if (!hasfraction) rng->resolution(1); } } } else if ( hasType(coldef.datadef().domain<>()->ilwisType(), itITEMDOMAIN)) { SPItemRange rng = coldef.datadef().range<ItemRange>(); SPItemRange rngDomain = coldef.datadef().domain<>()->range<ItemRange>(); std::vector<QVariant> values = column(coldef.id()); if ( values.size() > 0 && !rng.isNull()) { rng->clear(); for(auto qval : values) { quint32 id = qval.toUInt(); SPDomainItem item = rngDomain->item(id); if ( !item.isNull()) { rng->add(item->clone()); } } } } coldef.changed(false); }
void RasterValueImage::setTextureData(ValueTexture *tex, const unsigned int offsetX, const unsigned int offsetY, unsigned int texSizeX, unsigned int texSizeY, unsigned int zoomFactor) { long imageWidth = _raster->size().xsize(); long imageHeight = _raster->size().ysize(); long sizeX = texSizeX; // the size of the input (pixeliterator) long sizeY = texSizeY; if (offsetX + sizeX > imageWidth) sizeX = imageWidth - offsetX; if (offsetY + sizeY > imageHeight) sizeY = imageHeight - offsetY; if (sizeX == 0 || sizeY == 0) return; const long xSizeOut = (long)ceil((double)sizeX / ((double)zoomFactor)); // the size until which the pixels vector will be filled (this is commonly the same as texSizeX, except the rightmost / bottommost textures, as raster-images seldom have as size of ^2) texSizeX /= zoomFactor; // the actual size of the texture (commonly 256 or maxtexturesize, but smaller texture sizes may be allocated for the rightmost or bottommost textures) texSizeY /= zoomFactor; BoundingBox bb(Pixel(offsetX, offsetY), Pixel(offsetX + sizeX - 1, offsetY + sizeY - 1)); // the "pixels" array must be made 32-bit aligned (32-bit-alignment is required by QImage) int xl = (quint32)texSizeX % 4 == 0 ? texSizeX : ((texSizeX / 4) + 1) * 4; int rest = xl - texSizeX; quint32 size = xl * texSizeY; std::vector<quint8> * pixels = new std::vector<quint8> (); pixels->resize(size); PixelIterator pixIter(_raster, bb); // This iterator runs through bb. The corners of bb are "inclusive". SPNumericRange numrange = _raster->datadef().range<NumericRange>(); if (!numrange->isValid()) _raster->statistics(NumericStatistics::pBASIC); auto end = pixIter.end(); quint32 position = 0; while(pixIter != end){ double value = *pixIter; int index = isNumericalUndef2(value,_raster) ? 0 : 1 + (_colorTable.size() - 2) * (value - numrange->min()) / numrange->distance(); (*pixels)[position] = index; // int32 to quint8 conversion (do we want this?) pixIter += zoomFactor; if ( pixIter.ychanged()) { position += (rest + texSizeX - xSizeOut); if (zoomFactor > 1) pixIter += sizeX * (zoomFactor - 1) - ((zoomFactor - (sizeX % zoomFactor)) % zoomFactor); } ++position; } const uchar *datablock = (const uchar *)pixels->data(); QImage * image = new QImage(datablock, xl, texSizeY, QImage::Format_Indexed8); image->setColorTable(_colorTable); tex->setQImage(image, pixels); // carry over the image and the data-buffer to the texture object (see QImage documentation: the data-buffer must exist throughout the existence of the QImage) }