Esempio n. 1
0
int ILI1Reader::ReadTable(CPL_UNUSED const char *layername) {
    char **tokens = NULL;
    int ret = TRUE;
    int warned = FALSE;
    int geomIdx = -1;

    OGRFeatureDefn *featureDef = curLayer->GetLayerDefn();
    OGRFeature *feature = NULL;
    bool bFeatureAdded = false;

    while (ret && (tokens = ReadParseLine()) != NULL)
    {
      const char *firsttok = CSLGetField(tokens, 0);
      if (EQUAL(firsttok, "OBJE"))
      {
        if (featureDef->GetFieldCount() == 0)
        {
          CPLError( CE_Warning, CPLE_AppDefined,
                    "No field definition found for table: %s",
                    featureDef->GetName() );
          // Model not read - use heuristics.
          for( int fIndex=1; fIndex<CSLCount(tokens); fIndex++ )
          {
            char szFieldName[32];
            snprintf(szFieldName, sizeof(szFieldName), "Field%02d", fIndex);
            OGRFieldDefn oFieldDefn(szFieldName, OFTString);
            featureDef->AddFieldDefn(&oFieldDefn);
          }
        }
        //start new feature
        if( !bFeatureAdded )
            delete feature;
        feature = new OGRFeature(featureDef);

        for( int fIndex=1, fieldno = 0;
             fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount();
             fIndex++, fieldno++ )
        {
          if (!(tokens[fIndex][0] == codeUndefined && tokens[fIndex][1] == '\0')) {
#ifdef DEBUG_VERBOSE
            CPLDebug( "READ TABLE OGR_ILI", "Setting Field %d (Type %d): %s",
                      fieldno, featureDef->GetFieldDefn(fieldno)->GetType(),
                      tokens[fIndex] );
#endif
            if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTString) {
                // Interlis 1 encoding is ISO 8859-1 (Latin1) -> Recode to UTF-8
                char* pszRecoded = CPLRecode(
                    tokens[fIndex], CPL_ENC_ISO8859_1, CPL_ENC_UTF8);
                // Replace space marks
                for( char* pszString = pszRecoded;
                     *pszString != '\0';
                     pszString++ ) {
                    if (*pszString == codeBlank) *pszString = ' ';
                }
                feature->SetField(fieldno, pszRecoded);
                CPLFree(pszRecoded);
            } else {
              feature->SetField(fieldno, tokens[fIndex]);
            }
            if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal
                && fieldno > 0
                && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal) {
              // Check for Point geometry (Coord type).
              // If there is no ili model read,
              // we have no chance to detect the
              // geometry column.
              CPLString geomfldname
                  = featureDef->GetFieldDefn(fieldno)->GetNameRef();
              // Check if name ends with _1.
              if (geomfldname.size() >= 2 && geomfldname[geomfldname.size()-2]
                  == '_') {
                geomfldname = geomfldname.substr(0, geomfldname.size()-2);
                geomIdx = featureDef->GetGeomFieldIndex(geomfldname.c_str());
                if (geomIdx == -1)
                {
                  CPLError( CE_Warning, CPLE_AppDefined,
                            "No matching definition for field '%s' of "
                            "table %s found",
                            geomfldname.c_str(), featureDef->GetName() );
                }
              } else {
                geomIdx = -1;
              }
              if (geomIdx >= 0) {
                if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() ==
                    wkbPoint) {
                  // Add Point geometry.
                  OGRPoint *ogrPoint = new OGRPoint(
                      CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex]));
                  feature->SetGeomFieldDirectly(geomIdx, ogrPoint);
                } else if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() ==
                           wkbPoint25D && fieldno > 1 &&
                           featureDef->GetFieldDefn(fieldno-2)->GetType() ==
                           OFTReal) {
                  // Add 3D Point geometry.
                  OGRPoint *ogrPoint = new OGRPoint(
                      CPLAtof(tokens[fIndex-2]), CPLAtof(tokens[fIndex-1]),
                      CPLAtof(tokens[fIndex]) );
                  feature->SetGeomFieldDirectly(geomIdx, ogrPoint);
                }
              }
            }
          }
        }
        if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1) {
          CPLError( CE_Warning, CPLE_AppDefined,
                    "Field count of table %s doesn't match. %d declared, "
                    "%d found (e.g. ignored LINEATTR)",
                    featureDef->GetName(), featureDef->GetFieldCount(),
                    CSLCount(tokens) - 1 );
          warned = TRUE;
        }
        if (feature->GetFieldCount() > 0) {
          // USE _TID as FID. TODO: respect IDENT field from model.
          feature->SetFID(feature->GetFieldAsInteger64(0));
        }
        curLayer->AddFeature(feature);
        bFeatureAdded = true;
        geomIdx = -1; //Reset
      }
      else if (EQUAL(firsttok, "STPT") && feature != NULL)
      {
        //Find next non-Point geometry
        if (geomIdx < 0) geomIdx = 0;
        while (geomIdx < featureDef->GetGeomFieldCount() &&
               featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) {
            geomIdx++;
        }
        OGRwkbGeometryType geomType
            = (geomIdx < featureDef->GetGeomFieldCount()) ?
               featureDef->GetGeomFieldDefn(geomIdx)->GetType() : wkbNone;
        ReadGeom(tokens, geomIdx, geomType, feature);
      }
      else if (EQUAL(firsttok, "ELIN"))
      {
        // Empty geom.
      }
      else if (EQUAL(firsttok, "EDGE") && feature != NULL)
      {
        CSLDestroy(tokens);
        tokens = ReadParseLine(); //STPT
        //Find next non-Point geometry
        do {
            geomIdx++;
        } while (geomIdx < featureDef->GetGeomFieldCount() &&
                 featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint);
        ReadGeom(tokens, geomIdx, wkbMultiLineString, feature);
      }
      else if (EQUAL(firsttok, "PERI"))
      {
      }
      else if (EQUAL(firsttok, "ETAB"))
      {
        CPLDebug( "OGR_ILI", "Total features: " CPL_FRMT_GIB,
                  curLayer->GetFeatureCount() );
        CSLDestroy(tokens);
        if( !bFeatureAdded )
            delete feature;
        return TRUE;
      }
      else
      {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unexpected token: %s", firsttok );
      }

      CSLDestroy(tokens);
    }

    if( !bFeatureAdded )
        delete feature;

    return ret;
}
Esempio n. 2
0
OGRErr OGRSpatialReference::exportToPanorama( long *piProjSys, long *piDatum,
                                              long *piEllips, long *piZone,
                                              double *padfPrjParams ) const

{
    CPLAssert( padfPrjParams );

    const char  *pszProjection = GetAttrValue("PROJECTION");

/* -------------------------------------------------------------------- */
/*      Fill all projection parameters with zero.                       */
/* -------------------------------------------------------------------- */
    int     i;

    *piDatum = 0L;
    *piEllips = 0L;
    *piZone = 0L;
    for ( i = 0; i < 7; i++ )
        padfPrjParams[i] = 0.0;

/* ==================================================================== */
/*      Handle the projection definition.                               */
/* ==================================================================== */
    if( IsLocal() )
        *piProjSys = PAN_PROJ_NONE;

    else if( pszProjection == NULL )
    {
#ifdef DEBUG
        CPLDebug( "OSR_Panorama",
                  "Empty projection definition, considered as Geographic" );
#endif
        *piProjSys = PAN_PROJ_NONE;
    }

    else if( EQUAL(pszProjection, SRS_PT_MERCATOR_1SP) )
    {
        *piProjSys = PAN_PROJ_MERCAT;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[0] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[4] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_POLAR_STEREOGRAPHIC) )
    {
        *piProjSys = PAN_PROJ_PS;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[2] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[4] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_POLYCONIC) )
    {
        *piProjSys = PAN_PROJ_POLYC;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[2] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_EQUIDISTANT_CONIC) )
    {
        *piProjSys = PAN_PROJ_EC;
        padfPrjParams[0] =
            TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
        padfPrjParams[1] =
            TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[2] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
    {
        *piProjSys = PAN_PROJ_LCC;
        padfPrjParams[0] =
            TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
        padfPrjParams[1] =
            TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[2] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_TRANSVERSE_MERCATOR) )
    {
        int bNorth;

        *piZone = GetUTMZone( &bNorth );

        if( *piZone != 0 )
        {
            *piProjSys = PAN_PROJ_UTM;
            if( !bNorth )
                *piZone = - *piZone;
        }
        else
        {
            *piProjSys = PAN_PROJ_TM;
            padfPrjParams[3] =
                TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
            padfPrjParams[2] =
                TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
            padfPrjParams[4] =
                GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
            padfPrjParams[5] =
                GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
            padfPrjParams[6] =
                GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
        }
    }

    else if( EQUAL(pszProjection, SRS_PT_WAGNER_I) )
    {
        *piProjSys = PAN_PROJ_WAG1;
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_STEREOGRAPHIC) )
    {
        *piProjSys = PAN_PROJ_STEREO;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[2] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[4] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_AZIMUTHAL_EQUIDISTANT) )
    {
        *piProjSys = PAN_PROJ_AE;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 );
        padfPrjParams[0] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_GNOMONIC) )
    {
        *piProjSys = PAN_PROJ_GNOMON;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[2] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_MOLLWEIDE) )
    {
        *piProjSys = PAN_PROJ_MOLL;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
    {
        *piProjSys = PAN_PROJ_LAEA;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[0] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_EQUIRECTANGULAR) )
    {
        *piProjSys = PAN_PROJ_EQC;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[0] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_CYLINDRICAL_EQUAL_AREA) )
    {
        *piProjSys = PAN_PROJ_CEA;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[2] =
            TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    else if( EQUAL(pszProjection, SRS_PT_IMW_POLYCONIC) )
    {
        *piProjSys = PAN_PROJ_IMWP;
        padfPrjParams[3] =
            TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
        padfPrjParams[0] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, 0.0 );
        padfPrjParams[1] =
            TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, 0.0 );
        padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
        padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
    }

    // Projection unsupported by "Panorama" GIS
    else
    {
        CPLDebug( "OSR_Panorama",
                  "Projection \"%s\" unsupported by \"Panorama\" GIS. "
                  "Geographic system will be used.", pszProjection );
        *piProjSys = PAN_PROJ_NONE;
    }

/* -------------------------------------------------------------------- */
/*      Translate the datum.                                            */
/* -------------------------------------------------------------------- */
    const char  *pszDatum = GetAttrValue( "DATUM" );

    if ( pszDatum == NULL )
    {
        *piDatum = PAN_DATUM_NONE;
        *piEllips = PAN_ELLIPSOID_NONE;
    }
    else if ( EQUAL( pszDatum, "Pulkovo_1942" ) )
    {
        *piDatum = PAN_DATUM_PULKOVO42;
        *piEllips = PAN_ELLIPSOID_KRASSOVSKY;
    }
    else if( EQUAL( pszDatum, SRS_DN_WGS84 ) )
    {
        *piDatum = PAN_DATUM_WGS84;
        *piEllips = PAN_ELLIPSOID_WGS84;
    }

    // If not found well known datum, translate ellipsoid
    else
    {
        double      dfSemiMajor = GetSemiMajor();
        double      dfInvFlattening = GetInvFlattening();

#ifdef DEBUG
        CPLDebug( "OSR_Panorama",
                  "Datum \"%s\" unsupported by \"Panorama\" GIS. "
                  "Trying to translate an ellipsoid definition.", pszDatum );
#endif

        for ( i = 0; i < NUMBER_OF_ELLIPSOIDS; i++ )
        {
            if ( aoEllips[i] )
            {
                double  dfSM = 0.0;
                double  dfIF = 1.0;

                if ( OSRGetEllipsoidInfo( aoEllips[i], NULL,
                                          &dfSM, &dfIF ) == OGRERR_NONE
                     && CPLIsEqual(dfSemiMajor, dfSM)
                     && CPLIsEqual(dfInvFlattening, dfIF) )
                {
                    *piEllips = i;
                    break;
                }
            }
        }

        if ( i == NUMBER_OF_ELLIPSOIDS )    // Didn't found matches.
        {
#ifdef DEBUG
            CPLDebug( "OSR_Panorama",
                      "Ellipsoid \"%s\" unsupported by \"Panorama\" GIS.",
                      pszDatum );
#endif
            *piDatum = PAN_DATUM_NONE;
            *piEllips = PAN_ELLIPSOID_NONE;
        }
    }

    return OGRERR_NONE;
}
Esempio n. 3
0
static void 
RPCInverseTransformPoint( GDALRPCTransformInfo *psTransform,
                          double dfPixel, double dfLine, double dfHeight, 
                          double *pdfLong, double *pdfLat )

{
    double dfResultX, dfResultY;
    int    iIter;
    GDALRPCInfo *psRPC = &(psTransform->sRPC);

/* -------------------------------------------------------------------- */
/*      Compute an initial approximation based on linear                */
/*      interpolation from our reference point.                         */
/* -------------------------------------------------------------------- */
    dfResultX = psTransform->adfPLToLatLongGeoTransform[0]
        + psTransform->adfPLToLatLongGeoTransform[1] * dfPixel
        + psTransform->adfPLToLatLongGeoTransform[2] * dfLine;

    dfResultY = psTransform->adfPLToLatLongGeoTransform[3]
        + psTransform->adfPLToLatLongGeoTransform[4] * dfPixel
        + psTransform->adfPLToLatLongGeoTransform[5] * dfLine;

/* -------------------------------------------------------------------- */
/*      Now iterate, trying to find a closer LL location that will      */
/*      back transform to the indicated pixel and line.                 */
/* -------------------------------------------------------------------- */
    double dfPixelDeltaX=0.0, dfPixelDeltaY=0.0;

    for( iIter = 0; iIter < 10; iIter++ )
    {
        double dfBackPixel, dfBackLine;

        RPCTransformPoint( psRPC, dfResultX, dfResultY, dfHeight, 
                           &dfBackPixel, &dfBackLine );

        dfPixelDeltaX = dfBackPixel - dfPixel;
        dfPixelDeltaY = dfBackLine - dfLine;

        dfResultX = dfResultX 
            - dfPixelDeltaX * psTransform->adfPLToLatLongGeoTransform[1]
            - dfPixelDeltaY * psTransform->adfPLToLatLongGeoTransform[2];
        dfResultY = dfResultY 
            - dfPixelDeltaX * psTransform->adfPLToLatLongGeoTransform[4]
            - dfPixelDeltaY * psTransform->adfPLToLatLongGeoTransform[5];

        if( ABS(dfPixelDeltaX) < psTransform->dfPixErrThreshold
            && ABS(dfPixelDeltaY) < psTransform->dfPixErrThreshold )
        {
            iIter = -1;
            //CPLDebug( "RPC", "Converged!" );
            break;
        }

    }

    if( iIter != -1 )
        CPLDebug( "RPC", "Iterations %d: Got: %g,%g  Offset=%g,%g", 
                  iIter, 
                  dfResultX, dfResultY,
                  dfPixelDeltaX, dfPixelDeltaY );
    
    *pdfLong = dfResultX;
    *pdfLat = dfResultY;
}
CPLErr OGRMSSQLSpatialTableLayer::Initialize( const char *pszSchema,
                                              const char *pszLayerName, 
                                              const char *pszGeomCol,
                                              int nCoordDimension, 
                                              int nSRId,
                                              OGRwkbGeometryType eType )

{
    CPLODBCSession *poSession = poDS->GetSession();

    CPLFree( pszFIDColumn );
    pszFIDColumn = NULL;

/* -------------------------------------------------------------------- */
/*      Parse out schema name if present in layer.  We assume a         */
/*      schema is provided if there is a dot in the name, and that      */
/*      it is in the form <schema>.<tablename>                          */
/* -------------------------------------------------------------------- */
    const char *pszDot = strstr(pszLayerName,".");
    if( pszDot != NULL )
    {
        pszTableName = CPLStrdup(pszDot + 1);
        pszSchemaName = CPLStrdup(pszLayerName);
        pszSchemaName[pszDot - pszLayerName] = '\0';
    }
    else
    {
        pszTableName = CPLStrdup(pszLayerName);
        pszSchemaName = CPLStrdup(pszSchema);
    }

/* -------------------------------------------------------------------- */
/*      Do we have a simple primary key?                                */
/* -------------------------------------------------------------------- */
    CPLODBCStatement oGetKey( poSession );
    
    if( oGetKey.GetPrimaryKeys( pszTableName, poDS->GetCatalog(), pszSchemaName ) 
        && oGetKey.Fetch() )
    {
        pszFIDColumn = CPLStrdup(oGetKey.GetColData( 3 ));
        
        if( oGetKey.Fetch() ) // more than one field in key! 
        {
            CPLFree( pszFIDColumn );
            pszFIDColumn = NULL;

            CPLDebug( "OGR_MSSQLSpatial", "Table %s has multiple primary key fields, "
                      "ignoring them all.", pszTableName );
        }
    }

/* -------------------------------------------------------------------- */
/*      Have we been provided a geometry column?                        */
/* -------------------------------------------------------------------- */
    CPLFree( pszGeomColumn );
    if( pszGeomCol == NULL )
        pszGeomColumn = NULL;
    else
        pszGeomColumn = CPLStrdup( pszGeomCol );

/* -------------------------------------------------------------------- */
/*      Get the column definitions for this table.                      */
/* -------------------------------------------------------------------- */
    CPLODBCStatement oGetCol( poSession );
    CPLErr eErr;

    if( !oGetCol.GetColumns( pszTableName, poDS->GetCatalog(), pszSchemaName ) )
        return CE_Failure;

    eErr = BuildFeatureDefn( pszLayerName, &oGetCol );
    if( eErr != CE_None )
        return eErr;
        
    poFeatureDefn->SetGeomType(eType);

    if( poFeatureDefn->GetFieldCount() == 0 &&
        pszFIDColumn == NULL && pszGeomColumn == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "No column definitions found for table '%s', layer not usable.", 
                  pszLayerName );
        return CE_Failure;
    }
        
