Пример #1
2
OGRFeature *OGRDWGLayer::TranslateDIMENSION( OdDbEntityPtr poEntity )

{
    OdDbDimensionPtr poDim = OdDbDimension::cast( poEntity );
    OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

    double dfHeight = CPLAtof(poDS->GetVariable("$DIMTXT", "2.5"));
    OdGePoint3d oTextPos, oTarget1, oTarget2, oArrow1;
    CPLString osText;

    TranslateGenericProperties( poFeature, poEntity );

/* -------------------------------------------------------------------- */
/*      Generic Dimension stuff.                                        */
/* -------------------------------------------------------------------- */
    osText = (const char *) poDim->dimensionText();

    oTextPos = poDim->textPosition();

/* -------------------------------------------------------------------- */
/*      Specific based on the subtype.                                  */
/* -------------------------------------------------------------------- */
    OdRxClass *poClass = poEntity->isA();
    const OdString osName = poClass->name();
    const char *pszEntityClassName = (const char *) osName;

    if( EQUAL(pszEntityClassName,"AcDbRotatedDimension") )
    {
        OdDbRotatedDimensionPtr poRDim = OdDbDimension::cast( poEntity );

        oTarget2 = poRDim->xLine1Point();
        oTarget1 = poRDim->xLine2Point();
        oArrow1 = poRDim->dimLinePoint();
    }

    else if( EQUAL(pszEntityClassName,"AcDbAlignedDimension") )
    {
        OdDbAlignedDimensionPtr poADim = OdDbDimension::cast( poEntity );

        oTarget2 = poADim->xLine1Point();
        oTarget1 = poADim->xLine2Point();
        oArrow1 = poADim->dimLinePoint();
    }

/*************************************************************************

   DIMENSION geometry layout

                  (11,21)(text center point)
        |          DimText                  |
(10,20) X<--------------------------------->X (Arrow2 - computed)
(Arrow1)|                                   |
        |                                   |
        |                                   X (13,23) (Target2)
        |
        X (14,24) (Target1)

Given:
  Locations Arrow1, Target1, and Target2 we need to compute Arrow2.

Steps:
 1) Compute direction vector from Target1 to Arrow1 (Vec1).
 2) Compute direction vector for arrow as perpendicular to Vec1 (call Vec2).
 3) Compute Arrow2 location as intersection between line defined by
    Vec2 and Arrow1 and line defined by Target2 and direction Vec1 (call Arrow2)

Then we can draw lines for the various components.

Note that Vec1 and Vec2 may be horizontal, vertical or on an angle but
the approach is as above in all these cases.

*************************************************************************/

/* -------------------------------------------------------------------- */
/*      Step 1, compute direction vector between Target1 and Arrow1.    */
/* -------------------------------------------------------------------- */
    double dfVec1X, dfVec1Y;

    dfVec1X = (oArrow1.x - oTarget1.x);
    dfVec1Y = (oArrow1.y - oTarget1.y);

/* -------------------------------------------------------------------- */
/*      Step 2, compute the direction vector from Arrow1 to Arrow2      */
/*      as a perpendicular to Vec1.                                     */
/* -------------------------------------------------------------------- */
    double dfVec2X, dfVec2Y;

    dfVec2X = dfVec1Y;
    dfVec2Y = -dfVec1X;

/* -------------------------------------------------------------------- */
/*      Step 3, compute intersection of line from target2 along         */
/*      direction vector 1, with the line through Arrow1 and            */
/*      direction vector 2.                                             */
/* -------------------------------------------------------------------- */
    double dfL1M, dfL1B, dfL2M, dfL2B;
    double dfArrowX2, dfArrowY2;

    // special case if vec1 is vertical.
    if( dfVec1X == 0.0 )
    {
        dfArrowX2 = oTarget2.x;
        dfArrowY2 = oArrow1.y;
    }

    // special case if vec2 is horizontal.
    else if( dfVec1Y == 0.0 )
    {
        dfArrowX2 = oArrow1.x;
        dfArrowY2 = oTarget2.y;
    }

    else // General case for diagonal vectors.
    {
        // first convert vec1 + target2 into y = mx + b format: call this L1

        dfL1M = dfVec1Y / dfVec1X;
        dfL1B = oTarget2.y - dfL1M * oTarget2.x;

        // convert vec2 + Arrow1 into y = mx + b format, call this L2

        dfL2M = dfVec2Y / dfVec2X;
        dfL2B = oArrow1.y - dfL2M * oArrow1.x;

        // Compute intersection x = (b2-b1) / (m1-m2)

        dfArrowX2 = (dfL2B - dfL1B) / (dfL1M-dfL2M);
        dfArrowY2 = dfL2M * dfArrowX2 + dfL2B;
    }

/* -------------------------------------------------------------------- */
/*      Compute the text angle.                                         */
/* -------------------------------------------------------------------- */
    double dfAngle = atan2(dfVec2Y,dfVec2X) * 180.0 / M_PI;

/* -------------------------------------------------------------------- */
/*      Rescale the direction vectors so we can use them in             */
/*      constructing arrowheads.  We want them to be about 3% of the    */
/*      length of line on which the arrows will be drawn.               */
/* -------------------------------------------------------------------- */
#define VECTOR_LEN(x,y) sqrt( (x)*(x) + (y)*(y) )
#define POINT_DIST(x1,y1,x2,y2)  VECTOR_LEN((x2-x1),(y2-y1))

    double dfBaselineLength = POINT_DIST(oArrow1.x,oArrow1.y,
                                         dfArrowX2,dfArrowY2);
    double dfTargetLength = dfBaselineLength * 0.03;
    double dfScaleFactor;

    // recompute vector 2 to ensure the direction is regular
    dfVec2X = (dfArrowX2 - oArrow1.x);
    dfVec2Y = (dfArrowY2 - oArrow1.y);

    // vector 1
    dfScaleFactor = dfTargetLength / VECTOR_LEN(dfVec1X,dfVec1Y);
    dfVec1X *= dfScaleFactor;
    dfVec1Y *= dfScaleFactor;

    // vector 2
    dfScaleFactor = dfTargetLength / VECTOR_LEN(dfVec2X,dfVec2Y);
    dfVec2X *= dfScaleFactor;
    dfVec2Y *= dfScaleFactor;

/* -------------------------------------------------------------------- */
/*      Create geometries for the different components of the           */
/*      dimension object.                                               */
/* -------------------------------------------------------------------- */
    OGRMultiLineString *poMLS = new OGRMultiLineString();
    OGRLineString oLine;

    // main arrow line between Arrow1 and Arrow2
    oLine.setPoint( 0, oArrow1.x, oArrow1.y );
    oLine.setPoint( 1, dfArrowX2, dfArrowY2 );
    poMLS->addGeometry( &oLine );

    // dimension line from Target1 to Arrow1 with a small extension.
    oLine.setPoint( 0, oTarget1.x, oTarget1.y );
    oLine.setPoint( 1, oArrow1.x + dfVec1X, oArrow1.y + dfVec1Y );
    poMLS->addGeometry( &oLine );

    // dimension line from Target2 to Arrow2 with a small extension.
    oLine.setPoint( 0, oTarget2.x, oTarget2.y );
    oLine.setPoint( 1, dfArrowX2 + dfVec1X, dfArrowY2 + dfVec1Y );
    poMLS->addGeometry( &oLine );

    // add arrow1 arrow head.

    oLine.setPoint( 0, oArrow1.x, oArrow1.y );
    oLine.setPoint( 1,
                    oArrow1.x + dfVec2X*3 + dfVec1X,
                    oArrow1.y + dfVec2Y*3 + dfVec1Y );
    poMLS->addGeometry( &oLine );

    oLine.setPoint( 0, oArrow1.x, oArrow1.y );
    oLine.setPoint( 1,
                    oArrow1.x + dfVec2X*3 - dfVec1X,
                    oArrow1.y + dfVec2Y*3 - dfVec1Y );
    poMLS->addGeometry( &oLine );

    // add arrow2 arrow head.

    oLine.setPoint( 0, dfArrowX2, dfArrowY2 );
    oLine.setPoint( 1,
                    dfArrowX2 - dfVec2X*3 + dfVec1X,
                    dfArrowY2 - dfVec2Y*3 + dfVec1Y );
    poMLS->addGeometry( &oLine );

    oLine.setPoint( 0, dfArrowX2, dfArrowY2 );
    oLine.setPoint( 1,
                    dfArrowX2 - dfVec2X*3 - dfVec1X,
                    dfArrowY2 - dfVec2Y*3 - dfVec1Y );
    poMLS->addGeometry( &oLine );

    poFeature->SetGeometryDirectly( poMLS );

    PrepareLineStyle( poFeature );

/* -------------------------------------------------------------------- */
/*      Is the layer disabled/hidden/frozen/off?                        */
/* -------------------------------------------------------------------- */
    CPLString osLayer = poFeature->GetFieldAsString("Layer");

    int bHidden =
        EQUAL(poDS->LookupLayerProperty( osLayer, "Hidden" ), "1");

/* -------------------------------------------------------------------- */
/*      Work out the color for this feature.                            */
/* -------------------------------------------------------------------- */
    int nColor = 256;

    if( oStyleProperties.count("Color") > 0 )
        nColor = atoi(oStyleProperties["Color"]);

    // Use layer color?
    if( nColor < 1 || nColor > 255 )
    {
        const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" );
        if( pszValue != NULL )
            nColor = atoi(pszValue);
    }

    if( nColor < 1 || nColor > 255 )
        nColor = 8;

/* -------------------------------------------------------------------- */
/*      Prepare a new feature to serve as the dimension text label      */
/*      feature.  We will push it onto the layer as a pending           */
/*      feature for the next feature read.                              */
/* -------------------------------------------------------------------- */

    // a single space suppresses labeling.
    if( osText == " " )
        return poFeature;

    OGRFeature *poLabelFeature = poFeature->Clone();

    poLabelFeature->SetGeometryDirectly( new OGRPoint( oTextPos.x, oTextPos.y ) );

    // Do we need to compute the dimension value?
    if( osText.empty() )
    {
        FormatDimension( osText, POINT_DIST( oArrow1.x, oArrow1.y,
                                             dfArrowX2, dfArrowY2 ) );
    }

    CPLString osStyle;
    char szBuffer[64];
    char* pszComma = NULL;

    osStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",p:5",osText.c_str());

    if( dfAngle != 0.0 )
    {
        CPLsnprintf(szBuffer, sizeof(szBuffer), "%.3g", dfAngle);
        pszComma = strchr(szBuffer, ',');
        if (pszComma)
            *pszComma = '.';
        osStyle += CPLString().Printf(",a:%s", szBuffer);
    }

    if( dfHeight != 0.0 )
    {
        CPLsnprintf(szBuffer, sizeof(szBuffer), "%.3g", dfHeight);
        pszComma = strchr(szBuffer, ',');
        if (pszComma)
            *pszComma = '.';
        osStyle += CPLString().Printf(",s:%sg", szBuffer);
    }

    const unsigned char *pabyDWGColors = ACGetColorTable();

    snprintf( szBuffer, sizeof(szBuffer), ",c:#%02x%02x%02x",
              pabyDWGColors[nColor*3+0],
              pabyDWGColors[nColor*3+1],
              pabyDWGColors[nColor*3+2] );
    osStyle += szBuffer;

    if( bHidden )
        osStyle += "00";

    osStyle += ")";

    poLabelFeature->SetStyleString( osStyle );

    apoPendingFeatures.push( poLabelFeature );

    return poFeature;
}
Пример #2
0
void OGRPGResultLayer::SetSpatialFilter( int iGeomField, OGRGeometry * poGeomIn )

{
    if( iGeomField < 0 || iGeomField >= GetLayerDefn()->GetGeomFieldCount() ||
        GetLayerDefn()->GetGeomFieldDefn(iGeomField)->GetType() == wkbNone )
    {
        if( iGeomField != 0 )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Invalid geometry field index : %d", iGeomField);
        }
        return;
    }
    m_iGeomFieldFilter = iGeomField;

    OGRPGGeomFieldDefn* poGeomFieldDefn =
        poFeatureDefn->myGetGeomFieldDefn(m_iGeomFieldFilter);
    if( InstallFilter( poGeomIn ) )
    {
        if ( poGeomFieldDefn->ePostgisType == GEOM_TYPE_GEOMETRY ||
             poGeomFieldDefn->ePostgisType == GEOM_TYPE_GEOGRAPHY )
        {
            if( m_poFilterGeom != NULL)
            {
                char szBox3D_1[128];
                char szBox3D_2[128];
                OGREnvelope  sEnvelope;

                m_poFilterGeom->getEnvelope( &sEnvelope );
                if( poGeomFieldDefn->ePostgisType == GEOM_TYPE_GEOGRAPHY )
                {
                    if( sEnvelope.MinX < -180.0 )
                        sEnvelope.MinX = -180.0;
                    if( sEnvelope.MinY < -90.0 )
                        sEnvelope.MinY = -90.0;
                    if( sEnvelope.MaxX > 180.0 )
                        sEnvelope.MaxX = 180.0;
                    if( sEnvelope.MaxY > 90.0 )
                        sEnvelope.MaxY = 90.0;
                }
                CPLsnprintf(szBox3D_1, sizeof(szBox3D_1), "%.18g %.18g", sEnvelope.MinX, sEnvelope.MinY);
                CPLsnprintf(szBox3D_2, sizeof(szBox3D_2), "%.18g %.18g", sEnvelope.MaxX, sEnvelope.MaxY);
                osWHERE.Printf("WHERE %s && %s('BOX3D(%s, %s)'::box3d,%d) ",
                               OGRPGEscapeColumnName(poGeomFieldDefn->GetNameRef()).c_str(),
                               (poDS->sPostGISVersion.nMajor >= 2) ? "ST_SetSRID" : "SetSRID",
                               szBox3D_1, szBox3D_2, poGeomFieldDefn->nSRSId );
            }
            else
            {
                osWHERE = "";
            }

            BuildFullQueryStatement();
        }

        ResetReading();
    }

}
Пример #3
0
CPLErr PAuxRasterBand::SetNoDataValue( double dfNewValue )

