void CModCommand::AddHelp(CTable& Table) const {
	Table.AddRow();
	Table.SetCell("Command", GetCommand());
	Table.SetCell("Arguments", GetArgs());
	Table.SetCell("Description", GetDescription());
}
Exemple #2
0
/* SPI initialization and configuration */
int lgw_spi_open(void **spi_target_ptr) {
	struct mpsse_context *mpsse = NULL;
	int a, b;
	
	/* check input variables */
	CHECK_NULL(spi_target_ptr); /* cannot be null, must point on a void pointer (*spi_target_ptr can be null) */
	
	/* try to open the first available FTDI device matching VID/PID parameters */
	mpsse = OpenIndex(VID,PID,SPI0, SIX_MHZ, MSB, IFACE_A, NULL, NULL, 0);
	if (mpsse == NULL) {
		DEBUG_MSG("ERROR: MPSSE OPEN FUNCTION RETURNED NULL\n");
		return LGW_SPI_ERROR;
	}
	if (mpsse->open != 1) {
		DEBUG_MSG("ERROR: MPSSE OPEN FUNCTION FAILED\n");
		return LGW_SPI_ERROR;
	}
	
	/* toggle pin ADBUS5 of the FT232H */
	/* On the MTAC-LORA, it resets the SX1301 */
	a = PinLow(mpsse, GPIOL1);
	b = PinHigh(mpsse, GPIOL1);
	if ((a != MPSSE_OK) || (b != MPSSE_OK)) {
		DEBUG_MSG("ERROR: IMPOSSIBLE TO TOGGLE GPIOL1/ADBUS5\n");
		return LGW_SPI_ERROR;
	}
	
	DEBUG_PRINTF("SPI port opened and configured ok\ndesc: %s\nPID: 0x%04X\nVID: 0x%04X\nclock: %d\nLibmpsse version: 0x%02X\n", GetDescription(mpsse), GetPid(mpsse), GetVid(mpsse), GetClock(mpsse), Version());
	*spi_target_ptr = (void *)mpsse;
	return LGW_SPI_SUCCESS;
}
Exemple #3
0
//---------------------------------------------------------------------------//
  bool GpuProgramPipelineDX12::operator==(const GpuProgramPipelineDesc& anOtherDesc) const
  {
    return GetDescription() == anOtherDesc;
  }
Exemple #4
0
/*
 * WriteClt -- write the rpcs in the client
 */