/* -------------------------------------------------------------------- */
/*      If we got a geometry column, does it exist?  Is it binary?      */
/* -------------------------------------------------------------------- */
    if( pszGeomColumn != NULL )
    {
        int iColumn = oGetCol.GetColId( pszGeomColumn );
        if( iColumn < 0 )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "Column %s requested for geometry, but it does not exist.", 
                      pszGeomColumn );
            CPLFree( pszGeomColumn );
            pszGeomColumn = NULL;
        }
        else
        {
            if ( nGeomColumnType < 0 )
            {
                /* last attempt to identify the geometry column type */
                if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "geometry") )
                    nGeomColumnType = MSSQLCOLTYPE_GEOMETRY;
                else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "geography") )
                    nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY;
                else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "varchar") )
                    nGeomColumnType = MSSQLCOLTYPE_TEXT;
                else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "nvarchar") )
                    nGeomColumnType = MSSQLCOLTYPE_TEXT;
                else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "text") )
                    nGeomColumnType = MSSQLCOLTYPE_TEXT;
                else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "ntext") )
                    nGeomColumnType = MSSQLCOLTYPE_TEXT;
                else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "image") )
                    nGeomColumnType = MSSQLCOLTYPE_BINARY; 
                else
                {
                    CPLError( CE_Failure, CPLE_AppDefined, 
                          "Column type %s is not supported for geometry column.", 
                          oGetCol.GetColTypeName( iColumn ) );
                    CPLFree( pszGeomColumn );
                    pszGeomColumn = NULL;
                }
            }
        }
    }

/* -------------------------------------------------------------------- */
/*             Try to find out the spatial reference                    */
/* -------------------------------------------------------------------- */
    
    nSRSId = nSRId;

    if (nSRSId < 0)
        nSRSId = FetchSRSId();

    GetSpatialRef();

    return CE_None;
}
Esempio n. 5
0
GvData *gv_shapes_from_ogr_layer(void *ogr_layer)
{
    CPLDebug( "OpenEV", "gv_shapes_from_ogr_layer() called, "
              "but OGR not configured" );
    return NULL;
}
size_t VSICurlStreamingHandle::Read( void *pBuffer, size_t nSize, size_t nMemb )
{
    GByte* pabyBuffer = (GByte*)pBuffer;
    size_t nBufferRequestSize = nSize * nMemb;
    if (nBufferRequestSize == 0)
        return 0;
    size_t nRemaining = nBufferRequestSize;

    AcquireMutex();
    int bHastComputedFileSizeLocal = bHastComputedFileSize;
    vsi_l_offset fileSizeLocal = fileSize;
    ReleaseMutex();

    if (bHastComputedFileSizeLocal && curOffset >= fileSizeLocal)
    {
        CPLDebug("VSICURL", "Read attempt beyond end of file");
        bEOF = TRUE;
    }
    if (bEOF)
        return 0;

    if (curOffset < nRingBufferFileOffset)
        PutRingBufferInCache();

    if (ENABLE_DEBUG)
        CPLDebug("VSICURL", "Read [" CPL_FRMT_GUIB ", " CPL_FRMT_GUIB "[ in %s",
                 curOffset, curOffset + nBufferRequestSize, pszURL);

#ifdef notdef
    if( pCachedData != NULL && nCachedSize >= 1024 &&
        nRecomputedChecksumOfFirst1024Bytes == 0 )
    {
        for(size_t i = 0; i < 1024 / sizeof(int); i ++)
        {
            int nVal;
            memcpy(&nVal, pCachedData + i * sizeof(int), sizeof(int));
            nRecomputedChecksumOfFirst1024Bytes += nVal;
        }

        if( bHastComputedFileSizeLocal )
        {
            poFS->AcquireMutex();
            CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL);
            if( cachedFileProp->nChecksumOfFirst1024Bytes == 0 )
            {
                cachedFileProp->nChecksumOfFirst1024Bytes = nRecomputedChecksumOfFirst1024Bytes;
            }
            else if( nRecomputedChecksumOfFirst1024Bytes != cachedFileProp->nChecksumOfFirst1024Bytes )
            {
                CPLDebug("VSICURL", "Invalidating previously cached file size. First bytes of file have changed!");
                AcquireMutex();
                bHastComputedFileSize = FALSE;
                cachedFileProp->bHastComputedFileSize = FALSE;
                cachedFileProp->nChecksumOfFirst1024Bytes = 0;
                ReleaseMutex();
            }
            poFS->ReleaseMutex();
        }
    }
#endif

    /* Can we use the cache ? */
    if( pCachedData != NULL && curOffset < nCachedSize )
    {
        size_t nSz = MIN(nRemaining, (size_t)(nCachedSize - curOffset));
        if (ENABLE_DEBUG)
            CPLDebug("VSICURL", "Using cache for [%d, %d[ in %s",
                     (int)curOffset, (int)(curOffset + nSz), pszURL);
        memcpy(pabyBuffer, pCachedData + curOffset, nSz);
        pabyBuffer += nSz;
        curOffset += nSz;
        nRemaining -= nSz;
    }

    /* Is the request partially covered by the cache and going beyond file size ? */
    if ( pCachedData != NULL && bHastComputedFileSizeLocal &&
         curOffset <= nCachedSize &&
         curOffset + nRemaining > fileSizeLocal &&
         fileSize == nCachedSize )
    {
        size_t nSz = (size_t) (nCachedSize - curOffset);
        if (ENABLE_DEBUG && nSz != 0)
            CPLDebug("VSICURL", "Using cache for [%d, %d[ in %s",
                    (int)curOffset, (int)(curOffset + nSz), pszURL);
        memcpy(pabyBuffer, pCachedData + curOffset, nSz);
        pabyBuffer += nSz;
        curOffset += nSz;
        nRemaining -= nSz;
        bEOF = TRUE;
    }

    /* Has a Seek() being done since the last Read() ? */
    if (!bEOF && nRemaining > 0 && curOffset != nRingBufferFileOffset)
    {
        /* Backward seek : we need to restart the download from the start */
        if (curOffset < nRingBufferFileOffset)
            StopDownload();

        StartDownload();

#define SKIP_BUFFER_SIZE    32768
        GByte* pabyTmp = (GByte*)CPLMalloc(SKIP_BUFFER_SIZE);

        CPLAssert(curOffset >= nRingBufferFileOffset);
        vsi_l_offset nBytesToSkip = curOffset - nRingBufferFileOffset;
        while(nBytesToSkip > 0)
        {
            vsi_l_offset nBytesToRead = nBytesToSkip;

            AcquireMutex();
            if (nBytesToRead > oRingBuffer.GetSize())
                nBytesToRead = oRingBuffer.GetSize();
            if (nBytesToRead > SKIP_BUFFER_SIZE)
                nBytesToRead = SKIP_BUFFER_SIZE;
            oRingBuffer.Read(pabyTmp, (size_t)nBytesToRead);

            /* Signal to the producer that we have ingested some bytes */
            CPLCondSignal(hCondConsumer);
            ReleaseMutex();

            if (nBytesToRead)
                AddRegion(nRingBufferFileOffset, (size_t)nBytesToRead, pabyTmp);

            nBytesToSkip -= nBytesToRead;
            nRingBufferFileOffset += nBytesToRead;

            if (nBytesToRead == 0 && nBytesToSkip != 0)
            {
                if (ENABLE_DEBUG)
                    CPLDebug("VSICURL", "Waiting for writer to produce some bytes...");

                AcquireMutex();
                while(oRingBuffer.GetSize() == 0 && bDownloadInProgress)
                    CPLCondWait(hCondProducer, hRingBufferMutex);
                int bBufferEmpty = (oRingBuffer.GetSize() == 0);
                ReleaseMutex();

                if (bBufferEmpty && !bDownloadInProgress)
                    break;
            }
        }

        CPLFree(pabyTmp);

        if (nBytesToSkip != 0)
        {
            bEOF = TRUE;
            return 0;
        }
    }

    if (!bEOF && nRemaining > 0)
    {
        StartDownload();
        CPLAssert(curOffset == nRingBufferFileOffset);
    }

    /* Fill the destination buffer from the ring buffer */
    while(!bEOF && nRemaining > 0)
    {
        AcquireMutex();
        size_t nToRead = oRingBuffer.GetSize();
        if (nToRead > nRemaining)
            nToRead = nRemaining;
        oRingBuffer.Read(pabyBuffer, nToRead);

        /* Signal to the producer that we have ingested some bytes */
        CPLCondSignal(hCondConsumer);
        ReleaseMutex();

        if (nToRead)
            AddRegion(curOffset, nToRead, pabyBuffer);

        nRemaining -= nToRead;
        pabyBuffer += nToRead;
        curOffset += nToRead;
        nRingBufferFileOffset += nToRead;

        if (nToRead == 0 && nRemaining != 0)
        {
            if (ENABLE_DEBUG)
                CPLDebug("VSICURL", "Waiting for writer to produce some bytes...");

            AcquireMutex();
            while(oRingBuffer.GetSize() == 0 && bDownloadInProgress)
                CPLCondWait(hCondProducer, hRingBufferMutex);
            int bBufferEmpty = (oRingBuffer.GetSize() == 0);
            ReleaseMutex();

            if (bBufferEmpty && !bDownloadInProgress)
                break;
        }
    }

    if (ENABLE_DEBUG)
        CPLDebug("VSICURL", "Read(%d) = %d",
                (int)nBufferRequestSize, (int)(nBufferRequestSize - nRemaining));
    size_t nRet = (nBufferRequestSize - nRemaining) / nSize;
    if (nRet < nMemb)
        bEOF = TRUE;

    return nRet;
}
int VSICurlStreamingHandle::ReceivedBytes(GByte *buffer, size_t count, size_t nmemb)
{
    size_t nSize = count * nmemb;
    nBodySize += nSize;

    if (ENABLE_DEBUG)
        CPLDebug("VSICURL", "Receiving %d bytes...", (int)nSize);

    if( bHasCandidateFileSize && bCanTrustCandidateFileSize && !bHastComputedFileSize )
    {
        poFS->AcquireMutex();
        CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL);
        cachedFileProp->fileSize = fileSize = nCandidateFileSize;
        cachedFileProp->bHastComputedFileSize = bHastComputedFileSize = TRUE;
        if (ENABLE_DEBUG)
            CPLDebug("VSICURL", "File size = " CPL_FRMT_GUIB, fileSize);
        poFS->ReleaseMutex();
    }

    AcquireMutex();
    if (eExists == EXIST_UNKNOWN)
    {
        poFS->AcquireMutex();
        CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL);
        cachedFileProp->eExists = eExists = EXIST_YES;
        poFS->ReleaseMutex();
    }
    else if (eExists == EXIST_NO)
    {
        ReleaseMutex();
        return 0;
    }

    while(TRUE)
    {
        size_t nFree = oRingBuffer.GetCapacity() - oRingBuffer.GetSize();
        if (nSize <= nFree)
        {
            oRingBuffer.Write(buffer, nSize);

            /* Signal to the consumer that we have added bytes to the buffer */
            CPLCondSignal(hCondProducer);

            if (bAskDownloadEnd)
            {
                if (ENABLE_DEBUG)
                    CPLDebug("VSICURL", "Download interruption asked");

                ReleaseMutex();
                return 0;
            }
            break;
        }
        else
        {
            oRingBuffer.Write(buffer, nFree);
            buffer += nFree;
            nSize -= nFree;

            /* Signal to the consumer that we have added bytes to the buffer */
            CPLCondSignal(hCondProducer);

            if (ENABLE_DEBUG)
                CPLDebug("VSICURL", "Waiting for reader to consume some bytes...");

            while(oRingBuffer.GetSize() == oRingBuffer.GetCapacity() && !bAskDownloadEnd)
            {
                CPLCondWait(hCondConsumer, hRingBufferMutex);
            }

            if (bAskDownloadEnd)
            {
                if (ENABLE_DEBUG)
                    CPLDebug("VSICURL", "Download interruption asked");

                ReleaseMutex();
                return 0;
            }
        }
    }

    ReleaseMutex();

    return nmemb;
}
Esempio n. 8
0
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Does this look like a CUBE dataset?                             */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->pabyHeader == NULL
        || strstr((const char *)poOpenInfo->pabyHeader,"^QUBE") == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open the file using the large file API.                         */
/* -------------------------------------------------------------------- */
    FILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( fpQube == NULL )
        return NULL;

    ISIS2Dataset 	*poDS;

    poDS = new ISIS2Dataset();

    if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
    {
        VSIFCloseL( fpQube );
        delete poDS;
        return NULL;
    }
    
    VSIFCloseL( fpQube );

/* -------------------------------------------------------------------- */
/*	We assume the user is pointing to the label (ie. .lab) file.  	*/
/* -------------------------------------------------------------------- */
    // QUBE can be inline or detached and point to an image name
    // ^QUBE = 76
    // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image
    // ^QUBE = "ui31s015.img" - which implies no label or skip value

    const char *pszQube = poDS->GetKeyword( "^QUBE" );
    int nQube = atoi(pszQube);

    if( pszQube[0] == '"' || pszQube[0] == '(' )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "ISIS2 driver does not support detached images." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check if file an ISIS2 header file?  Read a few lines of text   */
