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; }
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(); }
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 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; }
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 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 } }