PRIVATE void
WriteClt(rpcArgs * argsP, char *serverName, int sign_no, FILE * itl_h)
{
    char *name, *name2, *typ;
    int i, j;

    name = GetName(serverName, sign_no);
    name2 = GetDescription(argsP);

    fprintf(itl_h, "\n/* %s */\n\n", name2);

    fprintf(itl_h, "\nvoid C_%s(struct rx_connection *conn) {\n", name);

    /* declare each arg */
    for (i = 0; i < argsP->argCount; i++) {
	WriteCltDecl(&argsP->argDescr[i], itl_h, i);
    }
    fprintf(itl_h, "\tint error;\n\tint errFlag;\n\n");

    /* initialize IN/INOUT args */
    for (i = 0; i < argsP->argCount; i++) {
	WriteCltInit(&argsP->argDescr[i], itl_h, i, FALSE);
    }

    /* call the server */
    fprintf(itl_h, "\terror = A%s(conn, ", name);

    /* pass each arg */
    for (i = 0; i < argsP->argCount; i++) {
	WriteCltCall(&argsP->argDescr[i], itl_h, i);
	fprintf(itl_h, ((i < (argsP->argCount - 1))) ? "," : ");\n");
    }

    fprintf(itl_h,
	    "\tif (error != 0) {\n"
	    "\t\tprintf(\"C_%s failed %%d\\n\", error);\n"
	    "\t\tfflush(stdout);\n" "\t\treturn;\n" "\t}\n", name);

    /*
     * check the in and inout parameters
     */
    for (i = 0; i < argsP->argCount; i++) {

	if ((!strcmp(argsP->argDescr[i].direction, "OUT"))
	    || (!strcmp(argsP->argDescr[i].direction, "INOUT"))) {

	    typ = argsP->argDescr[i].type;

	    if (!strncmp(typ, "ar_", 3)) {
		for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
		    fprintf(itl_h,
			    "\n\tCHECK%s(a%d.drpc_out_%s_t_val[%d], %s, \"C_%s_s\");",
			    (typ + 3), i, typ, j,
			    argsP->argDescr[i].outValue[j], name);
	    } else if (strstr(typ, "String")) {
		fprintf(itl_h, "\n\tCHECK%s((char *)a%d, %s, \"C_%s_s\");",
			typ, i, argsP->argDescr[i].outValue[0], name);
	    } else if (!strcmp(typ, "afs_int32")) {
		fprintf(itl_h, "\n\tCHECK%s(a%d, %sL, \"C_%s_s\");", typ, i,
			argsP->argDescr[i].outValue[0], name);
	    } else {
		fprintf(itl_h, "\n\tCHECK%s(a%d, %s, \"C_%s_s\");", typ, i,
			argsP->argDescr[i].outValue[0], name);
	    }
	}
    }

    /*
     * free up memory for dynamic input args
     */
    for (i = 0; i < argsP->argCount; i++) {
	if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
	    typ = argsP->argDescr[i].type;
	    fprintf(itl_h,
		    "\n\tif (a%d.drpc_out_%s_t_val) "
		    "free(a%d.drpc_out_%s_t_val);", i, typ, i, typ);
	}
    }


    fprintf(itl_h, "\n}\n");

    /*
     * Call the structure oriented rpc interface
     */

    fprintf(itl_h, "\nvoid C_%s_s(struct rx_connection *conn) {\n", name);
    fprintf(itl_h, "\tstruct %s_t s;\n", name);
    fprintf(itl_h, "\tint error;\n\tint errFlag;\n\n");

    /* initialize IN/INOUT args */
    for (i = 0; i < argsP->argCount; i++) {
	WriteCltInit(&argsP->argDescr[i], itl_h, i, TRUE);
    }

    /* call the server */
    fprintf(itl_h, "\terror = A%s_s(conn, &s);\n", name);

    fprintf(itl_h,
	    "\tif (error != 0) {\n"
	    "\t\tprintf(\"C_%s_s failed %%d\\n\", error);\n"
	    "\t\tfflush(stdout);\n" "\t\treturn;\n" "\t}\n", name);

    /*
     * check the in and inout parameters
     */
    for (i = 0; i < argsP->argCount; i++) {

	if ((!strcmp(argsP->argDescr[i].direction, "OUT"))
	    || (!strcmp(argsP->argDescr[i].direction, "INOUT"))) {

	    typ = argsP->argDescr[i].type;

	    if (!strncmp(typ, "ar_", 3)) {
		for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
		    fprintf(itl_h, "\n\tCHECK%s(s.a%d[%d], %s, \"C_%s_s\");",
			    (typ + 3), i, j, argsP->argDescr[i].outValue[j],
			    name);
	    } else if (strstr(typ, "String")) {
		fprintf(itl_h, "\n\tCHECK%s((char *)s.a%d, %s, \"C_%s_s\");",
			typ, i, argsP->argDescr[i].outValue[0], name);
	    } else if (!strcmp(typ, "afs_int32")) {
		fprintf(itl_h, "\n\tCHECK%s(s.a%d, %sL, \"C_%s_s\");", typ, i,
			argsP->argDescr[i].outValue[0], name);
	    } else {
		fprintf(itl_h, "\n\tCHECK%s(s.a%d, %s, \"C_%s_s\");", typ, i,
			argsP->argDescr[i].outValue[0], name);
	    }
	}
    }


    fprintf(itl_h, "\n}\n");

    free(name);
    free(name2);
}
Exemple #5
0
//---------------------------------------------------------------------------//
  bool Material::operator==(const MaterialDesc& aDesc) const 
  {
    return GetDescription() == aDesc;
  }
Exemple #6
0
CPLXMLNode *VRTRasterBand::SerializeToXML( const char *pszVRTPath )