{
    if( GetAccess() == GA_ReadOnly )
    {
        CPLError( CE_Failure, CPLE_NoWriteAccess,
                  "Can't update readonly dataset." );
        return CE_Failure;
    }

    char szTarget[128] = { '\0' };
    char szValue[128] = { '\0' };
    snprintf( szTarget, sizeof(szTarget),
              "METADATA_IMG_%d_NO_DATA_VALUE", nBand );
    CPLsnprintf( szValue, sizeof(szValue),
                 "%24.12f", dfNewValue );

    PAuxDataset *poPDS = reinterpret_cast<PAuxDataset *>( poDS );
    poPDS->papszAuxLines =
        CSLSetNameValue( poPDS->papszAuxLines, szTarget, szValue );

    poPDS->bAuxUpdated = TRUE;

    return CE_None;
}
Пример #4
0
static int json_gme_double_to_string(json_object *pjo,
                                     printbuf *pb,
                                     CPL_UNUSED int level,
                                     CPL_UNUSED int flags)
{
  char buf[128], *p, *q;
  int size;

  size = CPLsnprintf(buf, 128, "%.8f", json_object_get_double(pjo));
  p = strchr(buf, ',');
  if (p) {
    *p = '.';
  } else {
    p = strchr(buf, '.');
  }
  if (p) {
    /* last useful digit, always keep 1 zero */
    p++;
    for (q=p ; *q ; q++) {
      if (*q!='0') p=q;
    }
    /* drop trailing zeroes */
    *(++p) = 0;
    size = p-buf;
  }
  printbuf_memappend(pb, buf, size);
  return size;
}
Пример #5
0
void OGRCARTODBTableLayer::BuildWhere()

{
    osWHERE = "";

    if( m_poFilterGeom != NULL &&
        m_iGeomFieldFilter >= 0 &&
        m_iGeomFieldFilter < poFeatureDefn->GetGeomFieldCount() )
    {
        OGREnvelope  sEnvelope;

        m_poFilterGeom->getEnvelope( &sEnvelope );

        CPLString osGeomColumn(poFeatureDefn->GetGeomFieldDefn(m_iGeomFieldFilter)->GetNameRef());

        char szBox3D_1[128];
        char szBox3D_2[128];
        char* pszComma;

        CPLsnprintf(szBox3D_1, sizeof(szBox3D_1), "%.18g %.18g", sEnvelope.MinX, sEnvelope.MinY);
        while((pszComma = strchr(szBox3D_1, ',')) != NULL)
            *pszComma = '.';
        CPLsnprintf(szBox3D_2, sizeof(szBox3D_2), "%.18g %.18g", sEnvelope.MaxX, sEnvelope.MaxY);
        while((pszComma = strchr(szBox3D_2, ',')) != NULL)
            *pszComma = '.';
        osWHERE.Printf("(%s && 'BOX3D(%s, %s)'::box3d)",
                       OGRCARTODBEscapeIdentifier(osGeomColumn).c_str(),
                       szBox3D_1, szBox3D_2 );
    }

    if( strlen(osQuery) > 0 )
    {
        if( osWHERE.size() > 0 )
            osWHERE += " AND ";
        osWHERE += osQuery;
    }

    if( osFIDColName.size() == 0 )
    {
        osBaseSQL = osSELECTWithoutWHERE;
        if( osWHERE.size() )
        {
            osBaseSQL += " WHERE ";
            osBaseSQL += osWHERE;
        }
    }
}
Пример #6
0
int OGRDXFWriterLayer::WriteValue( int nCode, double dfValue )

{
    char szLinePair[64];

    CPLsnprintf(szLinePair, sizeof(szLinePair), "%3d\n%.15g\n", nCode, dfValue );
    size_t nLen = strlen(szLinePair);

    return VSIFWriteL( szLinePair,
                       1, nLen, fp ) == nLen;
}
Пример #7
0
void OGRMySQLTableLayer::BuildWhere()

{
    CPLFree( pszWHERE );
    const size_t nWHERELen = 500 + ((pszQuery) ? strlen(pszQuery) : 0);
    pszWHERE = (char*)CPLMalloc(nWHERELen);
    pszWHERE[0] = '\0';

    if( m_poFilterGeom != nullptr && pszGeomColumn )
    {
        char szEnvelope[400];
        OGREnvelope  sEnvelope;
        szEnvelope[0] = '\0';

        //POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
        m_poFilterGeom->getEnvelope( &sEnvelope );

        CPLsnprintf(szEnvelope, sizeof(szEnvelope),
                "POLYGON((%.18g %.18g, %.18g %.18g, %.18g %.18g, %.18g %.18g, %.18g %.18g))",
                sEnvelope.MinX, sEnvelope.MinY,
                sEnvelope.MaxX, sEnvelope.MinY,
                sEnvelope.MaxX, sEnvelope.MaxY,
                sEnvelope.MinX, sEnvelope.MaxY,
                sEnvelope.MinX, sEnvelope.MinY);

        const char* pszAxisOrder = "";
        OGRSpatialReference* l_poSRS = GetSpatialRef();
        if( poDS->GetMajorVersion() >= 8 && !poDS->IsMariaDB() &&
            l_poSRS && l_poSRS->IsGeographic() )
        {
            pszAxisOrder = ", 'axis-order=long-lat'";
        }

        snprintf( pszWHERE, nWHERELen,
                 "WHERE MBRIntersects(%s('%s', %d%s), `%s`)",
                 poDS->GetMajorVersion() >= 8 ? "ST_GeomFromText" : "GeomFromText",
                 szEnvelope,
                 nSRSId,
                 pszAxisOrder,
                 pszGeomColumn);
    }

    if( pszQuery != nullptr )
    {
        if( strlen(pszWHERE) == 0 )
            snprintf( pszWHERE, nWHERELen, "WHERE %s ", pszQuery  );
        else
            snprintf( pszWHERE+strlen(pszWHERE),
                      nWHERELen - strlen(pszWHERE), "&& (%s) ", pszQuery );
    }
}
Пример #8
0
static int OGR_json_double_with_precision_to_string(struct json_object *jso,
                                                    struct printbuf *pb,
                                                    CPL_UNUSED int level,
                                                    CPL_UNUSED int flags)
{
    char szBuffer[75];
    int nPrecision = (int) (size_t) jso->_userdata;
    OGRFormatDouble( szBuffer, sizeof(szBuffer), jso->o.c_double, '.',
                     (nPrecision < 0) ? 15 : nPrecision );
    if( szBuffer[0] == 't' /*oobig */ )
    {
        CPLsnprintf(szBuffer, sizeof(szBuffer), "%.18g", jso->o.c_double);
    }
    return printbuf_memappend(pb, szBuffer, strlen(szBuffer)); 
}
Пример #9
0
CPLString &CPLString::FormatC( double dfValue, const char *pszFormat )

{
    if( pszFormat == NULL )
        pszFormat = "%g";

    // presumably long enough for any number.
    const size_t buf_size = 512;
    char szWork[buf_size];

    CPLsnprintf( szWork, buf_size, pszFormat, dfValue );

    *this += szWork;

    return *this;
}
Пример #10
0
static bool WriteValue( VSILFILE *fp, int nCode, double dfValue )

{
    char szLinePair[64];

    CPLsnprintf(szLinePair, sizeof(szLinePair), "%3d\n%.15g\n", nCode, dfValue );
    size_t nLen = strlen(szLinePair);
    if( VSIFWriteL( szLinePair, 1, nLen, fp ) != nLen )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Attempt to write line to DXF file failed, disk full?." );
        return false;
    }

    return true;
}
Пример #11
0
CPLErr PAuxDataset::SetGeoTransform( double * padfGeoTransform )

{
    char szUpLeftX[128] = { '\0' };
    char szUpLeftY[128] = { '\0' };
    char szLoRightX[128] = { '\0' };
    char szLoRightY[128] = { '\0' };

    if( std::abs(padfGeoTransform[0]) < 181
        && std::abs(padfGeoTransform[1]) < 1 )
    {
        CPLsnprintf( szUpLeftX, sizeof(szUpLeftX), "%.12f",
                     padfGeoTransform[0] );
        CPLsnprintf( szUpLeftY, sizeof(szUpLeftY), "%.12f",
                     padfGeoTransform[3] );
        CPLsnprintf( szLoRightX, sizeof(szLoRightX), "%.12f",
                     padfGeoTransform[0] +
                     padfGeoTransform[1] * GetRasterXSize() );
        CPLsnprintf( szLoRightY, sizeof(szLoRightY), "%.12f",
                     padfGeoTransform[3] +
                     padfGeoTransform[5] * GetRasterYSize() );
    }
    else
    {
        CPLsnprintf( szUpLeftX, sizeof(szUpLeftX), "%.3f",
                     padfGeoTransform[0] );
        CPLsnprintf( szUpLeftY, sizeof(szUpLeftY), "%.3f",
                     padfGeoTransform[3] );
        CPLsnprintf( szLoRightX, sizeof(szLoRightX), "%.3f",
                     padfGeoTransform[0] +
                     padfGeoTransform[1] * GetRasterXSize() );
        CPLsnprintf( szLoRightY, sizeof(szLoRightY), "%.3f",
                     padfGeoTransform[3] +
                     padfGeoTransform[5] * GetRasterYSize() );
    }

    papszAuxLines = CSLSetNameValue( papszAuxLines, "UpLeftX", szUpLeftX );
    papszAuxLines = CSLSetNameValue( papszAuxLines, "UpLeftY", szUpLeftY );
    papszAuxLines = CSLSetNameValue( papszAuxLines, "LoRightX", szLoRightX );
    papszAuxLines = CSLSetNameValue( papszAuxLines, "LoRightY", szLoRightY );

    bAuxUpdated = TRUE;

    return CE_None;
}
Пример #12
0
void OGRDWGLayer::FormatDimension( CPLString &osText, double dfValue )

{
    int nPrecision = atoi(poDS->GetVariable("$LUPREC","4"));
    char szFormat[32];
    char szBuffer[64];

    // we could do a significantly more precise formatting if we want
    // to spend the effort.  See QCAD's rs_dimlinear.cpp and related files
    // for example.

    snprintf(szFormat, sizeof(szFormat), "%%.%df", nPrecision );
    CPLsnprintf(szBuffer, sizeof(szBuffer), szFormat, dfValue);
    char* pszComma = strchr(szBuffer, ',');
    if (pszComma)
        *pszComma = '.';
    osText = szBuffer;
}
Пример #13
0
CPLXMLNode *VRTKernelFilteredSource::SerializeToXML( const char *pszVRTPath )

{
    CPLXMLNode *psSrc = VRTFilteredSource::SerializeToXML( pszVRTPath );

    if( psSrc == nullptr )
        return nullptr;

    CPLFree( psSrc->pszValue );
    psSrc->pszValue = CPLStrdup("KernelFilteredSource" );

    if( m_nKernelSize == 0 )
        return psSrc;

    CPLXMLNode *psKernel = CPLCreateXMLNode( psSrc, CXT_Element, "Kernel" );

    if( m_bNormalized )
        CPLCreateXMLNode(
            CPLCreateXMLNode( psKernel, CXT_Attribute, "normalized" ),
            CXT_Text, "1" );
    else
        CPLCreateXMLNode(
            CPLCreateXMLNode( psKernel, CXT_Attribute, "normalized" ),
            CXT_Text, "0" );

    const int nCoefCount = m_nKernelSize * m_nKernelSize;
    const size_t nBufLen = nCoefCount * 32;
    char *pszKernelCoefs = static_cast<char *>( CPLMalloc(nBufLen) );

    strcpy( pszKernelCoefs, "" );
    for( int iCoef = 0; iCoef < nCoefCount; iCoef++ )
        CPLsnprintf( pszKernelCoefs + strlen(pszKernelCoefs),
                     nBufLen - strlen(pszKernelCoefs),
                     "%.8g ", m_padfKernelCoefs[iCoef] );

    CPLSetXMLValue( psKernel, "Size", CPLSPrintf( "%d", m_nKernelSize ) );
    CPLSetXMLValue( psKernel, "Coefs", pszKernelCoefs );

    CPLFree( pszKernelCoefs );

    return psSrc;
}
Пример #14
0
void OGRMySQLTableLayer::BuildWhere()

{
    CPLFree( pszWHERE );
    const size_t nWHERELen = 500 + ((pszQuery) ? strlen(pszQuery) : 0);
    pszWHERE = (char*)CPLMalloc(nWHERELen);
    pszWHERE[0] = '\0';

    if( m_poFilterGeom != NULL && pszGeomColumn )
    {
        char szEnvelope[400];
        OGREnvelope  sEnvelope;
        szEnvelope[0] = '\0';

        //POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
        m_poFilterGeom->getEnvelope( &sEnvelope );

        CPLsnprintf(szEnvelope, sizeof(szEnvelope),
                "POLYGON((%.18g %.18g, %.18g %.18g, %.18g %.18g, %.18g %.18g, %.18g %.18g))",
                sEnvelope.MinX, sEnvelope.MinY,
                sEnvelope.MaxX, sEnvelope.MinY,
                sEnvelope.MaxX, sEnvelope.MaxY,
                sEnvelope.MinX, sEnvelope.MaxY,
                sEnvelope.MinX, sEnvelope.MinY);

        snprintf( pszWHERE, nWHERELen,
                 "WHERE MBRIntersects(GeomFromText('%s'), `%s`)",
                 szEnvelope,
                 pszGeomColumn);

    }

    if( pszQuery != NULL )
    {
        if( strlen(pszWHERE) == 0 )
            snprintf( pszWHERE, nWHERELen, "WHERE %s ", pszQuery  );
        else
            snprintf( pszWHERE+strlen(pszWHERE),
                      nWHERELen - strlen(pszWHERE), "&& (%s) ", pszQuery );
    }
}
Пример #15
0
std::string ods_formula_node::TransformToString() const
{
    char szTmp[128];
    if (field_type == ODS_FIELD_TYPE_INTEGER)
    {
        snprintf(szTmp, sizeof(szTmp), "%d", int_value);
        return szTmp;
    }
    else if (field_type == ODS_FIELD_TYPE_FLOAT)
    {
        CPLsnprintf(szTmp, sizeof(szTmp), "%.16g", float_value);
        return szTmp;
    }
    else if (field_type == ODS_FIELD_TYPE_STRING)
    {
        return string_value;
    }
    else
    {
        return "";
    }
}
Пример #16
0
OGRGPXDataSource::~OGRGPXDataSource()