/*      searching for something starting with nrows or ncols.           */
/* -------------------------------------------------------------------- */
    GDALDataType eDataType = GDT_Byte;
    OGRSpatialReference oSRS;

    //image parameters
    int	nRows, nCols, nBands = 1;
    int nSkipBytes = 0;
    int itype;
    int  s_ix, s_iy, s_iz; // check SUFFIX_ITEMS params.
    int record_bytes;
    int	bNoDataSet = FALSE;
    char chByteOrder = 'M';  //default to MSB
 
    //Georef parameters
    double dfULXMap=0.5;
    double dfULYMap = 0.5;
    double dfXDim = 1.0;
    double dfYDim = 1.0;
    double dfNoData = 0.0;
    double xulcenter = 0.0;
    double yulcenter = 0.0;

    //projection parameters
    int	bProjectionSet = TRUE;
    double semi_major = 0.0;
    double semi_minor = 0.0;
    double iflattening = 0.0;
    float center_lat = 0.0;
    float center_lon = 0.0;
    float first_std_parallel = 0.0;
    float second_std_parallel = 0.0;
    FILE	*fp;

    /* -------------------------------------------------------------------- */
    /*      Checks to see if this is valid ISIS2 cube                       */
    /*      SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes  */
    /* -------------------------------------------------------------------- */
    s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 ));
    s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 ));
    s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 ));
     
    if( s_ix != 0 || s_iy != 0 || s_iz != 0 ) 
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n"
                  "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n"
                  "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz );
        return NULL;
    } 

    /**************** end SUFFIX_ITEM check ***********************/
    
    
    /***********   Grab layout type (BSQ, BIP, BIL) ************/
    //  AXIS_NAME = (SAMPLE,LINE,BAND)
    /***********************************************************/
    const char *value;

    char szLayout[10] = "BSQ"; //default to band seq.
    value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" );
    if (EQUAL(value,"(SAMPLE,LINE,BAND)") )
        strcpy(szLayout,"BSQ");
    else if (EQUAL(value,"(BAND,LINE,SAMPLE)") )
        strcpy(szLayout,"BIP");
    else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") )
        strcpy(szLayout,"BSQ");
    else {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s layout not supported. Abort\n\n", value);
        return NULL;
    }

    /***********   Grab samples lines band ************/
    nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1));
    nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2));
    nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3));
    
    /***********   Grab Qube record bytes  **********/
    record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES"));

    if (nQube > 0)
        nSkipBytes = (nQube - 1) * record_bytes;     
    else
        nSkipBytes = 0;     
     
    /********   Grab format type - isis2 only supports 8,16,32 *******/
    itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES",""));
    switch(itype) {
      case 1 :
        eDataType = GDT_Byte;
        dfNoData = NULL1;
        bNoDataSet = TRUE;
        break;
      case 2 :
        eDataType = GDT_Int16;
        dfNoData = NULL2;
        bNoDataSet = TRUE;
        break;
      case 4 :
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        bNoDataSet = TRUE;
        break;
      default :
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Itype of %d is not supported in ISIS 2.",
                  itype); 
        delete poDS;
        return NULL;
    }

    /***********   Grab samples lines band ************/
    value = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" );
    if( (EQUAL(value,"PC_INTEGER")) || 
        (EQUAL(value,"PC_UNSIGNED_INTEGER")) || 
        (EQUAL(value,"PC_REAL")) ) {
        chByteOrder = 'I';
    }
    
    /***********   Grab Cellsize ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE");
    if (strlen(value) > 0 ) {
        dfXDim = (float) atof(value) * 1000.0; /* convert from km to m */
        dfYDim = (float) atof(value) * 1000.0 * -1;
    }
    
    /***********   Grab LINE_PROJECTION_OFFSET ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET");
    if (strlen(value) > 0) {
        yulcenter = (float) atof(value);
        yulcenter = ((yulcenter) * dfYDim);
        dfULYMap = yulcenter - (dfYDim/2);
    }
     
    /***********   Grab SAMPLE_PROJECTION_OFFSET ************/
    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET");
    if( strlen(value) > 0 ) {
        xulcenter = (float) atof(value);
        xulcenter = ((xulcenter) * dfXDim);
        dfULXMap = xulcenter - (dfXDim/2);
    }
     
    /***********  Grab TARGET_NAME  ************/
    /**** This is the planets name i.e. MARS ***/
    CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME");
     
    /***********   Grab MAP_PROJECTION_TYPE ************/
    CPLString map_proj_name = 
        poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE");
    poDS->CleanString( map_proj_name );

    /***********   Grab SEMI-MAJOR ************/
    semi_major = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0;

    /***********   Grab semi-minor ************/
    semi_minor = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0;

    /***********   Grab CENTER_LAT ************/
    center_lat = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE"));

    /***********   Grab CENTER_LON ************/
    center_lon = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE"));

    /***********   Grab 1st std parallel ************/
    first_std_parallel = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL"));

    /***********   Grab 2nd std parallel ************/
    second_std_parallel = 
        atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL"));
     
    /*** grab  PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/
    // Need to further study how ocentric/ographic will effect the gdal library.
    // So far we will use this fact to define a sphere or ellipse for some projections
    // Frank - may need to talk this over
    char bIsGeographic = TRUE;
    value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE");
    if (EQUAL( value, "\"PLANETOCENTRIC\"" ))
        bIsGeographic = FALSE; 
     
    CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() );

    //Set oSRS projection and parameters
    if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
        (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ||
        (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) {
        oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
    } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { 
        oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
    } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) ||
               (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) {
        oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "MERCATOR" )) {
        oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) {
        oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) {
        oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) {
        oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
    } else {
        CPLDebug( "ISIS2",
                  "Dataset projection %s is not supported. Continuing...",
                  map_proj_name.c_str() );
        bProjectionSet = FALSE;
    }

    if (bProjectionSet) {
        //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
        CPLString proj_target_name = map_proj_name + " " + target_name;
        oSRS.SetProjCS(proj_target_name); //set ProjCS keyword
     
        //The geographic/geocentric name will be the same basic name as the body name
        //'GCS' = Geographic/Geocentric Coordinate System
        CPLString geog_name = "GCS_" + target_name;
        
        //The datum and sphere names will be the same basic name aas the planet
        CPLString datum_name = "D_" + target_name;
        CPLString sphere_name = target_name; // + "_IAU_IAG");  //Might not be IAU defined so don't add
          
        //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
        if ((semi_major - semi_minor) < 0.0000001) 
            iflattening = 0;
        else
            iflattening = semi_major / (semi_major - semi_minor);
     
        //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
        //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
        if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || 
             (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )))  
        {
            if (bIsGeographic) { 
                //Geograpraphic, so set an ellipse
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere using the semi-minor axis. I hope... 
                sphere_name += "_polarRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_minor, 0.0, 
                                "Reference_Meridian", 0.0 );
            }
        }
        else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || 
                  (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "STEREOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL" ))  ) {
            //isis uses the sphereical equation for these projections so force a sphere
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0, 
                            "Reference_Meridian", 0.0 );
        } 
        else if  ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || 
                  (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) {
            //Calculate localRadius using ISIS3 simple elliptical method 
            //  not the more standard Radius of Curvature method
            //PI = 4 * atan(1);
            double radLat, localRadius;
            if (center_lon == 0) { //No need to calculate local radius
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0, 
                                "Reference_Meridian", 0.0 );
            } else {  
                radLat = center_lat * PI / 180;  // in radians
                localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2)
                                                             + pow(semi_major*sin(radLat),2) );
                sphere_name += "_localRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                localRadius, 0.0, 
                                "Reference_Meridian", 0.0 );
                CPLDebug( "ISIS2", "local radius: %f", localRadius);
            }
        } 
        else { 
            //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
            //Geographic, so set an ellipse
            if (bIsGeographic) {
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                                "Reference_Meridian", 0.0 );
            } else { 
                //Geocentric, so force a sphere. I hope... 
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0, 
                                "Reference_Meridian", 0.0 );
            }
        }
        

        // translate back into a projection string.
        char *pszResult = NULL;
        oSRS.exportToWkt( &pszResult );
        poDS->osProjection = pszResult;
        CPLFree( pszResult );
    }

/* END ISIS2 Label Read */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    
/* -------------------------------------------------------------------- */
/*      Did we get the required keywords?  If not we return with        */
/*      this never having been considered to be a match. This isn't     */
/*      an error!                                                       */
/* -------------------------------------------------------------------- */
    if( nRows < 1 || nCols < 1 || nBands < 1 )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */
    
    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    else
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to open %s with write permission.\n%s", 
                  poOpenInfo->pszFilename, VSIStrerror( errno ) );
        delete poDS;
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Compute the line offset.                                        */
/* -------------------------------------------------------------------- */
    int     nItemSize = GDALGetDataTypeSize(eDataType)/8;
    int		nLineOffset, nPixelOffset, nBandOffset;
    
    if( EQUAL(szLayout,"BIP") )
    {
        nPixelOffset = nItemSize * nBands;
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nItemSize;
    }
    else if( EQUAL(szLayout,"BSQ") )
    {
        nPixelOffset = nItemSize;
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nLineOffset * nRows;
    }
    else /* assume BIL */
    {
        nPixelOffset = nItemSize;
        nLineOffset = nItemSize * nBands * nCols;
        nBandOffset = nItemSize * nCols;
    }
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int i;

    poDS->nBands = nBands;;
    for( i = 0; i < poDS->nBands; i++ )
    {
        RawRasterBand	*poBand;

        poBand = 
            new RawRasterBand( poDS, i+1, poDS->fpImage,
                               nSkipBytes + nBandOffset * i, 
                               nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB                               
                               chByteOrder == 'I' || chByteOrder == 'L',
#else
                               chByteOrder == 'M',
#endif        
                               TRUE );

        if( bNoDataSet )
            poBand->SetNoDataValue( dfNoData );

        poDS->SetBand( i+1, poBand );

        // Set offset/scale values at the PAM level.
        poBand->SetOffset( 
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0")));
        poBand->SetScale( 
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0")));
    }

/* -------------------------------------------------------------------- */
/*      Check for a .prj file. For isis2 I would like to keep this in   */
/* -------------------------------------------------------------------- */
    CPLString osPath, osName;

    osPath = CPLGetPath( poOpenInfo->pszFilename );
    osName = CPLGetBasename(poOpenInfo->pszFilename);
    const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );

    fp = VSIFOpen( pszPrjFile, "r" );
    if( fp != NULL )
    {
        char	**papszLines;
        OGRSpatialReference oSRS;

        VSIFClose( fp );
        
        papszLines = CSLLoad( pszPrjFile );

        if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE )
        {
            char *pszResult = NULL;
            oSRS.exportToWkt( &pszResult );
            poDS->osProjection = pszResult;
            CPLFree( pszResult );
        }

        CSLDestroy( papszLines );
    }

    
    if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfULXMap;
        poDS->adfGeoTransform[1] = dfXDim;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfULYMap;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = dfYDim;
    }
    
    if( !poDS->bGotTransform )
        poDS->bGotTransform = 
            GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", 
                               poDS->adfGeoTransform );

    if( !poDS->bGotTransform )
        poDS->bGotTransform = 
            GDALReadWorldFile( poOpenInfo->pszFilename, "wld", 
                               poDS->adfGeoTransform );

/* -------------------------------------------------------------------- */ 
/*      Initialize any PAM information.                                 */ 
/* -------------------------------------------------------------------- */ 
    poDS->SetDescription( poOpenInfo->pszFilename ); 
    poDS->TryLoadXML(); 

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
Esempio n. 9
0
int OGRSVGDataSource::Open( const char * pszFilename )

{
#ifdef HAVE_EXPAT
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Try to open the file.                                           */
/* -------------------------------------------------------------------- */
    CPLString osFilename(pszFilename);
    if (EQUAL(CPLGetExtension(pszFilename), "svgz") &&
        strstr(pszFilename, "/vsigzip/") == NULL)
    {
        osFilename = CPLString("/vsigzip/") + pszFilename;
        pszFilename = osFilename.c_str();
    }

    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp == NULL)
        return FALSE;
    
    eValidity = SVG_VALIDITY_UNKNOWN;

    XML_Parser oParser = OGRCreateExpatXMLParser();
    oCurrentParser = oParser;
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
    
    char aBuf[BUFSIZ];
    int nDone;
    unsigned int nLen;
    int nCount = 0;
    
    /* Begin to parse the file and look for the <svg> element */
    /* It *MUST* be the first element of an XML file */
    /* So once we have read the first element, we know if we can */
    /* handle the file or not with that driver */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && strstr(aBuf, "<svg"))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of SVG file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }
            eValidity = SVG_VALIDITY_INVALID;
            break;
        }
        if (eValidity == SVG_VALIDITY_INVALID)
        {
            break;
        }
        else if (eValidity == SVG_VALIDITY_VALID)
        {
            break;
        }
        else
        {
            /* After reading 50 * BUFSIZE bytes, and not finding whether the file */
            /* is SVG or not, we give up and fail silently */
            nCount ++;
            if (nCount == 50)
                break;
        }
    } while (!nDone && nLen > 0 );

    XML_ParserFree(oParser);

    VSIFCloseL(fp);

    if (eValidity == SVG_VALIDITY_VALID)
    {
        if (bIsCloudmade)
        {
            nLayers = 3;
            papoLayers =(OGRSVGLayer **) CPLRealloc(papoLayers,
                                            nLayers * sizeof(OGRSVGLayer*));
            papoLayers[0] = new OGRSVGLayer( pszFilename, "points", SVG_POINTS, this );
            papoLayers[1] = new OGRSVGLayer( pszFilename, "lines", SVG_LINES, this );
            papoLayers[2] = new OGRSVGLayer( pszFilename, "polygons", SVG_POLYGONS, this );
        }
        else
        {
            CPLDebug("SVG",
                     "%s seems to be a SVG file, but not a Cloudmade vector one.",
                     pszFilename);
        }
    }

    return (nLayers > 0);
#else
    char aBuf[256];
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp)
    {
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
        aBuf[nLen] = 0;
        if (strstr(aBuf, "<?xml") && strstr(aBuf, "<svg") &&
            strstr(aBuf, "http://cloudmade.com/"))
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/SVG driver has not been built with read support. "
                    "Expat library required");
        }
        VSIFCloseL(fp);
    }
    return FALSE;
#endif
}
Esempio n. 10
0
OGRErr OGRDXFLayer::CollectBoundaryPath( OGRGeometryCollection *poGC )

{
    int  nCode;
    char szLineBuf[257];

/* -------------------------------------------------------------------- */
/*      Read the boundary path type.                                    */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 92 )
        return OGRERR_FAILURE;

    int  nBoundaryPathType = atoi(szLineBuf);

/* ==================================================================== */
/*      Handle polyline loops.                                          */
/* ==================================================================== */
    if( nBoundaryPathType & 0x02 )
        return CollectPolylinePath( poGC );

/* ==================================================================== */
/*      Handle non-polyline loops.                                      */
/* ==================================================================== */

/* -------------------------------------------------------------------- */
/*      Read number of edges.                                           */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 93 )
        return OGRERR_FAILURE;

    int nEdgeCount = atoi(szLineBuf);
    
/* -------------------------------------------------------------------- */
/*      Loop reading edges.                                             */
/* -------------------------------------------------------------------- */
    int iEdge;

    for( iEdge = 0; iEdge < nEdgeCount; iEdge++ )
    {
/* -------------------------------------------------------------------- */
/*      Read the edge type.                                             */
/* -------------------------------------------------------------------- */
#define ET_LINE         1
#define ET_CIRCULAR_ARC 2
#define ET_ELLIPTIC_ARC 3
#define ET_SPLINE       4

        nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
        if( nCode != 72 )
            return OGRERR_FAILURE;

        int nEdgeType = atoi(szLineBuf);
        
/* -------------------------------------------------------------------- */
/*      Process a line edge.                                            */
/* -------------------------------------------------------------------- */
        if( nEdgeType == ET_LINE )
        {
            double dfStartX;
            double dfStartY;
            double dfEndX;
            double dfEndY;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 10 )
                dfStartX = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 20 )
                dfStartY = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 11 )
                dfEndX = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 21 )
                dfEndY = atof(szLineBuf);
            else
                break;

            OGRLineString *poLS = new OGRLineString();

            poLS->addPoint( dfStartX, dfStartY );
            poLS->addPoint( dfEndX, dfEndY );

            poGC->addGeometryDirectly( poLS );
        }
/* -------------------------------------------------------------------- */
/*      Process a circular arc.                                         */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_CIRCULAR_ARC )
        {
            double dfCenterX;
            double dfCenterY;
            double dfRadius;
            double dfStartAngle;
            double dfEndAngle;
            int    bCounterClockwise = FALSE;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 10 )
                dfCenterX = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 20 )
                dfCenterY = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 40 )
                dfRadius = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 50 )
                dfStartAngle = -1 * atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 51 )
                dfEndAngle = -1 * atof(szLineBuf);
            else
                break;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 73 )
                bCounterClockwise = atoi(szLineBuf);
            else if (nCode >= 0)
                poDS->UnreadValue();

            if( bCounterClockwise )
            {
                double dfTemp = dfStartAngle;
                dfStartAngle = dfEndAngle;
                dfEndAngle = dfTemp;
            }

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;

            OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles( 
                dfCenterX, dfCenterY, 0.0,
                dfRadius, dfRadius, 0.0,
                dfStartAngle, dfEndAngle, 0.0 );

            poArc->flattenTo2D();

            poGC->addGeometryDirectly( poArc );
        }

/* -------------------------------------------------------------------- */
/*      Process an elliptical arc.                                      */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_ELLIPTIC_ARC )
        {
            double dfCenterX;
            double dfCenterY;
            double dfMajorRadius, dfMinorRadius;
            double dfMajorX, dfMajorY;
            double dfStartAngle;
            double dfEndAngle;
            double dfRotation;
            double dfRatio;
            int    bCounterClockwise = FALSE;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 10 )
                dfCenterX = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 20 )
                dfCenterY = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 11 )
                dfMajorX = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 21 )
                dfMajorY = atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 40 )
                dfRatio = atof(szLineBuf) / 100.0;
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 50 )
                dfStartAngle = -1 * atof(szLineBuf);
            else
                break;

            if( poDS->ReadValue(szLineBuf,sizeof(szLineBuf)) == 51 )
                dfEndAngle = -1 * atof(szLineBuf);
            else
                break;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 73 )
                bCounterClockwise = atoi(szLineBuf);
            else if (nCode >= 0)
                poDS->UnreadValue();

            if( bCounterClockwise )
            {
                double dfTemp = dfStartAngle;
                dfStartAngle = dfEndAngle;
                dfEndAngle = dfTemp;
            }

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;

            dfMajorRadius = sqrt( dfMajorX * dfMajorX + dfMajorY * dfMajorY );
            dfMinorRadius = dfMajorRadius * dfRatio;

            dfRotation = -1 * atan2( dfMajorY, dfMajorX ) * 180 / PI;

            OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles( 
                dfCenterX, dfCenterY, 0.0,
                dfMajorRadius, dfMinorRadius, dfRotation,
                dfStartAngle, dfEndAngle, 0.0 );

            poArc->flattenTo2D();

            poGC->addGeometryDirectly( poArc );
        }
        else
        {
            CPLDebug( "DXF", "Unsupported HATCH boundary line type:%d",
                      nEdgeType );
            return OGRERR_UNSUPPORTED_OPERATION;
        }
    }

