bool IlwisObjectModel::isProjectedCoordinateSystem() const
{
    try {
        ICoordinateSystem csy;
        if ( hasType(_ilwisobject->ilwisType(), itCOVERAGE | itCOORDSYSTEM)){
            csy = hasType(_ilwisobject->ilwisType(), itCOVERAGE) ? _ilwisobject.as<Coverage>()->coordinateSystem() : _ilwisobject.as<CoordinateSystem>();
        } if ( hasType(_ilwisobject->ilwisType(), itGEOREF)){
            csy = _ilwisobject.as<GeoReference>()->coordinateSystem();
        }
        if ( csy.isValid()){
            if ( csy->isLatLon())
                return false;

            if (csy->ilwisType() != itCONVENTIONALCOORDSYSTEM)
                return false;

            return true;
        }

        return false;
    }catch(const ErrorObject& ){
        // no exceptions may escape here
    }
    return "";
}
Exemple #2
0
Envelope RootDrawer::envelope2RootEnvelope(const ICoordinateSystem &csSource, const Envelope &env)
{
    Envelope envelope = (!_coordinateSystem.isValid() ||
                         !csSource.isValid() ||
                         _coordinateSystem->isEqual(csSource.ptr()) ||
                         _coordinateSystem->isUnknown() ||
                         csSource->isUnknown()) ?
                env : _coordinateSystem->convertEnvelope(csSource, env);

    return envelope;
}
QString Ilwis3Connector::writeCsy(IlwisObject *obj, const ICoordinateSystem & csy) const
{
    QString csyName;
    if ( csy->code() != "unknown"){
        if ( csy->code() != "epsg:4326"){
            csyName = Resource::toLocalFile(csy->resource().url(true),true, "csy");
            if ( csy->isInternalObject()){
                QString csyFile = Resource::toLocalFile(sourceRef().url(),false, "csy");
                QString name = csy->name().trimmed();
                if (name.size() > 3 && !csy->isAnonymous()) { // threshold of min 4 chars for a credible csy name
                    name = name.replace(QRegExp("[/ .'\"]"),"_");
                    csyName =  QFileInfo(csyFile).absolutePath() + "/" + name + ".csy";
                } else
                    csyName = csyFile;
            }
            else if ( csyName == sUNDEF || csyName == "") {
                QString path = context()->workingCatalog()->filesystemLocation().toLocalFile() + "/";
                QString name = csy->name();
                if ( !csy->isAnonymous()) {
                    name = name.replace(QRegExp("[/ .'\"]"),"_");
                }
                csyName = path + name;
                if ( !csyName.endsWith(".csy"))
                    csyName += ".csy";
                //return ERROR2(ERR_NO_INITIALIZED_2, "CoordinateSystem", coverage->name());
            }
            int index = _odf->url().lastIndexOf("/");
            QString csyurl = _odf->url().left(index) + "/" + csyName;
            QFileInfo csyinf(QUrl(csyurl).toLocalFile());
            if ( !csyinf.exists()) { // if filepath doesnt exist we create if from scratch

                bool mustWriteCsyFile = csy.isValid();

                if (mustWriteCsyFile) {
                    QUrl url = csyurl; // new attempt to create a suitable path;
                    csy->connectTo(url,"coordsystem","ilwis3", IlwisObject::cmOUTPUT);
                    if(!csy->store({"storemode",Ilwis::IlwisObject::smMETADATA})){ // fail, we default to unknown
                        csyName = "Unknown.csy";
                        WARN2(ERR_NO_INITIALIZED_2,"CoordinateSystem",obj->name());
                    } else {
                        csyName = url.toLocalFile();
                    }
                }else
                    csyName = "Unknown.csy";
            }
        }else
            csyName = "LatLonWGS84.csy";
    }else
        csyName = "unknown.csy";
    return QFileInfo(csyName).fileName();
}
void SubGridLayer::calcEnvelope(Coordinate& cmin, Coordinate& cmax) const {
    cmin = layerManager()->rootLayer()->zoomEnvelope().min_corner();
    cmax = layerManager()->rootLayer()->zoomEnvelope().max_corner();
    if (!cmin.isValid() || !cmax.isValid())
        return;

    ICoordinateSystem screenCsy = layerManager()->rootLayer()->screenCsy();
    if (!screenCsy.isValid())
        return;

    if (screenCsy->isUnknown()) // cant do any extra calcs with unknown
        return;

    bool isLatLon = screenCsy->isLatLon();
    if (isLatLon) {
        if (cmin.y <= -89)
            cmin.y = -89;
        if (cmin.x < -180)
            cmin.x = -180;
        if (cmax.y >= 89)
            cmax.y = 89;
        if (cmax.x > 180)
            cmax.x = 180;
    }
    else {
        LatLon llmin = screenCsy->coord2latlon(cmin);
        LatLon llmax = screenCsy->coord2latlon(cmax);
        if (llmin.isValid() && llmax.isValid()) {
            if (llmin.Lat() <= -85)
                cmin.y = screenCsy->latlon2coord(LatLon(-85, llmin.Lon())).y;
            if (llmin.Lon() < -180)
                cmin.x = screenCsy->latlon2coord(LatLon(llmin.Lat(), -180)).x;
            if (llmax.Lat() > 85)
                cmax.y = screenCsy->latlon2coord(LatLon(85, llmax.Lon())).y;
            if (llmax.Lon() > 180)
                cmax.x = screenCsy->latlon2coord(LatLon(llmax.Lat(), 180)).x;
        }
    }
}
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 CoverageConnector::storeMetaData(IlwisObject *obj, IlwisTypes type, const DataDefinition& datadef)
{
    bool ok = Ilwis3Connector::storeMetaData(obj, type);
    if ( !ok)
        return false;

    Coverage *coverage = static_cast<Coverage *>(obj);

    const ICoordinateSystem csy = coverage->coordinateSystem();
    if (!csy.isValid())
        return ERROR2(ERR_NO_INITIALIZED_2, "CoordinateSystem", coverage->name());

    QString localName = Resource::toLocalFile(csy->source().url(),true);
    if ( localName == sUNDEF) {
        localName = CoordinateSystemConnector::createCsyFromCode(csy->code());
    }
    if ( localName == sUNDEF) {
        return ERROR2(ERR_NO_INITIALIZED_2, "CoordinateSystem", coverage->name());
    }
    _odf->setKeyValue("BaseMap","CoordSystem", localName);
    Box2D<double> bounds = coverage->envelope();
    if(!bounds.isValid())
        return ERROR2(ERR_NO_INITIALIZED_2, "Bounds", coverage->name());

    _odf->setKeyValue("BaseMap","CoordBounds",QString("%1 %2 %3 %4").
                      arg(bounds.min_corner().x(),10,'f').
                      arg(bounds.min_corner().y(),10,'f').
                      arg(bounds.max_corner().x(),10,'f').
                      arg(bounds.max_corner().y(),10,'f'));

    const IDomain dom = datadef.domain();
    if (!dom.isValid())
        return ERROR2(ERR_NO_INITIALIZED_2, "Domain", coverage->name());

    calcStatics(obj,NumericStatistics::pBASIC);
    if ( dom->ilwisType() == itNUMERICDOMAIN) {

        quint16 digits = coverage->statistics().significantDigits();
        qint32 delta = coverage->statistics()[NumericStatistics::pDELTA];
        if ( delta >= 0 && delta < 256 && digits == 0){
            if ( delta >= 0 && delta < 256 && digits == 0){
                if ( datadef.domain()->code() == "boolean"){
                    QString domInfo = QString("bool.dom;Byte;bool;0;;");
                    _odf->setKeyValue("BaseMap","DomainInfo",domInfo);
                    _odf->setKeyValue("BaseMap","Range","0:1:offset=-1");
                    _odf->setKeyValue("BaseMap","Domain","bool.dom");
                }
                else{
                    QString domInfo = QString("Image.dom;Byte;image;0;;");
                    _odf->setKeyValue("BaseMap","DomainInfo",domInfo);
                    _odf->setKeyValue("BaseMap","Range","0:255:offset=0");
                    _odf->setKeyValue("BaseMap","MinMax","0:255");
                    _odf->setKeyValue("BaseMap","Domain","Image.dom");
                }
            }
        }
        else {
            const NumericStatistics& stats = coverage->statistics();
            int digits = stats.significantDigits();
            RawConverter conv(stats[NumericStatistics::pMIN], stats[NumericStatistics::pMAX],pow(10, - digits));
            QString rangeString = QString("%1:%2:%3:offset=%4").arg(stats[NumericStatistics::pMIN]).arg(stats[NumericStatistics::pMAX]).arg(conv.scale()).arg(conv.offset());
            _odf->setKeyValue("BaseMap","Range",rangeString);
            _odf->setKeyValue("BaseMap","Domain","value.dom");

            _odf->setKeyValue("BaseMap","MinMax",QString("%1:%2").arg(stats[NumericStatistics::pMIN]).arg(stats[NumericStatistics::pMAX]));
            QString domInfo = QString("value.dom;Long;value;0;-9999999.9:9999999.9:0.1:offset=0");
            _odf->setKeyValue("BaseMap","DomainInfo",domInfo);
        }
    } if ( dom->ilwisType() == itITEMDOMAIN) {
        QString source = Resource::toLocalFile(dom->source().url(), true);
        if ( dom->valueType() == itTHEMATICITEM && coverage->ilwisType() == itRASTER) {
            IThematicDomain themdom = dom.get<ThematicDomain>();
            if ( themdom.isValid()) {
                QString domInfo = QString("%1;Byte;class;%2;;").arg(source).arg(themdom->count());
                _odf->setKeyValue("BaseMap","DomainInfo",domInfo);
                _odf->setKeyValue("BaseMap","Domain",source);
            }
        } else if(dom->valueType() == itINDEXEDITEM) {
            QString domName = _odf->fileinfo().fileName();
            QString domInfo = QString("%1;Long;UniqueID;0;;").arg(domName);
            _odf->setKeyValue("BaseMap","DomainInfo",domInfo);
            _odf->setKeyValue("BaseMap","Domain",domName);
        } else if ( dom->valueType() == itNAMEDITEM) {
            INamedIdDomain iddom = dom.get<NamedIdDomain>();
            QString domName = _odf->fileinfo().fileName();
            int index;
            if ( (index=domName.lastIndexOf("."))!= -1)             {
                domName = domName.left(index);
            }
            QString domInfo = QString("%1;;Int;id;%2;;").arg(domName).arg(iddom->count());
            _odf->setKeyValue("BaseMap","DomainInfo",domInfo);
            _odf->setKeyValue("BaseMap","Domain",domName);
            iddom->connectTo(QUrl(),"domain","ilwis3", IlwisObject::cmOUTPUT);
            iddom->store(Ilwis::IlwisObject::smMETADATA | Ilwis::IlwisObject::smBINARYDATA);
        }
    }

    ITable attTable = coverage->attributeTable();
    if ( attTable.isValid()) {
        QScopedPointer<TableConnector> conn(createTableConnector(attTable, coverage, type));
        conn->storeMetaData(attTable.ptr());
    }
    return true;
}
GeoReference *InternalIlwisObjectFactory::createGrfFromCode(const Resource& resource) const{
    QString code = resource.code();
//    int index = code.indexOf(":");
//    if ( index != -1)
//        code = code.mid(index + 1);
    QStringList parts = code.split(",");
    std::map<QString, QString> parameters;
    for(auto part : parts){
       int index = part.indexOf("=");
       QString key = part.left(index).trimmed();
       QString value = part.mid(index + 1).trimmed();
       parameters[key] = value;
    }
    bool isCorners = parameters["type"] == "corners";
    GeoReference *cgrf = 0;
    ICoordinateSystem csy;
    Envelope env;
    Size<> sz;
    if ( isCorners){
       cgrf = createFromResource<GeoReference>(resource, IOOptions());
       cgrf->create("corners");
       cgrf->name(ANONYMOUS_PREFIX + QString::number(cgrf->id()));
    }
    if ( cgrf == 0)
        return 0;

    for(auto kvp : parameters){
        if ( kvp.first == "csy"){
            bool ok;
            quint64 id = kvp.second.toULongLong(&ok);
            if ( ok){
                csy .prepare(id);
            }else {
                QString name = kvp.second;
                if ( name.left(4) == "epsg" ||  name.left(5) == "proj4")
                    name = "code=" + name;
                csy.prepare(kvp.second);
            }
            if (!csy.isValid())
                return 0;
        }
        if ( kvp.first == "envelope"){
            QString coordstring = kvp.second;
            QStringList coords = coordstring.split(" ");
            if (coords.size()!= 4)
                return 0;
            bool ok1, ok2;
            env += Coordinate(coords[0].toDouble(&ok1), coords[1].toDouble(&ok2));
            if (!ok1 || !ok2)
                return 0;
            env += Coordinate(coords[2].toDouble(&ok1), coords[3].toDouble(&ok2));
            if (!ok1 || !ok2)
                return 0;
        }
        if ( kvp.first == "gridsize"){
            QStringList dims = kvp.second.split(" ");
            sz = Size<>(dims[0].toUInt(), dims[1].toUInt(),1);

        }
        if ( kvp.first == "name"){
            cgrf->name(kvp.second);
        }
        if ( kvp.first == "cornerofcorners")
            cgrf->centerOfPixel(kvp.second.compare("yes") != 0);
    }
    if ( parameters.find("name") == parameters.end())
        cgrf->name(ANONYMOUS_PREFIX + QString::number(cgrf->id()));
    if ( csy.isValid() && env.isValid() && sz.isValid()){
        cgrf->coordinateSystem(csy);
		QSharedPointer< CornersGeoReference> spGrf = cgrf->as< CornersGeoReference>();
		spGrf->internalEnvelope(env);
        cgrf->size(sz);
        cgrf->compute();
        return cgrf;
    }
    return 0;
}
bool InternalIlwisObjectFactory::createCoverage(const Resource& resource, Coverage *coverage, const IOOptions &options) const {

    if (!coverage->prepare())
        return false;

    //coverage->setName(QString("%1%2").arg(ANONYMOUS_PREFIX).arg(coverage->id()));

    ICoordinateSystem csy;
    QString typnm = resource["coordinatesystem"].typeName();
    if (typnm == "Ilwis::ICoordinateSystem")
        csy = resource["coordinatesystem"].value<Ilwis::ICoordinateSystem>();
    else if( typnm == "QString" &&
             resource["coordinatesystem"].toString() != sUNDEF  ) {
        Resource newresource = resource.property2Resource("coordinatesystem", itCOORDSYSTEM);
        if ( newresource.isValid()) {
            if (!csy.prepare(newresource,options))
                return false;
        }
    } else if ( typnm == "qulonglong"){
        if(!csy.prepare(resource["coordinatesystem"].value<quint64>()))
            return 0;
    }
    if ( csy.isValid()){
        coverage->coordinateSystem(csy);
    }

    Envelope bounds;
    QString envType = resource["envelope"].typeName();
    if ( envType == "Ilwis::Box<double>" || envType == "Ilwis::Envelope") {
        bounds = resource["envelope"].value<Envelope>();
    }else if (QString(resource["envelope"].typeName()) == "QString" &&
              resource["envelope"].toString() != sUNDEF) {
        bounds = Envelope(resource["envelope"].toString());
    }
    if ( bounds.isValid()) {
        coverage->envelope(bounds);
    }
    if ( resource.ilwisType() == itRASTER) {
        IDomain dom;
        QString tpname = resource["domain"].typeName();
        if (tpname == "Ilwis::IDomain")
            dom = resource["domain"].value<Ilwis::IDomain>();
        else if( tpname == "QString" &&
                 resource["domain"].toString() != sUNDEF  ) {
            Resource newresource = resource.property2Resource("domain", itDOMAIN);
            if ( newresource.isValid()) {
                if (!dom.prepare(newresource, options))
                    return false;
            }
        } else if ( tpname == "qulonglong"){
            if(!dom.prepare(resource["domain"].value<quint64>()))
                return 0;
        }

        if ( dom.isValid()){
            RasterCoverage *raster = static_cast<RasterCoverage *>(coverage);
            raster->datadefRef().domain(dom);
        }
    }
    return true;
}
SPFeatureI FeatureCoverage::newFeature(const QString& wkt, const ICoordinateSystem& foreigncsy, bool load){
    geos::geom::Geometry *geom = GeometryHelper::fromWKT(wkt, foreigncsy.isValid() ? foreigncsy : coordinateSystem());
    if ( !geom)
        throw FeatureCreationError(TR("failed to create feature, is the wkt valid?"));
    return newFeature(geom,load);
}