bool FeatureConnector::isForwardStartDirection(const BinaryIlwis3Table& topTable, qint32 colForward, qint32 colBackward, qint32 colCoords, long index) {
    qint32 fwl, bwl;
    double v;
    topTable.get(abs(index),colForward, v );
    fwl = v;
    if ( fwl != iUNDEF)
        --fwl; // due to being raw values
    topTable.get(abs(index),colBackward, v );
    bwl = v;
    if ( bwl != iUNDEF)
        --bwl;

    if ( abs(fwl) == abs(bwl)	)
        return true;
    if ( index < 0)
        return false;
    std::vector<Coordinate2d> startLine, forwardLine;
    topTable.get(abs(index), colCoords,startLine);
    topTable.get(abs(fwl), colCoords, forwardLine);

    bool forward = false;
    if ( fwl > 0)
        forward =  startLine.back() == forwardLine.front();
    else
        forward = startLine.back() == forwardLine.back();

    return forward;

}
bool FeatureConnector::isForwardStartDirection(const BinaryIlwis3Table& topTable, qint32 colForward, qint32 colBackward, qint32 colCoords, long index) {
    qint32 fwl, bwl;
    double v;
    topTable.get(abs(index) - 1,colForward, v );
    fwl = v;
   // if ( fwl != iUNDEF)
   //     --fwl; // due to being raw values
    topTable.get(abs(index)-1,colBackward, v );
    bwl = v;
   // if ( bwl != iUNDEF)
   //    --bwl;

    if ( abs(fwl) == abs(bwl)	)
        return true;
    if ( index < 0)
        return false;
    //qDebug() << fwl << bwl;
    std::vector<Coordinate> startLine, forwardLine;
    topTable.get(abs(index) - 1, colCoords,startLine);
    topTable.get(abs(fwl) - 1, colCoords, forwardLine);

    bool forward = false;
    if ( forwardLine.size() == 0 || startLine.size() == 0)
        throw ErrorObject(TR("aborting topoplogy reading, polygon might be corrupted"));

    if ( fwl > 0)
        forward =  startLine.back() == forwardLine.front();
    else
        forward = startLine.back() == forwardLine.back();

    return forward;

}
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::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;
}
bool FeatureConnector::getRings(qint32 startIndex, const BinaryIlwis3Table& topTable, const BinaryIlwis3Table& polTable, std::vector<vector<Coordinate2d>>& rings ){
    qint32 row = startIndex;
    qint32 colCoords = topTable.index("Coords");
    qint32 colForward = topTable.index("ForwardLink");
    qint32 colBackward = topTable.index("BackwardLink");
    std::vector<Coordinate> ring;
    bool forward = isForwardStartDirection(topTable,colForward, colBackward, colCoords, row);
    do{
        std::vector<Coordinate> coords;
        topTable.get(row,colCoords,coords);
        if( coords.size() == 0 ||coords.back() == coords.front()){
            ring.resize(coords.size());
            std::copy(coords.begin(), coords.end(), ring.begin());
        } else if ( coords.back() == ring.back()) {
            ring.resize(coords.size());
            std::reverse_copy(coords.begin(), coords.end(), ring.begin());
        } else if ( ring.front() == coords.front()) {
            ring.resize(coords.size());
            std::reverse_copy(coords.begin(), coords.end(), ring.begin());
        } else if ( ring.front() == coords.back()) {
            ring.resize(coords.size());
            std::copy(coords.begin(), coords.end(), ring.begin());
        }

        if ( ring.front() == ring.back() && ring.size() > 3) {
            std::vector<Coordinate2d> ring2d;
            Coordinate crdOld;
            for(const Coordinate& crd : ring) {
                if ( crd == crdOld)  // remove duplicates
                    continue;
                ring2d.push_back(crd);
                crdOld = crd;
            }
            rings.push_back(ring2d);
            coords.clear();
            ring.clear();
        }
        qint32 oldIndex = row;
        double v;
        if ( forward)
            topTable.get(abs(row),colForward,v);
        else
            topTable.get(abs(row), colBackward, v);\
        row = v;
        if ( oldIndex == row && row != startIndex) // this would indicate infintite loop. corrupt data
            return false;
        forward = row > 0;
    } while(abs(row) != abs(startIndex) && row != iUNDEF);

    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::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;
}
Ejemplo n.º 9
0
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::getRings(FeatureCoverage *fcoverage, qint32 startIndex, const BinaryIlwis3Table& topTable, const BinaryIlwis3Table& polTable, std::vector<geos::geom::LinearRing *> *rings ){
    qint32 row = startIndex;
    qint32 colCoords = topTable.index("Coords");
    qint32 colForward = topTable.index("ForwardLink");
    qint32 colBackward = topTable.index("BackwardLink");
    bool outerIsCCW = true;
    std::vector<geos::geom::Coordinate> *ring =  new std::vector<geos::geom::Coordinate>();
    bool forward = isForwardStartDirection(topTable,colForward, colBackward, colCoords, row);
    do{
        std::vector<Coordinate> coords;
        topTable.get(abs(row) - 1,colCoords,coords);
        int ringsize =  (int)ring->size();
        ring->reserve(ring->size() + coords.size());

        if( ringsize == 0 ||coords.front() == ring->back()){
            for(int i = 0; i < coords.size() ; ++i){
                if ( ring->size() > 0 && ring->back() == coords[i])
                    continue;
                ring->push_back(coords[i]);
            }
        } else if ( ring->size() > 0 && coords.back() == ring->back()) {
            for(int i = 0; i < coords.size() ; ++i){
                const auto& crd = coords[coords.size() - i - 1];
                if ( ring->back() == crd)
                    continue;
                 ring->push_back(crd);
            }
        } else if ( ring->size() > 0 && ring->front() == coords.front()) {
            for(int i = 0; i < coords.size() ; ++i)
                 ring->push_back(coords[i]);
        } else if ( ring->size() > 0 && ring->front() == coords.back()) {
             for(int i = 0; i < coords.size() ; ++i)
                 ring->push_back(coords[i]);
        }

        if ( ring->size() > 3 && ring->front() == ring->back()) {
            ring->shrink_to_fit();

            geos::geom::CoordinateArraySequence * ringIn = new geos::geom::CoordinateArraySequence(ring);
            ringIn->removeRepeatedPoints();
            if ( rings->size() == 0)  {
                outerIsCCW = geos::algorithm::CGAlgorithms::isCCW(ringIn);
            }else {
                bool isCCW = geos::algorithm::CGAlgorithms::isCCW(ringIn);
                if ( outerIsCCW && isCCW){ // holes must have a different turning direction
                    geos::geom::CoordinateSequence::reverse(ringIn);
                }
            }
            rings->push_back( fcoverage->geomfactory()->createLinearRing(ringIn));
            ring =  new std::vector<geos::geom::Coordinate>();
        }
        qint32 oldIndex = row;
        double v;
        if ( forward)
            topTable.get(abs(row) - 1,colForward,v);
        else
            topTable.get(abs(row) - 1, colBackward, v);\
        row = v;
        if ( oldIndex == row && row != startIndex) // this would indicate infintite loop. corrupt data
            return false;
        forward = row > 0;
    } while(abs(row) != abs(startIndex) && row != iUNDEF);

    return true;
}