{
    CPLXMLNode *psTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTRasterBand" );

/* -------------------------------------------------------------------- */
/*      Various kinds of metadata.                                      */
/* -------------------------------------------------------------------- */
    CPLSetXMLValue( psTree, "#dataType",
                    GDALGetDataTypeName( GetRasterDataType() ) );

    if( nBand > 0 )
        CPLSetXMLValue( psTree, "#band", CPLSPrintf( "%d", GetBand() ) );

    CPLXMLNode *psMD = oMDMD.Serialize();
    if( psMD != NULL )
    {
        CPLAddXMLChild( psTree, psMD );
    }

    if( strlen(GetDescription()) > 0 )
        CPLSetXMLValue( psTree, "Description", GetDescription() );

    if( m_bNoDataValueSet )
    {
        if (CPLIsNan(m_dfNoDataValue))
            CPLSetXMLValue( psTree, "NoDataValue", "nan");
        else
            CPLSetXMLValue( psTree, "NoDataValue",
                            CPLSPrintf( "%.16g", m_dfNoDataValue ) );
    }

    if( m_bHideNoDataValue )
        CPLSetXMLValue( psTree, "HideNoDataValue",
                        CPLSPrintf( "%d", m_bHideNoDataValue ) );

    if( m_pszUnitType != NULL )
        CPLSetXMLValue( psTree, "UnitType", m_pszUnitType );

    if( m_dfOffset != 0.0 )
        CPLSetXMLValue( psTree, "Offset",
                        CPLSPrintf( "%.16g", m_dfOffset ) );

    if( m_dfScale != 1.0 )
        CPLSetXMLValue( psTree, "Scale",
                        CPLSPrintf( "%.16g", m_dfScale ) );

    if( m_eColorInterp != GCI_Undefined )
        CPLSetXMLValue( psTree, "ColorInterp",
                        GDALGetColorInterpretationName( m_eColorInterp ) );

/* -------------------------------------------------------------------- */
/*      Category names.                                                 */
/* -------------------------------------------------------------------- */
    if( m_papszCategoryNames != NULL )
    {
        CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element,
                                                 "CategoryNames" );
        CPLXMLNode* psLastChild = NULL;

        for( int iEntry=0; m_papszCategoryNames[iEntry] != NULL; iEntry++ )
        {
            CPLXMLNode *psNode = CPLCreateXMLElementAndValue( NULL, "Category",
                                         m_papszCategoryNames[iEntry] );
            if( psLastChild == NULL )
                psCT_XML->psChild = psNode;
            else
                psLastChild->psNext = psNode;
            psLastChild = psNode;
        }
    }

/* -------------------------------------------------------------------- */
/*      Histograms.                                                     */
/* -------------------------------------------------------------------- */
    if( m_psSavedHistograms != NULL )
        CPLAddXMLChild( psTree, CPLCloneXMLTree( m_psSavedHistograms ) );

/* -------------------------------------------------------------------- */
/*      Color Table.                                                    */
/* -------------------------------------------------------------------- */
    if( m_poColorTable != NULL )
    {
        CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element,
                                                 "ColorTable" );
        CPLXMLNode* psLastChild = NULL;

        for( int iEntry=0; iEntry < m_poColorTable->GetColorEntryCount();
             iEntry++ )
        {
            CPLXMLNode *psEntry_XML = CPLCreateXMLNode( NULL, CXT_Element,
                                                        "Entry" );
            if( psLastChild == NULL )
                psCT_XML->psChild = psEntry_XML;
            else
                psLastChild->psNext = psEntry_XML;
            psLastChild = psEntry_XML;

            GDALColorEntry sEntry;
            m_poColorTable->GetColorEntryAsRGB( iEntry, &sEntry );

            CPLSetXMLValue( psEntry_XML, "#c1", CPLSPrintf("%d",sEntry.c1) );
            CPLSetXMLValue( psEntry_XML, "#c2", CPLSPrintf("%d",sEntry.c2) );
            CPLSetXMLValue( psEntry_XML, "#c3", CPLSPrintf("%d",sEntry.c3) );
            CPLSetXMLValue( psEntry_XML, "#c4", CPLSPrintf("%d",sEntry.c4) );
        }
    }