/* -------------------------------------------------------------------- */
/*      Skip through source boundary objects if present.                */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 97 )
    {
        if (nCode < 0)
            return OGRERR_FAILURE;
        poDS->UnreadValue();
    }
    else
    {
        int iObj, nObjCount = atoi(szLineBuf);

        for( iObj = 0; iObj < nObjCount; iObj++ )
        {
            if (poDS->ReadValue( szLineBuf, sizeof(szLineBuf) ) < 0)
                return OGRERR_FAILURE;
        }
    }

    return OGRERR_NONE;
}
Esempio n. 11
0
static GDALDataset *OGRSEGYDriverOpen( GDALOpenInfo* poOpenInfo )
{
    if( poOpenInfo->eAccess == GA_Update ||
        poOpenInfo->fpL == NULL ||
        !poOpenInfo->TryToIngest(3200+400) ||
        poOpenInfo->nHeaderBytes < 3200+400 )
    {
        return NULL;
    }
    if( STARTS_WITH_CI((const char*)poOpenInfo->pabyHeader, "%PDF"))
    {
        return NULL;
    }

// --------------------------------------------------------------------
//      Try to decode the header encoded as EBCDIC and then ASCII
// --------------------------------------------------------------------

    int i, j, k;
    const GByte* pabyTextHeader = poOpenInfo->pabyHeader;
    GByte* pabyASCIITextHeader = (GByte*) CPLMalloc(3200 + 40 + 1);
    for( k=0; k<2; k++)
    {
        for( i=0, j=0;i<3200;i++)
        {
            GByte chASCII = (k == 0) ? EBCDICToASCII[pabyTextHeader[i]] :
                                       pabyTextHeader[i];
            if (chASCII < 32 && chASCII != '\t' &&
                chASCII != '\n' && chASCII != '\r')
            {
                break;
            }
            pabyASCIITextHeader[j++] = chASCII;
            if (chASCII != '\n' && ((i + 1) % 80) == 0)
                pabyASCIITextHeader[j++] = '\n';
        }
        pabyASCIITextHeader[j] = '\0';

        if (i == 3200)
            break;
        if (k == 1)
        {
            CPLFree(pabyASCIITextHeader);
            return NULL;
        }
    }

    CPLDebug("SIGY", "Header = \n%s", pabyASCIITextHeader);
    CPLFree(pabyASCIITextHeader);
    pabyASCIITextHeader = NULL;

// --------------------------------------------------------------------
//      Read the next 400 bytes, where the Binary File Header is
//      located
// --------------------------------------------------------------------

    const GByte* abyFileHeader = poOpenInfo->pabyHeader + 3200;

// --------------------------------------------------------------------
//      First check that this binary header is not EBCDIC nor ASCII
// --------------------------------------------------------------------
    for( k=0;k<2;k++ )
    {
        for( i=0;i<400;i++)
        {
            GByte chASCII = (k == 0) ? abyFileHeader[i] :
                                       EBCDICToASCII[abyFileHeader[i]];
            /* A translated 0 value, when source value is not 0, means an invalid */
            /* EBCDIC value. Bail out also for control characters */
            if (chASCII < 32 && chASCII != '\t' &&
                chASCII != '\n' && chASCII != '\r')
            {
                break;
            }
        }
        if (i == 400)
        {
            CPLFree(pabyASCIITextHeader);
            return NULL;
        }
    }

    OGRSEGYDataSource   *poDS = new OGRSEGYDataSource();

    if( !poDS->Open( poOpenInfo->pszFilename, (const char*)pabyASCIITextHeader ) )
    {
        CPLFree(pabyASCIITextHeader);
        delete poDS;
        poDS = NULL;
    }

    CPLFree(pabyASCIITextHeader);
    return poDS;
}
Esempio n. 12
0
json_object* OGRCARTODBDataSource::RunSQL(const char* pszUnescapedSQL)
{
    CPLString osSQL("POSTFIELDS=q=");
    /* Do post escaping */
    for(int i=0;pszUnescapedSQL[i] != 0;i++)
    {
        const int ch = ((unsigned char*)pszUnescapedSQL)[i];
        if (ch != '&' && ch >= 32 && ch < 128)
            osSQL += (char)ch;
        else
            osSQL += CPLSPrintf("%%%02X", ch);
    }

/* -------------------------------------------------------------------- */
/*      Provide the API Key                                             */
/* -------------------------------------------------------------------- */
    if( osAPIKey.size() )
    {
        osSQL += "&api_key=";
        osSQL += osAPIKey;
    }

/* -------------------------------------------------------------------- */
/*      Collection the header options and execute request.              */
/* -------------------------------------------------------------------- */
    const char* pszAPIURL = GetAPIURL();
    char** papszOptions = CSLAddString(
        strncmp(pszAPIURL, "/vsimem/", strlen("/vsimem/")) != 0 ? AddHTTPOptions(): NULL, osSQL);
    CPLHTTPResult * psResult = CPLHTTPFetch( GetAPIURL(), papszOptions);
    CSLDestroy(papszOptions);

/* -------------------------------------------------------------------- */
/*      Check for some error conditions and report.  HTML Messages      */
/*      are transformed info failure.                                   */
/* -------------------------------------------------------------------- */
    if (psResult && psResult->pszContentType &&
        strncmp(psResult->pszContentType, "text/html", 9) == 0)
    {
        CPLDebug( "CARTODB", "RunSQL HTML Response:%s", psResult->pabyData );
        CPLError(CE_Failure, CPLE_AppDefined, 
                 "HTML error page returned by server");
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }
    if (psResult && psResult->pszErrBuf != NULL) 
    {
        CPLDebug( "CARTODB", "RunSQL Error Message:%s", psResult->pszErrBuf );
    }
    else if (psResult && psResult->nStatus != 0) 
    {
        CPLDebug( "CARTODB", "RunSQL Error Status:%d", psResult->nStatus );
    }

    if( psResult->pabyData == NULL )
    {
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }
    
    if( strlen((const char*)psResult->pabyData) < 1000 )
        CPLDebug( "CARTODB", "RunSQL Response:%s", psResult->pabyData );
    
    json_tokener* jstok = NULL;
    json_object* poObj = NULL;

    jstok = json_tokener_new();
    poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1);
    if( jstok->err != json_tokener_success)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                    "JSON parsing error: %s (at offset %d)",
                    json_tokener_error_desc(jstok->err), jstok->char_offset);
        json_tokener_free(jstok);
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }
    json_tokener_free(jstok);

    CPLHTTPDestroyResult(psResult);

    if( poObj != NULL )
    {
        if( json_object_get_type(poObj) == json_type_object )
        {
            json_object* poError = json_object_object_get(poObj, "error");
            if( poError != NULL && json_object_get_type(poError) == json_type_array &&
                json_object_array_length(poError) > 0 )
            {
                poError = json_object_array_get_idx(poError, 0);
                if( poError != NULL && json_object_get_type(poError) == json_type_string )
                {
                    CPLError(CE_Failure, CPLE_AppDefined, 
                            "Error returned by server : %s", json_object_get_string(poError));
                    json_object_put(poObj);
                    return NULL;
                }
            }
        }
        else
        {
            json_object_put(poObj);
            return NULL;
        }
    }

    return poObj;
}
Esempio n. 13
0
OGRBoolean OGRLinearRing::isPointInRing(const OGRPoint* poPoint, int bTestEnvelope) const
{
    if ( NULL == poPoint )
    {
        CPLDebug( "OGR", "OGRLinearRing::isPointInRing(const  OGRPoint* poPoint) - passed point is NULL!" );
        return 0;
    }

    const int iNumPoints = getNumPoints();

    // Simple validation
    if ( iNumPoints < 4 )
        return 0;

    const double dfTestX = poPoint->getX();
    const double dfTestY = poPoint->getY();

    // Fast test if point is inside extent of the ring
    if (bTestEnvelope)
    {
        OGREnvelope extent;
        getEnvelope(&extent);
        if ( !( dfTestX >= extent.MinX && dfTestX <= extent.MaxX
            && dfTestY >= extent.MinY && dfTestY <= extent.MaxY ) )
        {
            return 0;
        }
    }

	// For every point p in ring,
    // test if ray starting from given point crosses segment (p - 1, p)
    int iNumCrossings = 0;

    double prev_diff_x = getX(0) - dfTestX;
    double prev_diff_y = getY(0) - dfTestY;

    for ( int iPoint = 1; iPoint < iNumPoints; iPoint++ ) 
    {
        const double x1 = getX(iPoint) - dfTestX;
        const double y1 = getY(iPoint) - dfTestY;

        const double x2 = prev_diff_x;
        const double y2 = prev_diff_y;

        if( ( ( y1 > 0 ) && ( y2 <= 0 ) ) || ( ( y2 > 0 ) && ( y1 <= 0 ) ) )
        {
            // Check if ray intersects with segment of the ring
            const double dfIntersection = ( x1 * y2 - x2 * y1 ) / (y2 - y1);
            if ( 0.0 < dfIntersection )
            {
                // Count intersections
                iNumCrossings++;
            }
        }

        prev_diff_x = x1;
        prev_diff_y = y1;
    }

    // If iNumCrossings number is even, given point is outside the ring,
    // when the crossings number is odd, the point is inside the ring.
    return ( ( iNumCrossings % 2 ) == 1 ? 1 : 0 );
}
Esempio n. 14
0
void ILI1Reader::ReadGeom( char **stgeom, int geomIdx, OGRwkbGeometryType eType,
                           OGRFeature *feature ) {
#ifdef DEBUG_VERBOSE
    CPLDebug( "OGR_ILI",
              "ILI1Reader::ReadGeom geomIdx: %d OGRGeometryType: %s",
              geomIdx, OGRGeometryTypeToName(eType) );
#endif
    if (eType == wkbNone)
    {
      CPLError( CE_Warning, CPLE_AppDefined,
                "Calling ILI1Reader::ReadGeom with wkbNone" );
    }

    // Initialize geometry.

    OGRCompoundCurve *ogrCurve = new OGRCompoundCurve();
    OGRCurvePolygon *ogrPoly = NULL; //current polygon
    OGRMultiCurve *ogrMultiLine = NULL; //current multi line

    if (eType == wkbMultiCurve || eType == wkbMultiLineString)
    {
      ogrMultiLine = new OGRMultiCurve();
    }
    else if (eType == wkbPolygon || eType == wkbCurvePolygon)
    {
      ogrPoly = new OGRCurvePolygon();
    }

    OGRPoint ogrPoint; // Current point.
    ogrPoint.setX(CPLAtof(stgeom[1])); ogrPoint.setY(CPLAtof(stgeom[2]));

    OGRLineString *ogrLine = new OGRLineString();
    ogrLine->addPoint(&ogrPoint);

    // Parse geometry.

    char **tokens = NULL;
    bool end = false;
    OGRCircularString *arc = NULL; //current arc

    while (!end && (tokens = ReadParseLine()) != NULL)
    {
      const char *firsttok = CSLGetField(tokens, 0);
      if (EQUAL(firsttok, "LIPT"))
      {
        ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2]));
        if (arc) {
          arc->addPoint(&ogrPoint);
          OGRErr error =  ogrCurve->addCurveDirectly(arc);
          if (error != OGRERR_NONE) {
            CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", arc->exportToJson() );
          }
          arc = NULL;
        }
        ogrLine->addPoint(&ogrPoint);
      }
      else if (EQUAL(firsttok, "ARCP"))
      {
        //Finish line and start arc
        if (ogrLine->getNumPoints() > 1) {
          OGRErr error = ogrCurve->addCurveDirectly(ogrLine);
          if (error != OGRERR_NONE) {
            CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", ogrLine->exportToJson() );
          }
          ogrLine = new OGRLineString();
        } else {
          ogrLine->empty();
        }
        arc = new OGRCircularString();
        arc->addPoint(&ogrPoint);
        ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2]));
        arc->addPoint(&ogrPoint);
      }
      else if (EQUAL(firsttok, "ELIN"))
      {
        if (ogrLine->getNumPoints() > 1) { // Ignore single LIPT after ARCP
          OGRErr error = ogrCurve->addCurveDirectly(ogrLine);
          if (error != OGRERR_NONE) {
            CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", ogrLine->exportToJson() );
          }
          ogrLine = NULL;
        }
        if (!ogrCurve->IsEmpty()) {
          if (ogrMultiLine)
          {
            OGRErr error = ogrMultiLine->addGeometryDirectly(ogrCurve);
            if (error != OGRERR_NONE) {
              CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", ogrCurve->exportToJson() );
            }
            ogrCurve = NULL;
          }
          if (ogrPoly)
          {
            OGRErr error = ogrPoly->addRingDirectly(ogrCurve);
            if (error != OGRERR_NONE) {
              CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", ogrCurve->exportToJson() );
            }
            ogrCurve = NULL;
          }
        }
        end = true;
      }
      else if (EQUAL(firsttok, "EEDG"))
      {
        end = true;
      }
      else if (EQUAL(firsttok, "LATT"))
      {
        //Line Attributes (ignored)
      }
      else if (EQUAL(firsttok, "EFLA"))
      {
        end = true;
      }
      else if (EQUAL(firsttok, "ETAB"))
      {
        end = true;
      }
      else
      {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unexpected token: %s", firsttok );
      }

      CSLDestroy(tokens);
    }

    delete ogrLine;

    //Set feature geometry
    if (eType == wkbMultiCurve)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine);
      delete ogrCurve;
    }
    else if (eType == wkbMultiLineString)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine->getLinearGeometry());
      delete ogrMultiLine;
      delete ogrCurve;
    }
    else if (eType == wkbCurvePolygon)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrPoly);
      delete ogrCurve;
    }
    else if (eType == wkbPolygon)
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrPoly->getLinearGeometry());
      delete ogrPoly;
      delete ogrCurve;
    }
    else
    {
      feature->SetGeomFieldDirectly(geomIdx, ogrCurve);
    }
}
Esempio n. 15
0
int OGRGeoRSSDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GeoRSS driver does not support opening a file in update mode");
        return FALSE;
    }
#ifdef HAVE_EXPAT
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Try to open the file.                                           */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp == NULL)
        return FALSE;
    
    validity = GEORSS_VALIDITY_UNKNOWN;
    
    XML_Parser oParser = OGRCreateExpatXMLParser();
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
    oCurrentParser = oParser;
    
    char aBuf[BUFSIZ];
    int nDone;
    unsigned int nLen;
    int nCount = 0;
    
    /* Begin to parse the file and look for the <rss> or <feed> element */
    /* It *MUST* be the first element of an XML file */
    /* So once we have read the first element, we know if we can */
    /* handle the file or not with that driver */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && (strstr(aBuf, "<rss") || strstr(aBuf, "<feed")))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of GeoRSS file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }
            validity = GEORSS_VALIDITY_INVALID;
            break;
        }
        if (validity == GEORSS_VALIDITY_INVALID)
        {
            break;
        }
        else if (validity == GEORSS_VALIDITY_VALID)
        {
            break;
        }
        else
        {
            /* After reading 50 * BUFSIZ bytes, and not finding whether the file */
            /* is GeoRSS or not, we give up and fail silently */
            nCount ++;
            if (nCount == 50)
                break;
        }
    } while (!nDone && nLen > 0 );
    
    XML_ParserFree(oParser);
    
    VSIFCloseL(fp);
    
    if (validity == GEORSS_VALIDITY_VALID)
    {
        CPLDebug("GeoRSS", "%s seems to be a GeoRSS file.", pszFilename);

        nLayers = 1;
        papoLayers = (OGRGeoRSSLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRGeoRSSLayer*));
        papoLayers[0] = new OGRGeoRSSLayer( pszName, "georss", this, NULL, FALSE );
    }

    return (validity == GEORSS_VALIDITY_VALID);
#else
    char aBuf[256];
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp)
    {
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
        aBuf[nLen] = 0;
        if (strstr(aBuf, "<?xml") && (strstr(aBuf, "<rss") || strstr(aBuf, "<feed")))
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GeoRSS driver has not been built with read support. Expat library required");
        }
        VSIFCloseL(fp);
    }
    return FALSE;
#endif
}
Esempio n. 16
0
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS )

{
    int            bGotSRS = FALSE;
    VSILFILE      *fp = NULL;
    GDALDataset	  *poGDALDS = NULL; 
    OGRLayer      *poLayer = NULL;
    const char    *pszProjection = NULL;
    CPLErrorHandler oErrorHandler = NULL;
    int bIsFile = FALSE;
    OGRErr eErr = OGRERR_NONE;
    int bDebug  = FALSE;

    /* temporarily suppress error messages we may get from xOpen() */
    bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF"));
    if ( ! bDebug )
        oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler );

    /* Test if argument is a file */
    fp = VSIFOpenL( pszInput, "r" );
    if ( fp )  {
        bIsFile = TRUE;
        VSIFCloseL( fp );
        CPLDebug( "gdalsrsinfo", "argument is a file" );
    } 
       
    /* try to open with GDAL */
    if( strncmp(pszInput, "http://spatialreference.org/",
                strlen("http://spatialreference.org/")) != 0 )
    {
        CPLDebug( "gdalsrsinfo", "trying to open with GDAL" );
        poGDALDS = (GDALDataset *) GDALOpenEx( pszInput, 0, NULL, NULL, NULL );
    }
    if ( poGDALDS != NULL ) {
        pszProjection = poGDALDS->GetProjectionRef( );
        if( pszProjection != NULL && pszProjection[0] != '\0' )
        {
            char* pszProjectionTmp = (char*) pszProjection;
            if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE ) {
                CPLDebug( "gdalsrsinfo", "got SRS from GDAL" );
                bGotSRS = TRUE;
            }
        }
        else if( poGDALDS->GetLayerCount() > 0 )
        {
            poLayer = poGDALDS->GetLayer( 0 );
            if ( poLayer != NULL ) {
                OGRSpatialReference *poSRS = poLayer->GetSpatialRef( );
                if ( poSRS != NULL ) {
                    CPLDebug( "gdalsrsinfo", "got SRS from OGR" );
                    bGotSRS = TRUE;
                    OGRSpatialReference* poSRSClone = poSRS->Clone();
                    oSRS = *poSRSClone;
                    OGRSpatialReference::DestroySpatialReference( poSRSClone );
                }
            }
        }
        GDALClose( (GDALDatasetH) poGDALDS );
        if ( ! bGotSRS ) 
            CPLDebug( "gdalsrsinfo", "did not open with GDAL" );
    }    
    
    /* Try ESRI file */
    if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from ESRI .prj file [%s]", pszInput );

        char **pszTemp;
        if ( strstr(pszInput,"ESRI::") != NULL )
            pszTemp = CSLLoad( pszInput+6 );
        else 
            pszTemp = CSLLoad( pszInput );

        if( pszTemp ) {
            eErr = oSRS.importFromESRI( pszTemp );
            CSLDestroy( pszTemp );
        }
        else 
            eErr = OGRERR_UNSUPPORTED_SRS;

        if( eErr != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" );
            bGotSRS = TRUE;
        }
    }

    /* Last resort, try OSRSetFromUserInput() */
    if ( ! bGotSRS ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from user input [%s]", pszInput );

        eErr = oSRS.SetFromUserInput( pszInput );
 
       if(  eErr != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from user input" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from user input" );
            bGotSRS = TRUE;
        }
    }
    
    /* restore error messages */
    if ( ! bDebug )
        CPLSetErrorHandler ( oErrorHandler );	


    return bGotSRS;
}
Esempio n. 17
0
int GDALJP2Box::ReadBox()

{
    GUInt32   nLBox;
    GUInt32   nTBox;

    nBoxOffset = VSIFTellL( fpVSIL );

    if( VSIFReadL( &nLBox, 4, 1, fpVSIL ) != 1
        || VSIFReadL( &nTBox, 4, 1, fpVSIL ) != 1 )
    {
        return FALSE;
    }

    memcpy( szBoxType, &nTBox, 4 );
    szBoxType[4] = '\0';

    nLBox = CPL_MSBWORD32( nLBox );

    if( nLBox != 1 )
    {
        nBoxLength = nLBox;
        nDataOffset = nBoxOffset + 8;
    }
    else
    {
        GByte abyXLBox[8];
        if( VSIFReadL( abyXLBox, 8, 1, fpVSIL ) != 1 )
            return FALSE;

        
        if( sizeof(nBoxLength) == 8 )
        {
            CPL_MSBPTR64( abyXLBox );
            memcpy( &nBoxLength, abyXLBox, 8 );
        }
        else
        {
            CPL_MSBPTR32( abyXLBox+4 );
            memcpy( &nBoxLength, abyXLBox+4, 4 );
        }

        nDataOffset = nBoxOffset + 16;
    }

    if( nBoxLength == 0 )
    {
        VSIFSeekL( fpVSIL, 0, SEEK_END );
        nBoxLength = VSIFTellL( fpVSIL ) - nBoxOffset;
    }

    if( EQUAL(szBoxType,"uuid") )
    {
        VSIFReadL( abyUUID, 16, 1, fpVSIL );
        nDataOffset += 16;
    }

    if( GetDataLength() < 0 )
    {
        CPLDebug("GDALJP2", "Invalid length for box %s", szBoxType);
        return FALSE;
    }

    return TRUE;
}
Esempio n. 18
0
CPLErr PrintSRS( const OGRSpatialReference &oSRS, 
                 const char * pszOutputType, 
                 int bPretty, int bPrintSep )

