bool CoordinateSystemConnector::loadMetaData(IlwisObject* data)
{
    Ilwis3Connector::loadMetaData(data);
    CoordinateSystem *csy = static_cast<CoordinateSystem *>(data);
    QString ellipsoideName;

    IEllipsoid ell = getEllipsoid();
    GeodeticDatum *datum = getDatum(ellipsoideName);
    if ( !ell.isValid() && ellipsoideName != sUNDEF){
        QString ellres = QString("ilwis://tables/ellipsoid?code=%1").arg(ellipsoideName);
       if (!ell.prepare(ellres)) {
              return ERROR1("No ellipsoid for this code %1",ellipsoideName);
       }
    }


    if ( type() == itCONVENTIONALCOORDSYSTEM ) {
        ConventionalCoordinateSystem *csycc = static_cast<ConventionalCoordinateSystem *>(csy);
        IProjection proj = getProjection();
        if ( !proj.isValid()) {
            return ERROR1(ERR_NO_INITIALIZED_1, "projection");
        }
        csycc->setDatum(datum);
        csycc->setEllipsoid(ell);
        csycc->setProjection(proj);
        proj->setCoordinateSystem(csycc);


        proj->setParameter(Projection::pvELLCODE, ell->toProj4());
        csycc->prepare();
    } else if ( type() == itUNKNOWN){
        //TODO other types of csy
    }
    return true;
}
void ConventionalCoordinateSystem::copyTo(IlwisObject *obj)
{
    Locker<> lock(_mutex);
    CoordinateSystem::copyTo(obj);
    ConventionalCoordinateSystem *csy = static_cast<ConventionalCoordinateSystem *>(obj);
    csy->_ellipsoid.set( static_cast<Ellipsoid *>(_ellipsoid->clone()));
    csy->_projection.set( static_cast<Projection *>(projection()->clone()));
    csy->projection()->setCoordinateSystem(this);
}
bool CoordinateSystemConnector::loadMetaData(IlwisObject* data, const IOOptions& options)
{
    Ilwis3Connector::loadMetaData(data, options);
    CoordinateSystem *csy = static_cast<CoordinateSystem *>(data);
    QString ellipsoideName;

    IEllipsoid ell = getEllipsoid();
    GeodeticDatum *datum = getDatum(ellipsoideName);
    if ( !ell.isValid() && ellipsoideName != sUNDEF){
        QString ellres = QString("ilwis://tables/ellipsoid?code=%1").arg(ellipsoideName);
       if (!ell.prepare(ellres)) {
              return ERROR1("No ellipsoid for this code %1",ellipsoideName);
       }
    }

    QString cb = _odf->value("CoordSystem", "CoordBounds");
    QStringList cbparts = cb.split(" ");
    if ( cbparts.size() == 4 && cbparts[0] != "-1e+308") {
        bool ok1, ok2, ok3, ok4;
        Envelope box( Coordinate(
                                cbparts[0].toDouble(&ok1),
                                cbparts[1].toDouble(&ok2)),
                           Coordinate(
                                cbparts[2].toDouble(&ok3),
                                cbparts[3].toDouble(&ok4)));
        if ( !( ok1 && ok2 && ok3 && ok4)) {
            return ERROR2(ERR_NO_INITIALIZED_2, TR("envelop"), csy->name());
        }
        csy->envelope(box);
    } else {
        QString type = _odf->value("CoordSystem", "Type");
        if ( type == "LatLon") {
            Envelope box(Coordinate(-180,-90), Coordinate(180,90));
            csy->envelope(box);
        }
    }

    if ( type() == itCONVENTIONALCOORDSYSTEM ) {
        ConventionalCoordinateSystem *csycc = static_cast<ConventionalCoordinateSystem *>(csy);
        IProjection proj = getProjection(csycc);
        if ( !proj.isValid()) {
            return ERROR1(ERR_NO_INITIALIZED_1, "projection");
        }
        csycc->setDatum(datum);
        csycc->setEllipsoid(ell);
        csycc->setProjection(proj);
        proj->setCoordinateSystem(csycc);


        proj->setParameter(Projection::pvELLCODE, ell->toProj4());
        csycc->prepare();
    } else if ( type() == itUNKNOWN){
        //TODO: other types of csy
    }
    return true;
}
bool CoordinateSystemSerializerV1::loadMetaData(IlwisObject *obj, const IOOptions &options)
{
    if (!VersionedSerializer::loadMetaData(obj, options))
        return false;
    CoordinateSystem *csy = static_cast<CoordinateSystem *>(obj);
    VersionedDataStreamFactory *factory = kernel()->factory<VersionedDataStreamFactory>("ilwis::VersionedDataStreamFactory");
    if (!factory)
        return false;

    if ( csy->ilwisType() == itCONVENTIONALCOORDSYSTEM){
        ConventionalCoordinateSystem *convCsy = static_cast<ConventionalCoordinateSystem *>(obj);
        quint64 type;
        QString version, url;
        _stream >> url;
        _stream >> type;
        if ( type != itUNKNOWN){
            _stream >> version;
            std::unique_ptr<DataInterface> projstreamer(factory->create(version, type,_stream));
            if ( !projstreamer)
                return false;
            IProjection proj(itPROJECTION);
            projstreamer->loadMetaData(proj.ptr(), options );
            convCsy->setProjection(proj);
        }
bool CoordinateSystemSerializerV1::store(IlwisObject *obj, const IOOptions &options)
{
    if (!VersionedSerializer::store(obj, options))
        return false;

    CoordinateSystem *csy = static_cast<CoordinateSystem *>(obj);
    if ( csy->ilwisType() == itCONVENTIONALCOORDSYSTEM){
        VersionedDataStreamFactory *factory = kernel()->factory<VersionedDataStreamFactory>("ilwis::VersionedDataStreamFactory");
        if (!factory)
            return false;
        std::unique_ptr<DataInterface> projstreamer(factory->create(Version::interfaceVersion, itPROJECTION,_stream));
        if ( !projstreamer)
            return false;
        ConventionalCoordinateSystem *ccsy = static_cast<ConventionalCoordinateSystem *>(csy);
        storeSystemPath(ccsy->projection()->resource());
        projstreamer->store(ccsy->projection().ptr(),options);
        std::unique_ptr<DataInterface> ellstreamer(factory->create(Version::interfaceVersion, itELLIPSOID,_stream));
        if ( !ellstreamer)
            return false;
        storeSystemPath(ccsy->ellipsoid()->resource());
        ellstreamer->store(ccsy->ellipsoid().ptr(),options);

        const std::unique_ptr<GeodeticDatum>& datum = ccsy->datum();
        if ( datum){
            _stream << itGEODETICDATUM << datum->name() << datum->code() << datum->description() << datum->area() << datum->authority();
            for(int i =0; i < 10; ++i)
                _stream << datum->parameter((GeodeticDatum::DatumParameters)i);
        }else
            _stream << itUNKNOWN;

        _stream << ccsy->unit();

    }
    _stream << csy->envelope().min_corner().x << csy->envelope().min_corner().y << csy->envelope().max_corner().x << csy->envelope().max_corner().y;
    return true;

}