/* ==================================================================== */
/*      Overviews                                                       */
/* ==================================================================== */

    for( int iOvr = 0; iOvr < static_cast<int>( m_apoOverviews.size() ); iOvr ++ )
    {
        CPLXMLNode *psOVR_XML = CPLCreateXMLNode( psTree, CXT_Element,
                                                 "Overview" );

        int bRelativeToVRT = FALSE;
        const char *pszRelativePath = NULL;
        VSIStatBufL sStat;

        if( VSIStatExL( m_apoOverviews[iOvr].osFilename, &sStat, VSI_STAT_EXISTS_FLAG ) != 0 )
        {
            pszRelativePath = m_apoOverviews[iOvr].osFilename;
            bRelativeToVRT = FALSE;
        }
        else
        {
            pszRelativePath =
                CPLExtractRelativePath( pszVRTPath, m_apoOverviews[iOvr].osFilename,
                                        &bRelativeToVRT );
        }

        CPLSetXMLValue( psOVR_XML, "SourceFilename", pszRelativePath );

        CPLCreateXMLNode(
            CPLCreateXMLNode( CPLGetXMLNode( psOVR_XML, "SourceFilename" ),
                            CXT_Attribute, "relativeToVRT" ),
            CXT_Text, bRelativeToVRT ? "1" : "0" );

        CPLSetXMLValue( psOVR_XML, "SourceBand",
                        CPLSPrintf("%d",m_apoOverviews[iOvr].nBand) );
    }

/* ==================================================================== */
/*      Mask band (specific to that raster band)                        */
/* ==================================================================== */

    if( m_poMaskBand != NULL )
    {
        CPLXMLNode *psBandTree =
            m_poMaskBand->SerializeToXML(pszVRTPath);

        if( psBandTree != NULL )
        {
            CPLXMLNode *psMaskBandElement = CPLCreateXMLNode( psTree, CXT_Element,
                                                              "MaskBand" );
            CPLAddXMLChild( psMaskBandElement, psBandTree );
        }
    }

    return psTree;
}
Exemple #7
0
void PrintLastErrorDescription() {
  fprintf(stderr, "%s\n", GetDescription(GetLastError()).c_str());
}
Exemple #8
0
CPLErr BTDataset::SetProjection( const char *pszNewProjection )