{
    if ( fpOutput != NULL )
    {
        if (nLastRteId != -1)
            PrintLine("</rte>");
        else if (nLastTrkId != -1)
        {
            PrintLine("  </trkseg>");
            PrintLine("</trk>");
        }
        PrintLine("</gpx>");
        if ( bIsBackSeekable )
        {
            /* Write the <bound> element in the reserved space */
            if (dfMinLon <= dfMaxLon)
            {
                char szMetadata[SPACE_FOR_METADATA+1];
                int nRet = CPLsnprintf(szMetadata, SPACE_FOR_METADATA,
                         "<metadata><bounds minlat=\"%.15f\" minlon=\"%.15f\" maxlat=\"%.15f\" maxlon=\"%.15f\"/></metadata>",
                        dfMinLat, dfMinLon, dfMaxLat, dfMaxLon);
                if (nRet < SPACE_FOR_METADATA)
                {
                    VSIFSeekL(fpOutput, nOffsetBounds, SEEK_SET);
                    VSIFWriteL(szMetadata, 1, strlen(szMetadata), fpOutput);
                }
            }
            VSIFCloseL( fpOutput);
        }
    }

    for( int i = 0; i < nLayers; i++ )
        delete papoLayers[i];
    CPLFree( papoLayers );
    CPLFree( pszExtensionsNS );
    CPLFree( pszName );
    CPLFree( pszVersion );
}
Пример #17
0
GDALDataset * AAIGDataset::CreateCopy(
    const char *pszFilename, GDALDataset *poSrcDS,
    int /* bStrict */,
    char **papszOptions,
    GDALProgressFunc pfnProgress, void *pProgressData )
{
    const int nBands = poSrcDS->GetRasterCount();
    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();

    // Some rudimentary checks.
    if( nBands != 1 )
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "AAIG driver doesn't support %d bands.  Must be 1 band.",
                 nBands);

        return nullptr;
    }

    if( !pfnProgress(0.0, nullptr, pProgressData) )
        return nullptr;

    // Create the dataset.
    VSILFILE *fpImage = VSIFOpenL(pszFilename, "wt");
    if( fpImage == nullptr )
    {
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "Unable to create file %s.",
                 pszFilename);
        return nullptr;
    }

    // Write ASCII Grid file header.
    double adfGeoTransform[6] = {};
    char szHeader[2000] = {};
    const char *pszForceCellsize =
        CSLFetchNameValue(papszOptions, "FORCE_CELLSIZE");

    poSrcDS->GetGeoTransform(adfGeoTransform);

    if( std::abs(adfGeoTransform[1] + adfGeoTransform[5]) < 0.0000001 ||
        std::abs(adfGeoTransform[1]-adfGeoTransform[5]) < 0.0000001 ||
        (pszForceCellsize && CPLTestBool(pszForceCellsize)) )
    {
        CPLsnprintf(
            szHeader, sizeof(szHeader),
            "ncols        %d\n"
            "nrows        %d\n"
            "xllcorner    %.12f\n"
            "yllcorner    %.12f\n"
            "cellsize     %.12f\n",
            nXSize, nYSize,
            adfGeoTransform[0],
            adfGeoTransform[3] - nYSize * adfGeoTransform[1],
            adfGeoTransform[1]);
    }
    else
    {
        if( pszForceCellsize == nullptr )
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Producing a Golden Surfer style file with DX and DY "
                     "instead of CELLSIZE since the input pixels are "
                     "non-square.  Use the FORCE_CELLSIZE=TRUE creation "
                     "option to force use of DX for even though this will "
                     "be distorted.  Most ASCII Grid readers (ArcGIS "
                     "included) do not support the DX and DY parameters.");
        CPLsnprintf(
            szHeader, sizeof(szHeader),
            "ncols        %d\n"
            "nrows        %d\n"
            "xllcorner    %.12f\n"
            "yllcorner    %.12f\n"
            "dx           %.12f\n"
            "dy           %.12f\n",
            nXSize, nYSize,
            adfGeoTransform[0],
            adfGeoTransform[3] + nYSize * adfGeoTransform[5],
            adfGeoTransform[1],
            fabs(adfGeoTransform[5]));
    }

    // Builds the format string used for printing float values.
    char szFormatFloat[32] = { '\0' };
    strcpy(szFormatFloat, " %.20g");
    const char *pszDecimalPrecision =
        CSLFetchNameValue(papszOptions, "DECIMAL_PRECISION");
    const char *pszSignificantDigits =
        CSLFetchNameValue(papszOptions, "SIGNIFICANT_DIGITS");
    bool bIgnoreSigDigits = false;
    if( pszDecimalPrecision && pszSignificantDigits )
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Conflicting precision arguments, using DECIMAL_PRECISION");
        bIgnoreSigDigits = true;
    }
    int nPrecision;
    if ( pszSignificantDigits && !bIgnoreSigDigits )
    {
        nPrecision = atoi(pszSignificantDigits);
        if (nPrecision >= 0)
            snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%dg",
                     nPrecision);
        CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat);
    }
    else if( pszDecimalPrecision )
    {
        nPrecision = atoi(pszDecimalPrecision);
        if ( nPrecision >= 0 )
            snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%df",
                     nPrecision);
        CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat);
    }

    // Handle nodata (optionally).
    GDALRasterBand *poBand = poSrcDS->GetRasterBand(1);
    const bool bReadAsInt =
        poBand->GetRasterDataType() == GDT_Byte ||
        poBand->GetRasterDataType() == GDT_Int16 ||
        poBand->GetRasterDataType() == GDT_UInt16 ||
        poBand->GetRasterDataType() == GDT_Int32;

    // Write `nodata' value to header if it is exists in source dataset
    int bSuccess = FALSE;
    const double dfNoData = poBand->GetNoDataValue(&bSuccess);
    if ( bSuccess )
    {
        snprintf(szHeader + strlen(szHeader),
                 sizeof(szHeader) - strlen(szHeader), "%s", "NODATA_value ");
        if( bReadAsInt )
            snprintf(szHeader + strlen(szHeader),
                     sizeof(szHeader) - strlen(szHeader), "%d",
                     static_cast<int>(dfNoData));
        else
            CPLsnprintf(szHeader + strlen(szHeader),
                        sizeof(szHeader) - strlen(szHeader),
                        szFormatFloat, dfNoData);
        snprintf(szHeader + strlen(szHeader),
                 sizeof(szHeader) - strlen(szHeader), "%s", "\n");
    }

    if( VSIFWriteL(szHeader, strlen(szHeader), 1, fpImage) != 1)
    {
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpImage));
        return nullptr;
    }

    // Loop over image, copying image data.

    // Write scanlines to output file
    int *panScanline = bReadAsInt
                           ? static_cast<int *>(CPLMalloc(
                                 nXSize * GDALGetDataTypeSizeBytes(GDT_Int32)))
                           : nullptr;

    double *padfScanline =
        bReadAsInt ? nullptr
                   : static_cast<double *>(CPLMalloc(
                         nXSize * GDALGetDataTypeSizeBytes(GDT_Float64)));

    CPLErr eErr = CE_None;

    bool bHasOutputDecimalDot = false;
    for( int iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ )
    {
        CPLString osBuf;
        eErr = poBand->RasterIO(
            GF_Read, 0, iLine, nXSize, 1,
            bReadAsInt ? reinterpret_cast<void *>(panScanline) :
            reinterpret_cast<void *>(padfScanline),
            nXSize, 1, bReadAsInt ? GDT_Int32 : GDT_Float64,
            0, 0, nullptr);

        if( bReadAsInt )
        {
            for ( int iPixel = 0; iPixel < nXSize; iPixel++ )
            {
                snprintf(szHeader, sizeof(szHeader),
                         " %d", panScanline[iPixel]);
                osBuf += szHeader;
                if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 )
                {
                    if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1,
                                    fpImage) != 1 )
                    {
                        eErr = CE_Failure;
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "Write failed, disk full?");
                        break;
                    }
                    osBuf = "";
                }
            }
        }
        else
        {
            for ( int iPixel = 0; iPixel < nXSize; iPixel++ )
            {
                CPLsnprintf(szHeader, sizeof(szHeader),
                            szFormatFloat, padfScanline[iPixel]);

                // Make sure that as least one value has a decimal point (#6060)
                if( !bHasOutputDecimalDot )
                {
                    if( strchr(szHeader, '.') || strchr(szHeader, 'e') ||
                        strchr(szHeader, 'E') )
                    {
                        bHasOutputDecimalDot = true;
                    }
                    else if( !CPLIsInf(padfScanline[iPixel]) &&
                             !CPLIsNan(padfScanline[iPixel]) )
                    {
                        strcat(szHeader, ".0");
                        bHasOutputDecimalDot = true;
                    }
                }

                osBuf += szHeader;
                if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 )
                {
                  if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1,
                                  fpImage) != 1 )
                    {
                        eErr = CE_Failure;
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "Write failed, disk full?");
                        break;
                    }
                    osBuf = "";
                }
            }
        }
        if( VSIFWriteL("\n", 1, 1, fpImage) != 1 )
            eErr = CE_Failure;

        if( eErr == CE_None &&
            !pfnProgress((iLine + 1) / static_cast<double>(nYSize), nullptr,
                         pProgressData) )
        {
            eErr = CE_Failure;
            CPLError(CE_Failure, CPLE_UserInterrupt,
                     "User terminated CreateCopy()");
        }
    }

    CPLFree(panScanline);
    CPLFree(padfScanline);
    if( VSIFCloseL(fpImage) != 0 )
        eErr = CE_Failure;

    if( eErr != CE_None )
        return nullptr;

    // Try to write projection file.
    const char *pszOriginalProjection = poSrcDS->GetProjectionRef();
    if( !EQUAL(pszOriginalProjection, "") )
    {
        char *pszDirname = CPLStrdup(CPLGetPath(pszFilename));
        char *pszBasename = CPLStrdup(CPLGetBasename(pszFilename));
        char *pszPrjFilename =
            CPLStrdup(CPLFormFilename(pszDirname, pszBasename, "prj"));
        VSILFILE *fp = VSIFOpenL(pszPrjFilename, "wt");
        if (fp != nullptr)
        {
            OGRSpatialReference oSRS;
            oSRS.importFromWkt(pszOriginalProjection);
            oSRS.morphToESRI();
            char *pszESRIProjection = nullptr;
            oSRS.exportToWkt(&pszESRIProjection);
            CPL_IGNORE_RET_VAL(VSIFWriteL(pszESRIProjection, 1,
                                          strlen(pszESRIProjection), fp));

            CPL_IGNORE_RET_VAL(VSIFCloseL(fp));
            CPLFree(pszESRIProjection);
        }
        else
        {
            CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.",
                     pszPrjFilename);
        }
        CPLFree(pszDirname);
        CPLFree(pszBasename);
        CPLFree(pszPrjFilename);
    }

    // Re-open dataset, and copy any auxiliary pam information.

    // If writing to stdout, we can't reopen it, so return
    // a fake dataset to make the caller happy.
    CPLPushErrorHandler(CPLQuietErrorHandler);
    GDALPamDataset *poDS =
        reinterpret_cast<GDALPamDataset *>(GDALOpen(pszFilename, GA_ReadOnly));
    CPLPopErrorHandler();
    if (poDS)
    {
        poDS->CloneInfo(poSrcDS, GCIF_PAM_DEFAULT);
        return poDS;
    }

    CPLErrorReset();

    AAIGDataset *poAAIG_DS = new AAIGDataset();
    poAAIG_DS->nRasterXSize = nXSize;
    poAAIG_DS->nRasterYSize = nYSize;
    poAAIG_DS->nBands = 1;
    poAAIG_DS->SetBand(1, new AAIGRasterBand(poAAIG_DS, 1));
    return poAAIG_DS;
}
Пример #18
0
GDALDataset *
RCreateCopy( const char * pszFilename,
             GDALDataset *poSrcDS,
             CPL_UNUSED int bStrict,
             char ** papszOptions,
             GDALProgressFunc pfnProgress,
             void * pProgressData )
{
    const int nBands = poSrcDS->GetRasterCount();
    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();
    const bool bASCII = CPLFetchBool(papszOptions, "ASCII", false);
    const bool bCompressed = CPLFetchBool(papszOptions, "COMPRESS", !bASCII);

    // Some some rudimentary checks.

    // Setup the filename to actually use.  We prefix with
    // /vsigzip/ if we want compressed output.
    const CPLString osAdjustedFilename =
        std::string(bCompressed ? "/vsigzip/" : "") + pszFilename;

    // Create the file.
    VSILFILE *fp = VSIFOpenL(osAdjustedFilename, "wb");
    if( fp == NULL )
    {
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "Unable to create file %s.",
                 pszFilename);
        return NULL;
    }

    // Write header with version, etc.
    if( bASCII )
    {
        const char *pszHeader = "RDA2\nA\n";
        VSIFWriteL(pszHeader, 1, strlen(pszHeader), fp);
    }
    else
    {
        const char *pszHeader = "RDX2\nX\n";
        VSIFWriteL(pszHeader, 1, strlen(pszHeader), fp);
    }

    RWriteInteger(fp, bASCII, 2);
    RWriteInteger(fp, bASCII, 133377);
    RWriteInteger(fp, bASCII, 131840);

    // Establish the primary pairlist with one component object.
    RWriteInteger(fp, bASCII, 1026);
    RWriteInteger(fp, bASCII, 1);

    // Write the object name.  Eventually we should derive this
    // from the filename, possible with override by a creation option.
    RWriteString(fp, bASCII, "gg");

    // For now we write the raster as a numeric array with attributes (526).
    RWriteInteger(fp, bASCII, 526);
    RWriteInteger(fp, bASCII, nXSize * nYSize * nBands);

    // Write the raster data.
    CPLErr eErr = CE_None;

    double *padfScanline =
        static_cast<double *>(CPLMalloc(nXSize * sizeof(double)));

    for( int iBand = 0; iBand < nBands; iBand++ )
    {
        GDALRasterBand *poBand = poSrcDS->GetRasterBand(iBand + 1);

        for( int iLine = 0; iLine < nYSize && eErr == CE_None; iLine++ )
        {
            eErr = poBand->RasterIO(GF_Read, 0, iLine, nXSize, 1,
                                    padfScanline, nXSize, 1, GDT_Float64,
                                    sizeof(double), 0, NULL);

            if( bASCII )
            {
                for( int iValue = 0; iValue < nXSize; iValue++ )
                {
                    char szValue[128] = { '\0' };
                    CPLsnprintf(szValue, sizeof(szValue), "%.16g\n",
                                padfScanline[iValue]);
                    VSIFWriteL(szValue, 1, strlen(szValue), fp);
                }
            }
            else
            {
                for( int iValue = 0; iValue < nXSize; iValue++ )
                    CPL_MSBPTR64(padfScanline + iValue);

                VSIFWriteL(padfScanline, 8, nXSize, fp);
            }

            if( eErr == CE_None &&
                !pfnProgress((iLine + 1) / static_cast<double>(nYSize),
                             NULL, pProgressData) )
            {
                eErr = CE_Failure;
                CPLError(CE_Failure, CPLE_UserInterrupt,
                         "User terminated CreateCopy()");
            }
        }
    }

    CPLFree(padfScanline);

    // Write out the dims attribute.
    RWriteInteger(fp, bASCII, 1026);
    RWriteInteger(fp, bASCII, 1);

    RWriteString(fp, bASCII, "dim");

    RWriteInteger(fp, bASCII, 13);
    RWriteInteger(fp, bASCII, 3);
    RWriteInteger(fp, bASCII, nXSize);
    RWriteInteger(fp, bASCII, nYSize);
    RWriteInteger(fp, bASCII, nBands);

    RWriteInteger(fp, bASCII, 254);

    // Terminate overall pairlist.
    RWriteInteger(fp, bASCII, 254);

    // Cleanup.
    VSIFCloseL(fp);

    if( eErr != CE_None )
        return NULL;

    // Re-open dataset, and copy any auxiliary pam information.
    GDALPamDataset *poDS =
        static_cast<GDALPamDataset *>(GDALOpen(pszFilename, GA_ReadOnly));

    if( poDS )
        poDS->CloneInfo(poSrcDS, GCIF_PAM_DEFAULT);

    return poDS;
}
Пример #19
0
static GDALDataset *
DTEDCreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
                int bStrict, char ** /* papszOptions */,
                GDALProgressFunc pfnProgress, void *pProgressData)

