void IlwisObjectModel::resetAttributeModel(const QString& attributeName){ auto setAttributeModel = [&](int i, const ColumnDefinition& coldef, const QString& attributeName){ if ( coldef.name() == attributeName){ AttributeModel *attribute = new AttributeModel(coldef, this, _ilwisobject); _attributes[i] = attribute; } }; IlwisTypes objecttype = _ilwisobject->ilwisType(); if ( objecttype == itRASTER){ IRasterCoverage raster = _ilwisobject.as<RasterCoverage>(); if ( raster->hasAttributes()){ for(int i = 0; i < raster->attributeTable()->columnCount(); ++i){ setAttributeModel(i,raster->attributeTable()->columndefinition(i), attributeName); } } } else if ( hasType(objecttype,itFEATURE)){ IFeatureCoverage features = _ilwisobject.as<FeatureCoverage>(); for(int i = 0; i < features->attributeDefinitions().definitionCount(); ++i){ setAttributeModel(i,features->attributeTable()->columndefinition(i), attributeName); } } else if ( hasType(objecttype,itTABLE)){ ITable tbl = _ilwisobject.as<Table>(); for(int i = 0; i < tbl->columnCount(); ++i){ setAttributeModel(i,tbl->columndefinition(i),attributeName); } } }
bool FeatureConnector::loadData(Ilwis::IlwisObject *obj, const IOOptions &) { if ( obj == nullptr) return false; FeatureCoverage *fcoverage = static_cast<FeatureCoverage *>(obj); QString file = _odf->value("BaseMap", "AttributeTable"); ITable extTable; if ( file != sUNDEF) { if(!extTable.prepare(file)){ kernel()->issues()->log(file,TR(ERR_NO_INITIALIZED_1).arg(file),IssueObject::itWarning); return false; } } bool ok = false; try { _binaryIsLoaded = true; // to prevent any subsequent calls to this routine while loading (which mat trigger it). if (fcoverage->featureTypes() == itPOINT) ok = loadBinaryPoints(fcoverage); else if (fcoverage->featureTypes() == itLINE) ok = loadBinarySegments(fcoverage); else if (fcoverage->featureTypes() == itPOLYGON) ok = loadBinaryPolygons(fcoverage); _binaryIsLoaded = ok; if ( ok && extTable.isValid()) { ITable attTbl = fcoverage->attributeTable(); quint32 nrAttrCols = std::min(attTbl->columnCount(),extTable->columnCount()); // quint32 keyIndex = extTable->columnIndex(COVERAGEKEYCOLUMN); for(quint32 rowExt=0; rowExt < extTable->recordCount(); ++rowExt) { if ( rowExt < fcoverage->featureCount()){ vector<QVariant> rec = extTable->record(rowExt); rec.resize(nrAttrCols); // extTable received an extra "Domain" column, which is not there (and will not be there) in attTbl attTbl->record(rowExt,rec); } } } } catch (FeatureCreationError& ) { } if ( ok) _binaryIsLoaded = true; return ok; }
bool GdalFeatureConnector::loadData(IlwisObject* data, const IOOptions &){ if(!GdalConnector::loadMetaData(data, IOOptions())) return false; bool ok = true; FeatureCoverage *fcoverage = static_cast<FeatureCoverage *>(data); if ( fcoverage->isValid() ) { ITable attTable = fcoverage->attributeTable(); if (!attTable.isValid()){ ERROR2(ERR_NO_INITIALIZED_2,"attribute table",_filename.toString()); return false; } fcoverage->setFeatureCount(itFEATURE, iUNDEF, FeatureInfo::ALLFEATURES); // metadata already set it to correct number, creating new features will up the count agains; so reset to 0. OGRLayerH hLayer = getLayerHandle(); if ( hLayer) { GdalTableLoader loader; attTable->dataLoaded(true); // new table, dont want any loading behaviour loader.setColumnCallbacks(attTable.ptr(), hLayer); std::vector<QVariant> record(attTable->columnCount()); OGRFeatureH hFeature = 0; gdal()->resetReading(hLayer); //each FEATURE try { while( (hFeature = gdal()->getNextFeature(hLayer)) != NULL){ loader.loadRecord(attTable.ptr(), hFeature, record); geos::geom::Geometry * geometry = fillFeature(fcoverage, gdal()->getGeometryRef(hFeature)); if (geometry){ auto feature = fcoverage->newFeature(geometry, false); feature->record(record); }else{ ERROR1("GDAL error during load of binary data: no geometry detected for feature in %1", _filename.toString()); } gdal()->destroyFeature( hFeature ); } } catch (FeatureCreationError& ) { gdal()->destroyFeature( hFeature ); ok = false; } } //layer envelopes/extents Envelope bbox; OGREnvelope envelope;//might sometimes be supported as 3D now only posssible from OGRGeometry OGRErr err = gdal()->getLayerExtent(hLayer, &envelope , TRUE);//TRUE to FORCE if (err != OGRERR_NONE && fcoverage->featureCount() != 0){ ERROR0(QString("Couldn't load extent of a layer from %1 after binary was loaded: %2").arg(_filename.toString()).arg(gdal()->translateOGRERR(err))); }else{ bbox = Envelope(Coordinate(envelope.MinX,envelope.MinY),Coordinate(envelope.MaxX,envelope.MaxY)); } fcoverage->envelope(bbox); } gdal()->closeFile(sourceRef().toLocalFile(), data->id()); _binaryIsLoaded = ok; return ok; }
bool GdalFeatureConnector::setDataSourceAndLayers(const IFeatureCoverage& features, std::vector<SourceHandles>& datasources,std::vector<bool>& validAttributes) { ITable tbl = features->attributeTable(); validAttributes.resize(tbl->columnCount(), false); std::vector<OGRFieldDefnH> fielddefs(tbl->columnCount()); int index = 0; for(int i=0; i < tbl->columnCount(); ++i){ OGRFieldType ogrtype = ilwisType2GdalFieldType(tbl->columndefinition(i).datadef().domain<>()->valueType()); OGRFieldDefnH fieldef = gdal()->createAttributeDefintion(tbl->columndefinition(i).name().toLocal8Bit(),ogrtype); if ( fieldef == 0){ WARN2(ERR_INVALID_INIT_FOR_2, TR("data-type"), tbl->columndefinition(i).name()); }else validAttributes[i] = true; fielddefs[index++] = fieldef; } bool ok = false; OGRSpatialReferenceH srs = createSRS(features->coordinateSystem()); IlwisTypes types = features->featureTypes(); bool multipleoutputs = (types == (itPOINT | itLINE)) || (types == (itPOINT | itPOLYGON)) || (types == (itLINE | itPOLYGON)) || (types == (itFEATURE)); if ( multipleoutputs){ if ((features->featureTypes() & itPOINT) != 0) { ok = createDataSourceAndLayers(itPOINT, "point", features, srs,fielddefs,datasources,validAttributes); } if ((features->featureTypes() & itLINE) != 0) { ok = createDataSourceAndLayers(itLINE, "line", features, srs,fielddefs,datasources,validAttributes); } if ((features->featureTypes() & itPOLYGON) != 0) { ok = createDataSourceAndLayers(itPOLYGON, "polygon", features, srs,fielddefs,datasources,validAttributes); } }else { ok = createDataSourceAndLayers(types, "", features, srs,fielddefs,datasources,validAttributes); } for(OGRFieldDefnH fieldef : fielddefs) { gdal()->destroyAttributeDefintion(fieldef); } return ok; }
bool GdalFeatureConnector::createAttributes(const ITable& tbl, OGRLayerH layer, const std::vector<OGRFieldDefnH>& fielddefs,std::vector<bool>& validAttributes) { if ( layer == 0) return false; int index=0; for(int i=0; i < tbl->columnCount(); ++i){ if ( validAttributes[i]) { if(gdal()->addAttribute(layer,fielddefs[index],TRUE) != OGRERR_NONE){ validAttributes[i] = false; WARN2(ERR_NO_INITIALIZED_2,tbl->columndefinition(i).name(),tbl->name()); } ++index; } } return true; }
void FeatureCoverage::attributesFromTable(const ITable& otherTable) { _attributeDefinition.clearAttributeDefinitions(); for(int col =0; col < otherTable->columnCount(); ++col){ _attributeDefinition.addColumn(otherTable->columndefinition(col)); } if (otherTable->recordCount() != _features.size()) return; for(int rec =0; rec < otherTable->recordCount(); ++rec){ auto& feature= _features[rec]; feature->record(otherTable->record(rec)); } }
QQmlListProperty<AttributeModel> IlwisObjectModel::attributes() { try { if ( _attributes.size() == 0){ if ( _ilwisobject.isValid()) { IlwisTypes objecttype = _ilwisobject->ilwisType(); if ( objecttype == itRASTER){ IRasterCoverage raster = _ilwisobject.as<RasterCoverage>(); if ( raster->hasAttributes()){ for(int i = 0; i < raster->attributeTable()->columnCount(); ++i){ AttributeModel *attribute = new AttributeModel(raster->attributeTable()->columndefinition(i), this, _ilwisobject); _attributes.push_back(attribute); } }else { AttributeModel *attribute = new AttributeModel(ColumnDefinition(PIXELVALUE, raster->datadef(),i64UNDEF), this, _ilwisobject); _attributes.push_back(attribute); } } else if ( hasType(objecttype,itFEATURE)){ IFeatureCoverage features = _ilwisobject.as<FeatureCoverage>(); for(int i = 0; i < features->attributeDefinitions().definitionCount(); ++i){ AttributeModel *attribute = new AttributeModel(features->attributeDefinitions().columndefinition(i), this, _ilwisobject); _attributes.push_back(attribute); } } else if ( hasType(objecttype,itTABLE)){ ITable tbl = _ilwisobject.as<Table>(); for(int i = 0; i < tbl->columnCount(); ++i){ AttributeModel *attribute = new AttributeModel(tbl->columndefinition(i), this, _ilwisobject); _attributes.push_back(attribute); } } } } if ( _attributes.size() > 0){ return QQmlListProperty<AttributeModel>(this, _attributes) ; } } catch(const ErrorObject& ){ // no exceptions may escape here } return QQmlListProperty<AttributeModel>(); }
void tableCase(const IIlwisObject &obj, const QString& condition, int parmIndex, QVariantList& result) { ITable tbl ; if (hasType(obj->ilwisType(), itCOVERAGE)){ ICoverage coverage = obj.as<Coverage>(); tbl = coverage->attributeTable(); }else if (hasType(obj->ilwisType(), itTABLE) ){ tbl = obj.as<Table>(); } QVariantMap mp; mp["parameterIndex"] = parmIndex; QStringList names; int index; IlwisTypes domainType = itTEXTDOMAIN | itITEMDOMAIN | itNUMERICDOMAIN; if ( (index = condition.indexOf(" with ")) != -1){ QString domainPart = condition.mid(index + 6); QStringList parts = domainPart.split("="); QVariantMap mp; if ( parts.size() == 2){ QStringList types = parts[1].split(","); IlwisTypes domainType = 0; for(auto tp: types){ domainType |= IlwisObject::name2Type(tp); } } } for(int c=0; c < tbl->columnCount(); ++c){ if ( domainType != itUNKNOWN){ DataDefinition def = tbl->columndefinition(c).datadef(); if ( hasType(def.domain()->ilwisType(), domainType)) names.append(tbl->columndefinition(c).name()); }else { names.append(tbl->columndefinition(c).name()); } } mp["result"] = names; mp["uielement"] = "list"; result.append(mp); }
bool FeatureConnector::storeBinaryDataTable(IlwisObject *obj, IlwisTypes tp, const QString& baseName) { FeatureCoverage *fcoverage = static_cast<FeatureCoverage *>(obj); ITable attTable = fcoverage->attributeTable(); if ( attTable.isValid() && attTable->columnCount() > 0) { QFileInfo basename (baseName); QScopedPointer<TableConnector> conn(createTableStoreConnector(attTable, fcoverage, tp, basename.baseName())); IFeatureCoverage cov(fcoverage); FeatureIterator iter(cov); quint32 i = 0; std::vector<quint32> recordnr(fcoverage->featureCount(tp)); for(quint32 rec=0; rec < fcoverage->featureCount(); ++rec){ if ( hasType((*iter)->geometryType(), tp)) recordnr[i++] = rec; ++iter; }; conn->selectedRecords(recordnr); return conn->storeBinaryData(attTable.ptr()); } return true; // no store needed }
bool FeatureConnector::storeMetaData(FeatureCoverage *fcov, IlwisTypes type) { if ( type == itUNKNOWN) return true;//if type is itUNKNOWN we dont store DataDefinition datadef; ITable attTable = fcov->attributeTable(); QString primkey = attTable->primaryKey(); if (primkey == sUNDEF) primkey = COVERAGEKEYCOLUMN; int index = attTable->columnIndex(primkey); if ( index != iUNDEF ) { const ColumnDefinition& coldef = attTable->columndefinitionRef(index); if ( coldef.datadef().domain<>()->ilwisType() == itITEMDOMAIN) datadef = DataDefinition(coldef.datadef().domain(),coldef.datadef().range()->clone()); } if ( !datadef.isValid()) { INamedIdDomain indexdom; indexdom.prepare(); indexdom->name(fcov->name()); NamedIdentifierRange range; for(quint32 i=0; i < fcov->featureCount(type); ++i){ QStringList parts = Ilwis3Connector::ilwis3ClassName(type).split(" "); QString itemname = QString("%1_%2").arg(parts[0]).arg(i); range << itemname; } indexdom->setRange(range); datadef.domain(indexdom); QFileInfo inf ( _resource.url(true).toLocalFile()); QString filename = context()->workingCatalog()->filesystemLocation().toLocalFile() + "/" + inf.baseName() + ".dom"; indexdom->connectTo(filename,"domain","ilwis3", Ilwis::IlwisObject::cmOUTPUT); indexdom->store(); } bool isMulti = (fcov->featureTypes() & (fcov->featureTypes() - 1)) != 0; QString baseName = Ilwis3Connector::outputNameFor(fcov, isMulti, type); index = baseName.lastIndexOf("."); if ( index != -1) { baseName = baseName.left(index); } bool ok = CoverageConnector::storeMetaData(fcov, type, datadef, baseName); if ( !ok) return false; if ( datadef.domain()->valueType() == itINDEXEDITEM) { _odf->setKeyValue("Domain","Type","DomainUniqueID"); _odf->setKeyValue("DomainSort","Sorting","AlphaNumeric"); _odf->setKeyValue("DomainSort","Prefix","feature"); _odf->setKeyValue("DomainSort","Class","Domain UniqueID"); _odf->setKeyValue("DomainIdentifier","Nr",IniFile::FormatElement(fcov->featureCount(type))); } Envelope bounds = fcov->envelope(); if ( bounds.isNull() || !bounds.isValid()) bounds = fcov->coordinateSystem()->envelope(); _odf->setKeyValue("BaseMap","CoordBounds",QString("%1 %2 %3 %4"). arg(bounds.min_corner().x,0,'f',10). arg(bounds.max_corner().y,0,'f',10). arg(bounds.max_corner().x,0,'f',10). arg(bounds.min_corner().y,0,'f',10)); QString ext = "mpa"; if ( hasType(type, itPOLYGON)){ ok = storeMetaPolygon(fcov, baseName); } if ( hasType(type, itLINE)){ ok = storeMetaLine(fcov, baseName); ext = "mps"; } if ( hasType(type, itPOINT)){ ok = storeMetaPoint(fcov, baseName); ext = "mpp"; } if ( attTable.isValid() && attTable->columnCount() > 0) { QFileInfo basename (baseName); QScopedPointer<TableConnector> conn(createTableStoreConnector(attTable, fcov, type, basename.baseName())); std::vector<quint32> recs(_itemCount); conn->selectedRecords(recs); conn->storeMetaData(attTable.ptr()); } _odf->store(ext, QFileInfo(baseName)); return ok; }
bool PercentileFilterStretch::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>(); IRasterCoverage zoneRaster = _inputZones.as<RasterCoverage>(); ITable low = _lowPercentile.as<Table>(); ITable high = _highPercentile.as<Table>(); PixelIterator iterIn(inputRaster, BoundingBox(), PixelIterator::fZXY); PixelIterator iterZone(zoneRaster, BoundingBox(), PixelIterator::fXYZ); // only one layer so Z is irrelevant PixelIterator iterOut(outputRaster, BoundingBox(), PixelIterator::fZXY); PixelIterator inEnd = iterIn.end(); _nb = inputRaster->size().zsize(); int rows = inputRaster->size().xsize(); int cols = inputRaster->size().ysize(); std::vector<double> slice(_nb); std::vector<int> percentage(_nb); int totalRows = low->recordCount(); // same as high->recordCount() int totalCols = low->columnCount(); // same as high->columnCount() std::vector<double> lowtab(low->columnCount() * low->recordCount()); std::vector<double> hightab(high->columnCount() * high->recordCount()); for (int row = 0; row < totalRows; ++row) for (int col = 0; col < totalCols; ++col) { // Let the first column in the percentile table match the start of time series int actCol = (col + totalCols - _startDekad) % totalCols; lowtab[actCol + row * totalCols] = low->cell(col, row).toDouble(); hightab[actCol + row * totalCols] = high->cell(col, row).toDouble(); } // timeseries are assumed to be 10 day periods. int pixCount = 0; while (iterIn != inEnd) { trq()->update(pixCount++); // get the time slice at the current location std::copy(iterIn, iterIn + _nb, slice.begin()); // get the zone at the current location double dzone = *iterZone; // row index into low and high percentile tables if (dzone == rUNDEF) { // for out of area locations set to zero percent std::fill(percentage.begin(), percentage.end(), 0); } else { int zone = (long) dzone; std::vector<double>::const_iterator liter = lowtab.begin() + zone * totalCols; std::vector<double>::const_iterator hiter = hightab.begin() + zone * totalCols; std::vector<int>::iterator piter = percentage.begin(); for (std::vector<double>::const_iterator siter = slice.begin(); siter != slice.end(); siter++) { *piter = std::max(0, std::min(100, int(100.0 * (*hiter - *siter) / (*hiter - *liter)))); if (*piter <= 5) *piter = 0; else if (*piter <= 10) *piter = 10; piter++; liter++; hiter++; } } std::copy(percentage.begin(), percentage.end(), iterOut); iterIn += _nb; iterOut += _nb; iterZone += 1; } trq()->update(rows * cols); trq()->inform("\nWriting...\n"); trq()->stop(); bool resource = true; if ( resource && ctx != 0) { QVariant value; value.setValue<IRasterCoverage>(outputRaster); ctx->setOutput(symTable, value, outputRaster->name(), itRASTER, outputRaster->resource() ); } return resource; }