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;
}
bool FeatureConnector::loadBinaryPolygons30(FeatureCoverage *fcoverage, ITable& tbl) {
    BinaryIlwis3Table polTable;
    if ( !polTable.load(_odf)) {
        return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_odf->url())    ;
    }

    BinaryIlwis3Table topTable;
    if ( !topTable.load(_odf,"top")) {
        return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_odf->url())    ;
    }

    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;
    fcoverage->setFeatureCount(itFEATURE, iUNDEF, FeatureInfo::ALLFEATURES); // reset all counts

    double v;
    map<quint32,vector<geos::geom::Geometry *>> polygons;
    std::vector<double> featureValues(isNumeric ? nrPolygons : 0);
    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<geos::geom::LinearRing *> *rings = new std::vector<geos::geom::LinearRing *>();
        if (getRings(fcoverage,index, topTable, polTable, rings)) {
            if ( rings->size() == 0)
                continue;
            geos::geom::LinearRing *outer = rings->front();
            vector<geos::geom::Geometry *> *inners = new vector<geos::geom::Geometry *>(rings->size() - 1);
            for(int j=1; j < rings->size(); ++j) {
                (*inners)[j-1] = rings->at(j);
            }

            geos::geom::Polygon *pol = fcoverage->geomfactory()->createPolygon(outer, inners);

            //collect all polygons in a map; the key is either a unique number ( index j) or the raw value from the polygon
            //in this way all polygons with the same raw value will become a multipolygon
            double value;
            polTable.get(i, colValue, value);
            if (value == rUNDEF || value == iILW3UNDEF || value == shILW3UNDEF)
                continue;
            polygons[isNumeric ? i + 1 : (quint32)value].push_back(pol);
            if ( isNumeric) {
                featureValues[i] = value;
            }
        }
    }
    addFeatures(polygons, fcoverage,featureValues, itPOLYGON);
    return true;
}
bool FeatureConnector::loadBinaryPoints(FeatureCoverage *fcoverage) {
    BinaryIlwis3Table mppTable;
    if ( !mppTable.load(_odf)) {
        return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_odf->url())    ;
    }
    // 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");
    bool isNumeric = _odf->value("BaseMap","Range") != sUNDEF;

    std::vector<double> featureValues(isNumeric ? mppTable.rows() : 0);
    bool newCase =  coordColumnX == iUNDEF;
    fcoverage->setFeatureCount(itFEATURE, iUNDEF, FeatureInfo::ALLFEATURES); // reset all counts

    map<quint32,vector<geos::geom::Geometry *>> points;
    for(quint32 i= 0; i < mppTable.rows(); ++i) {
        Coordinate c;
        double value;
        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,value);
        geos::geom::Point *point = fcoverage->geomfactory()->createPoint(c);
        points[isNumeric ? i + 1 : (quint32)value].push_back(point);
        if ( isNumeric) {
            featureValues[i] = value;
        }

    }
    addFeatures(points, fcoverage,featureValues, itPOINT);
    return true;
}
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 FeatureConnector::loadBinarySegments(FeatureCoverage *fcoverage) {
    BinaryIlwis3Table mpsTable;
    if ( !mpsTable.load(_odf)) {
        return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_odf->url())    ;
    }
    int colCoords = mpsTable.index("Coords");
    int colItemId = mpsTable.index("SegmentValue");
    bool isNumeric = _odf->value("BaseMap","Range") != sUNDEF;
    fcoverage->setFeatureCount(itFEATURE, iUNDEF, FeatureInfo::ALLFEATURES); // reset all counts

    map<quint32,vector<geos::geom::Geometry *>> lines;
    std::vector<double> featureValues(isNumeric ? mpsTable.rows() : 0);
    double value;
    for(quint32 i= 0; i < mpsTable.rows(); ++i) {
        std::vector<Coordinate > coords;
        mpsTable.get(i,colCoords,coords);
        geos::geom::CoordinateArraySequence *vertices = new geos::geom::CoordinateArraySequence(coords.size());
        for(int i=0; i < coords.size(); ++i)
            vertices->setAt(geos::geom::Coordinate(coords[i].x, coords[i].y, coords[i].z), i);
        geos::geom::LineString *line = fcoverage->geomfactory()->createLineString(vertices);
        mpsTable.get(i, colItemId,value);

        //collect all lines in a map; the key is either a unique number ( index j) or the raw value from the line
        //in this way all lines with the same raw value will become a multilinestring
        lines[isNumeric ? i + 1 : (quint32)value].push_back(line);
        if ( isNumeric) {
            featureValues[i] = value;
        }


    }
    addFeatures(lines, fcoverage,featureValues, itLINE);
    return true;


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


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