{
/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    const int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "DTED driver does not support source dataset with zero band.\n");
        return nullptr;
    }

    if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported,
                  "DTED driver only uses the first band of the dataset.\n");
        if (bStrict)
            return nullptr;
    }

    if( pfnProgress && !pfnProgress( 0.0, nullptr, pProgressData ) )
        return nullptr;

/* -------------------------------------------------------------------- */
/*      Work out the level.                                             */
/* -------------------------------------------------------------------- */
    int nLevel;

    if( poSrcDS->GetRasterYSize() == 121 )
        nLevel = 0;
    else if( poSrcDS->GetRasterYSize() == 1201 )
        nLevel = 1;
    else if( poSrcDS->GetRasterYSize() == 3601 )
        nLevel = 2;
    else
    {
        CPLError( CE_Warning, CPLE_AppDefined,
               "The source does not appear to be a properly formatted cell." );
        nLevel = 1;
    }

/* -------------------------------------------------------------------- */
/*      Checks the input SRS                                            */
/* -------------------------------------------------------------------- */
    OGRSpatialReference ogrsr_input;
    ogrsr_input.importFromWkt(poSrcDS->GetProjectionRef());
    OGRSpatialReference ogrsr_wgs84;
    ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" );
    if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE)
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "The source projection coordinate system is %s. Only WGS 84 is supported.\n"
                  "The DTED driver will generate a file as if the source was WGS 84 projection coordinate system.",
                  poSrcDS->GetProjectionRef() );
    }

/* -------------------------------------------------------------------- */
/*      Work out the LL origin.                                         */
/* -------------------------------------------------------------------- */
    double adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    int nLLOriginLat = (int)
        floor(adfGeoTransform[3]
              + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5);

    int nLLOriginLong = (int) floor(adfGeoTransform[0] + 0.5);

    if (fabs(nLLOriginLat - (adfGeoTransform[3]
              + (poSrcDS->GetRasterYSize() - 0.5) * adfGeoTransform[5])) > 1e-10 ||
        fabs(nLLOriginLong - (adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10)
    {
        CPLError( CE_Warning, CPLE_AppDefined,
               "The corner coordinates of the source are not properly "
               "aligned on plain latitude/longitude boundaries.");
    }

/* -------------------------------------------------------------------- */
/*     Check horizontal source size.                                    */
/* -------------------------------------------------------------------- */
    int expectedXSize;
    int nReferenceLat = nLLOriginLat < 0 ? - (nLLOriginLat + 1) : nLLOriginLat;
    if( nReferenceLat >= 80 )
        expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 6 + 1;
    else if( nReferenceLat >= 75 )
        expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 4 + 1;
    else if( nReferenceLat >= 70 )
        expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 3 + 1;
    else if( nReferenceLat >= 50 )
        expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 2 + 1;
    else
        expectedXSize = poSrcDS->GetRasterYSize();

    if (poSrcDS->GetRasterXSize() != expectedXSize)
    {
        CPLError( CE_Warning, CPLE_AppDefined,
               "The horizontal source size is not conformant with the one "
               "expected by DTED Level %d at this latitude (%d pixels found instead of %d).", nLevel,
                poSrcDS->GetRasterXSize(), expectedXSize);
    }

/* -------------------------------------------------------------------- */
/*      Create the output dted file.                                    */
/* -------------------------------------------------------------------- */
    const char *pszError
        = DTEDCreate( pszFilename, nLevel, nLLOriginLat, nLLOriginLong );

    if( pszError != nullptr )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "%s", pszError );
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Open the DTED file so we can output the data to it.             */
/* -------------------------------------------------------------------- */
    DTEDInfo *psDTED
        = DTEDOpen( pszFilename, "rb+", FALSE );
    if( psDTED == nullptr )
        return nullptr;

/* -------------------------------------------------------------------- */
/*      Read all the data in a single buffer.                           */
/* -------------------------------------------------------------------- */
    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );
    GInt16 *panData = (GInt16 *)
        VSI_MALLOC_VERBOSE(sizeof(GInt16) * psDTED->nXSize * psDTED->nYSize);
    if (panData == nullptr)
    {
        DTEDClose(psDTED);
        return nullptr;
    }

    for( int iY = 0; iY < psDTED->nYSize; iY++ )
    {
        if( poSrcBand->RasterIO( GF_Read, 0, iY, psDTED->nXSize, 1,
                            (void *) (panData + iY * psDTED->nXSize), psDTED->nXSize, 1,
                            GDT_Int16, 0, 0, nullptr ) != CE_None )
        {
            DTEDClose( psDTED );
            CPLFree( panData );
            return nullptr;
        }

        if( pfnProgress && !pfnProgress(0.5 * (iY+1) / (double) psDTED->nYSize, nullptr, pProgressData ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt,
                        "User terminated CreateCopy()" );
            DTEDClose( psDTED );
            CPLFree( panData );
            return nullptr;
        }
    }

    int bSrcBandHasNoData;
    double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData);

/* -------------------------------------------------------------------- */
/*      Write all the profiles.                                         */
/* -------------------------------------------------------------------- */
    GInt16      anProfData[3601];
    int         dfNodataCount=0;
    GByte       iPartialCell;

    for( int iProfile = 0; iProfile < psDTED->nXSize; iProfile++ )
    {
        for( int iY = 0; iY < psDTED->nYSize; iY++ )
        {
            anProfData[iY] = panData[iProfile + iY * psDTED->nXSize];
            if ( bSrcBandHasNoData && anProfData[iY] == srcBandNoData)
            {
                anProfData[iY] = DTED_NODATA_VALUE;
                dfNodataCount++;
            }
            else if ( anProfData[iY] == DTED_NODATA_VALUE )
                dfNodataCount++;
        }
        DTEDWriteProfile( psDTED, iProfile, anProfData );

        if( pfnProgress
            && !pfnProgress( 0.5 + 0.5 * (iProfile+1) / (double) psDTED->nXSize,
                             nullptr, pProgressData ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt,
                      "User terminated CreateCopy()" );
            DTEDClose( psDTED );
            CPLFree( panData );
            return nullptr;
        }
    }
    CPLFree( panData );

/* -------------------------------------------------------------------- */
/* Partial cell indicator: 0 for complete coverage; 1-99 for incomplete */
/* -------------------------------------------------------------------- */
    char szPartialCell[3];

    if ( dfNodataCount == 0 )
        iPartialCell = 0;
    else
    {
      iPartialCell = (GByte)int(floor(100.0 -
           (dfNodataCount*100.0/(psDTED->nXSize * psDTED->nYSize))));
        if (iPartialCell < 1)
           iPartialCell=1;
    }

    CPLsnprintf( szPartialCell, sizeof(szPartialCell), "%02d",iPartialCell);
    DTEDSetMetadata(psDTED, DTEDMD_PARTIALCELL_DSI, szPartialCell);

/* -------------------------------------------------------------------- */
/*      Try to copy any matching available metadata.                    */
/* -------------------------------------------------------------------- */
    if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_UHL,
                     poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) );

    if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_ACC,
                    poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) );

    if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_UHL,
                    poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) );

    if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_DSI,
                    poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) );

    if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_UHL,
                         poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) );

    if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_DSI,
                         poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) );

    if( poSrcDS->GetMetadataItem( "DTED_DataEdition" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_DATA_EDITION,
                         poSrcDS->GetMetadataItem( "DTED_DataEdition" ) );

    if( poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_VERSION,
                     poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) );

    if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_MAINT_DATE,
                         poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) );

    if( poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_DATE,
                         poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) );

    if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_MAINT_DESCRIPTION,
                 poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) );

    if( poSrcDS->GetMetadataItem( "DTED_Producer" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_PRODUCER,
                         poSrcDS->GetMetadataItem( "DTED_Producer" ) );

    if( poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_VERTDATUM,
                         poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) );

    if( poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_HORIZDATUM,
                         poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) );

    if( poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_DIGITIZING_SYS,
                         poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) );

    if( poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_COMPILATION_DATE,
                         poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) );

    if( poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_HORIZACCURACY,
                     poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) );

    if( poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_REL_HORIZACCURACY,
                   poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) );

    if( poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) != nullptr )
        DTEDSetMetadata( psDTED, DTEDMD_REL_VERTACCURACY,
                     poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) );

/* -------------------------------------------------------------------- */
/*      Try to open the resulting DTED file.                            */
/* -------------------------------------------------------------------- */
    DTEDClose( psDTED );

/* -------------------------------------------------------------------- */
/*      Reopen and copy missing information into a PAM file.            */
/* -------------------------------------------------------------------- */
    GDALPamDataset *poDS = (GDALPamDataset *)
        GDALOpen( pszFilename, GA_ReadOnly );

    if( poDS )
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );

    return poDS;
}
Пример #20
0
CPLXMLNode *GMLFeatureClass::SerializeToXML()

