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 "";
}
bool GeorefConnector::loadGeorefCorners(const IniFile& odf, IlwisObject *data) {
    GeoReference *grf = static_cast<GeoReference *>(data);
    QString csyName = odf.value("GeoRef","CoordSystem");
    QUrl path = mastercatalog()->name2url(csyName, itCOORDSYSTEM);
    ICoordinateSystem csy;
    if(!csy.prepare(path.toLocalFile())) {
        kernel()->issues()->log(TR("Couldnt find coordinate system %1, loading unknown").arg(csyName),IssueObject::itWarning);
        QString resource = QString("ilwis://file/unknown.csy");
        if(!csy.prepare(resource)) {
            kernel()->issues()->log(TR("Cound find coordinate system unknown, corrupt system file"));
            return false;
        }
    }

    grf->coordinateSystem(csy);
    double maxx = odf.value("GeoRefCorners","MaxX").toDouble();
    double maxy = odf.value("GeoRefCorners","MaxY").toDouble();
    double minx = odf.value("GeoRefCorners","MinX").toDouble();
    double miny = odf.value("GeoRefCorners","MinY").toDouble();
    if ( maxx == rUNDEF || maxy == rUNDEF || minx == rUNDEF || miny == rUNDEF) {
        kernel()->issues()->log(TR("Uninitialized boundaries for georeference %1").arg(_resource.name()));
        return false;
    }

    grf->impl<CornersGeoReference>()->setEnvelope(Box2D<double>(Coordinate(minx, miny), Coordinate(maxx, maxy)));
    return true;
}
bool GeorefConnector::loadGeorefTiepoints(const IniFile& odf, GeoReference *grf) {
    QString csyName = odf.value("GeoRef","CoordSystem");
    QUrl path = mastercatalog()->name2url(csyName, itCOORDSYSTEM);
    ICoordinateSystem csy;
    if(!csy.prepare(path.toString())) {
        return ERROR2(ERR_COULD_NOT_LOAD_2, "coordinate system",csyName);
    }
    grf->coordinateSystem(csy);
    QSharedPointer<PlanarCTPGeoReference> grfctp(grf->as<PlanarCTPGeoReference>());
    BinaryIlwis3Table tbl;
    tbl.load(_odf);
    std::vector<int> colindexes(10, iUNDEF);
    enum ColIndexID{ciiX=0, ciiY=1, ciiZ=2, ciiLAT=3, ciiLON=4, ciiXP=5, ciiYP=6, ciiACT=7, ciiDX=8, ciiDY=9, ciiNEVER=10};
    colindexes[ciiX] = tbl.index("X");
    colindexes[ciiY] = tbl.index("Y");
    colindexes[ciiZ] = tbl.index("Z");
    colindexes[ciiXP] = tbl.index("Col");
    colindexes[ciiYP] = tbl.index("Row");
    colindexes[ciiACT] = tbl.index("Active");
    //colindexes[ciiDX] = tbl.index("DCol");
    //colindexes[ciiDY] = tbl.index("DRow");
    for(int rec = 0; rec < tbl.rows(); ++rec){
        double x=rUNDEF;
        tbl.get(rec,colindexes[ciiX],x);
        double y=rUNDEF;
        tbl.get(rec,colindexes[ciiY],y);
            double z=0;
        if (colindexes[ciiZ] != iUNDEF) {
            tbl.get(rec,colindexes[ciiZ],z);
        }
        double xp=rUNDEF;
        tbl.get(rec,colindexes[ciiXP],xp);
        double yp=rUNDEF;
        tbl.get(rec,colindexes[ciiYP],yp);

        double active=1;
        tbl.get(rec,colindexes[ciiACT],active);
        ControlPoint ctp(Coordinate(x,y,z),Pixeld(xp,yp));
        ctp.active(active != 0);
        grfctp->setControlPoint(ctp);
    }
    QString transf = odf.value("GeoRefCTP", "Transformation");
    PlanarCTPGeoReference::Transformation transformation;
    if (transf == "Conform")
      transformation =  PlanarCTPGeoReference::tCONFORM;
    else if (transf == "Affine")
      transformation =  PlanarCTPGeoReference::tAFFINE;
    else if (transf == "SecondOrder")
      transformation =  PlanarCTPGeoReference::tSECONDORDER;
    else if (transf == "FullSecondOrder")
      transformation =  PlanarCTPGeoReference::tFULLSECONDORDER;
    else if (transf == "ThirdOrder")
      transformation =  PlanarCTPGeoReference::tTHIRDORDER;
    else if (transf == "Projective")
      transformation =  PlanarCTPGeoReference::tPROJECTIVE;
    grfctp->transformation(transformation);
    grfctp->compute();

    return true;
}
Coordinate ConventionalCoordinateSystem::coord2coord(const ICoordinateSystem &sourceCs, const Coordinate &crdSource) const
{
    if (sourceCs->isEqual(*this))
        return crdSource;
    LatLon ll = sourceCs->coord2latlon(crdSource);
    if ( ll.isValid()) {
        return latlon2coord(ll);
    }
    return Coordinate();
}
Coordinate ConventionalCoordinateSystem::coord2coord(const ICoordinateSystem &sourceCs, const Coordinate &crdSource) const
{
    //TODO isLatLon guard doesn't consider latlon cs other than WGS84!
    if (sourceCs->id() == id()) //  the 'real'isEqual test is too expensive here, as this method can be called 100000's of times (resample)
        return crdSource;
    LatLon ll = sourceCs->isLatLon() ? LatLon(crdSource.y,crdSource.x) : sourceCs->coord2latlon(crdSource);
    if ( ll.isValid()) {
        return isLatLon() ? ll : latlon2coord(ll);
    }
    return Coordinate();
}
Example #6
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;
}
void CatalogWorker::calcLatLon(const ICoordinateSystem& csyWgs84,Ilwis::Resource& resource, std::vector<Resource>& updatedResources){
    try{
        if ( !resource.hasProperty("latlonenvelope")){
            ICoverage cov(resource);
            if ( cov.isValid()){
                if ( cov->coordinateSystem()->isUnknown()) // we cant do anything with unknown
                    return;
                if ( cov->coordinateSystem()->isLatLon()){
                    QString envelope = cov->envelope().toString();
                    resource.addProperty("latlonenvelope",envelope);
                }else {
                    Envelope env = cov->envelope();
                    if ( env.isNull() || !env.isValid())
                        return;
                    Envelope llEnvelope = csyWgs84->convertEnvelope(cov->coordinateSystem(), env);
                    if ( llEnvelope.isNull() || !llEnvelope.isValid())
                        return;

                    resource.addProperty("latlonenvelope",llEnvelope.toString());
                }
                updatedResources.push_back(resource);
            }
        }
    } catch(const ErrorObject&){
    } catch( std::exception& ){
    }
}
Example #8
0
void OpenGLHelper::getLineVertices(const ICoordinateSystem& csyRoot,
                                   const ICoordinateSystem& csyGeom,
                                   const Ilwis::UPGeometry &geometry,
                                   Raw objectid,
                                   QVector<QVector3D> &points,
                                   QVector<QVector3D> &normals,
                                   std::vector<VertexIndex> &indices){

    int n = geometry->getNumGeometries();
    for(int  geom = 0; geom < n; ++geom ){
        const geos::geom::Geometry *subgeom = geometry->getGeometryN(geom);
        if (!subgeom)
            continue;
        auto *coords = subgeom->getCoordinates();
        quint32 oldend = points.size();
        indices.push_back(VertexIndex(oldend, coords->size(), GL_LINE_STRIP, objectid));
        points.resize(oldend + coords->size());
        bool conversionNeeded = csyRoot != csyGeom;
        Coordinate crd;
        for(int i = 0; i < coords->size(); ++i){
            coords->getAt(i, crd);
            if ( conversionNeeded){
                crd = csyRoot->coord2coord(csyGeom, crd);
            }
            points[oldend + i] = QVector3D(crd.x, crd.y, crd.z);
        }
        delete coords;
    }

}
bool CoverageConnector::loadMetaData(Ilwis::IlwisObject *data)
{
    Ilwis3Connector::loadMetaData(data);

    Coverage *coverage = static_cast<Coverage *>(data);
    QString csyName = _odf->value("BaseMap","CoordSystem");
    if ( csyName.toLower() == "latlonwgs84.csy")
        csyName = "code=epsg:4326";
    ICoordinateSystem csy;
    if ( !csy.prepare(csyName)) {
        kernel()->issues()->log(csyName,TR("Coordinate system couldnt be initialized, defaulting to 'unknown'"),IssueObject::itWarning);
        QString resource = QString("ilwis://file/unknown.csy");
        if (!csy.prepare(resource)) {
            kernel()->issues()->log(TR("Fallback to 'unknown failed', corrupt system files defintion"));
            return false;
        }
    }
    coverage->setCoordinateSystem(csy);


    QString attfile = _odf->value("BaseMap", "AttributeTable");
    QString basemaptype = _odf->value("BaseMap", "Type");
    // feature coverages always have an attribute table; rasters might have
    if ( basemaptype != "Map" || attfile != sUNDEF) {
        ITable attTable = prepareAttributeTable(attfile, basemaptype);
        if (!attTable.isValid())
            return false;

        coverage->attributeTable(attTable);
    }

    QString cbounds = _odf->value("BaseMap","CoordBounds");
    QStringList parts = cbounds.split(" ");
    if ( parts.size() == 4) {
        double minx = parts[0].toDouble();
        double miny = parts[1].toDouble();
        double maxx = parts[2].toDouble();
        double maxy = parts[3].toDouble();
        Box2D<double> env(Coordinate(minx, miny), Coordinate(maxx, maxy));
        coverage->envelope(env);
    } else {
        kernel()->issues()->log(TR(ERR_INVALID_PROPERTY_FOR_2).arg("Coordinate boundaries", data->name()), IssueObject::itWarning);
    }


    return true;
}
void LayerManager::linkAcceptMessage(const QVariantMap& parameters) {
    try {
        if (parameters.contains("linktype")) {
            QString linktype = parameters["linktype"].toString();
            if (linktype == "zoomextent") {
                bool ok;

                QString env = parameters["envelope"].toString();
                if (env == "") {
                    QVariantMap extent = parameters["envelope"].toMap();
                    if (extent.contains("maxx")) {
                        env = QString("%1,%2,%3,%4").arg(extent["minx"].toDouble()).arg(extent["miny"].toDouble()).arg(extent["maxx"].toDouble()).arg(extent["maxy"].toDouble());
                    }
                }
                quint64 csyid = parameters["csyid"].toULongLong(&ok);
                if (!ok)
                    return;

                if (rootLayer()->screenCsy()->id() != csyid) {
                    ICoordinateSystem csy;
                    if (!csy.prepare(csyid))
                        return;
                    QStringList parts = env.split(",");
                    if (parts.size() == 4 || parts.size() == 6) {
                        bool ok1, ok2;
                        Coordinate crd1(parts[0].toDouble(&ok1), parts[1].toDouble(&ok2));
                        if (!ok1 || !ok2)
                            return;
                        Coordinate crd2(parts[2].toDouble(&ok1), parts[3].toDouble(&ok2));
                        if (!ok1 || !ok2)
                            return;
                        crd1 = rootLayer()->screenCsy()->coord2coord(csy, crd1);
                        crd2 = rootLayer()->screenCsy()->coord2coord(csy, crd2);
                        if (!crd1.isValid() || !crd2.isValid())
                            return;
                        env = QString("%1,%2,%3,%4").arg(crd1.x).arg(crd1.y).arg(crd2.x).arg(crd2.y);
                    }
                }
                QString cmd = QString("setviewextent(%1, %2)").arg(modelId()).arg(env);
                addCommand(cmd);
            }
        }
    }
    catch (const ErrorObject&) {}
}
Example #11
0
bool GeorefConnector::loadGeorefCorners(const IniFile& odf, IlwisObject *data) {
    GeoReference *grf = static_cast<GeoReference *>(data);
    QString csyName = odf.value("GeoRef","CoordSystem");
    ICoordinateSystem csy;
    if ( csyName.toLower() == "latlonwgs84.csy"){
        Resource resource = mastercatalog()->name2Resource("code=epsg:4326", itCOORDSYSTEM);
        if(!csy.prepare(resource))
            return false;
    }else {
        if ( csyName == "unknown.csy" || csyName == "" || csyName == sUNDEF){
            Resource resource = mastercatalog()->name2Resource("code=csy:unknown", itCOORDSYSTEM);
            if(!csy.prepare(resource)) {
                return false;
            }
        }else {

            QUrl path = mastercatalog()->name2url(csyName, itCOORDSYSTEM);
            if( !csy.prepare(path.toString())) {
                kernel()->issues()->log(TR("Couldn't find coordinate system %1, defaulting to unknown").arg(csyName),IssueObject::itWarning);
                Resource resource = mastercatalog()->name2Resource("code=csy:unknown", itCOORDSYSTEM);
                if(!csy.prepare(resource)) {
                    return false;
                }
            }
        }
    }

    grf->coordinateSystem(csy);
    double maxx = odf.value("GeoRefCorners","MaxX").toDouble();
    double maxy = odf.value("GeoRefCorners","MaxY").toDouble();
    double minx = odf.value("GeoRefCorners","MinX").toDouble();
    double miny = odf.value("GeoRefCorners","MinY").toDouble();
    if ( maxx == rUNDEF || maxy == rUNDEF || minx == rUNDEF || miny == rUNDEF) {
        kernel()->issues()->log(TR("Uninitialized boundaries for georeference %1").arg(_resource.name()));
        return false;
    }

    grf->envelope(Envelope(Coordinate(minx, miny), Coordinate(maxx, maxy)));
    bool centerOfCornerPixels = (odf.value("GeoRefCorners","CornersOfCorners").compare("No") == 0);
    grf->centerOfPixel(centerOfCornerPixels);
    grf->compute();
    return true;
}
Coordinate ConventionalCoordinateSystem::coord2coord(const ICoordinateSystem &sourceCs, const Coordinate &crdSource) const
{
    //TODO isLatLon guard doesn't consider latlon cs other than WGS84!
    if (sourceCs->id() == id()) //  the 'real'isEqual test is too expensive here, as this method can be called 100000's of times (resample)
        return crdSource;
    LatLon ll = sourceCs->isLatLon() ? LatLon(crdSource.y,crdSource.x) : sourceCs->coord2latlon(crdSource);
    if (ll.isValid()) {
        if (hasType(sourceCs->ilwisType(), itCONVENTIONALCOORDSYSTEM)) {
            const IConventionalCoordinateSystem & srcCs = sourceCs.as<ConventionalCoordinateSystem>();
            if (srcCs->datum().get() && datum().get() && !srcCs->datum()->equal(*datum().get())) { // different datums given, datum shift needed
                ll = srcCs->datum()->llToWGS84(ll, *srcCs->ellipsoid().ptr());
                ll = datum()->llFromWGS84(ll, *ellipsoid().ptr());
            }
        }
        return isLatLon() ? ll : latlon2coord(ll);
    }

    return Coordinate();
}
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();
}
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;
        }
    }
}
Example #15
0
std::vector<std::vector<float> > IlwisTesselator::getContours(const geos::geom::Geometry *geometry,const ICoordinateSystem &csyRoot, const ICoordinateSystem &csyGeom)
{


    bool conversionNeeded = csyRoot != csyGeom;
    const geos::geom::Polygon *polygon = dynamic_cast<const geos::geom::Polygon *>(geometry);
    if (polygon){
        const geos::geom::LineString *outerRing = polygon->getExteriorRing();
        std::vector<std::vector<float>> contours(1);
        contours[0].resize(outerRing->getNumPoints() * 2);

        auto addCoord = [&](const geos::geom::Coordinate& crd, int index, int i) {
            if ( conversionNeeded){
                Coordinate crdTransformed = csyRoot->coord2coord(csyGeom,crd);
                contours[index][i] = crdTransformed.x;
                contours[index][i+1] = crdTransformed.y;
            } else{
                contours[index][i] = crd.x;
                contours[index][i+1] = crd.y;
            }
        };

        for(int i = 0 ; i < outerRing->getNumPoints(); ++i){
            const geos::geom::Coordinate& crd = outerRing->getCoordinateN(i);
            addCoord(crd, 0, i * 2);
        }
        if ( polygon->getNumInteriorRing() > 0){
            contours.resize(polygon->getNumInteriorRing() + 1);
            for(int i = 0; i < polygon->getNumInteriorRing(); ++i){
                const geos::geom::LineString *innerRing = polygon->getInteriorRingN(i);
                contours[i + 1].resize(innerRing->getNumPoints() * 2); // contours[0] is outer ring
                for(int j = 0 ; j < innerRing->getNumPoints(); ++j){
                    const geos::geom::Coordinate& crd = innerRing->getCoordinateN(j);
                    addCoord(crd, i+1, j * 2);
                }
            }
        }
        return contours;
    }
    return std::vector<std::vector<float>>();
}
Example #16
0
void OpenGLHelper::getPointVertices(const ICoordinateSystem& csyRoot,
                                    const ICoordinateSystem& csyGeom,
                                    const Ilwis::UPGeometry &geometry,
                                    Raw objectid, QVector<QVector3D> &points,
                                    QVector<QVector3D> &normals,
                                    std::vector<VertexIndex> &indices){

    int n = geometry->getNumGeometries();
    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();
        indices.push_back(VertexIndex(points.size(),1,GL_POINTS,objectid));
        bool conversionNeeded = csyRoot != csyGeom;
        Coordinate coord = *crd;
        if ( conversionNeeded){
            coord = csyRoot->coord2coord(csyGeom, *crd);
        }
        points.push_back(QVector3D(coord.x, coord.y, coord.z));
    }
}
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();
}
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);
}
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;
}
Coordinate BoundsOnlyCoordinateSystem::coord2coord(const ICoordinateSystem &sourceCs, const Coordinate &crdSource) const
{
    if ( sourceCs->id() == id())
        return crdSource;
    return Coordinate();
}
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;
}