{
    CPLErr eErr = CE_None;

    CPLFree( pszProjection );
    pszProjection = CPLStrdup( pszNewProjection );

    bHeaderModified = TRUE;

/* -------------------------------------------------------------------- */
/*      Parse projection.                                               */
/* -------------------------------------------------------------------- */
    OGRSpatialReference oSRS( pszProjection );
    GInt16  nShortTemp;

/* -------------------------------------------------------------------- */
/*      Linear units.                                                   */
/* -------------------------------------------------------------------- */
    if( oSRS.IsGeographic() )
        nShortTemp = 0;
    else 
    {
        double dfLinear = oSRS.GetLinearUnits();

        if( ABS(dfLinear - 0.3048) < 0.0000001 )
            nShortTemp = 2;
        else if( ABS(dfLinear - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
            nShortTemp = 3;
        else
            nShortTemp = 1;
    }

    nShortTemp = CPL_LSBWORD16( 1 );
    memcpy( abyHeader + 22, &nShortTemp, 2 );
    
/* -------------------------------------------------------------------- */
/*      UTM Zone                                                        */
/* -------------------------------------------------------------------- */
    int bNorth;

    nShortTemp = (GInt16) oSRS.GetUTMZone( &bNorth );
    if( bNorth )
        nShortTemp = -nShortTemp;

    nShortTemp = CPL_LSBWORD16( nShortTemp );
    memcpy( abyHeader + 24, &nShortTemp, 2 );
    
/* -------------------------------------------------------------------- */
/*      Datum                                                           */
/* -------------------------------------------------------------------- */
    if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL
        && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") )
        nShortTemp = (GInt16) (atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" )) + 2000);
    else
        nShortTemp = -2;
    nShortTemp = CPL_LSBWORD16( nShortTemp ); /* datum unknown */
    memcpy( abyHeader + 26, &nShortTemp, 2 );

/* -------------------------------------------------------------------- */
/*      Write out the projection to a .prj file.                        */
/* -------------------------------------------------------------------- */
    const char  *pszPrjFile = CPLResetExtension( GetDescription(), "prj" );
    VSILFILE * fp;

    fp = VSIFOpenL( pszPrjFile, "wt" );
    if( fp != NULL )
    {
        VSIFPrintfL( fp, "%s\n", pszProjection );
        VSIFCloseL( fp );
        abyHeader[60] = 1;
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Unable to write out .prj file." );
        eErr = CE_Failure;
    }

    return eErr;
}
Exemple #9
0
OGRErr PDFWritableVectorDataset::SyncToDisk()
{
    if (nLayers == 0 || !bModified)
        return OGRERR_NONE;

    bModified = FALSE;

    OGREnvelope sGlobalExtent;
    int bHasExtent = FALSE;
    for(int i=0;i<nLayers;i++)
    {
        OGREnvelope sExtent;
        if (papoLayers[i]->GetExtent(&sExtent) == OGRERR_NONE)
        {
            bHasExtent = TRUE;
            sGlobalExtent.Merge(sExtent);
        }
    }
    if (!bHasExtent ||
        sGlobalExtent.MinX == sGlobalExtent.MaxX ||
        sGlobalExtent.MinY == sGlobalExtent.MaxY)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot compute spatial extent of features");
        return OGRERR_FAILURE;
    }

    PDFCompressMethod eStreamCompressMethod = COMPRESS_DEFLATE;
    const char* pszStreamCompressMethod = CSLFetchNameValue(papszOptions, "STREAM_COMPRESS");
    if (pszStreamCompressMethod)
    {
        if( EQUAL(pszStreamCompressMethod, "NONE") )
            eStreamCompressMethod = COMPRESS_NONE;
        else if( EQUAL(pszStreamCompressMethod, "DEFLATE") )
            eStreamCompressMethod = COMPRESS_DEFLATE;
        else
        {
            CPLError( CE_Warning, CPLE_NotSupported,
                    "Unsupported value for STREAM_COMPRESS.");
        }
    }

    const char* pszGEO_ENCODING =
        CSLFetchNameValueDef(papszOptions, "GEO_ENCODING", "ISO32000");

    const char* pszDPI = CSLFetchNameValue(papszOptions, "DPI");
    double dfDPI = DEFAULT_DPI;
    if( pszDPI != nullptr )
    {
        dfDPI = CPLAtof(pszDPI);
        if (dfDPI < DEFAULT_DPI)
            dfDPI = DEFAULT_DPI;
    }
    else
    {
        dfDPI = DEFAULT_DPI;
    }

    const char* pszWriteUserUnit = CSLFetchNameValue(papszOptions, "WRITE_USERUNIT");
    bool bWriteUserUnit;
    if( pszWriteUserUnit != nullptr )
        bWriteUserUnit = CPLTestBool( pszWriteUserUnit );
    else
        bWriteUserUnit = ( pszDPI == nullptr );

    const char* pszNEATLINE = CSLFetchNameValue(papszOptions, "NEATLINE");

    int nMargin = atoi(CSLFetchNameValueDef(papszOptions, "MARGIN", "0"));

    PDFMargins sMargins;
    sMargins.nLeft = nMargin;
    sMargins.nRight = nMargin;
    sMargins.nTop = nMargin;
    sMargins.nBottom = nMargin;

    const char* pszLeftMargin = CSLFetchNameValue(papszOptions, "LEFT_MARGIN");
    if (pszLeftMargin) sMargins.nLeft = atoi(pszLeftMargin);

    const char* pszRightMargin = CSLFetchNameValue(papszOptions, "RIGHT_MARGIN");
    if (pszRightMargin) sMargins.nRight = atoi(pszRightMargin);

    const char* pszTopMargin = CSLFetchNameValue(papszOptions, "TOP_MARGIN");
    if (pszTopMargin) sMargins.nTop = atoi(pszTopMargin);

    const char* pszBottomMargin = CSLFetchNameValue(papszOptions, "BOTTOM_MARGIN");
    if (pszBottomMargin) sMargins.nBottom = atoi(pszBottomMargin);

    const char* pszExtraImages = CSLFetchNameValue(papszOptions, "EXTRA_IMAGES");
    const char* pszExtraStream = CSLFetchNameValue(papszOptions, "EXTRA_STREAM");
    const char* pszExtraLayerName = CSLFetchNameValue(papszOptions, "EXTRA_LAYER_NAME");

    const char* pszOGRDisplayField = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_FIELD");
    const char* pszOGRDisplayLayerNames = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_LAYER_NAMES");
    const bool bWriteOGRAttributes =
        CPLFetchBool(papszOptions, "OGR_WRITE_ATTRIBUTES", true);
    const char* pszOGRLinkField = CSLFetchNameValue(papszOptions, "OGR_LINK_FIELD");

    const char* pszOffLayers = CSLFetchNameValue(papszOptions, "OFF_LAYERS");
    const char* pszExclusiveLayers = CSLFetchNameValue(papszOptions, "EXCLUSIVE_LAYERS");

    const char* pszJavascript = CSLFetchNameValue(papszOptions, "JAVASCRIPT");
    const char* pszJavascriptFile = CSLFetchNameValue(papszOptions, "JAVASCRIPT_FILE");

/* -------------------------------------------------------------------- */
/*      Create file.                                                    */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(GetDescription(), "wb");
    if( fp == nullptr )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Unable to create PDF file %s.\n",
                  GetDescription() );
        return OGRERR_FAILURE;
    }

    GDALPDFWriter oWriter(fp);

    double dfRatio = (sGlobalExtent.MaxY - sGlobalExtent.MinY) / (sGlobalExtent.MaxX - sGlobalExtent.MinX);

    int nWidth, nHeight;

    if (dfRatio < 1)
    {
        nWidth = 1024;
        nHeight = static_cast<int>(nWidth * dfRatio);
    }
    else
    {
        nHeight = 1024;
        nWidth = static_cast<int>(nHeight / dfRatio);
    }

    GDALDataset* poSrcDS = MEMDataset::Create( "MEM:::", nWidth, nHeight, 0, GDT_Byte, nullptr );

    double adfGeoTransform[6];
    adfGeoTransform[0] = sGlobalExtent.MinX;
    adfGeoTransform[1] = (sGlobalExtent.MaxX - sGlobalExtent.MinX) / nWidth;
    adfGeoTransform[2] = 0;
    adfGeoTransform[3] = sGlobalExtent.MaxY;
    adfGeoTransform[4] = 0;
    adfGeoTransform[5] = - (sGlobalExtent.MaxY - sGlobalExtent.MinY) / nHeight;

    poSrcDS->SetGeoTransform(adfGeoTransform);

    OGRSpatialReference* poSRS = papoLayers[0]->GetSpatialRef();
    if (poSRS)
    {
        char* pszWKT = nullptr;
        poSRS->exportToWkt(&pszWKT);
        poSrcDS->SetProjection(pszWKT);
        CPLFree(pszWKT);
    }

    oWriter.SetInfo(poSrcDS, papszOptions);

    oWriter.StartPage(poSrcDS,
                      dfDPI,
                      bWriteUserUnit,
                      pszGEO_ENCODING,
                      pszNEATLINE,
                      &sMargins,
                      eStreamCompressMethod,
                      bWriteOGRAttributes);

    int iObj = 0;

    char** papszLayerNames = CSLTokenizeString2(pszOGRDisplayLayerNames,",",0);

    for(int i=0;i<nLayers;i++)
    {
        CPLString osLayerName;
        if (CSLCount(papszLayerNames) < nLayers)
            osLayerName = papoLayers[i]->GetName();
        else
            osLayerName = papszLayerNames[i];

        oWriter.WriteOGRLayer((OGRDataSourceH)this,
                              i,
                              pszOGRDisplayField,
                              pszOGRLinkField,
                              osLayerName,
                              bWriteOGRAttributes,
                              iObj);
    }

    CSLDestroy(papszLayerNames);

    oWriter.EndPage(pszExtraImages,
                    pszExtraStream,
                    pszExtraLayerName,
                    pszOffLayers,
                    pszExclusiveLayers);

    if (pszJavascript)
        oWriter.WriteJavascript(pszJavascript);
    else if (pszJavascriptFile)
        oWriter.WriteJavascriptFile(pszJavascriptFile);

    oWriter.Close();

    delete poSrcDS;

    return OGRERR_NONE;
}