{
    CPLXMLNode  *psRoot;
    int         iProperty;

/* -------------------------------------------------------------------- */
/*      Set feature class and core information.                         */
/* -------------------------------------------------------------------- */
    psRoot = CPLCreateXMLNode( NULL, CXT_Element, "GMLFeatureClass" );

    CPLCreateXMLElementAndValue( psRoot, "Name", GetName() );
    CPLCreateXMLElementAndValue( psRoot, "ElementPath", GetElementName() );
    
    if( m_nGeometryPropertyCount > 1 )
    {
        for(int i=0; i < m_nGeometryPropertyCount; i++)
        {
            GMLGeometryPropertyDefn* poGeomFDefn = m_papoGeometryProperty[i];

            CPLXMLNode *psPDefnNode;
            psPDefnNode = CPLCreateXMLNode( psRoot, CXT_Element, "GeomPropertyDefn" );
            if( strlen(poGeomFDefn->GetName()) > 0 )
                CPLCreateXMLElementAndValue( psPDefnNode, "Name", 
                                             poGeomFDefn->GetName() );
            if( poGeomFDefn->GetSrcElement() != NULL && strlen(poGeomFDefn->GetSrcElement()) > 0 )
                CPLCreateXMLElementAndValue( psPDefnNode, "ElementPath", 
                                             poGeomFDefn->GetSrcElement() );
            
            if( poGeomFDefn->GetType() != 0 /* wkbUnknown */ )
            {
                char szValue[128];

                OGRwkbGeometryType eType = (OGRwkbGeometryType)poGeomFDefn->GetType();

                CPLString osStr(OGRToOGCGeomType(eType));
                if( wkbHasZ(eType) ) osStr += "Z";
                CPLCreateXMLNode( psPDefnNode, CXT_Comment, osStr.c_str() );

                sprintf( szValue, "%d", eType );
                CPLCreateXMLElementAndValue( psPDefnNode, "Type", szValue );
            }
        }
    }
    else if( m_nGeometryPropertyCount == 1 )
    {
        GMLGeometryPropertyDefn* poGeomFDefn = m_papoGeometryProperty[0];
        
        if( strlen(poGeomFDefn->GetName()) > 0 )
            CPLCreateXMLElementAndValue( psRoot, "GeometryName", 
                                         poGeomFDefn->GetName() );

        if( poGeomFDefn->GetSrcElement() != NULL && strlen(poGeomFDefn->GetSrcElement()) > 0 )
            CPLCreateXMLElementAndValue( psRoot, "GeometryElementPath", 
                                         poGeomFDefn->GetSrcElement() );
        
        if( poGeomFDefn->GetType() != 0 /* wkbUnknown */ )
        {
            char szValue[128];

            OGRwkbGeometryType eType = (OGRwkbGeometryType)poGeomFDefn->GetType();

            CPLString osStr(OGRToOGCGeomType(eType));
            if( wkbHasZ(eType) ) osStr += "Z";
            CPLCreateXMLNode( psRoot, CXT_Comment, osStr.c_str() );

            sprintf( szValue, "%d", eType );
            CPLCreateXMLElementAndValue( psRoot, "GeometryType", szValue );
        }
    }
    else
    {
        CPLCreateXMLElementAndValue( psRoot, "GeometryType", "100" );
    }

    const char* pszSRSName = GetSRSName();
    if( pszSRSName )
    {
        CPLCreateXMLElementAndValue( psRoot, "SRSName", pszSRSName );
    }

/* -------------------------------------------------------------------- */
/*      Write out dataset specific information.                         */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psDSI;

    if( m_bHaveExtents || m_nFeatureCount != -1 || m_pszExtraInfo != NULL )
    {
        psDSI = CPLCreateXMLNode( psRoot, CXT_Element, "DatasetSpecificInfo" );

        if( m_nFeatureCount != -1 )
        {
            char szValue[128];

            sprintf( szValue, CPL_FRMT_GIB, m_nFeatureCount );
            CPLCreateXMLElementAndValue( psDSI, "FeatureCount", szValue );
        }

        if( m_bHaveExtents &&
            fabs(m_dfXMin) < 1e100 &&
            fabs(m_dfXMax) < 1e100 &&
            fabs(m_dfYMin) < 1e100 &&
            fabs(m_dfYMax) < 1e100 )
        {
            char szValue[128];

            CPLsnprintf( szValue, sizeof(szValue), "%.5f", m_dfXMin );
            CPLCreateXMLElementAndValue( psDSI, "ExtentXMin", szValue );

            CPLsnprintf( szValue, sizeof(szValue), "%.5f", m_dfXMax );
            CPLCreateXMLElementAndValue( psDSI, "ExtentXMax", szValue );

            CPLsnprintf( szValue, sizeof(szValue), "%.5f", m_dfYMin );
            CPLCreateXMLElementAndValue( psDSI, "ExtentYMin", szValue );

            CPLsnprintf( szValue, sizeof(szValue), "%.5f", m_dfYMax );
            CPLCreateXMLElementAndValue( psDSI, "ExtentYMax", szValue );
        }

        if( m_pszExtraInfo )
            CPLCreateXMLElementAndValue( psDSI, "ExtraInfo", m_pszExtraInfo );
    }
    
/* -------------------------------------------------------------------- */
/*      emit property information.                                      */
/* -------------------------------------------------------------------- */
    for( iProperty = 0; iProperty < GetPropertyCount(); iProperty++ )
    {
        GMLPropertyDefn *poPDefn = GetProperty( iProperty );
        CPLXMLNode *psPDefnNode;
        const char *pszTypeName = "Unknown";

        psPDefnNode = CPLCreateXMLNode( psRoot, CXT_Element, "PropertyDefn" );
        CPLCreateXMLElementAndValue( psPDefnNode, "Name", 
                                     poPDefn->GetName() );
        CPLCreateXMLElementAndValue( psPDefnNode, "ElementPath", 
                                     poPDefn->GetSrcElement() );
        switch( poPDefn->GetType() )
        {
          case GMLPT_Untyped:
            pszTypeName = "Untyped";
            break;
            
          case GMLPT_String:
          case GMLPT_Boolean:
            pszTypeName = "String";
            break;
            
          case GMLPT_Integer:
          case GMLPT_Short:
          case GMLPT_Integer64:
            pszTypeName = "Integer";
            break;
            
          case GMLPT_Real:
          case GMLPT_Float:
            pszTypeName = "Real";
            break;
            
          case GMLPT_Complex:
            pszTypeName = "Complex";
            break;

          case GMLPT_IntegerList:
          case GMLPT_Integer64List:
            pszTypeName = "IntegerList";
            break;

          case GMLPT_RealList:
            pszTypeName = "RealList";
            break;

          case GMLPT_StringList:
          case GMLPT_BooleanList:
            pszTypeName = "StringList";
            break;

          /* should not happen in practise for now because this is not */
          /* autodetected */
          case GMLPT_FeatureProperty:
            pszTypeName = "FeatureProperty";
            break;

          /* should not happen in practise for now because this is not */
          /* autodetected */
          case GMLPT_FeaturePropertyList:
            pszTypeName = "FeaturePropertyList";
            break;
        }
        CPLCreateXMLElementAndValue( psPDefnNode, "Type", pszTypeName );
        if( poPDefn->GetType() == GMLPT_Boolean || poPDefn->GetType() == GMLPT_BooleanList )
            CPLCreateXMLElementAndValue( psPDefnNode, "Subtype", "Boolean" );
        else if( poPDefn->GetType() == GMLPT_Short )
            CPLCreateXMLElementAndValue( psPDefnNode, "Subtype", "Short" );
        else if( poPDefn->GetType() == GMLPT_Float )
            CPLCreateXMLElementAndValue( psPDefnNode, "Subtype", "Float" );
        else if( poPDefn->GetType() == GMLPT_Integer64 ||
                 poPDefn->GetType() == GMLPT_Integer64List )
            CPLCreateXMLElementAndValue( psPDefnNode, "Subtype", "Integer64" );

        if( EQUAL(pszTypeName,"String") )
        {
            char szMaxLength[48];
            sprintf(szMaxLength, "%d", poPDefn->GetWidth());
            CPLCreateXMLElementAndValue ( psPDefnNode, "Width", szMaxLength );
        }
        if( poPDefn->GetWidth() > 0 && EQUAL(pszTypeName,"Integer") )
        {
            char szLength[48];
            sprintf(szLength, "%d", poPDefn->GetWidth());
            CPLCreateXMLElementAndValue ( psPDefnNode, "Width", szLength );
        }
        if( poPDefn->GetWidth() > 0 && EQUAL(pszTypeName,"Real") )
        {
            char szLength[48];
            sprintf(szLength, "%d", poPDefn->GetWidth());
            CPLCreateXMLElementAndValue ( psPDefnNode, "Width", szLength );
            char szPrecision[48];
            sprintf(szPrecision, "%d", poPDefn->GetPrecision());
            CPLCreateXMLElementAndValue ( psPDefnNode, "Precision", szPrecision );
        }
    }

    return psRoot;
}
Пример #21
0
char *GXFGetMapProjectionAsOGCWKT( GXFHandle hGXF )

{
    GXFInfo_t	*psGXF = (GXFInfo_t *) hGXF;
    char	**papszMethods = NULL;
    char	szWKT[1024];
    char	szGCS[512];
    char	szProjection[512];

/* -------------------------------------------------------------------- */
/*      If there was nothing in the file return "unknown".              */
/* -------------------------------------------------------------------- */
    if( CSLCount(psGXF->papszMapProjection) < 2 )
        return( CPLStrdup( "" ) );

    strcpy( szWKT, "" );
    strcpy( szGCS, "" );
    strcpy( szProjection, "" );

/* -------------------------------------------------------------------- */
/*      Parse the third line, looking for known projection methods.     */
/* -------------------------------------------------------------------- */
    if( psGXF->papszMapProjection[2] != NULL )
    {
        /* We allow more than 80 characters if the projection parameters */
        /* are on 2 lines as allowed by GXF 3 */
        if( strlen(psGXF->papszMapProjection[2]) > 120 )
            return( CPLStrdup( "" ) );
        papszMethods = CSLTokenizeStringComplex(psGXF->papszMapProjection[2],
                                                ",", TRUE, TRUE );
    }

#ifdef DBMALLOC
    malloc_chain_check(1);
#endif

/* -------------------------------------------------------------------- */
/*      Create the PROJCS.                                              */
/* -------------------------------------------------------------------- */
    if( papszMethods == NULL
        || papszMethods[0] == NULL
        || EQUAL(papszMethods[0],"Geographic") )
    {
        /* do nothing */
    }

    else if( EQUAL(papszMethods[0],"Lambert Conic Conformal (1SP)") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_SCALE_FACTOR,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Lambert Conic Conformal (2SP)") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP,
                       SRS_PP_STANDARD_PARALLEL_1,
                       SRS_PP_STANDARD_PARALLEL_2,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Lambert Conformal (2SP Belgium)") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM,
                       SRS_PP_STANDARD_PARALLEL_1,
                       SRS_PP_STANDARD_PARALLEL_2,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Mercator (1SP)"))
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_MERCATOR_1SP,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_SCALE_FACTOR,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Mercator (2SP)"))
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_MERCATOR_2SP,
                       SRS_PP_LATITUDE_OF_ORIGIN,/* should it be StdParalle1?*/
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Laborde Oblique Mercator") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_LABORDE_OBLIQUE_MERCATOR,
                       SRS_PP_LATITUDE_OF_CENTER,
                       SRS_PP_LONGITUDE_OF_CENTER,
                       SRS_PP_AZIMUTH,
                       SRS_PP_SCALE_FACTOR,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL );

    }

    else if( EQUAL(papszMethods[0],"Hotine Oblique Mercator") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_HOTINE_OBLIQUE_MERCATOR,
                       SRS_PP_LATITUDE_OF_CENTER,
                       SRS_PP_LONGITUDE_OF_CENTER,
                       SRS_PP_AZIMUTH,
                       SRS_PP_RECTIFIED_GRID_ANGLE,
                       SRS_PP_SCALE_FACTOR, /* not in normal formulation */
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING );
    }

    else if( EQUAL(papszMethods[0],"New Zealand Map Grid") )

    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_NEW_ZEALAND_MAP_GRID,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Oblique Stereographic") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_OBLIQUE_STEREOGRAPHIC,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_SCALE_FACTOR,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Polar Stereographic") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_POLAR_STEREOGRAPHIC,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_SCALE_FACTOR,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Swiss Oblique Cylindrical") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_SWISS_OBLIQUE_CYLINDRICAL,
                       SRS_PP_LATITUDE_OF_CENTER,
                       SRS_PP_LONGITUDE_OF_CENTER,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Transverse Mercator") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_TRANSVERSE_MERCATOR,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_SCALE_FACTOR,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"Transverse Mercator (South Oriented)")
          || EQUAL(papszMethods[0],"Transverse Mercator (South Orientated)"))
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_SCALE_FACTOR,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"*Albers Conic") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_ALBERS_CONIC_EQUAL_AREA,
                       SRS_PP_STANDARD_PARALLEL_1,
                       SRS_PP_STANDARD_PARALLEL_2,
                       SRS_PP_LATITUDE_OF_CENTER,
                       SRS_PP_LONGITUDE_OF_CENTER,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"*Equidistant Conic") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_EQUIDISTANT_CONIC,
                       SRS_PP_STANDARD_PARALLEL_1,
                       SRS_PP_STANDARD_PARALLEL_2,
                       SRS_PP_LATITUDE_OF_CENTER,
                       SRS_PP_LONGITUDE_OF_CENTER,
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL );
    }

    else if( EQUAL(papszMethods[0],"*Polyconic") )
    {
        OGCWKTSetProj( szProjection, sizeof(szProjection), papszMethods,
                       SRS_PT_POLYCONIC,
                       SRS_PP_LATITUDE_OF_ORIGIN,
                       SRS_PP_CENTRAL_MERIDIAN,
                       SRS_PP_SCALE_FACTOR, /* not normally expected */
                       SRS_PP_FALSE_EASTING,
                       SRS_PP_FALSE_NORTHING,
                       NULL,
                       NULL );
    }

    CSLDestroy( papszMethods );

/* -------------------------------------------------------------------- */
/*      Extract the linear Units specification.                         */
/* -------------------------------------------------------------------- */
    if( psGXF->pszUnitName != NULL && strlen(szProjection) > 0 )
    {
        if( strlen(psGXF->pszUnitName) > 80 )
            return CPLStrdup("");

        CPLsnprintf( szProjection+strlen(szProjection),
                     sizeof(szProjection) - strlen(szProjection),
                 ",UNIT[\"%s\",%.15g]",
                 psGXF->pszUnitName, psGXF->dfUnitToMeter );
    }