{
    if ( ! pszOutputType || EQUAL(pszOutputType,""))
        return CE_None;

    CPLDebug( "gdalsrsinfo", "PrintSRS( oSRS, %s, %d, %d )\n",
              pszOutputType, bPretty, bPrintSep );
    
    char *pszOutput = NULL;

    if ( EQUAL("proj4", pszOutputType ) ) {
        if ( bPrintSep ) printf( "PROJ.4 : ");
        oSRS.exportToProj4( &pszOutput );
        printf( "\'%s\'\n", pszOutput );
    }

    else if ( EQUAL("wkt", pszOutputType ) ) {
        if ( bPrintSep ) printf("OGC WKT :\n");
        if ( bPretty ) 
            oSRS.exportToPrettyWkt( &pszOutput, FALSE );
        else
            oSRS.exportToWkt( &pszOutput );
        printf("%s\n",pszOutput);
    }
        
    else if (  EQUAL("wkt_simple", pszOutputType ) ) {
        if ( bPrintSep ) printf("OGC WKT (simple) :\n");
        oSRS.exportToPrettyWkt( &pszOutput, TRUE );
        printf("%s\n",pszOutput);
    }
        
    else if ( EQUAL("wkt_noct", pszOutputType ) ) {
        if (  bPrintSep ) printf("OGC WKT (no CT) :\n");
        OGRSpatialReference *poSRS = oSRS.Clone();
        poSRS->StripCTParms( );
        if ( bPretty ) 
            poSRS->exportToPrettyWkt( &pszOutput, FALSE );
        else
            poSRS->exportToWkt( &pszOutput );
        OGRSpatialReference::DestroySpatialReference( poSRS );
        printf("%s\n",pszOutput);
    }
        
    else if ( EQUAL("wkt_esri", pszOutputType ) ) {
        if ( bPrintSep ) printf("ESRI WKT :\n");
        OGRSpatialReference *poSRS = oSRS.Clone();
        poSRS->morphToESRI( );
        if ( bPretty ) 
            poSRS->exportToPrettyWkt( &pszOutput, FALSE );
        else
            poSRS->exportToWkt( &pszOutput );
        OGRSpatialReference::DestroySpatialReference( poSRS );
        printf("%s\n",pszOutput);
    }
        
    else if ( EQUAL("mapinfo", pszOutputType ) ) {
        if ( bPrintSep ) printf("MAPINFO : ");
        oSRS.exportToMICoordSys( &pszOutput );
        printf("\'%s\'\n",pszOutput);
    }
        
    else if ( EQUAL("xml", pszOutputType ) ) {
        if ( bPrintSep ) printf("XML :\n");
        oSRS.exportToXML( &pszOutput, NULL );
        printf("%s\n",pszOutput);
    }

    else {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "ERROR - %s output not supported",
                  pszOutputType );
        return CE_Failure;
    }

    CPLFree( pszOutput );
    
    return CE_None;
}
Esempio n. 19
0
vsi_l_offset VSICurlStreamingHandle::GetFileSize()
{
    WriteFuncStruct sWriteFuncData;
    WriteFuncStruct sWriteFuncHeaderData;

    AcquireMutex();
    if (bHastComputedFileSize)
    {
        vsi_l_offset nRet = fileSize;
        ReleaseMutex();
        return nRet;
    }
    ReleaseMutex();

#if LIBCURL_VERSION_NUM < 0x070B00
    /* Curl 7.10.X doesn't manage to unset the CURLOPT_RANGE that would have been */
    /* previously set, so we have to reinit the connection handle */
    if (hCurlHandle)
    {
        curl_easy_cleanup(hCurlHandle);
        hCurlHandle = curl_easy_init();
    }
#endif

    CURL* hLocalHandle = curl_easy_init();

    VSICurlSetOptions(hLocalHandle, pszURL);

    VSICURLStreamingInitWriteFuncStruct(&sWriteFuncHeaderData);

    /* HACK for mbtiles driver: proper fix would be to auto-detect servers that don't accept HEAD */
    /* http://a.tiles.mapbox.com/v3/ doesn't accept HEAD, so let's start a GET */
    /* and interrupt is as soon as the header is found */
    if (strstr(pszURL, ".tiles.mapbox.com/") != NULL)
    {
        curl_easy_setopt(hLocalHandle, CURLOPT_HEADERDATA, &sWriteFuncHeaderData);
        curl_easy_setopt(hLocalHandle, CURLOPT_HEADERFUNCTION, VSICurlStreamingHandleWriteFuncForHeader);

        sWriteFuncHeaderData.bIsHTTP = strncmp(pszURL, "http", 4) == 0;
        sWriteFuncHeaderData.bDownloadHeaderOnly = TRUE;
    }
    else
    {
        curl_easy_setopt(hLocalHandle, CURLOPT_NOBODY, 1);
        curl_easy_setopt(hLocalHandle, CURLOPT_HTTPGET, 0);
        curl_easy_setopt(hLocalHandle, CURLOPT_HEADER, 1);
    }

    /* We need that otherwise OSGEO4W's libcurl issue a dummy range request */
    /* when doing a HEAD when recycling connections */
    curl_easy_setopt(hLocalHandle, CURLOPT_RANGE, NULL);

    /* Bug with older curl versions (<=7.16.4) and FTP. See http://curl.haxx.se/mail/lib-2007-08/0312.html */
    VSICURLStreamingInitWriteFuncStruct(&sWriteFuncData);
    curl_easy_setopt(hLocalHandle, CURLOPT_WRITEDATA, &sWriteFuncData);
    curl_easy_setopt(hLocalHandle, CURLOPT_WRITEFUNCTION, VSICurlStreamingHandleWriteFuncForHeader);

    char szCurlErrBuf[CURL_ERROR_SIZE+1];
    szCurlErrBuf[0] = '\0';
    curl_easy_setopt(hLocalHandle, CURLOPT_ERRORBUFFER, szCurlErrBuf );

    double dfSize = 0;
    curl_easy_perform(hLocalHandle);

    AcquireMutex();

    eExists = EXIST_UNKNOWN;
    bHastComputedFileSize = TRUE;

    if (strncmp(pszURL, "ftp", 3) == 0)
    {
        if (sWriteFuncData.pBuffer != NULL &&
            strncmp(sWriteFuncData.pBuffer, "Content-Length: ", strlen( "Content-Length: ")) == 0)
        {
            const char* pszBuffer = sWriteFuncData.pBuffer + strlen("Content-Length: ");
            eExists = EXIST_YES;
            fileSize = CPLScanUIntBig(pszBuffer, sWriteFuncData.nSize - strlen("Content-Length: "));
            if (ENABLE_DEBUG)
                CPLDebug("VSICURL", "GetFileSize(%s)=" CPL_FRMT_GUIB,
                        pszURL, fileSize);
        }
    }

    if (eExists != EXIST_YES)
    {
        CURLcode code = curl_easy_getinfo(hLocalHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &dfSize );
        if (code == 0)
        {
            eExists = EXIST_YES;
            if (dfSize < 0)
                fileSize = 0;
            else
                fileSize = (GUIntBig)dfSize;
        }
        else
        {
            eExists = EXIST_NO;
            fileSize = 0;
            CPLError(CE_Failure, CPLE_AppDefined,
                     "VSICurlStreamingHandle::GetFileSize failed");
        }

        long response_code = 0;
        curl_easy_getinfo(hLocalHandle, CURLINFO_HTTP_CODE, &response_code);
        if (response_code != 200)
        {
            eExists = EXIST_NO;
            fileSize = 0;
        }

        /* Try to guess if this is a directory. Generally if this is a directory, */
        /* curl will retry with an URL with slash added */
        char *pszEffectiveURL = NULL;
        curl_easy_getinfo(hLocalHandle, CURLINFO_EFFECTIVE_URL, &pszEffectiveURL);
        if (pszEffectiveURL != NULL &&
            strncmp(pszURL, pszEffectiveURL, strlen(pszURL)) == 0 &&
            pszEffectiveURL[strlen(pszURL)] == '/')
        {
            eExists = EXIST_YES;
            fileSize = 0;
            bIsDirectory = TRUE;
        }

        if (ENABLE_DEBUG)
            CPLDebug("VSICURL", "GetFileSize(%s)=" CPL_FRMT_GUIB "  response_code=%d",
                    pszURL, fileSize, (int)response_code);
    }

    CPLFree(sWriteFuncData.pBuffer);
    CPLFree(sWriteFuncHeaderData.pBuffer);

    poFS->AcquireMutex();
    CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL);
    cachedFileProp->bHastComputedFileSize = TRUE;
#ifdef notdef
    cachedFileProp->nChecksumOfFirst1024Bytes = nRecomputedChecksumOfFirst1024Bytes;
#endif
    cachedFileProp->fileSize = fileSize;
    cachedFileProp->eExists = eExists;
    cachedFileProp->bIsDirectory = bIsDirectory;
    poFS->ReleaseMutex();

    vsi_l_offset nRet = fileSize;
    ReleaseMutex();

    if (hCurlHandle == NULL)
        hCurlHandle = hLocalHandle;
    else
        curl_easy_cleanup(hLocalHandle);

    return nRet;
}
Esempio n. 20
0
int SearchCSVForWKT( const char *pszFileCSV, const char *pszTarget )
{
    const char *pszFilename = NULL;
    const char *pszWKT = NULL;
    char szTemp[1024];
    int nPos = 0;
    const char *pszTemp = NULL;

    VSILFILE *fp = NULL;
    OGRSpatialReference oSRS;
    int nCode = 0;
    int nFound = -1;

    CPLDebug( "gdalsrsinfo", 
              "SearchCSVForWKT()\nfile=%s\nWKT=%s\n",
              pszFileCSV, pszTarget);

/* -------------------------------------------------------------------- */
/*      Find and open file.                                             */
/* -------------------------------------------------------------------- */
    // pszFilename = pszFileCSV;
    pszFilename = CPLFindFile( "gdal", pszFileCSV );
    if( pszFilename == NULL )
    {
        CPLDebug( "gdalsrsinfo", "could not find support file %s",
                   pszFileCSV );
        // return OGRERR_UNSUPPORTED_SRS;
        return -1;
    }

    /* support gzipped file */
    if ( strstr( pszFileCSV,".gz") != NULL )
        sprintf( szTemp, "/vsigzip/%s", pszFilename);
    else
        sprintf( szTemp, "%s", pszFilename);

    CPLDebug( "gdalsrsinfo", "SearchCSVForWKT() using file %s",
              szTemp );

    fp = VSIFOpenL( szTemp, "r" );
    if( fp == NULL ) 
    {
        CPLDebug( "gdalsrsinfo", "could not open support file %s",
                  pszFilename );

        // return OGRERR_UNSUPPORTED_SRS;
        return -1;
    }

/* -------------------------------------------------------------------- */
/*      Process lines.                                                  */
/* -------------------------------------------------------------------- */
    const char *pszLine;

    while( (pszLine = CPLReadLine2L(fp,-1,NULL)) != NULL )

    {
        // CPLDebug( "gdalsrsinfo", "read line %s", pszLine );

        if( pszLine[0] == '#' )
            continue;
            /* do nothing */;

        // else if( EQUALN(pszLine,"include ",8) )
        // {
        //     eErr = importFromDict( pszLine + 8, pszCode );
        //     if( eErr != OGRERR_UNSUPPORTED_SRS )
        //         break;
        // }

        // else if( strstr(pszLine,",") == NULL )
        //     /* do nothing */;

        pszTemp = strstr(pszLine,",");
        if (pszTemp)
        {
            nPos = pszTemp - pszLine;

            if ( nPos == 0 )
                continue;
            
            strncpy( szTemp, pszLine, nPos );
            szTemp[nPos] = '\0';
            nCode = atoi(szTemp);

            pszWKT = (char *) pszLine + nPos +1;

            // CPLDebug( "gdalsrsinfo", 
            //           "code=%d\nWKT=\n[%s]\ntarget=\n[%s]\n",
            //           nCode,pszWKT, pszTarget );

            if ( EQUAL(pszTarget,pszWKT) )
            {
                nFound = nCode;
                CPLDebug( "gdalsrsinfo", "found EPSG:%d\n"
                          "current=%s\ntarget= %s\n",
                          nCode, pszWKT, pszTarget );
                break;
            }
        }
    }
    
    VSIFCloseL( fp );

    return nFound;

}
Esempio n. 21
0
int VSICurlStreamingHandle::ReceivedBytesHeader(GByte *buffer, size_t count, size_t nmemb)
{
    size_t nSize = count * nmemb;
    if (ENABLE_DEBUG)
        CPLDebug("VSICURL", "Receiving %d bytes for header...", (int)nSize);

    /* Reset buffer if we have followed link after a redirect */
    if (nSize >=9 && (nHTTPCode == 301 || nHTTPCode == 302) &&
        (EQUALN((const char*)buffer, "HTTP/1.0 ", 9) ||
         EQUALN((const char*)buffer, "HTTP/1.1 ", 9)))
    {
        nHeaderSize = 0;
        nHTTPCode = 0;
    }

    if (nHeaderSize < HEADER_SIZE)
    {
        size_t nSz = MIN(nSize, HEADER_SIZE - nHeaderSize);
        memcpy(pabyHeaderData + nHeaderSize, buffer, nSz);
        pabyHeaderData[nHeaderSize + nSz] = '\0';
        nHeaderSize += nSz;

        //CPLDebug("VSICURL", "Header : %s", pabyHeaderData);

        AcquireMutex();

        if (eExists == EXIST_UNKNOWN && nHTTPCode == 0 &&
            strchr((const char*)pabyHeaderData, '\n') != NULL &&
            (EQUALN((const char*)pabyHeaderData, "HTTP/1.0 ", 9) ||
                EQUALN((const char*)pabyHeaderData, "HTTP/1.1 ", 9)))
        {
            nHTTPCode = atoi((const char*)pabyHeaderData + 9);
            if (ENABLE_DEBUG)
                CPLDebug("VSICURL", "HTTP code = %d", nHTTPCode);

            /* If moved permanently/temporarily, go on */
            if( !(nHTTPCode == 301 || nHTTPCode == 302) )
            {
                poFS->AcquireMutex();
                CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL);
                cachedFileProp->eExists = eExists = (nHTTPCode == 200) ? EXIST_YES : EXIST_NO;
                poFS->ReleaseMutex();
            }
        }

        if ( !(nHTTPCode == 301 || nHTTPCode == 302) && !bHastComputedFileSize)
        {
            /* Caution: when gzip compression is enabled, the content-length is the compressed */
            /* size, which we are not interested in, so we must not take it into account. */

            const char* pszContentLength = strstr((const char*)pabyHeaderData, "Content-Length: ");
            const char* pszEndOfLine = pszContentLength ? strchr(pszContentLength, '\n') : NULL;
            if( bCanTrustCandidateFileSize && pszEndOfLine != NULL )
            {
                const char* pszVal = pszContentLength + strlen("Content-Length: ");
                bHasCandidateFileSize = TRUE;
                nCandidateFileSize = CPLScanUIntBig(pszVal, pszEndOfLine - pszVal);
                if (ENABLE_DEBUG)
                    CPLDebug("VSICURL", "Has found candidate file size = " CPL_FRMT_GUIB, nCandidateFileSize);
            }

            const char* pszContentEncoding = strstr((const char*)pabyHeaderData, "Content-Encoding: ");
            pszEndOfLine = pszContentEncoding ? strchr(pszContentEncoding, '\n') : NULL;
            if( bHasCandidateFileSize && pszEndOfLine != NULL )
            {
                const char* pszVal = pszContentEncoding + strlen("Content-Encoding: ");
                if( strncmp(pszVal, "gzip", 4) == 0 )
                {
                    if (ENABLE_DEBUG)
                        CPLDebug("VSICURL", "GZip compression enabled --> cannot trust candidate file size");
                    bCanTrustCandidateFileSize = FALSE;
                }
            }
        }

        ReleaseMutex();
    }

    return nmemb;
}
Esempio n. 22
0
int main( int argc, char ** argv ) 

