void OGRSOSIDataSource::buildOGRLineString(int nNumCoo, long iSerial) {
    if (papoBuiltGeometries[iSerial] != NULL) {
        return;
    }

    OGRLineString *poLS = new OGRLineString();
    poLS->setNumPoints(nNumCoo);

    long i;
    double dfEast = 0, dfNorth = 0;
    for (i=1; i<=nNumCoo; i++) {
        LC_GetTK(i, &dfEast, &dfNorth);
        poLS->setPoint(i-1, dfEast, dfNorth);
    }
    papoBuiltGeometries[iSerial] = poLS;
}
void OGRSOSIDataSource::buildOGRMultiPoint(int nNumCoo, long iSerial) {
    if (papoBuiltGeometries[iSerial] != NULL) {
        return;
    }

    OGRMultiPoint *poMP = new OGRMultiPoint();

    long i;
    double dfEast = 0, dfNorth = 0;
    for (i=(nNumCoo>1)?2:1; i<=nNumCoo; i++) {
        LC_GetTK(i, &dfEast, &dfNorth);
        OGRPoint poP = OGRPoint(dfEast, dfNorth);
        poMP->addGeometry(&poP); /*poP will be cloned before returning*/
    }
    papoBuiltGeometries[iSerial] = poMP;
}
void OGRSOSIDataSource::buildOGRPoint(long iSerial) {
    double dfEast = 0, dfNorth = 0;
    LC_GetTK(1, &dfEast, &dfNorth);
    papoBuiltGeometries[iSerial] = new OGRPoint(dfEast, dfNorth);
}
void OGRSOSIDataSource::buildOGRLineStringFromArc(long iSerial) {
    if (papoBuiltGeometries[iSerial] != NULL) {
        return;
    }

    OGRLineString *poLS = new OGRLineString();
   
    /* fetch reference points on circle (easting, northing) */
    double e1 = 0, e2 = 0, e3 = 0;
    double n1 = 0, n2 = 0, n3 = 0;
    LC_GetTK(1, &e1, &n1);
    LC_GetTK(2, &e2, &n2);
    LC_GetTK(3, &e3, &n3);

    /* helper constants */
    double p12  = (e1 * e1 - e2 * e2 + n1 * n1 - n2 * n2) / 2;
    double p13  = (e1 * e1 - e3 * e3 + n1 * n1 - n3 * n3) / 2;

    double dE12 = e1 - e2;
    double dE13 = e1 - e3;
    double dN12 = n1 - n2;
    double dN13 = n1 - n3;

    /* center of the circle */
    double cE = (dN13 * p12 - dN12 * p13) / (dE12 * dN13 - dN12 * dE13) ; 
    double cN = (dE13 * p12 - dE12 * p13) / (dN12 * dE13 - dE12 * dN13) ;

    /* radius of the circle */
    double r = sqrt(sqr(e1 - cE) + sqr(n1 - cN));

    /* angles of points A and B (1 and 3) */
    double th1 = atan2(n1 - cN, e1 - cE);
    double th3 = atan2(n3 - cN, e3 - cE);

    /* interpolation step in radians */
    double dth = th3 - th1;
    if (dth < 0) {dth  += 2 * M_PI;}
    if (dth > M_PI) { 
      dth = - 2*M_PI + dth;
    }
    int    npt = (int)(ARC_INTERPOLATION_FULL_CIRCLE * dth / 2*M_PI);
    if (npt < 0) npt=-npt;
    if (npt < 3) npt=3;
    poLS->setNumPoints(npt);
    dth = dth / (npt-1);

    long i;
    double dfEast = 0, dfNorth = 0;
    
    for (i=0; i<npt; i++) {
        dfEast  = cE + r * cos(th1 + dth * i);
        dfNorth = cN + r * sin(th1 + dth * i);
        if (dfEast != dfEast) { /* which is a wonderful property of nans */
          CPLError( CE_Warning, CPLE_AppDefined,
                    "Calculated %lf for point %li of %i in curve %li.", dfEast, i, npt, iSerial);
        }
        poLS->setPoint(i, dfEast, dfNorth);
    }
    papoBuiltGeometries[iSerial] = poLS;
     
    
}