/* -------------------------------------------------------------------- */
/*      Build GEOGCS.  There are still "issues" with the generation     */
/*      of the GEOGCS/Datum and Spheroid names.  Of these, only the     */
/*      datum name is really significant.                               */
/* -------------------------------------------------------------------- */
    if( CSLCount(psGXF->papszMapProjection) > 1 )
    {
        char	**papszTokens;

        if( strlen(psGXF->papszMapProjection[1]) > 80 )
            return CPLStrdup("");

        papszTokens = CSLTokenizeStringComplex(psGXF->papszMapProjection[1],
                                               ",", TRUE, TRUE );


        if( CSLCount(papszTokens) > 2 )
        {
            double	dfMajor = CPLAtof(papszTokens[1]);
            double	dfEccentricity = CPLAtof(papszTokens[2]);
            double	dfInvFlattening, dfMinor;
            char	*pszOGCDatum;

            /* translate eccentricity to inv flattening. */
            if( dfEccentricity == 0.0 )
                dfInvFlattening = 0.0;
            else
            {
                dfMinor = dfMajor * pow(1.0-dfEccentricity*dfEccentricity,0.5);
                dfInvFlattening = OSRCalcInvFlattening(dfMajor, dfMinor);
            }

            pszOGCDatum = CPLStrdup(papszTokens[0]);
            WKTMassageDatum( &pszOGCDatum );

            CPLsnprintf( szGCS,
                        sizeof(szGCS),
                     "GEOGCS[\"%s\","
                       "DATUM[\"%s\","
                       "SPHEROID[\"%s\",%s,%.15g]],",
                     papszTokens[0],
                     pszOGCDatum,
                     papszTokens[0], /* this is datum, but should be ellipse*/
                     papszTokens[1],
                     dfInvFlattening );
            CPLFree( pszOGCDatum );
        }

        if( CSLCount(papszTokens) > 3 )
            CPLsnprintf( szGCS + strlen(szGCS),
                         sizeof(szGCS) - strlen(szGCS),
                     "PRIMEM[\"unnamed\",%s],",
                     papszTokens[3] );

        CPLsnprintf( szGCS + strlen(szGCS),
                     sizeof(szGCS) - strlen(szGCS),
                     "%s",
                     "UNIT[\"degree\",0.0174532925199433]]" );

        CSLDestroy( papszTokens );
    }

    CPLAssert(strlen(szProjection) < sizeof(szProjection));
    CPLAssert(strlen(szGCS) < sizeof(szGCS));

/* -------------------------------------------------------------------- */
/*      Put this all together into a full projection.                   */
/* -------------------------------------------------------------------- */
    if( strlen(szProjection) > 0 )
    {
        if( strlen(psGXF->papszMapProjection[0]) > 80 )
            return CPLStrdup("");

        if( psGXF->papszMapProjection[0][0] == '"' )
            snprintf( szWKT, sizeof(szWKT),
                     "PROJCS[%s,%s,%s]",
                     psGXF->papszMapProjection[0],
                     szGCS,
                     szProjection );
        else
            snprintf( szWKT, sizeof(szWKT),
                     "PROJCS[\"%s\",%s,%s]",
                     psGXF->papszMapProjection[0],
                     szGCS,
                     szProjection );
    }
    else
    {
        strcpy( szWKT, szGCS );
    }

    return( CPLStrdup( szWKT ) );
}
Пример #22
0
OGRErr OGRGMLLayer::ICreateFeature( OGRFeature *poFeature )

{
    int bIsGML3Output = poDS->IsGML3Output();
    VSILFILE *fp = poDS->GetOutputFP();
    int bWriteSpaceIndentation = poDS->WriteSpaceIndentation();
    const char* pszPrefix = poDS->GetAppPrefix();
    int bRemoveAppPrefix = poDS->RemoveAppPrefix();

    if( !bWriter )
        return OGRERR_FAILURE;

    poFeature->FillUnsetWithDefault(TRUE, NULL);
    if( !poFeature->Validate( OGR_F_VAL_ALL & ~OGR_F_VAL_GEOM_TYPE & ~OGR_F_VAL_ALLOW_NULL_WHEN_DEFAULT, TRUE ) )
        return OGRERR_FAILURE;

    if (bWriteSpaceIndentation)
        VSIFPrintfL(fp, "  ");
    if (bIsGML3Output)
    {
        if( bRemoveAppPrefix )
            poDS->PrintLine( fp, "<featureMember>" );
        else
            poDS->PrintLine( fp, "<%s:featureMember>", pszPrefix );
    }
    else
        poDS->PrintLine( fp, "<gml:featureMember>" );

    if( iNextGMLId == 0 )
    {
        bSameSRS = true;
        for( int iGeomField = 1; iGeomField < poFeatureDefn->GetGeomFieldCount(); iGeomField++ )
        {
            OGRGeomFieldDefn *poFieldDefn0 = poFeatureDefn->GetGeomFieldDefn(0);
            OGRGeomFieldDefn *poFieldDefn = poFeatureDefn->GetGeomFieldDefn(iGeomField);
            OGRSpatialReference* poSRS0 = poFieldDefn0->GetSpatialRef();
            OGRSpatialReference* poSRS = poFieldDefn->GetSpatialRef();
            if( poSRS0 != NULL && poSRS == NULL )
                bSameSRS = false;
            else if( poSRS0 == NULL && poSRS != NULL )
                bSameSRS = false;
            else if( poSRS0 != NULL && poSRS != NULL &&
                     poSRS0 != poSRS && !poSRS0->IsSame(poSRS) )
            {
                bSameSRS = false;
            }
        }
    }

    if( poFeature->GetFID() == OGRNullFID )
        poFeature->SetFID( iNextGMLId++ );

    int nGMLIdIndex = -1;
    if (bWriteSpaceIndentation)
        VSIFPrintfL(fp, "    ");
    VSIFPrintfL(fp, "<");
    if( !bRemoveAppPrefix )
        VSIFPrintfL(fp, "%s:", pszPrefix);
    if (bIsGML3Output)
    {
        nGMLIdIndex = poFeatureDefn->GetFieldIndex("gml_id");
        if (nGMLIdIndex >= 0 && poFeature->IsFieldSet( nGMLIdIndex ) )
            poDS->PrintLine( fp, "%s gml:id=\"%s\">",
                             poFeatureDefn->GetName(),
                             poFeature->GetFieldAsString(nGMLIdIndex) );
        else
            poDS->PrintLine( fp, "%s gml:id=\"%s." CPL_FRMT_GIB "\">",
                             poFeatureDefn->GetName(),
                             poFeatureDefn->GetName(),
                             poFeature->GetFID() );
    }
    else
    {
        nGMLIdIndex = poFeatureDefn->GetFieldIndex("fid");
        if (bUseOldFIDFormat)
        {
            poDS->PrintLine( fp, "%s fid=\"F" CPL_FRMT_GIB "\">",
                             poFeatureDefn->GetName(),
                             poFeature->GetFID() );
        }
        else if (nGMLIdIndex >= 0 && poFeature->IsFieldSet( nGMLIdIndex ) )
        {
            poDS->PrintLine( fp, "%s fid=\"%s\">",
                             poFeatureDefn->GetName(),
                             poFeature->GetFieldAsString(nGMLIdIndex) );
        }
        else
        {
            poDS->PrintLine( fp, "%s fid=\"%s." CPL_FRMT_GIB "\">",
                             poFeatureDefn->GetName(),
                             poFeatureDefn->GetName(),
                             poFeature->GetFID() );
        }
    }


    for( int iGeomField = 0; iGeomField < poFeatureDefn->GetGeomFieldCount(); iGeomField++ )
    {
        OGRGeomFieldDefn *poFieldDefn = poFeatureDefn->GetGeomFieldDefn(iGeomField);

        // Write out Geometry - for now it isn't indented properly.
        /* GML geometries don't like very much the concept of empty geometry */
        OGRGeometry* poGeom = poFeature->GetGeomFieldRef(iGeomField);
        if( poGeom != NULL && !poGeom->IsEmpty())
        {
            char    *pszGeometry;
            OGREnvelope3D sGeomBounds;

            int nCoordDimension = poGeom->getCoordinateDimension();

            poGeom->getEnvelope( &sGeomBounds );
            if( bSameSRS )
                poDS->GrowExtents( &sGeomBounds, nCoordDimension );

            if (poGeom->getSpatialReference() == NULL && poFieldDefn->GetSpatialRef() != NULL)
                poGeom->assignSpatialReference(poFieldDefn->GetSpatialRef());

            if (bIsGML3Output && poDS->WriteFeatureBoundedBy())
            {
                bool bCoordSwap;

                char* pszSRSName = GML_GetSRSName(poGeom->getSpatialReference(), poDS->IsLongSRSRequired(), &bCoordSwap);
                char szLowerCorner[75], szUpperCorner[75];
                if (bCoordSwap)
                {
                    OGRMakeWktCoordinate(szLowerCorner, sGeomBounds.MinY, sGeomBounds.MinX, sGeomBounds.MinZ, nCoordDimension);
                    OGRMakeWktCoordinate(szUpperCorner, sGeomBounds.MaxY, sGeomBounds.MaxX, sGeomBounds.MaxZ, nCoordDimension);
                }
                else
                {
                    OGRMakeWktCoordinate(szLowerCorner, sGeomBounds.MinX, sGeomBounds.MinY, sGeomBounds.MinZ, nCoordDimension);
                    OGRMakeWktCoordinate(szUpperCorner, sGeomBounds.MaxX, sGeomBounds.MaxY, sGeomBounds.MaxZ, nCoordDimension);
                }
                if (bWriteSpaceIndentation)
                    VSIFPrintfL(fp, "      ");
                poDS->PrintLine( fp, "<gml:boundedBy><gml:Envelope%s%s><gml:lowerCorner>%s</gml:lowerCorner><gml:upperCorner>%s</gml:upperCorner></gml:Envelope></gml:boundedBy>",
                                (nCoordDimension == 3) ? " srsDimension=\"3\"" : "",pszSRSName, szLowerCorner, szUpperCorner);
                CPLFree(pszSRSName);
            }

            char** papszOptions = (bIsGML3Output) ? CSLAddString(NULL, "FORMAT=GML3") : NULL;
            if (bIsGML3Output && !poDS->IsLongSRSRequired())
                papszOptions = CSLAddString(papszOptions, "GML3_LONGSRS=NO");
            const char* pszSRSDimensionLoc = poDS->GetSRSDimensionLoc();
            if( pszSRSDimensionLoc != NULL )
                papszOptions = CSLSetNameValue(papszOptions, "SRSDIMENSION_LOC", pszSRSDimensionLoc);
            if (poDS->IsGML32Output())
            {
                if( poFeatureDefn->GetGeomFieldCount() > 1 )
                    papszOptions = CSLAddString(papszOptions,
                        CPLSPrintf("GMLID=%s.%s." CPL_FRMT_GIB,
                                   poFeatureDefn->GetName(),
                                   poFieldDefn->GetNameRef(),
                                   poFeature->GetFID()));
                else
                    papszOptions = CSLAddString(papszOptions,
                        CPLSPrintf("GMLID=%s.geom." CPL_FRMT_GIB,
                                   poFeatureDefn->GetName(), poFeature->GetFID()));
            }
            if( !bIsGML3Output && OGR_GT_IsNonLinear(poGeom->getGeometryType()) )
            {
                OGRGeometry* poGeomTmp = OGRGeometryFactory::forceTo(
                    poGeom->clone(),OGR_GT_GetLinear(poGeom->getGeometryType()));
                pszGeometry = poGeomTmp->exportToGML(papszOptions);
                delete poGeomTmp;
            }
            else
                pszGeometry = poGeom->exportToGML(papszOptions);
            CSLDestroy(papszOptions);
            if (bWriteSpaceIndentation)
                VSIFPrintfL(fp, "      ");
            if( bRemoveAppPrefix )
                poDS->PrintLine( fp, "<%s>%s</%s>",
                                 poFieldDefn->GetNameRef(),
                                 pszGeometry,
                                 poFieldDefn->GetNameRef() );
            else
                poDS->PrintLine( fp, "<%s:%s>%s</%s:%s>",
                                 pszPrefix, poFieldDefn->GetNameRef(),
                                 pszGeometry,
                                 pszPrefix, poFieldDefn->GetNameRef() );
            CPLFree( pszGeometry );
        }
    }

    // Write all "set" fields.
    for( int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    {

        OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn( iField );

        if( poFeature->IsFieldSet( iField ) && iField != nGMLIdIndex )
        {
            OGRFieldType eType = poFieldDefn->GetType();
            if (eType == OFTStringList )
            {
                char ** papszIter =  poFeature->GetFieldAsStringList( iField );
                while( papszIter != NULL && *papszIter != NULL )
                {
                    char *pszEscaped = OGRGetXML_UTF8_EscapedString( *papszIter );
                    GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix,
                                  bRemoveAppPrefix, poFieldDefn, pszEscaped);
                    CPLFree( pszEscaped );

                    papszIter ++;
                }
            }
            else if (eType == OFTIntegerList )
            {
                int nCount = 0;
                const int* panVals = poFeature->GetFieldAsIntegerList( iField, &nCount );
                if(  poFieldDefn->GetSubType() == OFSTBoolean )
                {
                    for(int i = 0; i < nCount; i++)
                    {
                        /* 0 and 1 are OK, but the canonical representation is false and true */
                        GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix,
                                      bRemoveAppPrefix, poFieldDefn,
                                      panVals[i] ? "true" : "false");
                    }
                }
                else
                {
                    for(int i = 0; i < nCount; i++)
                    {
                        GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix,
                                      bRemoveAppPrefix, poFieldDefn,
                                      CPLSPrintf("%d", panVals[i]));
                    }
                }
            }
            else if (eType == OFTInteger64List )
            {
                int nCount = 0;
                const GIntBig* panVals = poFeature->GetFieldAsInteger64List( iField, &nCount );
                if(  poFieldDefn->GetSubType() == OFSTBoolean )
                {
                    for(int i = 0; i < nCount; i++)
                    {
                        /* 0 and 1 are OK, but the canonical representation is false and true */
                        GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix,
                                      bRemoveAppPrefix, poFieldDefn,
                                      panVals[i] ? "true" : "false");
                    }
                }
                else
                {
                    for(int i = 0; i < nCount; i++)
                    {
                        GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix,
                                      bRemoveAppPrefix, poFieldDefn,
                                      CPLSPrintf(CPL_FRMT_GIB, panVals[i]));
                    }
                }
            }
            else if (eType == OFTRealList )
            {
                int nCount = 0;
                const double* padfVals = poFeature->GetFieldAsDoubleList( iField, &nCount );
                for(int i = 0; i < nCount; i++)
                {
                    char szBuffer[80];
                    CPLsnprintf( szBuffer, sizeof(szBuffer), "%.15g", padfVals[i]);
                    GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix,
                                  bRemoveAppPrefix, poFieldDefn, szBuffer);
                }
            }
            else if ((eType == OFTInteger || eType == OFTInteger64) &&
                     poFieldDefn->GetSubType() == OFSTBoolean )
            {
                /* 0 and 1 are OK, but the canonical representation is false and true */
                GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix,
                              bRemoveAppPrefix, poFieldDefn,
                              (poFeature->GetFieldAsInteger(iField)) ? "true" : "false");
            }
            else
            {
                const char *pszRaw = poFeature->GetFieldAsString( iField );

                char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw );

                GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix,
                              bRemoveAppPrefix, poFieldDefn, pszEscaped);
                CPLFree( pszEscaped );
            }
        }
    }

    if (bWriteSpaceIndentation)
        VSIFPrintfL(fp, "    ");
    if( bRemoveAppPrefix )
        poDS->PrintLine( fp, "</%s>", poFeatureDefn->GetName() );
    else
        poDS->PrintLine( fp, "</%s:%s>", pszPrefix, poFeatureDefn->GetName() );
    if (bWriteSpaceIndentation)
        VSIFPrintfL(fp, "  ");
    if (bIsGML3Output)
    {
        if( bRemoveAppPrefix )
            poDS->PrintLine( fp, "</featureMember>" );
        else
            poDS->PrintLine( fp, "</%s:featureMember>", pszPrefix );
    }
    else
        poDS->PrintLine( fp, "</gml:featureMember>" );

    return OGRERR_NONE;
}
Пример #23
0
char *SPrintArray( GDALDataType eDataType, const void *paDataArray,
                          int nValues, const char *pszDelimiter )
{
    const int iFieldSize = 32 + static_cast<int>(strlen( pszDelimiter ) );
    char *pszField = static_cast<char *>( CPLMalloc( iFieldSize + 1 ) );
    const int iStringSize = nValues * iFieldSize + 1;
    char *pszString = static_cast<char *>( CPLMalloc( iStringSize ) );
    memset( pszString, 0, iStringSize );
    for( int i = 0; i < nValues; i++ )
    {
        switch ( eDataType )
        {
            case GDT_Byte:
                snprintf( pszField, iFieldSize + 1, "%d%s",
                         reinterpret_cast<GByte *>(
                             const_cast<void *>( paDataArray ) )[i],
                         (i < nValues - 1)?pszDelimiter:"" );
                break;
            case GDT_UInt16:
                snprintf( pszField, iFieldSize + 1, "%u%s",
                         reinterpret_cast<GUInt16 *>(
                             const_cast<void *>(  paDataArray ) )[i],
                         (i < nValues - 1)?pszDelimiter:"" );
                break;
            case GDT_Int16:
            default:
                snprintf( pszField, iFieldSize + 1, "%d%s",
                         reinterpret_cast<GInt16 *>(
                             const_cast<void *>(  paDataArray ) )[i],
                         (i < nValues - 1)?pszDelimiter:"" );
                break;
            case GDT_UInt32:
                snprintf( pszField, iFieldSize + 1, "%u%s",
                         reinterpret_cast<GUInt32 *>(
                             const_cast<void *>(  paDataArray ) )[i],
                     (i < nValues - 1)?pszDelimiter:"" );
                break;
            case GDT_Int32:
                snprintf( pszField, iFieldSize + 1, "%d%s",
                         reinterpret_cast<GInt32 *>(
                                const_cast<void *>(  paDataArray ) )[i],
                         (i < nValues - 1)?pszDelimiter:"" );
                break;
            case GDT_Float32:
                CPLsnprintf( pszField, iFieldSize + 1, "%.10g%s",
                             reinterpret_cast<float *>(
                                 const_cast<void *>(  paDataArray ) )[i],
                             (i < nValues - 1)?pszDelimiter:"" );
                break;
            case GDT_Float64:
                CPLsnprintf( pszField, iFieldSize + 1, "%.15g%s",
                             reinterpret_cast<double *>(
                                 const_cast<void *>(  paDataArray ) )[i],
                             (i < nValues - 1)?pszDelimiter:"" );
                break;
        }
        strcat( pszString, pszField );
    }

    CPLFree( pszField );
    return pszString;
}
Пример #24
0
GDALDataset* XYZDataset::CreateCopy( const char * pszFilename,
                                     GDALDataset *poSrcDS, 
                                     int bStrict, char ** papszOptions, 
                                     GDALProgressFunc pfnProgress,
                                     void * pProgressData )
{
/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "XYZ driver does not support source dataset with zero band.\n");
        return NULL;
    }

    if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
                  "XYZ driver only uses the first band of the dataset.\n");
        if (bStrict)
            return NULL;
    }

    if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Get source dataset info                                         */