{
    int            i;
    int            bGotSRS = FALSE;
    int            bPretty = FALSE;
    int            bValidate = FALSE;
    int            bFindEPSG = FALSE;
    int            nEPSGCode = -1;
    const char     *pszInput = NULL;
    const char     *pszOutputType = "default";
    OGRSpatialReference  oSRS;

    /* Check strict compilation and runtime library version as we use C++ API */
    if (! GDAL_CHECK_VERSION(argv[0]))
        exit(1);

    EarlySetConfigOptions(argc, argv);

/* -------------------------------------------------------------------- */
/*      Register standard GDAL and OGR drivers.                         */
/* -------------------------------------------------------------------- */
    GDALAllRegister();
#ifdef OGR_ENABLED
    OGRRegisterAll();
#endif

/* -------------------------------------------------------------------- */
/*      Register standard GDAL drivers, and process generic GDAL        */
/*      command options.                                                */
/* -------------------------------------------------------------------- */
    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    for( i = 1; i < argc; i++ )
    {
        CPLDebug( "gdalsrsinfo", "got arg #%d : [%s]", i, argv[i] );

        if( EQUAL(argv[i], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(argv[i], "-h") || EQUAL(argv[i], "--help") )
            Usage();
        else if( EQUAL(argv[i], "-e") )
            bFindEPSG = TRUE;
        else if( EQUAL(argv[i], "-o") )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszOutputType = argv[++i];
        }
        else if( EQUAL(argv[i], "-p") )
            bPretty = TRUE;
        else if( EQUAL(argv[i], "-V") )
            bValidate = TRUE;
        else if( argv[i][0] == '-' )
        {
            Usage(CPLSPrintf("Unknown option name '%s'", argv[i]));
        }
        else  
            pszInput = argv[i];
    }

    if ( pszInput == NULL ) {
        CSLDestroy( argv );
        Usage("No input specified.");
    }

    /* Search for SRS */
    bGotSRS = FindSRS( pszInput, oSRS );

    CPLDebug( "gdalsrsinfo", 
              "bGotSRS: %d bValidate: %d pszOutputType: %s bPretty: %d",
              bGotSRS, bValidate, pszOutputType, bPretty  );
      

    /* Make sure we got a SRS */
    if ( ! bGotSRS ) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "ERROR - failed to load SRS definition from %s",
                  pszInput );
    }

    else {

        /* Find EPSG code - experimental */
        if ( EQUAL(pszOutputType,"epsg") )
            bFindEPSG = TRUE;
        if ( bFindEPSG ) {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "EPSG detection is experimental and requires new data files (see bug #4345)" );
            nEPSGCode = FindEPSG( oSRS );
            /* If found, replace oSRS based on EPSG code */
            if(nEPSGCode != -1) {
                CPLDebug( "gdalsrsinfo", 
                          "Found EPSG code %d", nEPSGCode );
                OGRSpatialReference oSRS2;
                if ( oSRS2.importFromEPSG( nEPSGCode ) == OGRERR_NONE )
                    oSRS = oSRS2;
            }
        }
        /* Validate - not well tested!*/
        if ( bValidate ) {
            OGRErr eErr = oSRS.Validate( );
            if ( eErr != OGRERR_NONE ) {
                printf( "\nValidate Fails" );
                if ( eErr == OGRERR_CORRUPT_DATA )
                    printf( " - SRS is not well formed");
                else if ( eErr == OGRERR_UNSUPPORTED_SRS )
                    printf(" - contains non-standard PROJECTION[] values");
                printf("\n");
            }
            else
                printf( "\nValidate Succeeds\n" );
        }
        
        /* Output */
        if ( EQUAL("default", pszOutputType ) ) {
            /* does this work in MSVC? */
            const char* papszOutputTypes[] = 
                { "proj4", "wkt", NULL };      
            if ( bFindEPSG ) 
                printf("\nEPSG:%d\n",nEPSGCode);
            PrintSRSOutputTypes( oSRS, papszOutputTypes );
        }
        else if ( EQUAL("all", pszOutputType ) ) {
            if ( bFindEPSG ) 
                printf("\nEPSG:%d\n\n",nEPSGCode);
            const char* papszOutputTypes[] = 
                {"proj4","wkt","wkt_simple","wkt_noct","wkt_esri","mapinfo","xml",NULL};
            PrintSRSOutputTypes( oSRS, papszOutputTypes );
        }
        else if ( EQUAL("wkt_all", pszOutputType ) ) {
            const char* papszOutputTypes[] = 
                { "wkt", "wkt_simple", "wkt_noct", "wkt_esri", NULL };
            PrintSRSOutputTypes( oSRS, papszOutputTypes );
        }
        else {
            if ( bPretty )
                printf( "\n" );
            if ( EQUAL(pszOutputType,"epsg") )
                printf("EPSG:%d\n",nEPSGCode);
            else
                PrintSRS( oSRS, pszOutputType, bPretty, FALSE );
            if ( bPretty )
                printf( "\n" );        
        }

    }

    /* cleanup anything left */
    GDALDestroyDriverManager();
#ifdef OGR_ENABLED
    OGRCleanupAll();
#endif
    CSLDestroy( argv );

    return 0;
}
CPLODBCStatement* OGRMSSQLSpatialTableLayer::BuildStatement(const char* pszColumns)

{
    CPLODBCStatement* poStatement = new CPLODBCStatement( poDS->GetSession() );
    poStatement->Append( "select " );
    poStatement->Append( pszColumns );
    poStatement->Append( " from " );
    poStatement->Append( pszSchemaName );
    poStatement->Append( "." );
    poStatement->Append( pszTableName );

    /* Append attribute query if we have it */
    if( pszQuery != NULL )
        poStatement->Appendf( " where (%s)", pszQuery );

    /* If we have a spatial filter, query on it */
    if ( m_poFilterGeom != NULL )
    {
        if (nGeomColumnType == MSSQLCOLTYPE_GEOMETRY 
            || nGeomColumnType == MSSQLCOLTYPE_GEOGRAPHY)
        {
            if( pszQuery == NULL )
                poStatement->Append( " where" );
            else
                poStatement->Append( " and" );

            poStatement->Appendf(" [%s].STIntersects(", pszGeomColumn );

            if (nGeomColumnType == MSSQLCOLTYPE_GEOGRAPHY)
                poStatement->Append( "geography::" );
            else
                poStatement->Append( "geometry::" );
            
            if ( m_sFilterEnvelope.MinX == m_sFilterEnvelope.MaxX || 
                 m_sFilterEnvelope.MinY == m_sFilterEnvelope.MaxY)
                poStatement->Appendf("STGeomFromText('POINT(%.15g %.15g)',%d)) = 1", 
                            m_sFilterEnvelope.MinX, m_sFilterEnvelope.MinY, nSRSId >= 0? nSRSId : 0);
            else
                poStatement->Appendf( "STGeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g))',%d)) = 1", 
                                            m_sFilterEnvelope.MinX, m_sFilterEnvelope.MinY,
                                            m_sFilterEnvelope.MaxX, m_sFilterEnvelope.MinY, 
                                            m_sFilterEnvelope.MaxX, m_sFilterEnvelope.MaxY,
                                            m_sFilterEnvelope.MinX, m_sFilterEnvelope.MaxY,
                                            m_sFilterEnvelope.MinX, m_sFilterEnvelope.MinY,
                                            nSRSId >= 0? nSRSId : 0 );
        }
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "Spatial filter is supported only on geometry and geography column types." );
            
            delete poStatement;
            return NULL;
        }
    }

    CPLDebug( "OGR_MSSQLSpatial", "ExecuteSQL(%s)", poStatement->GetCommand() );
    if( poStatement->ExecuteSQL() )
        return poStatement;
    else
    {
        delete poStatement;
        return NULL;
    }
}
Esempio n. 24
0
OGRErr OGRSpatialReference::importFromOzi( const char *pszDatum,
                                           const char *pszProj,
                                           const char *pszProjParms )

{
    Clear();

/* -------------------------------------------------------------------- */
/*      Operate on the basis of the projection name.                    */
/* -------------------------------------------------------------------- */
    char    **papszProj = CSLTokenizeStringComplex( pszProj, ",", TRUE, TRUE );
    char    **papszProjParms = CSLTokenizeStringComplex( pszProjParms, ",", 
                                                         TRUE, TRUE );
    char    **papszDatum = NULL;
                                                         
    if (CSLCount(papszProj) < 2)
    {
        goto not_enough_data;
    }

    if ( EQUALN(papszProj[1], "Latitude/Longitude", 18) )
    {
    }

    else if ( EQUALN(papszProj[1], "Mercator", 8) )
    {
        if (CSLCount(papszProjParms) < 6) goto not_enough_data;
        double dfScale = CPLAtof(papszProjParms[3]);
        if (papszProjParms[3][0] == 0) dfScale = 1; /* if unset, default to scale = 1 */
        SetMercator( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]),
                     dfScale,
                     CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "Transverse Mercator", 19) )
    {
        if (CSLCount(papszProjParms) < 6) goto not_enough_data;
        SetTM( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]),
               CPLAtof(papszProjParms[3]),
               CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "Lambert Conformal Conic", 23) )
    {
        if (CSLCount(papszProjParms) < 8) goto not_enough_data;
        SetLCC( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]),
                CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]),
                CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "Sinusoidal", 10) )
    {
        if (CSLCount(papszProjParms) < 6) goto not_enough_data;
        SetSinusoidal( CPLAtof(papszProjParms[2]),
                       CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else if ( EQUALN(papszProj[1], "Albers Equal Area", 17) )
    {
        if (CSLCount(papszProjParms) < 8) goto not_enough_data;
        SetACEA( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]),
                 CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]),
                 CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) );
    }

    else
    {
        CPLDebug( "OSR_Ozi", "Unsupported projection: \"%s\"", papszProj[1] );
        SetLocalCS( CPLString().Printf("\"Ozi\" projection \"%s\"",
                                       papszProj[1]) );
    }

/* -------------------------------------------------------------------- */
/*      Try to translate the datum/spheroid.                            */
/* -------------------------------------------------------------------- */
    papszDatum = CSLTokenizeString2( pszDatum, ",",
                                               CSLT_ALLOWEMPTYTOKENS
                                               | CSLT_STRIPLEADSPACES
                                               | CSLT_STRIPENDSPACES );
    if ( papszDatum == NULL)
        goto not_enough_data;
        
    if ( !IsLocal() )
    {

/* -------------------------------------------------------------------- */
/*      Verify that we can find the CSV file containing the datums      */
/* -------------------------------------------------------------------- */
        if( CSVScanFileByName( CSVFilename( "ozi_datum.csv" ),
                            "EPSG_DATUM_CODE",
                            "4326", CC_Integer ) == NULL )
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                    "Unable to open OZI support file %s.\n"
                    "Try setting the GDAL_DATA environment variable to point\n"
                    "to the directory containing OZI csv files.",
                    CSVFilename( "ozi_datum.csv" ) );
            goto other_error;
        }

/* -------------------------------------------------------------------- */
/*      Search for matching datum                                       */
/* -------------------------------------------------------------------- */
        const char *pszOziDatum = CSVFilename( "ozi_datum.csv" );
        CPLString osDName = CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                    CC_ApproxString, "NAME" );
        if( strlen(osDName) == 0 )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "Failed to find datum %s in ozi_datum.csv.",
                    papszDatum[0] );
            goto other_error;
        }

        int nDatumCode = atoi( CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                            CC_ApproxString, "EPSG_DATUM_CODE" ) );

        if ( nDatumCode > 0 ) // There is a matching EPSG code
        {
            OGRSpatialReference oGCS;
            oGCS.importFromEPSG( nDatumCode );
            CopyGeogCSFrom( &oGCS );
        }
        else // We use the parameters from the CSV files
        {
            CPLString osEllipseCode = CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                                CC_ApproxString, "ELLIPSOID_CODE" );
            double dfDeltaX = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                                CC_ApproxString, "DELTAX" ) );
            double dfDeltaY = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                                CC_ApproxString, "DELTAY" ) );
            double dfDeltaZ = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0],
                                                CC_ApproxString, "DELTAZ" ) );


    /* -------------------------------------------------------------------- */
    /*      Verify that we can find the CSV file containing the ellipsoids  */
    /* -------------------------------------------------------------------- */
            if( CSVScanFileByName( CSVFilename( "ozi_ellips.csv" ),
                                "ELLIPSOID_CODE",
                                "20", CC_Integer ) == NULL )
            {
                CPLError( CE_Failure, CPLE_OpenFailed,
                    "Unable to open OZI support file %s.\n"
                    "Try setting the GDAL_DATA environment variable to point\n"
                    "to the directory containing OZI csv files.",
                    CSVFilename( "ozi_ellips.csv" ) );
                goto other_error;
            }

    /* -------------------------------------------------------------------- */
    /*      Lookup the ellipse code.                                        */
    /* -------------------------------------------------------------------- */
            const char *pszOziEllipse = CSVFilename( "ozi_ellips.csv" );

            CPLString osEName = CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode,
                                        CC_ApproxString, "NAME" );
            if( strlen(osEName) == 0 )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                        "Failed to find ellipsoid %s in ozi_ellips.csv.",
                        osEllipseCode.c_str() );
                goto other_error;
            }

            double dfA = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode,
                                        CC_ApproxString, "A" ));
            double dfInvF = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode,
                                            CC_ApproxString, "INVF" ));

    /* -------------------------------------------------------------------- */
    /*      Create geographic coordinate system.                            */
    /* -------------------------------------------------------------------- */

            SetGeogCS( osDName, osDName, osEName, dfA, dfInvF );
            SetTOWGS84( dfDeltaX, dfDeltaY, dfDeltaZ );

        }
    }

/* -------------------------------------------------------------------- */
/*      Grid units translation                                          */
/* -------------------------------------------------------------------- */
    if( IsLocal() || IsProjected() )
        SetLinearUnits( SRS_UL_METER, 1.0 );

    FixupOrdering();

    CSLDestroy(papszProj);
    CSLDestroy(papszProjParms);
    CSLDestroy(papszDatum);

    return OGRERR_NONE;

not_enough_data:

    CSLDestroy(papszProj);
    CSLDestroy(papszProjParms);
    CSLDestroy(papszDatum);

    return OGRERR_NOT_ENOUGH_DATA;

other_error:

    CSLDestroy(papszProj);
    CSLDestroy(papszProjParms);
    CSLDestroy(papszDatum);

    return OGRERR_FAILURE;
}
Esempio n. 25
0
OGRErr OGRSpatialReference::importFromPanorama( long iProjSys, long iDatum,
                                                long iEllips,
                                                double *padfPrjParams )

