bool SelectionBase::ExpressionPart::match(const SPFeatureI &feature,SelectionBase *operation) const { if ( _type == ExpressionPart::ptFEATURETYPE){ return hasType(feature->geometryType(), _geometryType); } if ( _type == ExpressionPart::ptENVELOPE && _envelope.isValid()) { return _envelope.contains(feature->geometry().get()); } if ( _type == ExpressionPart::ptPOLYGON && _polygon.get() != 0) { return _polygon->contains(feature->geometry().get()); } if ( _type == ExpressionPart::ptATTRIBUTESELECTION ) { QVariant val = feature(_leftSide); ColumnDefinition coldef = feature->attributedefinition(_leftSide); if ( coldef.datadef().domain()->ilwisType() == itITEMDOMAIN){ val = coldef.datadef().domain()->impliedValue(val); } if ( QString(val.typeName()) == "QString" && QString(_rightSide.typeName()) == "QString"){ return operation->compare1(_operator,val.toString(), _rightSide.toString()); } else { bool ok1,ok2; double v1 = val.toDouble(&ok1); double v2 = _rightSide.toDouble(&ok2); bool ok3 = operation->compare2(_operator, v1, v2, true); return ok1&& ok2 && ok3; } } return false; }
FeatureDrawing SimplePointSetter::setSpatialAttributes(const SPFeatureI &feature, QVector<QVector3D> &vertices, QVector<QVector3D> &) const { Envelope env = _rootDrawer->attribute("coverageenvelope").value<Envelope>(); double size = env.xlength() / 150.0; const UPGeometry& geometry = feature->geometry(); int n = geometry->getNumGeometries(); FeatureDrawing drawing(itPOINT); for(int geom = 0; geom < n; ++geom ){ const geos::geom::Geometry *subgeom = geometry->getGeometryN(geom); if (!subgeom) continue; const geos::geom::Coordinate *crd = subgeom->getCoordinate(); Coordinate coord = *crd; if ( coordinateConversionNeeded()){ coord = _targetSystem->coord2coord(_sourceSystem, *crd); } drawing._indices.push_back(VertexIndex(vertices.size(),5,GL_LINE_STRIP,feature->featureid())); double z = coord.z == rUNDEF || std::isnan(coord.z)? 0 : coord.z; vertices.push_back(QVector3D(coord.x + size, coord.y + size, z)); vertices.push_back(QVector3D(coord.x - size, coord.y + size, z)); vertices.push_back(QVector3D(coord.x - size, coord.y - size, z)); vertices.push_back(QVector3D(coord.x + size, coord.y - size, z)); vertices.push_back(QVector3D(coord.x + size, coord.y + size, z)); drawing._center = QVector3D(coord.x, coord.y, coord.z); } return drawing; }
bool PostgresqlFeatureCoverageLoader::loadData(FeatureCoverage *fcoverage) const { //qDebug() << "PostgresqlFeatureCoverageLoader::loadData()"; ITable table; PostgresqlDatabaseUtil pgUtil(_resource,_options); Resource tableResource = pgUtil.resourceForType(itFLATTABLE); table.prepare(tableResource, _options); PostgresqlTableLoader tableLoader(table->source(), _options); if (!tableLoader.loadData(table.ptr())) { ERROR1("Could not load table data for table '%1'", table->name()); return false; } // metadata already set it to correct number, creating new features will up the count agains; so reset to 0. fcoverage->setFeatureCount(itFEATURE, iUNDEF, FeatureInfo::ALLFEATURES); QList<MetaGeometryColumn> metaGeometries; pgUtil.getMetaForGeometryColumns(metaGeometries); QSqlQuery query = pgUtil.doQuery(selectGeometries(metaGeometries), "featurecoverageloader"); quint32 geometriesPerFeature = metaGeometries.size(); IDomain semantics; pgUtil.prepareSubFeatureSemantics(semantics, metaGeometries); while (query.next()) { if (geometriesPerFeature == 0) { fcoverage->newFeature(0); } else { // index 0 is root, indeces > 0 are subfeatures of root bool atRoot = true; SPFeatureI rootFeature; // iterate semantics to keep predefined order ItemRangeIterator iter(semantics->range<>().data()); while (iter.isValid()) { QString geomName = (*iter)->name(); ICoordinateSystem crs; std::for_each(metaGeometries.begin(), metaGeometries.end(), [&crs,geomName](MetaGeometryColumn c) { if (c.geomColumn == geomName) { crs = c.crs; } }); if (atRoot) { atRoot = false; geos::geom::Geometry *rootGeometry = createGeometry(query, geomName, crs); rootFeature = fcoverage->newFeature(rootGeometry, false); } else { geos::geom::Geometry *subGeometry = createGeometry(query, geomName, crs); rootFeature->createSubFeature(geomName,subGeometry); } ++iter; } } } fcoverage->attributesFromTable(table); return true; }
FeatureDrawing SimplePolygonSetter::setSpatialAttributes(const SPFeatureI &feature, QVector<QVector3D> &vertices, QVector<QVector3D> &normals) const { IlwisTesselator tesselator; const UPGeometry& geometry = feature->geometry(); int n = geometry->getNumGeometries(); FeatureDrawing drawing(itPOLYGON); for(int geom = 0; geom < n; ++geom ){ const geos::geom::Geometry *subgeom = geometry->getGeometryN(geom); if (!subgeom) continue; tesselator.tesselate(_targetSystem,_sourceSystem, subgeom,feature->featureid(), vertices, drawing._indices); } return drawing; }
bool FeatureConnector::loadBinaryPolygons30(FeatureCoverage *fcoverage, ITable& tbl) { BinaryIlwis3Table polTable; if ( !polTable.load(_odf)) { return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_odf->fileinfo().fileName()) ; } BinaryIlwis3Table topTable; if ( !topTable.load(_odf,"top")) { return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_odf->fileinfo().fileName()) ; } qint32 colValue = polTable.index("PolygonValue"); qint32 colTopStart = polTable.index("TopStart"); qint32 colArea = polTable.index("Area"); int nrPolygons = polTable.rows(); bool isNumeric = _odf->value("BaseMap","Range") != sUNDEF; double v; for(int i = 0; i < nrPolygons; ++i) { polTable.get(i,colArea, v); if ( v < 0) continue; polTable.get(i,colTopStart,v); qint32 index = v; std::vector<std::vector<Coordinate2d>> rings; if (getRings(index, topTable, polTable, rings)) { if ( rings.size() == 0) continue; Polygon polygon; polygon.outer().resize(rings[0].size()); std::copy(rings[0].begin(), rings[0].end(), polygon.outer().begin()); for(int j = 1; j < rings.size(); ++j) { polygon.inners()[j-1].resize(rings[j].size()); std::copy(rings[j].begin(), rings[j].end(), polygon.inners()[j-1].begin()); } polTable.get(i, colValue, v); if ( isNumeric) { tbl->cell(COVERAGEKEYCOLUMN, i, QVariant(i)); tbl->cell(FEATUREVALUECOLUMN, i, QVariant(v)); fcoverage->newFeature({polygon}); } else { quint32 itemId = v; tbl->cell(COVERAGEKEYCOLUMN, i, QVariant(itemId)); SPFeatureI feature = fcoverage->newFeature({polygon}); tbl->cell(FEATUREIDCOLUMN, i, QVariant(feature->featureid())); } } } return true; }
bool GdalFeatureConnector::store(IlwisObject *obj, const IOOptions& ) { if (!loadDriver()) return false; IFeatureCoverage coverage; coverage.set(static_cast<FeatureCoverage *>(obj)); std::vector<SourceHandles> datasources(3); std::vector<bool> validAttributes; if(!setDataSourceAndLayers(coverage, datasources, validAttributes)) return false; std::vector<ColumnDefinition> defs; for(int i=0; i < coverage->attributeTable()->columnCount(); ++i){ defs.push_back(coverage->attributeTable()->columndefinition(i)); } FeatureIterator fiter(coverage); FeatureIterator endIter = end(coverage); for(; fiter != endIter; ++fiter) { SPFeatureI feature = *fiter; IlwisTypes geomType = feature->geometryType(); if ( geomType != 0){ OGRLayerH lyr = datasources[ilwisType2Index(geomType)]._layers[0]; OGRFeatureH hfeature = gdal()->createFeature(gdal()->getLayerDef(lyr)); if (hfeature) { setAttributes(hfeature, feature, validAttributes, defs); const geos::geom::Geometry* geometry = feature->geometry().get(); if (gdal()->setGeometryDirectly(hfeature,createFeature(geometry)) != OGRERR_NONE) ERROR2(ERR_COULD_NOT_ALLOCATE_2, TR("geometry"), _filename.toString()); if (gdal()->addFeature2Layer(lyr, hfeature) != OGRERR_NONE) { ERROR2(ERR_COULD_NOT_ALLOCATE_2, TR("feature"), _filename.toString()); } gdal()->destroyFeature(hfeature); }; } } for(auto& datasource : datasources){ if ( datasource._source != 0) gdal()->destroyDataSource(datasource._source); } return true; }
bool FeatureConnector::loadBinaryPolygons37(FeatureCoverage *fcoverage, ITable& tbl) { QString datafile = _odf->value("PolygonMapStore","DataPol"); datafile = context()->workingCatalog()->filesystemLocation().toLocalFile() + "/" + datafile; QFile file(datafile); if (!file.exists()){ kernel()->issues()->log(TR(ERR_MISSING_DATA_FILE_1).arg(file.fileName())); return false; } if(!file.open(QIODevice::ReadOnly )){ kernel()->issues()->log(TR(ERR_COULD_NOT_OPEN_READING_1).arg(file.fileName())); return false; } QDataStream stream(&file); int nrPolygons = fcoverage->featureCount(itPOLYGON); SPAttributeRecord record( new AttributeRecord(tbl,FEATUREIDCOLUMN)); bool isNumeric = _odf->value("BaseMap","Range") != sUNDEF; for(int j=0; j < nrPolygons; ++j) { Polygon pol; readRing(stream, pol.outer()); double value; quint32 numberOfHoles; stream.readRawData((char *)&value, 8); stream.readRawData((char *)&numberOfHoles, 4); pol.inners().resize(numberOfHoles); for(quint32 i=0; i< numberOfHoles;++i) readRing(stream, pol.inners()[i]); if ( isNumeric) { tbl->cell(COVERAGEKEYCOLUMN, j, QVariant(j)); tbl->cell(FEATUREVALUECOLUMN, j, QVariant(value)); SPFeatureI feature = fcoverage->newFeature({pol}); tbl->cell(FEATUREIDCOLUMN, j, QVariant(feature->featureid())); } else { quint32 itemId = value; tbl->cell(COVERAGEKEYCOLUMN, j, QVariant(itemId)); SPFeatureI feature = fcoverage->newFeature({pol}); tbl->cell(FEATUREIDCOLUMN, j, QVariant(feature->featureid())); } } file.close(); return true; }
SPFeatureI FeatureCoverage::newFeatureFrom(const SPFeatureI& existingFeature) { Locker lock(_mutex); if ( existingFeature.isNull() || existingFeature->isValid() == false) return SPFeatureI(); SPFeatureI newFeature = new Feature(this); for(int i=0; i < existingFeature->trackSize(); ++i) newFeature->set(existingFeature->geometry(),i); _features.push_back(newFeature); quint32 cnt = featureCount(newFeature->ilwisType()); setFeatureCount(newFeature->ilwisType(),++cnt ); return _features.back(); }
void GdalFeatureConnector::setAttributes(OGRFeatureH hfeature, SPFeatureI& feature, const std::vector<bool>& validAttributes, const std::vector<ColumnDefinition>& columnDef) { int index = 0; for(int i=0; i < feature->attributeColumnCount(); ++i){ if ( !validAttributes[i]) continue; IDomain dom = columnDef[i].datadef().domain<>(); if(hasType(dom->valueType(),itINTEGER)) { gdal()->setIntegerAttribute(hfeature,index,feature->cell(i).toInt()); } else if (hasType(dom->valueType(),itDOUBLE | itFLOAT)) { gdal()->setDoubleAttribute(hfeature,index,feature->cell(i).toDouble()); } else if (hasType(dom->valueType(),itTHEMATICITEM | itNAMEDITEM | itINDEXEDITEM | itNUMERICITEM | itTIMEITEM)) { gdal()->setStringAttribute(hfeature,index,dom->impliedValue(feature->cell(i)).toString().toLocal8Bit()); } else if (hasType(dom->valueType(), itDATETIME)) { QVariant v = feature->cell(i); if ( QString(v.typeName()).compare("Ilwis::Time") != 0){ ERROR2(ERR_COULD_NOT_CONVERT_2,v.toString(), "time"); gdal()->setDateTimeAttribute(hfeature,index,0,0,0,0,0,0,0); }else{ Time time = v.value<Ilwis::Time>(); gdal()->setDateTimeAttribute(hfeature,index, time.get(Time::tpYEAR), time.get(Time::tpMONTH), time.get(Time::tpDAYOFMONTH), time.get(Time::tpHOUR), time.get(Time::tpMINUTE), time.get(Time::tpSECOND), 0);//TODO TimeZone?? } } else if (hasType(dom->valueType(),itSTRING)){ gdal()->setStringAttribute(hfeature,index,feature->cell(i).toString().toLocal8Bit()); } ++index; } }
bool FeatureConnector::loadBinarySegments(FeatureCoverage *fcoverage) { BinaryIlwis3Table mpsTable; if ( !mpsTable.load(_odf)) { return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_odf->fileinfo().fileName()) ; } int colCoords = mpsTable.index("Coords"); int colItemId = mpsTable.index("SegmentValue"); bool isNumeric = _odf->value("BaseMap","Range") != sUNDEF; ITable tbl = fcoverage->attributeTable(); // if ( isNumeric) // in other case nr of record already has been set as it is based on a real table // tbl->setRows(mpsTable.rows()); double value; for(quint32 i= 0; i < mpsTable.rows(); ++i) { std::vector<Coordinate > coords; mpsTable.get(i,colCoords,coords); Line2D<Coordinate2d > line; line.resize(coords.size()); std::copy(coords.begin(), coords.end(), line.begin()); mpsTable.get(i, colItemId,value); if ( isNumeric) { tbl->cell(COVERAGEKEYCOLUMN, i, QVariant(i)); tbl->cell(FEATUREVALUECOLUMN, i, QVariant(value)); SPFeatureI feature = fcoverage->newFeature({line}); tbl->cell(FEATUREIDCOLUMN, i, QVariant(feature->featureid())); } else { quint32 itemId = value; tbl->cell(COVERAGEKEYCOLUMN, i, QVariant(itemId)); SPFeatureI feature = fcoverage->newFeature({line}); tbl->cell(FEATUREIDCOLUMN, i, QVariant(feature->featureid())); } } return true; }
void Polygon2Line::extractBoundary(const UPGeometry& g, quint32& record){ const geos::geom::Geometry *geom1 = g.get(); std::vector<geos::geom::CoordinateSequence *> coords = GeometryHelper::geometry2coords(geom1); geos::geom::Geometry *geometry; if ( coords.size() == 1) geometry = _outputfeatures->geomfactory()->createLineString(coords[0]); else if ( coords.size() > 1){ std::vector<geos::geom::Geometry *> lines; for(int i=0; i < coords.size(); ++i) lines.push_back(_outputfeatures->geomfactory()->createLineString(coords[i])); geometry = _outputfeatures->geomfactory()->createMultiLineString(lines); } if ( geometry){ SPFeatureI outfeature = _outputfeatures->newFeature(geometry); if (_singleId){ outfeature->setCell(0,0); }else { outfeature->setCell(0, record); } } }
SPFeatureI FeatureCoverage::newFeatureFrom(const SPFeatureI& existingFeature, const ICoordinateSystem& csySource) { Locker<> lock(_mutex); auto transform = [&](const UPGeometry& geom)->geos::geom::Geometry * { if ( geom.get() == 0) return 0; geos::geom::Geometry *newgeom = geom->clone(); if ( csySource.isValid() && !csySource->isEqual(coordinateSystem().ptr())){ CsyTransform trans(csySource, coordinateSystem()); newgeom->apply_rw(&trans); newgeom->geometryChangedAction(); } GeometryHelper::setCoordinateSystem(newgeom, coordinateSystem().ptr()); return newgeom; }; if (!connector()->dataIsLoaded()) { connector()->loadData(this); } auto *newfeature = createNewFeature(existingFeature->geometryType()); const UPGeometry& geom = existingFeature->geometry(); newfeature->geometry(transform(geom)) ; auto variantIndexes = _attributeDefinition.indexes(); for(auto index : variantIndexes){ const auto& variant = existingFeature[index]; auto *variantFeature = createNewFeature(variant->geometryType()); const auto& geom = variant->geometry(); variantFeature->geometry(transform(geom)) ; newfeature->setSubFeature(index, variantFeature); } _features.push_back(newfeature); return _features.back(); }
bool FeatureConnector::loadBinaryPoints(FeatureCoverage *fcoverage) { BinaryIlwis3Table mppTable; if ( !mppTable.load(_odf)) { return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_odf->fileinfo().fileName()) ; } // two cases; the old case; 2 columns for x and y. and the new case one column for coord int coordColumnX = mppTable.index("x"); int coordColumnY = mppTable.index("y"); int coordColumn = mppTable.index("Coordinate"); int colItemId = mppTable.index("Name"); ITable tbl = fcoverage->attributeTable(); bool newCase = coordColumnX == iUNDEF; for(quint32 i= 0; i < mppTable.rows(); ++i) { Coordinate c; double itemIdT; if ( newCase) { mppTable.get(i, coordColumn, c); } else { double x,y; mppTable.get(i, coordColumnX, x); mppTable.get(i, coordColumnY, y); c = Coordinate(x,y); } mppTable.get(i, colItemId,itemIdT); quint32 itemId = itemIdT; tbl->cell(COVERAGEKEYCOLUMN, i, QVariant(itemId)); SPFeatureI feature = fcoverage->newFeature({c}); tbl->cell(FEATUREIDCOLUMN, i, QVariant(feature->featureid())); } return true; }
bool PostgresqlFeatureCoverageLoader::storeData(FeatureCoverage *fcoverage) const { bool queryOk = true; ITable baseData = fcoverage->attributeTable(); PostgresqlParameters params (_resource.url(true).toString()); PostgresqlDatabaseUtil pgUtil(params); SqlStatementHelper sqlHelper(params); bool newTable = false; if ( !pgUtil.tableExists()){ if(!pgUtil.createTable(fcoverage)){ return false; } newTable = true; } IDomain semantics; // subfeature semantics QList<QString> primaryKeys; // readonly keys QList<MetaGeometryColumn> metaGeomColumns; // geometry columns pgUtil.getMetaForGeometryColumns(metaGeomColumns); pgUtil.prepareSubFeatureSemantics(semantics, metaGeomColumns, _options); pgUtil.getPrimaryKeys(primaryKeys); // add geoms to update/insert data table FeatureIterator featureIter(fcoverage); featureIter.flow(FeatureIterator::fDEPTHFIRST); QString columnNamesCommaSeparated = sqlHelper.columnNamesCommaSeparated(baseData.ptr()); QString code = fcoverage->coordinateSystem()->code(); QString srid = code.right(code.indexOf(":")); QString qtablename = params.table().toLower(); while(featureIter != featureIter.end()) { SPFeatureI feature = (*featureIter); bool newFeature = newTable ? true : !pgUtil.exists(feature); QString columnValuesCommaSeparated = sqlHelper.columnValuesCommaSeparated(feature); QString sqlStmt; if (newFeature) { sqlStmt = "INSERT INTO "; sqlStmt.append(qtablename); sqlStmt.append(" ( "); sqlStmt.append(columnNamesCommaSeparated); foreach (MetaGeometryColumn geomMeta, metaGeomColumns) { sqlStmt.append(", "); sqlStmt.append(geomMeta.geomColumn); } sqlStmt.append(" ) "); sqlStmt.append(" VALUES ( "); sqlStmt.append(columnValuesCommaSeparated); sqlStmt.append(", "); // add geometry values /* // TODO storing level n data only makes sense // if subfeatures are stored in separate // tables related via foreign keys, but // separate tables aren't supported now ITabel levelData = fcoverage->attributeTable(level); PostgresqlTableConnector connector(_resource,false); tableOk = connector.store(levelData.ptr(), options); */ QString rootGeomColumn = fcoverage->attributeDefinitionsRef().index((quint32)0); // have to iterate the order of given geom columns foreach (MetaGeometryColumn geomMeta, metaGeomColumns) { QString wkt = "NULL"; QString geomColumn = geomMeta.geomColumn; if (rootGeomColumn == geomColumn || rootGeomColumn == sUNDEF) { if (feature->geometry() != nullptr){ wkt = QString("'%1'").arg(GeometryHelper::toWKT(feature->geometry().get())); } } else if (feature[geomColumn]->geometry() != nullptr){ // access subfeature geometries SPFeatureI subfeature = feature[geomColumn]; wkt = QString("'%1'").arg(GeometryHelper::toWKT(subfeature->geometry().get())); } sqlStmt.append("st_geomfromtext(").append(wkt); sqlStmt.append(", ").append(srid).append(")"); sqlStmt.append(","); // skip subfeature's geometries, as accessed already via domain ++featureIter; } sqlStmt = sqlHelper.trimAndRemoveLastCharacter(sqlStmt); sqlStmt.append(" ); "); } else {
void FeatureCoverageTest::testVariants() { Ilwis::IFeatureCoverage featureCoverage; featureCoverage.prepare(); Ilwis::ICoordinateSystem csy("code=proj4:+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"); Ilwis::Envelope env(Ilwis::LatLon(50,-30), Ilwis::LatLon(-50, 60)); featureCoverage->coordinateSystem(csy); featureCoverage->envelope(env); Ilwis::ITimeDomain dom; dom.prepare(); dom->range(new Ilwis::TimeInterval("20090101", "20110101")); std::vector<QString> times = {"20090101","20090131","20090602","20090703", "20100109","20110101"}; featureCoverage->attributeDefinitionsRef().addColumn("population", "value"); featureCoverage->attributeDefinitionsRef().setSubDefinition(dom,times); Ilwis::SPFeatureI feature1 = featureCoverage->newFeature(0); geos::geom::Geometry *geom = Ilwis::GeometryHelper::fromWKT("Linestring(40 20, 10 12, -20 -10)", featureCoverage->coordinateSystem().ptr()); feature1->geometry(geom); feature1("population", 200); geom = Ilwis::GeometryHelper::fromWKT("Linestring(40 30, 10 12, -20 -10)", featureCoverage->coordinateSystem().ptr()); Ilwis::SPFeatureI feature2 = featureCoverage->newFeature(geom); feature2("population", 300); geom = Ilwis::GeometryHelper::fromWKT("Linestring(40 30, 12 12, -20 -10)", featureCoverage->coordinateSystem().ptr()); Ilwis::SPFeatureI feature3 = featureCoverage->newFeature(geom); feature3("population", 100); feature1->createSubFeature("20090101", geom); feature1->createSubFeature("20090703", geom); geom = Ilwis::GeometryHelper::fromWKT("Linestring(30 10, 10 15, -23 -12)",featureCoverage->coordinateSystem().ptr()); feature1->createSubFeature("20090101", geom); geom = Ilwis::GeometryHelper::fromWKT("Linestring(20 10, 10 15, -23 -12)",featureCoverage->coordinateSystem().ptr()); feature2->createSubFeature("20090101", geom); auto *attrdef = new Ilwis::FeatureAttributeDefinition(); attrdef->addColumn("temperature", "value"); featureCoverage->attributeDefinitionsRef().featureAttributeDefinition(attrdef); feature1["20090101"]("temperature", 26.5); feature2["20090101"]("temperature", 19.5); FeatureIterator featureIter(featureCoverage); featureIter.flow(FeatureIterator::fDEPTHFIRST); while(featureIter != featureIter.end()) { SPFeatureI f = (*featureIter); f->geometry(); // test if geometry is null DOTEST(true, "geometry of (sub)feature not null."); featureIter++; // move to next } }