/* -------------------------------------------------------------------- */

    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    double adfGeoTransform[6];
    poSrcDS->GetGeoTransform(adfGeoTransform);
    if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "XYZ driver does not support CreateCopy() from skewed or rotated dataset.\n");
        return NULL;
    }

    GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    GDALDataType eReqDT;
    if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16 ||
        eSrcDT == GDT_UInt16 || eSrcDT == GDT_Int32)
        eReqDT = GDT_Int32;
    else
        eReqDT = GDT_Float32;

/* -------------------------------------------------------------------- */
/*      Create target file                                              */
/* -------------------------------------------------------------------- */

    VSILFILE* fp = VSIFOpenL(pszFilename, "wb");
    if (fp == NULL)
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Cannot create %s", pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read creation options                                           */
/* -------------------------------------------------------------------- */
    const char* pszColSep =
            CSLFetchNameValue(papszOptions, "COLUMN_SEPARATOR");
    if (pszColSep == NULL)
        pszColSep = " ";
    else if (EQUAL(pszColSep, "COMMA"))
        pszColSep = ",";
    else if (EQUAL(pszColSep, "SPACE"))
        pszColSep = " ";
    else if (EQUAL(pszColSep, "SEMICOLON"))
        pszColSep = ";";
    else if (EQUAL(pszColSep, "\\t") || EQUAL(pszColSep, "TAB"))
        pszColSep = "\t";

    const char* pszAddHeaderLine =
            CSLFetchNameValue(papszOptions, "ADD_HEADER_LINE");
    if (pszAddHeaderLine != NULL && CSLTestBoolean(pszAddHeaderLine))
    {
        VSIFPrintfL(fp, "X%sY%sZ\n", pszColSep, pszColSep);
    }

/* -------------------------------------------------------------------- */
/*      Copy imagery                                                    */
/* -------------------------------------------------------------------- */
    void* pLineBuffer = (void*) CPLMalloc(nXSize * sizeof(int));
    int i, j;
    CPLErr eErr = CE_None;
    for(j=0;j<nYSize && eErr == CE_None;j++)
    {
        eErr = poSrcDS->GetRasterBand(1)->RasterIO(
                                            GF_Read, 0, j, nXSize, 1,
                                            pLineBuffer, nXSize, 1,
                                            eReqDT, 0, 0, NULL);
        if (eErr != CE_None)
            break;
        double dfY = adfGeoTransform[3] + (j + 0.5) * adfGeoTransform[5];
        CPLString osBuf;
        for(i=0;i<nXSize;i++)
        {
            char szBuf[256];
            double dfX = adfGeoTransform[0] + (i + 0.5) * adfGeoTransform[1];
            if (eReqDT == GDT_Int32)
                CPLsnprintf(szBuf, sizeof(szBuf), "%.18g%c%.18g%c%d\n", dfX, pszColSep[0], dfY, pszColSep[0], ((int*)pLineBuffer)[i]);
            else
                CPLsnprintf(szBuf, sizeof(szBuf), "%.18g%c%.18g%c%.18g\n", dfX, pszColSep[0], dfY, pszColSep[0], ((float*)pLineBuffer)[i]);
            osBuf += szBuf;
            if( (i & 1023) == 0 || i == nXSize - 1 )
            {
                if ( VSIFWriteL( osBuf, (int)osBuf.size(), 1, fp ) != 1 )
                {
                    eErr = CE_Failure;
                    CPLError( CE_Failure, CPLE_AppDefined, 
                              "Write failed, disk full?\n" );
                    break;
                }
                osBuf = "";
            }
        }
        if (!pfnProgress( (j+1) * 1.0 / nYSize, NULL, pProgressData))
        {
            eErr = CE_Failure;
            break;
        }
    }
    CPLFree(pLineBuffer);
    VSIFCloseL(fp);
    
    if (eErr != CE_None)
        return NULL;