{
    Clear();

/* -------------------------------------------------------------------- */
/*      Use safe defaults if projection parameters are not supplied.    */
/* -------------------------------------------------------------------- */
    int bProjAllocated = false;

    if( padfPrjParams == NULL )
    {
        int     i;

        padfPrjParams = (double *)CPLMalloc( 8 * sizeof(double) );
        if ( !padfPrjParams )
            return OGRERR_NOT_ENOUGH_MEMORY;
        for ( i = 0; i < 7; i++ )
            padfPrjParams[i] = 0.0;
        bProjAllocated = true;
    }

/* -------------------------------------------------------------------- */
/*      Operate on the basis of the projection code.                    */
/* -------------------------------------------------------------------- */
    switch ( iProjSys )
    {
        case PAN_PROJ_NONE:
            break;

        case PAN_PROJ_UTM:
            {
                int nZone;

                if ( padfPrjParams[7] == 0.0 )
                    nZone = (int) TO_ZONE(padfPrjParams[3]);
                else
                    nZone = (int) padfPrjParams[7];

                // XXX: no way to determine south hemisphere. Always assume
                // northern hemisphere.
                SetUTM( nZone, TRUE );
            }
            break;

        case PAN_PROJ_WAG1:
            SetWagner( 1, 0.0,
                       padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_MERCAT:
            SetMercator( TO_DEGREES * padfPrjParams[0],
                         TO_DEGREES * padfPrjParams[3],
                         padfPrjParams[4],
                         padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_PS:
            SetPS( TO_DEGREES * padfPrjParams[2],
                   TO_DEGREES * padfPrjParams[3],
                   padfPrjParams[4],
                   padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_POLYC:
            SetPolyconic( TO_DEGREES * padfPrjParams[2],
                          TO_DEGREES * padfPrjParams[3],
                          padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_EC:
            SetEC( TO_DEGREES * padfPrjParams[0],
                   TO_DEGREES * padfPrjParams[1],
                   TO_DEGREES * padfPrjParams[2],
                   TO_DEGREES * padfPrjParams[3],
                   padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_LCC:
            SetLCC( TO_DEGREES * padfPrjParams[0],
                    TO_DEGREES * padfPrjParams[1],
                    TO_DEGREES * padfPrjParams[2],
                    TO_DEGREES * padfPrjParams[3],
                    padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_TM:
            {
                // XXX: we need zone number to compute false easting
                // parameter, because usually it is not contained in the
                // "Panorama" projection definition.
                // FIXME: what to do with negative values?
                int    nZone;
                double  dfCenterLong;

                if ( padfPrjParams[7] == 0.0 )
                {
                    nZone = (int)TO_ZONE(padfPrjParams[3]);
                    dfCenterLong = TO_DEGREES * padfPrjParams[3];
                }
                else
                {
                    nZone = (int) padfPrjParams[7];
                    dfCenterLong = 6 * (double)nZone - 3;
                }

                padfPrjParams[5] = nZone * 1000000.0 + 500000.0;
                padfPrjParams[4] = 1.0;
                SetTM( TO_DEGREES * padfPrjParams[2],
                       dfCenterLong,
                       padfPrjParams[4],
                       padfPrjParams[5], padfPrjParams[6] );
            }
            break;

        case PAN_PROJ_STEREO:
            SetStereographic( TO_DEGREES * padfPrjParams[2],
                              TO_DEGREES * padfPrjParams[3],
                              padfPrjParams[4],
                              padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_AE:
            SetAE( TO_DEGREES * padfPrjParams[0],
                   TO_DEGREES * padfPrjParams[3],
                   padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_GNOMON:
            SetGnomonic( TO_DEGREES * padfPrjParams[2],
                         TO_DEGREES * padfPrjParams[3],
                         padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_MOLL:
            SetMollweide( TO_DEGREES * padfPrjParams[3],
                          padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_LAEA:
            SetLAEA( TO_DEGREES * padfPrjParams[0],
                     TO_DEGREES * padfPrjParams[3],
                     padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_EQC:
            SetEquirectangular( TO_DEGREES * padfPrjParams[0],
                                TO_DEGREES * padfPrjParams[3],
                                padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_CEA:
            SetCEA( TO_DEGREES * padfPrjParams[0],
                    TO_DEGREES * padfPrjParams[3],
                    padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_IMWP:
            SetIWMPolyconic( TO_DEGREES * padfPrjParams[0],
                             TO_DEGREES * padfPrjParams[1],
                             TO_DEGREES * padfPrjParams[3],
                             padfPrjParams[5], padfPrjParams[6] );
            break;

        case PAN_PROJ_MILLER:
            SetMC(TO_DEGREES * padfPrjParams[5],
                TO_DEGREES * padfPrjParams[4],
                padfPrjParams[6], padfPrjParams[7]);
            break;

        default:
            CPLDebug( "OSR_Panorama", "Unsupported projection: %ld", iProjSys );
            SetLocalCS( CPLString().Printf("\"Panorama\" projection number %ld",
                                   iProjSys) );
            break;

    }

/* -------------------------------------------------------------------- */
/*      Try to translate the datum/spheroid.                            */
/* -------------------------------------------------------------------- */

    if ( !IsLocal() )
    {
        if ( iDatum > 0 && iDatum < NUMBER_OF_DATUMS && aoDatums[iDatum] )
        {
            OGRSpatialReference oGCS;
            oGCS.importFromEPSG( aoDatums[iDatum] );
            CopyGeogCSFrom( &oGCS );
        }

        else if ( iEllips > 0
                  && iEllips < NUMBER_OF_ELLIPSOIDS
                  && aoEllips[iEllips] )
        {
            char    *pszName = NULL;
            double  dfSemiMajor, dfInvFlattening;

            if ( OSRGetEllipsoidInfo( aoEllips[iEllips], &pszName,
                            &dfSemiMajor, &dfInvFlattening ) == OGRERR_NONE )
            {
                SetGeogCS( CPLString().Printf(
                            "Unknown datum based upon the %s ellipsoid",
                            pszName ),
                           CPLString().Printf(
                            "Not specified (based on %s spheroid)", pszName ),
                           pszName, dfSemiMajor, dfInvFlattening,
                           NULL, 0.0, NULL, 0.0 );
                SetAuthority( "SPHEROID", "EPSG", aoEllips[iEllips] );
            }
            else
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                          "Failed to lookup ellipsoid code %ld, likely due to"
                          " missing GDAL gcs.csv\n"
                          " file.  Falling back to use Pulkovo 42.", iEllips );
                SetWellKnownGeogCS( "EPSG:4284" );
            }

            if ( pszName )
                CPLFree( pszName );
        }

        else
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Wrong datum code %ld. Supported datums are 1--%ld only.\n"
                      "Falling back to use Pulkovo 42.",
                      iDatum, NUMBER_OF_DATUMS - 1 );
            SetWellKnownGeogCS( "EPSG:4284" );
        }
    }

/* -------------------------------------------------------------------- */
/*      Grid units translation                                          */
/* -------------------------------------------------------------------- */
    if( IsLocal() || IsProjected() )
        SetLinearUnits( SRS_UL_METER, 1.0 );

    FixupOrdering();

    if ( bProjAllocated && padfPrjParams )
        CPLFree( padfPrjParams );

    return OGRERR_NONE;
}
Esempio n. 26
0
CPLErr 
GTIFFBuildOverviews( const char * pszFilename,
                     int nBands, GDALRasterBand **papoBandList, 
                     int nOverviews, int * panOverviewList,
                     const char * pszResampling, 
                     GDALProgressFunc pfnProgress, void * pProgressData )

{
    TIFF    *hOTIFF;
    int     nBitsPerPixel=0, nCompression=COMPRESSION_NONE, nPhotometric=0;
    int     nSampleFormat=0, nPlanarConfig, iOverview, iBand;
    int     nXSize=0, nYSize=0;

    if( nBands == 0 || nOverviews == 0 )
        return CE_None;

    if (!GTiffOneTimeInit())
        return CE_Failure;

/* -------------------------------------------------------------------- */
/*      Verify that the list of bands is suitable for emitting in       */
/*      TIFF file.                                                      */
/* -------------------------------------------------------------------- */
    for( iBand = 0; iBand < nBands; iBand++ )
    {
        int     nBandBits, nBandFormat;
        GDALRasterBand *hBand = papoBandList[iBand];

        switch( hBand->GetRasterDataType() )
        {
          case GDT_Byte:
            nBandBits = 8;
            nBandFormat = SAMPLEFORMAT_UINT;
            break;

          case GDT_UInt16:
            nBandBits = 16;
            nBandFormat = SAMPLEFORMAT_UINT;
            break;

          case GDT_Int16:
            nBandBits = 16;
            nBandFormat = SAMPLEFORMAT_INT;
            break;

          case GDT_UInt32:
            nBandBits = 32;
            nBandFormat = SAMPLEFORMAT_UINT;
            break;

          case GDT_Int32:
            nBandBits = 32;
            nBandFormat = SAMPLEFORMAT_INT;
            break;

          case GDT_Float32:
            nBandBits = 32;
            nBandFormat = SAMPLEFORMAT_IEEEFP;
            break;

          case GDT_Float64:
            nBandBits = 64;
            nBandFormat = SAMPLEFORMAT_IEEEFP;
            break;

          case GDT_CInt16:
            nBandBits = 32;
            nBandFormat = SAMPLEFORMAT_COMPLEXINT;
            break;

          case GDT_CInt32:
            nBandBits = 64;
            nBandFormat = SAMPLEFORMAT_COMPLEXINT;
            break;

          case GDT_CFloat32:
            nBandBits = 64;
            nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP;
            break;

          case GDT_CFloat64:
            nBandBits = 128;
            nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP;
            break;

          default:
            CPLAssert( FALSE );
            return CE_Failure;
        }

        if( hBand->GetMetadataItem( "NBITS", "IMAGE_STRUCTURE" ) )
        {
            nBandBits = 
                atoi(hBand->GetMetadataItem("NBITS","IMAGE_STRUCTURE"));

            if( nBandBits == 1 
                && EQUALN(pszResampling,"AVERAGE_BIT2",12) )
                nBandBits = 8;
        }

        if( iBand == 0 )
        {
            nBitsPerPixel = nBandBits;
            nSampleFormat = nBandFormat;
            nXSize = hBand->GetXSize();
            nYSize = hBand->GetYSize();
        }
        else if( nBitsPerPixel != nBandBits || nSampleFormat != nBandFormat )
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "GTIFFBuildOverviews() doesn't support a mixture of band"
                      " data types." );
            return CE_Failure;
        }
        else if( hBand->GetColorTable() != NULL )
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "GTIFFBuildOverviews() doesn't support building"
                      " overviews of multiple colormapped bands." );
            return CE_Failure;
        }
        else if( hBand->GetXSize() != nXSize 
                 || hBand->GetYSize() != nYSize )
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "GTIFFBuildOverviews() doesn't support building"
                      " overviews of different sized bands." );
            return CE_Failure;
        }
    }

/* -------------------------------------------------------------------- */
/*      Use specified compression method.                               */
/* -------------------------------------------------------------------- */
    const char *pszCompress = CPLGetConfigOption( "COMPRESS_OVERVIEW", NULL );

    if( pszCompress != NULL && pszCompress[0] != '\0' )
    {
        nCompression = GTIFFGetCompressionMethod(pszCompress, "COMPRESS_OVERVIEW");
        if (nCompression < 0)
            return CE_Failure;
    }
    
    if( nCompression == COMPRESSION_JPEG && nBitsPerPixel > 8 )
    {  
        if( nBitsPerPixel > 16 )
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "GTIFFBuildOverviews() doesn't support building"
                      " JPEG compressed overviews of nBitsPerPixel > 16." );
            return CE_Failure;
        }

        nBitsPerPixel = 12;
    }

/* -------------------------------------------------------------------- */
/*      Figure out the planar configuration to use.                     */
/* -------------------------------------------------------------------- */
    if( nBands == 1 )
        nPlanarConfig = PLANARCONFIG_CONTIG;
    else
        nPlanarConfig = PLANARCONFIG_SEPARATE;

    const char* pszInterleave = CPLGetConfigOption( "INTERLEAVE_OVERVIEW", NULL );
    if (pszInterleave != NULL && pszInterleave[0] != '\0')
    {
        if( EQUAL( pszInterleave, "PIXEL" ) )
            nPlanarConfig = PLANARCONFIG_CONTIG;
        else if( EQUAL( pszInterleave, "BAND" ) )
            nPlanarConfig = PLANARCONFIG_SEPARATE;
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "INTERLEAVE_OVERVIEW=%s unsupported, value must be PIXEL or BAND. ignoring",
                      pszInterleave );
        }
    }

/* -------------------------------------------------------------------- */
/*      Figure out the photometric interpretation to use.               */
/* -------------------------------------------------------------------- */
    if( nBands == 3 )
        nPhotometric = PHOTOMETRIC_RGB;
    else if( papoBandList[0]->GetColorTable() != NULL 
             && !EQUALN(pszResampling,"AVERAGE_BIT2",12) )
    {
        nPhotometric = PHOTOMETRIC_PALETTE;
        /* should set the colormap up at this point too! */
    }
    else
        nPhotometric = PHOTOMETRIC_MINISBLACK;

    const char* pszPhotometric = CPLGetConfigOption( "PHOTOMETRIC_OVERVIEW", NULL );
    if (pszPhotometric != NULL && pszPhotometric[0] != '\0')
    {
        if( EQUAL( pszPhotometric, "MINISBLACK" ) )
            nPhotometric = PHOTOMETRIC_MINISBLACK;
        else if( EQUAL( pszPhotometric, "MINISWHITE" ) )
            nPhotometric = PHOTOMETRIC_MINISWHITE;
        else if( EQUAL( pszPhotometric, "RGB" ))
        {
            nPhotometric = PHOTOMETRIC_RGB;
        }
        else if( EQUAL( pszPhotometric, "CMYK" ))
        {
            nPhotometric = PHOTOMETRIC_SEPARATED;
        }
        else if( EQUAL( pszPhotometric, "YCBCR" ))
        {
            nPhotometric = PHOTOMETRIC_YCBCR;

            /* Because of subsampling, setting YCBCR without JPEG compression leads */
            /* to a crash currently. Would need to make GTiffRasterBand::IWriteBlock() */
            /* aware of subsampling so that it doesn't overrun buffer size returned */
            /* by libtiff */
            if ( nCompression != COMPRESSION_JPEG )
            {
                CPLError(CE_Failure, CPLE_NotSupported,
                         "Currently, PHOTOMETRIC_OVERVIEW=YCBCR requires COMPRESS_OVERVIEW=JPEG");
                return CE_Failure;
            }

            if (pszInterleave != NULL && pszInterleave[0] != '\0' && nPlanarConfig == PLANARCONFIG_SEPARATE)
            {
                CPLError(CE_Failure, CPLE_NotSupported,
                         "PHOTOMETRIC_OVERVIEW=YCBCR requires INTERLEAVE_OVERVIEW=PIXEL");
                return CE_Failure;
            }
            else
            {
                nPlanarConfig = PLANARCONFIG_CONTIG;
            }

            /* YCBCR strictly requires 3 bands. Not less, not more */
            /* Issue an explicit error message as libtiff one is a bit cryptic : */
            /* JPEGLib:Bogus input colorspace */
            if ( nBands != 3 )
            {
                CPLError(CE_Failure, CPLE_NotSupported,
                         "PHOTOMETRIC_OVERVIEW=YCBCR requires a source raster with only 3 bands (RGB)");
                return CE_Failure;
            }
        }
        else if( EQUAL( pszPhotometric, "CIELAB" ))
        {
            nPhotometric = PHOTOMETRIC_CIELAB;
        }
        else if( EQUAL( pszPhotometric, "ICCLAB" ))
        {
            nPhotometric = PHOTOMETRIC_ICCLAB;
        }
        else if( EQUAL( pszPhotometric, "ITULAB" ))
        {
            nPhotometric = PHOTOMETRIC_ITULAB;
        }
        else
        {
            CPLError( CE_Warning, CPLE_IllegalArg, 
                      "PHOTOMETRIC_OVERVIEW=%s value not recognised, ignoring.\n",
                      pszPhotometric );
        }
    }

/* -------------------------------------------------------------------- */
/*      Figure out the predictor value to use.                          */
/* -------------------------------------------------------------------- */
    int nPredictor = PREDICTOR_NONE;
    if ( nCompression == COMPRESSION_LZW ||
         nCompression == COMPRESSION_ADOBE_DEFLATE )
    {
        const char* pszPredictor = CPLGetConfigOption( "PREDICTOR_OVERVIEW", NULL );
        if( pszPredictor  != NULL )
        {
            nPredictor =  atoi( pszPredictor );
        }
    }