/* -------------------------------------------------------------------- */
/*      We don't want to call GDALOpen() since it will be expensive,    */
/*      so we "hand prepare" an XYZ dataset referencing our file.       */
/* -------------------------------------------------------------------- */
    XYZDataset* poXYZ_DS = new XYZDataset();
    poXYZ_DS->nRasterXSize = nXSize;
    poXYZ_DS->nRasterYSize = nYSize;
    poXYZ_DS->nBands = 1;
    poXYZ_DS->SetBand( 1, new XYZRasterBand( poXYZ_DS, 1, eReqDT ) );
    /* If outputing to stdout, we can't reopen it --> silence warning */
    CPLPushErrorHandler(CPLQuietErrorHandler);
    poXYZ_DS->fp = VSIFOpenL( pszFilename, "rb" );
    CPLPopErrorHandler();
    memcpy( &(poXYZ_DS->adfGeoTransform), adfGeoTransform, sizeof(double)*6 );
    poXYZ_DS->nXIndex = 0;
    poXYZ_DS->nYIndex = 1;
    poXYZ_DS->nZIndex = 2;
    if( pszAddHeaderLine )
    {
        poXYZ_DS->nDataLineNum = 1;
        poXYZ_DS->bHasHeaderLine = TRUE;
    }

    return poXYZ_DS;
}
Пример #25
0
static herr_t HDF5AttrIterate( hid_t hH5ObjID,
                               const char *pszAttrName,
                               // TODO(schwehr): void * -> HDF5Dataset *
                               void *pDS )
{
    char **papszTokens = nullptr;
    CPLString osKey;
    HDF5Dataset *const poDS = static_cast<HDF5Dataset *>(pDS);

    // Convert "/" into "_" for the path component
    const char *pszPath = poDS->poH5CurrentObject->pszUnderscorePath;
    if(pszPath != nullptr && strlen(pszPath) > 0)
    {
        papszTokens = CSLTokenizeString2(pszPath, "/", CSLT_HONOURSTRINGS);

        for( hsize_t i = 0; papszTokens != nullptr && papszTokens[i] != nullptr; ++i )
        {
            if( i != 0)
                osKey += '_';
            osKey += papszTokens[i];
        }
        CSLDestroy(papszTokens);
    }

    // Convert whitespaces into "_" for the attribute name component
    papszTokens = CSLTokenizeString2(
        pszAttrName, " ", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES);
    for( hsize_t i = 0; papszTokens != nullptr && papszTokens[i] != nullptr; ++i )
    {
        if(!osKey.empty())
            osKey += '_';
        osKey += papszTokens[i];
    }
    CSLDestroy(papszTokens);

    const hid_t hAttrID = H5Aopen_name(hH5ObjID, pszAttrName);
    const hid_t hAttrTypeID = H5Aget_type(hAttrID);
    const hid_t hAttrNativeType =
        H5Tget_native_type(hAttrTypeID, H5T_DIR_DEFAULT);
    const hid_t hAttrSpace = H5Aget_space(hAttrID);

    if( H5Tget_class(hAttrNativeType) == H5T_VLEN )
        return 0;

    hsize_t nSize[64] = {};
    const unsigned int nAttrDims =
        H5Sget_simple_extent_dims(hAttrSpace, nSize, nullptr);

    unsigned int nAttrElmts = 1;
    for( hsize_t i = 0; i < nAttrDims; i++ )
    {
        nAttrElmts *= static_cast<int>(nSize[i]);
    }

    char *szData = nullptr;
    hsize_t nAttrSize = 0;
    char *szValue = nullptr;

    if( H5Tget_class(hAttrNativeType) == H5T_STRING )
    {
        if ( H5Tis_variable_str(hAttrNativeType) )
        {
            char **papszStrings =
                static_cast<char **>(CPLMalloc(nAttrElmts * sizeof(char *)));

            // Read the values.
            H5Aread(hAttrID, hAttrNativeType, papszStrings);

            // Concatenate all values as one string separated by a space.
            CPLString osVal = papszStrings[0];
            for( hsize_t i = 1; i < nAttrElmts; i++ )
            {
                osVal += " ";
                osVal += papszStrings[i];
            }

            szValue = static_cast<char *>(CPLMalloc(osVal.length() + 1));
            strcpy(szValue, osVal.c_str());

            H5Dvlen_reclaim(hAttrNativeType, hAttrSpace, H5P_DEFAULT,
                            papszStrings);
            CPLFree(papszStrings);
        }
        else
        {
            nAttrSize = H5Aget_storage_size(hAttrID);
            szValue = static_cast<char *>(CPLMalloc((size_t)(nAttrSize + 1)));
            H5Aread(hAttrID, hAttrNativeType, szValue);
            szValue[nAttrSize] = '\0';
        }
    }
    else
    {
        const size_t nDataLen = 8192;
        void *buf = nullptr;

        if( nAttrElmts > 0 )
        {
            buf = CPLMalloc(nAttrElmts * H5Tget_size(hAttrNativeType));
            szData = static_cast<char *>(CPLMalloc(nDataLen));
            szValue = static_cast<char *>(CPLMalloc(MAX_METADATA_LEN));
            szData[0] = '\0';
            szValue[0] = '\0';
            H5Aread(hAttrID, hAttrNativeType, buf);
        }
        if( H5Tequal(H5T_NATIVE_CHAR, hAttrNativeType ) ||
            H5Tequal(H5T_NATIVE_SCHAR, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%c ", static_cast<char *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_UCHAR, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%c", static_cast<char *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_SHORT, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%d ", static_cast<short *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_USHORT, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
              snprintf(szData, nDataLen, "%ud ",
                       static_cast<unsigned short *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_INT, hAttrNativeType) )
        {
            for( hsize_t i=0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%d ", static_cast<int *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_UINT, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%ud ",
                         static_cast<unsigned int *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_LONG, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                snprintf(szData, nDataLen, "%ld ", static_cast<long *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_ULONG, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ ) {
                snprintf(szData, nDataLen, "%lu ",
                         static_cast<unsigned long *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_FLOAT, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                CPLsnprintf(szData, nDataLen, "%.8g ",
                            static_cast<float *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        else if( H5Tequal(H5T_NATIVE_DOUBLE, hAttrNativeType) )
        {
            for( hsize_t i = 0; i < nAttrElmts; i++ )
            {
                CPLsnprintf(szData, nDataLen, "%.15g ",
                            static_cast<double *>(buf)[i]);
                if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >=
                    MAX_METADATA_LEN )
                    CPLError(CE_Warning, CPLE_OutOfMemory,
                             "Header data too long. Truncated");
            }
        }
        CPLFree(buf);
    }
    H5Sclose(hAttrSpace);
    H5Tclose(hAttrNativeType);
    H5Tclose(hAttrTypeID);
    H5Aclose(hAttrID);
    poDS->papszMetadata = CSLSetNameValue(poDS->papszMetadata, osKey, szValue);

    CPLFree(szData);
    CPLFree(szValue);

    return 0;
}
Пример #26
0
static void MakeKMLCoordinate( char *pszTarget, size_t nTargetLen,
                               double x, double y, double z, int b3D )

{
    if (y < -90 || y > 90)
    {
        if (y > 90 && y < 90 + EPSILON)
        {
            y = 90;
        }
        else if (y > -90 - EPSILON  && y < -90)
        {
            y = -90;
        }
        else
        {
            static bool bFirstWarning = true;
            if( bFirstWarning )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "Latitude %f is invalid. Valid range is [-90,90]. "
                          "This warning will not be issued any more",
                          y );
                bFirstWarning = false;
            }
        }
    }

    if (x < -180 || x > 180)
    {
        if (x > 180 && x < 180 + EPSILON)
        {
            x = 180;
        }
        else if (x > -180 - EPSILON  && x < -180)
        {
            x = -180;
        }
        else
        {
            static bool bFirstWarning = true;
            if( bFirstWarning )
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                          "Longitude %f has been modified to fit into "
                          "range [-180,180]. This warning will not be "
                          "issued any more",
                          x );
                bFirstWarning = false;
            }

            if (x > 180)
                x -= (static_cast<int>((x+180)/360)*360);
            else if (x < -180)
                x += (static_cast<int>(180 - x)/360)*360;
        }
    }

    OGRMakeWktCoordinate( pszTarget, x, y, z, b3D ? 3 : 2 );
    while( *pszTarget != '\0' )
    {
        if( *pszTarget == ' ' )
            *pszTarget = ',';
        pszTarget++;
        nTargetLen --;
    }

#if 0
    if( !b3D )
    {
        if( x == static_cast<int>(x) && y == static_cast<int>(y) )
            snprintf( pszTarget, nTargetLen, "%d,%d",
                      static_cast<int>(x), static_cast<int>(y) );
        else if( fabs(x) < 370 && fabs(y) < 370 )
            CPLsnprintf( pszTarget, nTargetLen, "%.16g,%.16g", x, y );
        else if( fabs(x) > 100000000.0 || fabs(y) > 100000000.0 )
            CPLsnprintf( pszTarget, nTargetLen, "%.16g,%.16g", x, y );
        else
            CPLsnprintf( pszTarget, nTargetLen, "%.3f,%.3f", x, y );
    }
    else
    {
        if( x == static_cast<int>(x) &&
            y == static_cast<int>(y) &&
            z == static_cast<int>(z) )
            snprintf( pszTarget, nTargetLen, "%d,%d,%d",
                      static_cast<int>(x), static_cast<int>(y),
                      static_cast<int>(z) );
        else if( fabs(x) < 370 && fabs(y) < 370 )
            CPLsnprintf( pszTarget, nTargetLen, "%.16g,%.16g,%.16g", x, y, z );
        else if( fabs(x) > 100000000.0 || fabs(y) > 100000000.0
                 || fabs(z) > 100000000.0 )
            CPLsnprintf( pszTarget, nTargetLen, "%.16g,%.16g,%.16g", x, y, z );
        else
            CPLsnprintf( pszTarget, nTargetLen, "%.3f,%.3f,%.3f", x, y, z );
    }
#endif
}
Пример #27
0
static void EXIFPrintData(char* pszData, GUInt16 type,
                   GUInt32 count, unsigned char* data)
{
  const char* sep = "";
  char  pszTemp[128];
  char* pszDataEnd = pszData;

  pszData[0]='\0';

  switch (type) {

  case TIFF_UNDEFINED:
  case TIFF_BYTE:
    for(;count>0;count--) {
      snprintf(pszTemp, sizeof(pszTemp), "%s%#02x", sep, *data++), sep = " ";
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;

  case TIFF_SBYTE:
    for(;count>0;count--) {
      snprintf(pszTemp, sizeof(pszTemp), "%s%d", sep, *(char *)data++), sep = " ";
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;

  case TIFF_ASCII:
    memcpy( pszData, data, count );
    pszData[count] = '\0';
    break;

  case TIFF_SHORT: {
    register GUInt16 *wp = (GUInt16*)data;
    for(;count>0;count--) {
      snprintf(pszTemp, sizeof(pszTemp), "%s%u", sep, *wp++), sep = " ";
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;
  }
  case TIFF_SSHORT: {
    register GInt16 *wp = (GInt16*)data;
    for(;count>0;count--) {
      snprintf(pszTemp, sizeof(pszTemp), "%s%d", sep, *wp++);
      sep = " ";
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;
  }
  case TIFF_LONG: {
    register GUInt32 *lp = (GUInt32*)data;
    for(;count>0;count--) {
      snprintf(pszTemp, sizeof(pszTemp), "%s%lu", sep, (unsigned long) *lp++);
      sep = " ";
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;
  }
  case TIFF_SLONG: {
    register GInt32 *lp = (GInt32*)data;
    for(;count>0;count--) {
      snprintf(pszTemp, sizeof(pszTemp), "%s%ld", sep, (long) *lp++), sep = " ";
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;
  }
  case TIFF_RATIONAL: {
    register GUInt32 *lp = (GUInt32*)data;
      //      if(bSwabflag)
      //      TIFFSwabArrayOfLong((GUInt32*) data, 2*count);
    for(;count>0;count--) {
      if( (lp[0]==0) && (lp[1] == 0) ) {
          snprintf(pszTemp, sizeof(pszTemp), "%s(0)",sep);
      }
      else{
          CPLsnprintf(pszTemp, sizeof(pszTemp), "%s(%g)", sep,
              (double) lp[0]/ (double)lp[1]);
      }
      sep = " ";
      lp += 2;
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;
  }
  case TIFF_SRATIONAL: {
    register GInt32 *lp = (GInt32*)data;
    for(;count>0;count--) {
      CPLsnprintf(pszTemp, sizeof(pszTemp), "%s(%g)", sep,
          (float) lp[0]/ (float) lp[1]);
      sep = " ";
      lp += 2;
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;
  }
  case TIFF_FLOAT: {
    register float *fp = (float *)data;
    for(;count>0;count--) {
      CPLsnprintf(pszTemp, sizeof(pszTemp), "%s%g", sep, *fp++), sep = " ";
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;
  }
  case TIFF_DOUBLE: {
    register double *dp = (double *)data;
    for(;count>0;count--) {
      CPLsnprintf(pszTemp, sizeof(pszTemp), "%s%g", sep, *dp++), sep = " ";
      if (strlen(pszTemp) + pszDataEnd - pszData >= MAXSTRINGLENGTH)
          break;
      strcat(pszDataEnd,pszTemp);
      pszDataEnd += strlen(pszDataEnd);
    }
    break;
  }

  default:
    return;
  }

  if (type != TIFF_ASCII && count != 0)
  {
      CPLError(CE_Warning, CPLE_AppDefined, "EXIF metadata truncated");
  }
}
Пример #28
0
GDALDataset * SRTMHGTDataset::CreateCopy( const char * pszFilename,
                                          GDALDataset *poSrcDS,
                                          int bStrict,
                                          char ** /* papszOptions*/,
                                          GDALProgressFunc pfnProgress,
                                          void * pProgressData )
{
/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    const int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "SRTMHGT driver does not support source dataset with zero band.\n");
        return nullptr;
    }
    else if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported,
                  "SRTMHGT driver only uses the first band of the dataset.\n");
        if (bStrict)
            return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Checks the input SRS                                            */
/* -------------------------------------------------------------------- */
    OGRSpatialReference ogrsr_input;
    ogrsr_input.importFromWkt(poSrcDS->GetProjectionRef());

    OGRSpatialReference ogrsr_wgs84;
    ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" );

    if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE)
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "The source projection coordinate system is %s. Only WGS 84 "
                  "is supported.\nThe SRTMHGT driver will generate a file as "
                  "if the source was WGS 84 projection coordinate system.",
                  poSrcDS->GetProjectionRef() );
    }

/* -------------------------------------------------------------------- */
/*      Work out the LL origin.                                         */
/* -------------------------------------------------------------------- */
    double adfGeoTransform[6];
    if (poSrcDS->GetGeoTransform( adfGeoTransform ) != CE_None)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Source image must have a geo transform matrix.");
        return nullptr;
    }

    const int nLLOriginLat = static_cast<int>(
        std::floor(adfGeoTransform[3]
              + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5) );

    int nLLOriginLong = static_cast<int>(
        std::floor(adfGeoTransform[0] + 0.5) );

    if (std::abs(nLLOriginLat - (
            adfGeoTransform[3] + (poSrcDS->GetRasterYSize() - 0.5 )
            * adfGeoTransform[5] ) ) > 1e-10 ||
        std::abs(nLLOriginLong - (
            adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10 )
    {
        CPLError( CE_Warning, CPLE_AppDefined,
               "The corner coordinates of the source are not properly "
               "aligned on plain latitude/longitude boundaries.");
    }

/* -------------------------------------------------------------------- */
/*      Check image dimensions.                                         */
/* -------------------------------------------------------------------- */
    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();

    if (!((nXSize == 1201 && nYSize == 1201) ||
          (nXSize == 3601 && nYSize == 3601) ||
          (nXSize == 1801 && nYSize == 3601)))
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Image dimensions should be 1201x1201, 3601x3601 or 1801x3601.");
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Check filename.                                                 */
/* -------------------------------------------------------------------- */
    char expectedFileName[12];

    CPLsnprintf(expectedFileName, sizeof(expectedFileName), "%c%02d%c%03d.HGT",
             (nLLOriginLat >= 0) ? 'N' : 'S',
             (nLLOriginLat >= 0) ? nLLOriginLat : -nLLOriginLat,
             (nLLOriginLong >= 0) ? 'E' : 'W',
             (nLLOriginLong >= 0) ? nLLOriginLong : -nLLOriginLong);

    if (!EQUAL(expectedFileName, CPLGetFilename(pszFilename)))
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Expected output filename is %s.", expectedFileName);
    }

/* -------------------------------------------------------------------- */
/*      Write output file.                                              */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(pszFilename, "wb");
    if (fp == nullptr)
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Cannot create file %s", pszFilename );
        return nullptr;
    }

    GInt16* panData
        = reinterpret_cast<GInt16 *>( CPLMalloc(sizeof(GInt16) * nXSize) );
    GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(1);

    int bSrcBandHasNoData;
    double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData);

    for( int iY = 0; iY < nYSize; iY++ )
    {
        if( poSrcBand->RasterIO( GF_Read, 0, iY, nXSize, 1,
                                 reinterpret_cast<void *>( panData ), nXSize, 1,
                                 GDT_Int16, 0, 0, nullptr ) != CE_None )
        {
            VSIFCloseL(fp);
            CPLFree( panData );
            return nullptr;
        }

        /* Translate nodata values */
        if (bSrcBandHasNoData && srcBandNoData != SRTMHG_NODATA_VALUE)
        {
            for( int iX = 0; iX < nXSize; iX++ )
            {
                if (panData[iX] == srcBandNoData)
                    panData[iX] = SRTMHG_NODATA_VALUE;
            }
        }

#ifdef CPL_LSB
        GDALSwapWords(panData, 2, nXSize, 2);
#endif

        if( VSIFWriteL( panData,sizeof(GInt16) * nXSize,1,fp ) != 1)
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Failed to write line %d in SRTMHGT dataset.\n",
                      iY );
            VSIFCloseL(fp);
            CPLFree( panData );
            return nullptr;
        }

        if( pfnProgress && !pfnProgress( (iY+1) / static_cast<double>( nYSize ),
                                         nullptr, pProgressData ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt,
                        "User terminated CreateCopy()" );
            VSIFCloseL(fp);
            CPLFree( panData );
            return nullptr;
        }
    }

    CPLFree( panData );
    VSIFCloseL(fp);

/* -------------------------------------------------------------------- */
/*      Reopen and copy missing information into a PAM file.            */
/* -------------------------------------------------------------------- */
    GDALPamDataset *poDS = reinterpret_cast<GDALPamDataset *>(
        GDALOpen( pszFilename, GA_ReadOnly ) );

    if( poDS )
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT);

    return poDS;
}