/* -------------------------------------------------------------------- */
/*      Create the file, if it does not already exist.                  */
/* -------------------------------------------------------------------- */
    VSIStatBufL  sStatBuf;

    if( VSIStatExL( pszFilename, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
    {
    /* -------------------------------------------------------------------- */
    /*      Compute the uncompressed size.                                  */
    /* -------------------------------------------------------------------- */
        double  dfUncompressedOverviewSize = 0;
        int nDataTypeSize = GDALGetDataTypeSize(papoBandList[0]->GetRasterDataType())/8;

        for( iOverview = 0; iOverview < nOverviews; iOverview++ )
        {
            int    nOXSize, nOYSize;

            nOXSize = (nXSize + panOverviewList[iOverview] - 1) 
                / panOverviewList[iOverview];
            nOYSize = (nYSize + panOverviewList[iOverview] - 1) 
                / panOverviewList[iOverview];

            dfUncompressedOverviewSize += 
                nOXSize * ((double)nOYSize) * nBands * nDataTypeSize;
        }

        if( nCompression == COMPRESSION_NONE 
            && dfUncompressedOverviewSize > 4200000000.0 )
        {
    #ifndef BIGTIFF_SUPPORT
            CPLError( CE_Failure, CPLE_NotSupported, 
                    "The overview file would be larger than 4GB\n"
                    "but this is the largest size a TIFF can be, and BigTIFF is unavailable.\n"
                    "Creation failed." );
            return CE_Failure;
    #endif
        }
    /* -------------------------------------------------------------------- */
    /*      Should the file be created as a bigtiff file?                   */
    /* -------------------------------------------------------------------- */
        const char *pszBIGTIFF = CPLGetConfigOption( "BIGTIFF_OVERVIEW", NULL );

        if( pszBIGTIFF == NULL )
            pszBIGTIFF = "IF_NEEDED";

        int bCreateBigTIFF = FALSE;
        if( EQUAL(pszBIGTIFF,"IF_NEEDED") )
        {
            if( nCompression == COMPRESSION_NONE 
                && dfUncompressedOverviewSize > 4200000000.0 )
                bCreateBigTIFF = TRUE;
        }
        else if( EQUAL(pszBIGTIFF,"IF_SAFER") )
        {
            /* Look at the size of the base image and suppose that */
            /* the added overview levels won't be more than 1/2 of */
            /* the size of the base image. The theory says 1/3 of the */
            /* base image size if the overview levels are 2, 4, 8, 16... */
            /* Thus take 1/2 as the security margin for 1/3 */
            double dfUncompressedImageSize =
                        nXSize * ((double)nYSize) * nBands * nDataTypeSize;
            if( dfUncompressedImageSize * .5 > 4200000000.0 )
                bCreateBigTIFF = TRUE;
        }
        else
        {
            bCreateBigTIFF = CSLTestBoolean( pszBIGTIFF );
            if (!bCreateBigTIFF && nCompression == COMPRESSION_NONE 
                && dfUncompressedOverviewSize > 4200000000.0 )
            {
                CPLError( CE_Failure, CPLE_NotSupported, 
                    "The overview file will be larger than 4GB, so BigTIFF is necessary.\n"
                    "Creation failed.");
                return CE_Failure;
            }
        }

    #ifndef BIGTIFF_SUPPORT
        if( bCreateBigTIFF )
        {
            CPLError( CE_Warning, CPLE_NotSupported,
                    "BigTIFF requested, but GDAL built without BigTIFF\n"
                    "enabled libtiff, request ignored." );
            bCreateBigTIFF = FALSE;
        }
    #endif

        if( bCreateBigTIFF )
            CPLDebug( "GTiff", "File being created as a BigTIFF." );

        hOTIFF = VSI_TIFFOpen( pszFilename, (bCreateBigTIFF) ? "w+8" : "w+" );
        if( hOTIFF == NULL )
        {
            if( CPLGetLastErrorNo() == 0 )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "Attempt to create new tiff file `%s'\n"
                          "failed in VSI_TIFFOpen().\n",
                          pszFilename );

            return CE_Failure;
        }
    }
/* -------------------------------------------------------------------- */
/*      Otherwise just open it for update access.                       */
/* -------------------------------------------------------------------- */
    else 
    {
        hOTIFF = VSI_TIFFOpen( pszFilename, "r+" );
        if( hOTIFF == NULL )
        {
            if( CPLGetLastErrorNo() == 0 )
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "Attempt to create new tiff file `%s'\n"
                          "failed in VSI_TIFFOpen().\n",
                          pszFilename );

            return CE_Failure;
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we have a palette?  If so, create a TIFF compatible version. */
/* -------------------------------------------------------------------- */
    unsigned short      *panRed=NULL, *panGreen=NULL, *panBlue=NULL;

    if( nPhotometric == PHOTOMETRIC_PALETTE )
    {
        GDALColorTable *poCT = papoBandList[0]->GetColorTable();
        int nColorCount;

        if( nBitsPerPixel <= 8 )
            nColorCount = 256;
        else
            nColorCount = 65536;

        panRed   = (unsigned short *) 
            CPLCalloc(nColorCount,sizeof(unsigned short));
        panGreen = (unsigned short *) 
            CPLCalloc(nColorCount,sizeof(unsigned short));
        panBlue  = (unsigned short *) 
            CPLCalloc(nColorCount,sizeof(unsigned short));

        for( int iColor = 0; iColor < nColorCount; iColor++ )
        {
            GDALColorEntry  sRGB;

            if( poCT->GetColorEntryAsRGB( iColor, &sRGB ) )
            {
                panRed[iColor] = (unsigned short) (257 * sRGB.c1);
                panGreen[iColor] = (unsigned short) (257 * sRGB.c2);
                panBlue[iColor] = (unsigned short) (257 * sRGB.c3);
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we need some metadata for the overviews?                     */
/* -------------------------------------------------------------------- */
    CPLString osMetadata;
    GDALDataset *poBaseDS = papoBandList[0]->GetDataset();

    GTIFFBuildOverviewMetadata( pszResampling, poBaseDS, osMetadata );

/* -------------------------------------------------------------------- */
/*      Loop, creating overviews.                                       */
/* -------------------------------------------------------------------- */
    int nOvrBlockXSize, nOvrBlockYSize;
    GTIFFGetOverviewBlockSize(&nOvrBlockXSize, &nOvrBlockYSize);
    for( iOverview = 0; iOverview < nOverviews; iOverview++ )
    {
        int    nOXSize, nOYSize;

        nOXSize = (nXSize + panOverviewList[iOverview] - 1) 
            / panOverviewList[iOverview];
        nOYSize = (nYSize + panOverviewList[iOverview] - 1) 
            / panOverviewList[iOverview];

        GTIFFWriteDirectory(hOTIFF, FILETYPE_REDUCEDIMAGE,
                            nOXSize, nOYSize, nBitsPerPixel, 
                            nPlanarConfig, nBands,
                            nOvrBlockXSize, nOvrBlockYSize, TRUE, nCompression,
                            nPhotometric, nSampleFormat, nPredictor,
                            panRed, panGreen, panBlue,
                            0, NULL, /* FIXME? how can we fetch extrasamples */
                            osMetadata );
    }

    if (panRed)
    {
        CPLFree(panRed);
        CPLFree(panGreen);
        CPLFree(panBlue);
        panRed = panGreen = panBlue = NULL;
    }

    XTIFFClose( hOTIFF );

/* -------------------------------------------------------------------- */
/*      Open the overview dataset so that we can get at the overview    */
/*      bands.                                                          */
/* -------------------------------------------------------------------- */
    GDALDataset *hODS;
    CPLErr eErr = CE_None;

    hODS = (GDALDataset *) GDALOpen( pszFilename, GA_Update );
    if( hODS == NULL )
        return CE_Failure;
    
/* -------------------------------------------------------------------- */
/*      Do we need to set the jpeg quality?                             */
/* -------------------------------------------------------------------- */
    TIFF *hTIFF = (TIFF*) hODS->GetInternalHandle(NULL);

    if( nCompression == COMPRESSION_JPEG 
        && CPLGetConfigOption( "JPEG_QUALITY_OVERVIEW", NULL ) != NULL )
    {
        int nJpegQuality = atoi(CPLGetConfigOption("JPEG_QUALITY_OVERVIEW","75"));
        TIFFSetField( hTIFF, TIFFTAG_JPEGQUALITY, 
                      nJpegQuality );
        GTIFFSetJpegQuality((GDALDatasetH)hODS, nJpegQuality);
    }

/* -------------------------------------------------------------------- */
/*      Loop writing overview data.                                     */
/* -------------------------------------------------------------------- */

    if (nCompression != COMPRESSION_NONE &&
        nPlanarConfig == PLANARCONFIG_CONTIG &&
        GDALDataTypeIsComplex(papoBandList[0]->GetRasterDataType()) == FALSE &&
        papoBandList[0]->GetColorTable() == NULL &&
        (EQUALN(pszResampling, "NEAR", 4) || EQUAL(pszResampling, "AVERAGE") || EQUAL(pszResampling, "GAUSS")))
    {
        /* In the case of pixel interleaved compressed overviews, we want to generate */
        /* the overviews for all the bands block by block, and not band after band, */
        /* in order to write the block once and not loose space in the TIFF file */
        GDALRasterBand ***papapoOverviewBands;

        papapoOverviewBands = (GDALRasterBand ***) CPLCalloc(sizeof(void*),nBands);
        for( iBand = 0; iBand < nBands && eErr == CE_None; iBand++ )
        {
            GDALRasterBand    *hDstBand = hODS->GetRasterBand( iBand+1 );
            papapoOverviewBands[iBand] = (GDALRasterBand **) CPLCalloc(sizeof(void*),nOverviews);
            papapoOverviewBands[iBand][0] = hDstBand;
            for( int i = 0; i < nOverviews-1 && eErr == CE_None; i++ )
            {
                papapoOverviewBands[iBand][i+1] = hDstBand->GetOverview(i);
                if (papapoOverviewBands[iBand][i+1] == NULL)
                    eErr = CE_Failure;
            }
        }

        if (eErr == CE_None)
            eErr = GDALRegenerateOverviewsMultiBand(nBands, papoBandList,
                                            nOverviews, papapoOverviewBands,
                                            pszResampling, pfnProgress, pProgressData );

        for( iBand = 0; iBand < nBands; iBand++ )
        {
            CPLFree(papapoOverviewBands[iBand]);
        }
        CPLFree(papapoOverviewBands);
    }
    else
    {
        GDALRasterBand   **papoOverviews;

        papoOverviews = (GDALRasterBand **) CPLCalloc(sizeof(void*),128);

        for( iBand = 0; iBand < nBands && eErr == CE_None; iBand++ )
        {
            GDALRasterBand    *hSrcBand = papoBandList[iBand];
            GDALRasterBand    *hDstBand;
            int               nDstOverviews;

            hDstBand = hODS->GetRasterBand( iBand+1 );

            papoOverviews[0] = hDstBand;
            nDstOverviews = hDstBand->GetOverviewCount() + 1;
            CPLAssert( nDstOverviews < 128 );
            nDstOverviews = MIN(128,nDstOverviews);

            for( int i = 0; i < nDstOverviews-1 && eErr == CE_None; i++ )
            {
                papoOverviews[i+1] = hDstBand->GetOverview(i);
                if (papoOverviews[i+1] == NULL)
                    eErr = CE_Failure;
            }

            void         *pScaledProgressData;

            pScaledProgressData = 
                GDALCreateScaledProgress( iBand / (double) nBands, 
                                        (iBand+1) / (double) nBands,
                                        pfnProgress, pProgressData );

            if (eErr == CE_None)
                eErr = 
                    GDALRegenerateOverviews( (GDALRasterBandH) hSrcBand, 
                                        nDstOverviews, 
                                        (GDALRasterBandH *) papoOverviews, 
                                        pszResampling,
                                        GDALScaledProgress, 
                                        pScaledProgressData);

            GDALDestroyScaledProgress( pScaledProgressData );
        }

        CPLFree( papoOverviews );
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    if (eErr == CE_None)
        hODS->FlushCache();
    delete hODS;

    pfnProgress( 1.0, NULL, pProgressData );

    return eErr;
}
static
void* OGRSQLiteRegisterSQLFunctions(sqlite3* hDB)
{
    OGRSQLiteExtensionData* pData = new OGRSQLiteExtensionData(hDB);

    sqlite3_create_function(hDB, "ogr_version", 0, SQLITE_ANY, NULL,
                           OGR2SQLITE_ogr_version, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_version", 1, SQLITE_ANY, NULL,
                           OGR2SQLITE_ogr_version, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_deflate", 1, SQLITE_ANY, NULL,
                            OGR2SQLITE_ogr_deflate, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_deflate", 2, SQLITE_ANY, NULL,
                            OGR2SQLITE_ogr_deflate, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_inflate", 1, SQLITE_ANY, NULL,
                            OGR2SQLITE_ogr_inflate, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_geocode", -1, SQLITE_ANY, pData,
                            OGR2SQLITE_ogr_geocode, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_geocode_reverse", -1, SQLITE_ANY, pData,
                            OGR2SQLITE_ogr_geocode_reverse, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_datasource_load_layers", 1, SQLITE_ANY, hDB,
                            OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_datasource_load_layers", 2, SQLITE_ANY, hDB,
                            OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_datasource_load_layers", 3, SQLITE_ANY, hDB,
                            OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);

#if notdef
    sqlite3_create_function(hDB, "ogr_GetConfigOption", 1, SQLITE_ANY, NULL,
                            OGR2SQLITE_ogr_GetConfigOption, NULL, NULL);

    sqlite3_create_function(hDB, "ogr_SetConfigOption", 2, SQLITE_ANY, NULL,
                            OGR2SQLITE_ogr_SetConfigOption, NULL, NULL);
#endif

    // Custom and undocumented function, not sure I'll keep it.
    sqlite3_create_function(hDB, "Transform3", 3, SQLITE_ANY, pData,
                            OGR2SQLITE_Transform, NULL, NULL);

    // HSTORE functions
    sqlite3_create_function(hDB, "hstore_get_value", 2, SQLITE_ANY, NULL,
                            OGRSQLITE_hstore_get_value, NULL, NULL);

#ifdef MINIMAL_SPATIAL_FUNCTIONS
    /* Check if spatialite is available */
    int rc = sqlite3_exec(hDB, "SELECT spatialite_version()", NULL, NULL, NULL);
    
    /* Reset error flag */
    sqlite3_exec(hDB, "SELECT 1", NULL, NULL, NULL);
    
    if( rc != SQLITE_OK &&
        CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_SPATIAL_FUNCTIONS", "YES")) )
    {
        CPLDebug("SQLITE",
                 "Spatialite not available. Implementing a few functions");

#define REGISTER_ST_op(argc, op) \
        sqlite3_create_function(hDB, #op, argc, SQLITE_ANY, NULL, \
                                OGR2SQLITE_ST_##op, NULL, NULL); \
        sqlite3_create_function(hDB, "ST_" #op, argc, SQLITE_ANY, NULL, \
                                OGR2SQLITE_ST_##op, NULL, NULL);

        REGISTER_ST_op(1, AsText);
        REGISTER_ST_op(1, AsBinary);
        REGISTER_ST_op(1, GeomFromText);
        REGISTER_ST_op(2, GeomFromText);
        REGISTER_ST_op(1, GeomFromWKB);
        REGISTER_ST_op(2, GeomFromWKB);

        REGISTER_ST_op(1, IsEmpty);
        REGISTER_ST_op(1, IsSimple);
        REGISTER_ST_op(1, IsValid);

        REGISTER_ST_op(2, Intersects);
        REGISTER_ST_op(2, Equals);
        REGISTER_ST_op(2, Disjoint);
        REGISTER_ST_op(2, Touches);
        REGISTER_ST_op(2, Crosses);
        REGISTER_ST_op(2, Within);
        REGISTER_ST_op(2, Contains);
        REGISTER_ST_op(2, Overlaps);

        REGISTER_ST_op(2, Intersection);
        REGISTER_ST_op(2, Difference);
        // Union() is invalid
        sqlite3_create_function(hDB, "ST_Union", 2, SQLITE_ANY, NULL,
                                OGR2SQLITE_ST_Union, NULL, NULL);
        REGISTER_ST_op(2, SymDifference);

        REGISTER_ST_op(1, SRID);
        REGISTER_ST_op(1, Area);
        REGISTER_ST_op(2, Buffer);
        REGISTER_ST_op(2, MakePoint);
        REGISTER_ST_op(3, MakePoint);
    }
#endif // #ifdef MINIMAL_SPATIAL_FUNCTIONS

    pData->SetRegExpCache(OGRSQLiteRegisterRegExpFunction(hDB));

    return pData;
}
Esempio n. 28
0
void OGRDWGDataSource::ReadBlocksSection()

{
    OGRDWGLayer *poReaderLayer = (OGRDWGLayer *) GetLayerByName( "Entities" );
    int bMergeBlockGeometries = CSLTestBoolean(
        CPLGetConfigOption( "DWG_MERGE_BLOCK_GEOMETRIES", "TRUE" ) );

/* -------------------------------------------------------------------- */
/*      Loop over all the block tables, skipping *Model_Space which     */
/*      we assume is primary entities.                                  */
/* -------------------------------------------------------------------- */
    OdDbBlockTableRecordPtr  poModelSpace, poBlock;
    OdDbBlockTablePtr pTable = GetDB()->getBlockTableId().safeOpenObject();
    OdDbSymbolTableIteratorPtr pBlkIter = pTable->newIterator();
    
    for (pBlkIter->start(); ! pBlkIter->done(); pBlkIter->step())
    {
        poBlock = pBlkIter->getRecordId().safeOpenObject();
        CPLString osBlockName = (const char *) poBlock->getName();

        if( EQUAL(osBlockName,"*Model_Space") )
        {
            poModelSpace = poBlock;
            continue;
        }

        poReaderLayer->SetBlockTable( poBlock );

        // Now we will process entities till we run out.
        // We aggregate the geometries of the features into a multi-geometry,
        // but throw away other stuff attached to the features.

        OGRFeature *poFeature;
        OGRGeometryCollection *poColl = new OGRGeometryCollection();
        std::vector<OGRFeature*> apoFeatures;

        while( (poFeature = poReaderLayer->GetNextUnfilteredFeature()) != NULL )
        {
            if( (poFeature->GetStyleString() != NULL
                 && strstr(poFeature->GetStyleString(),"LABEL") != NULL)
                || !bMergeBlockGeometries )
            {
                apoFeatures.push_back( poFeature );
            }
            else
            {
                poColl->addGeometryDirectly( poFeature->StealGeometry() );
                delete poFeature;
            }
        }

        if( poColl->getNumGeometries() == 0 )
            delete poColl;
        else
            oBlockMap[osBlockName].poGeometry = SimplifyBlockGeometry(poColl);

        if( apoFeatures.size() > 0 )
            oBlockMap[osBlockName].apoFeatures = apoFeatures;
    }

    CPLDebug( "DWG", "Read %d blocks with meaningful geometry.", 
              (int) oBlockMap.size() );

    poReaderLayer->SetBlockTable( poModelSpace );
}
Esempio n. 29
0
void NASReader::SetFeatureProperty( const char *pszElement, 
                                    const char *pszValue )

{
    GMLFeature *poFeature = GetState()->m_poFeature;

    CPLAssert( poFeature  != NULL );

/* -------------------------------------------------------------------- */
/*      Does this property exist in the feature class?  If not, add     */
/*      it.                                                             */
/* -------------------------------------------------------------------- */
    GMLFeatureClass *poClass = poFeature->GetClass();
    int      iProperty;

    for( iProperty=0; iProperty < poClass->GetPropertyCount(); iProperty++ )
    {
        if( EQUAL(poClass->GetProperty( iProperty )->GetSrcElement(),
                  pszElement ) )
            break;
    }
    
    if( iProperty == poClass->GetPropertyCount() )
    {
        if( poClass->IsSchemaLocked() )
        {
            CPLDebug("GML","Encountered property missing from class schema.");
            return;
        }

        CPLString osFieldName;
        
        if( strchr(pszElement,'|') == NULL )
            osFieldName = pszElement;
        else
        {
            osFieldName = strrchr(pszElement,'|') + 1;
            if( poClass->GetPropertyIndex(osFieldName) != -1 )
                osFieldName = pszElement;
        }

        // Does this conflict with an existing property name? 
        while( poClass->GetProperty(osFieldName) != NULL )
        {
            osFieldName += "_";
        }

        GMLPropertyDefn *poPDefn = new GMLPropertyDefn(osFieldName,pszElement);

        if( EQUAL(CPLGetConfigOption( "GML_FIELDTYPES", ""), "ALWAYS_STRING") )
            poPDefn->SetType( GMLPT_String );

        poClass->AddProperty( poPDefn );
    }

/* -------------------------------------------------------------------- */
/*      Set the property                                                */
/* -------------------------------------------------------------------- */
    poFeature->SetProperty( iProperty, pszValue );

/* -------------------------------------------------------------------- */
/*      Do we need to update the property type?                         */
/* -------------------------------------------------------------------- */
    if( !poClass->IsSchemaLocked() )
    {
        poClass->GetProperty(iProperty)->AnalysePropertyValue(
                             poFeature->GetProperty(iProperty));
    }
}
Esempio n. 30
0
int ILI1Reader::ReadFeatures() {
    char **tokens = NULL;
    const char *pszLine = NULL;
    char *topic = CPLStrdup("(null)");
    int ret = TRUE;

    while (ret && (tokens = ReadParseLine()) != NULL)
    {
      const char *firsttok = tokens[0];
      if (EQUAL(firsttok, "SCNT"))
      {
        //read description
        do
        {
          pszLine = CPLReadLine( fpItf );
        }
        while (pszLine && !STARTS_WITH_CI(pszLine, "////"));
        ret = (pszLine != NULL);
      }
      else if (EQUAL(firsttok, "MOTR"))
      {
        //read model
        do
        {
          pszLine = CPLReadLine( fpItf );
        }
        while (pszLine && !STARTS_WITH_CI(pszLine, "////"));
        ret = (pszLine != NULL);
      }
      else if (EQUAL(firsttok, "MTID"))
      {
      }
      else if (EQUAL(firsttok, "MODL"))
      {
      }
      else if (EQUAL(firsttok, "TOPI") && CSLCount(tokens) >= 2)
      {
        CPLFree(topic);
        topic = CPLStrdup(CSLGetField(tokens, 1));
      }
      else if (EQUAL(firsttok, "TABL") && CSLCount(tokens) >= 2)
      {
        const char *layername
            = GetLayerNameString(topic, CSLGetField(tokens, 1));
        CPLDebug( "OGR_ILI", "Reading table '%s'", layername );
        curLayer = GetLayerByName(layername);

        if (curLayer == NULL) { //create one
          CPLError( CE_Warning, CPLE_AppDefined,
                    "No model definition for table '%s' found, "
                    "using default field names.", layername );
          OGRFeatureDefn* poFeatureDefn
            = new OGRFeatureDefn(
                GetLayerNameString(topic, CSLGetField(tokens, 1)));
          poFeatureDefn->SetGeomType( wkbUnknown );
          GeomFieldInfos oGeomFieldInfos;
          curLayer = new OGRILI1Layer(poFeatureDefn, oGeomFieldInfos, NULL);
          AddLayer(curLayer);
        }
        if(curLayer != NULL) {
          for (int i=0; i < curLayer->GetLayerDefn()->GetFieldCount(); i++) {
            CPLDebug( "OGR_ILI", "Field %d: %s", i,
                      curLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef());
          }
        }
        ret = ReadTable(layername);
      }
      else if (EQUAL(firsttok, "ETOP"))
      {
      }
      else if (EQUAL(firsttok, "EMOD"))
      {
      }
      else if (EQUAL(firsttok, "ENDE"))
      {
        CSLDestroy(tokens);
        CPLFree(topic);
        return TRUE;
      }
      else
      {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unexpected token: %s", firsttok );
      }

      CSLDestroy(tokens);
      tokens = NULL;
    }

    CSLDestroy(tokens);
    CPLFree(topic);

    return ret;
}