Esempio n. 1
0
int main (int argc, const char * argv[]) {
  
  if (argc < 2 || argc > 3 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
    std::cout << "=== prepair Help ===\n" << std::endl;
    std::cout << "Usage:   triface 'POLYGON(...)'" << std::endl;
    std::cout << "OR" << std::endl;
    std::cout << "Usage:   triface -f infile.txt (infile.txt must contain one WKT on the 1st line)" << std::endl;
    return 0;
  }
  
  // Read input
  unsigned int bufferSize = 10000000;
  char *inputWKT = (char *)malloc(bufferSize*sizeof(char *));
  
  for (int argNum = 1; argNum < argc; ++argNum) {
    if (strcmp(argv[argNum], "-f") == 0) {
      
      if (argNum + 1 <= argc - 1 && argv[argNum+1][0] != '-') {
        std::ifstream infile(argv[argNum+1], std::ifstream::in);
        infile.getline(inputWKT, bufferSize);
        ++argNum;
      } else {
        std::cerr << "Error: Missing input file name." << std::endl;
        return 1;
      }
    }
    else 
      strcpy(inputWKT, argv[argNum]);
  }
  
//  std::cout << "Processing: " << inputWKT << std::endl;
  
  OGRGeometry *geometry;
  OGRGeometryFactory::createFromWkt(&inputWKT, NULL, &geometry);
  if (geometry == NULL) {
    std::cout << "Error: WKT is not valid" << std::endl;
    return 1;
  }

  if (geometry->getGeometryType() != wkbPolygon25D) {
    std::cout << "Error: input geometry is not a 3D polygon" << std::endl;
    return 1;
  }
  
  //-- project to proper plane + get flattened geometry
  int proj = get_projection_plane(geometry);
  OGRGeometry *flatgeom = geometry->clone();
  if (proj == 1) {
    OGRPolygon *polygon = (OGRPolygon *)flatgeom;
    for (int curp = 0; curp < polygon->getExteriorRing()->getNumPoints(); ++curp) 
      polygon->getExteriorRing()->setPoint(curp, polygon->getExteriorRing()->getX(curp), polygon->getExteriorRing()->getZ(curp), 0);
    for (int currentRing = 0; currentRing < polygon->getNumInteriorRings(); ++currentRing) {
      for (int curp = 0; curp < polygon->getInteriorRing(currentRing)->getNumPoints(); ++curp)
        polygon->getInteriorRing(currentRing)->setPoint(curp, polygon->getInteriorRing(currentRing)->getX(curp), polygon->getInteriorRing(currentRing)->getZ(curp), 0);
    }
  }
  else if (proj == 0) {
    OGRPolygon *polygon = (OGRPolygon *)geometry;
    for (int curp = 0; curp < polygon->getExteriorRing()->getNumPoints(); ++curp)
      polygon->getExteriorRing()->setPoint(curp, polygon->getExteriorRing()->getY(curp), polygon->getExteriorRing()->getZ(curp), 0);
    for (int currentRing = 0; currentRing < polygon->getNumInteriorRings(); ++currentRing) {
      for (int curp = 0; curp < polygon->getInteriorRing(currentRing)->getNumPoints(); ++curp)
        polygon->getInteriorRing(currentRing)->setPoint(curp, polygon->getInteriorRing(currentRing)->getY(curp), polygon->getInteriorRing(currentRing)->getZ(curp), 0);
    }
  }
  flatgeom->flattenTo2D();
//  std::cout << "geom: " << geometry->getCoordinateDimension() << std::endl;
//  std::cout << "flatgeom: " << flatgeom->getCoordinateDimension() << std::endl;
  
  //-- check if flattened geometry is valid
  if (flatgeom->IsValid() == FALSE) {
    std::cout << "Error: input polygon is not valid." << std::endl;
    return 1;
  }
  
  if (proj == 2) {
    Triangulationxy triangulation;
    triangulateandtag_xy(geometry, triangulation);
    for (Triangulationxy::Finite_faces_iterator currentFace = triangulation.finite_faces_begin(); currentFace != triangulation.finite_faces_end(); ++currentFace) {
      std::cout << "--triangle--" << std::endl;
      Point p = currentFace->vertex(0)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(1)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(2)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
    }
  }
  else if (proj == 1) {
    Triangulationxz triangulation;
    triangulateandtag_xz(geometry, triangulation);
    for (Triangulationxz::Finite_faces_iterator currentFace = triangulation.finite_faces_begin(); currentFace != triangulation.finite_faces_end(); ++currentFace) {
      std::cout << "--triangle--" << std::endl;
      Point p = currentFace->vertex(0)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(1)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(2)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
    }
  }
  else { //-- proj == 0
    Triangulationyz triangulation;
    triangulateandtag_yz(geometry, triangulation);    
    for (Triangulationyz::Finite_faces_iterator currentFace = triangulation.finite_faces_begin(); currentFace != triangulation.finite_faces_end(); ++currentFace) {
      std::cout << "--triangle--" << std::endl;
      Point p = currentFace->vertex(0)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(1)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(2)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
    }
  }
     
  return 0;
}
OGRErr OGRDXFLayer::CollectBoundaryPath( OGRGeometryCollection *poGC )

{
    int  nCode;
    char szLineBuf[257];

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

    int  nBoundaryPathType = atoi(szLineBuf);

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

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

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

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

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

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

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

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

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

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

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

            OGRLineString *poLS = new OGRLineString();

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

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

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

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

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

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

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

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

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;
            if( bCounterClockwise )
            {
                dfStartAngle *= -1; 
                dfEndAngle *= -1; 
            }

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

            poArc->flattenTo2D();

            poGC->addGeometryDirectly( poArc );
        }

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

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

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

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

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

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

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

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

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

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;
            if( bCounterClockwise )
            {
                dfStartAngle *= -1; 
                dfEndAngle *= -1; 
            }

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

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

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

            poArc->flattenTo2D();

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

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

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

    return OGRERR_NONE;
}
OGRErr OGRMySQLTableLayer::CreateFeature( OGRFeature *poFeature )

{
    MYSQL_RES           *hResult=NULL;
    CPLString           osCommand;
    int                 i, bNeedComma = FALSE;

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */
    osCommand.Printf( "INSERT INTO `%s` (", poFeatureDefn->GetName() );

    if( poFeature->GetGeometryRef() != NULL )
    {
        osCommand = osCommand + "`" + pszGeomColumn + "` ";
        bNeedComma = TRUE;
    }

    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
    {
        if( bNeedComma )
            osCommand += ", ";
        
        osCommand = osCommand + "`" + pszFIDColumn + "` ";
        bNeedComma = TRUE;
    }

    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( !bNeedComma )
            bNeedComma = TRUE;
        else
            osCommand += ", ";

        osCommand = osCommand + "`"
             + poFeatureDefn->GetFieldDefn(i)->GetNameRef() + "`";
    }

    osCommand += ") VALUES (";

    // Set the geometry 
    bNeedComma = poFeature->GetGeometryRef() != NULL;
    if( poFeature->GetGeometryRef() != NULL)
    {
        char    *pszWKT = NULL;

        if( poFeature->GetGeometryRef() != NULL )
        {
            OGRGeometry *poGeom = (OGRGeometry *) poFeature->GetGeometryRef();
            
            poGeom->closeRings();
            poGeom->flattenTo2D();
            poGeom->exportToWkt( &pszWKT );
        }

        if( pszWKT != NULL )
        {

            osCommand += 
                CPLString().Printf(
                    "GeometryFromText('%s',%d) ", pszWKT, nSRSId );

            OGRFree( pszWKT );
        }
        else
            osCommand += "''";
    }


    // Set the FID 
    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
    {
        if( bNeedComma )
            osCommand += ", ";
        osCommand += CPLString().Printf( "%ld ", poFeature->GetFID() );
        bNeedComma = TRUE;
    }

    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( bNeedComma )
            osCommand += ", ";
        else
            bNeedComma = TRUE;

        const char *pszStrValue = poFeature->GetFieldAsString(i);

        if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTBinary )
        {
            int         iChar;

            //We need to quote and escape string fields. 
            osCommand += "'";

            for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ )
            {
                if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList
                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList
                    && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0
                    && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() )
                {
                    CPLDebug( "MYSQL",
                              "Truncated %s field value, it was too long.",
                              poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
                    break;
                }

                if( pszStrValue[iChar] == '\\'
                    || pszStrValue[iChar] == '\'' )
                {
                    osCommand += '\\';
                    osCommand += pszStrValue[iChar];
                }
                else
                    osCommand += pszStrValue[iChar];
            }

            osCommand += "'";
        }
        else if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTBinary )
        {
            int binaryCount = 0;
            GByte* binaryData = poFeature->GetFieldAsBinary(i, &binaryCount);
            char* pszHexValue = CPLBinaryToHex( binaryCount, binaryData );

            osCommand += "x'";
            osCommand += pszHexValue;
            osCommand += "'";

            CPLFree( pszHexValue );
        }
        else
        {
            osCommand += pszStrValue;
        }

    }

    osCommand += ")";
    
    int nQueryResult = mysql_query(poDS->GetConn(), osCommand.c_str() );
    const my_ulonglong nFID = mysql_insert_id( poDS->GetConn() );
    
    if( nQueryResult ){   
        int eErrorCode = mysql_errno(poDS->GetConn());
        if (eErrorCode == 1153) {//ER_NET_PACKET_TOO_LARGE)
            poDS->ReportError("CreateFeature failed because the MySQL server " \
                              "cannot read the entire query statement.  Increase " \
                              "the size of statements your server will allow by " \
                              "altering the 'max_allowed_packet' parameter in "\
                              "your MySQL server configuration.");
        }
        else
        {
        CPLDebug("MYSQL","Error number %d", eErrorCode);
            poDS->ReportError(  osCommand.c_str() );
        }

        // make sure to attempt to free results
        hResult = mysql_store_result( poDS->GetConn() );
        if( hResult != NULL )
            mysql_free_result( hResult );
        hResult = NULL;
            
        return OGRERR_FAILURE;   
    }

    if( nFID > 0 ) {
        poFeature->SetFID( nFID );
    }

    // make sure to attempt to free results of successful queries
    hResult = mysql_store_result( poDS->GetConn() );
    if( hResult != NULL )
        mysql_free_result( hResult );
    hResult = NULL;
    
    return OGRERR_NONE;

}
OGRErr OGRDXFLayer::CollectBoundaryPath( OGRGeometryCollection *poGC )

{
    int  nCode;
    char szLineBuf[257];

/* -------------------------------------------------------------------- */
/*      Read the boundary path type.                                    */
/* -------------------------------------------------------------------- */
#define BPT_DEFAULT    0
#define BPT_EXTERNAL   1
#define BPT_POLYLINE   2
#define BPT_DERIVED    3
#define BPT_TEXTBOX    4
#define BPT_OUTERMOST  5

    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 92 )
        return NULL;

    int  nBoundaryPathType = atoi(szLineBuf);
    
    // for now we don't implement polyline support.
    if( nBoundaryPathType == BPT_POLYLINE )
    {
        CPLDebug( "DXF", "HATCH polyline boundaries not yet supported." );
        return OGRERR_UNSUPPORTED_OPERATION;
    }

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

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

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

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

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

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

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

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

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

            OGRLineString *poLS = new OGRLineString();

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

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

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

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

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

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

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

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

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

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;

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

            poArc->flattenTo2D();

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

/* -------------------------------------------------------------------- */
/*      Number of source boundary objects.                              */
/* -------------------------------------------------------------------- */
    nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf));
    if( nCode != 97 )
        poDS->UnreadValue();
    else
    {
        if( atoi(szLineBuf) != 0 )
        {
            CPLDebug( "DXF", "got unsupported HATCH boundary object references." );
            return OGRERR_UNSUPPORTED_OPERATION;
        }
    }

    return OGRERR_NONE;
}
Esempio n. 5
0
OGRErr OGRDXFLayer::CollectBoundaryPath( OGRGeometryCollection *poGC,
    const double dfElevation )

{
    char szLineBuf[257];

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

    const int nBoundaryPathType = atoi(szLineBuf);

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

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

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

    const int nEdgeCount = atoi(szLineBuf);

/* -------------------------------------------------------------------- */
/*      Loop reading edges.                                             */
/* -------------------------------------------------------------------- */
    for( int iEdge = 0; iEdge < nEdgeCount; iEdge++ )
    {
/* -------------------------------------------------------------------- */
/*      Read the edge type.                                             */
/* -------------------------------------------------------------------- */
        const int ET_LINE = 1;
        const int ET_CIRCULAR_ARC = 2;
        const int ET_ELLIPTIC_ARC = 3;
        const int ET_SPLINE = 4;

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

        int nEdgeType = atoi(szLineBuf);

/* -------------------------------------------------------------------- */
/*      Process a line edge.                                            */
/* -------------------------------------------------------------------- */
        if( nEdgeType == ET_LINE )
        {
            double dfStartX = 0.0;

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

            double dfStartY = 0.0;

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

            double dfEndX = 0.0;

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

            double dfEndY = 0.0;

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

            OGRLineString *poLS = new OGRLineString();

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

            poGC->addGeometryDirectly( poLS );
        }
/* -------------------------------------------------------------------- */
/*      Process a circular arc.                                         */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_CIRCULAR_ARC )
        {
            double dfCenterX = 0.0;

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

            double dfCenterY = 0.0;

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

            double dfRadius = 0.0;

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

            double dfStartAngle = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 50 )
                dfStartAngle = CPLAtof(szLineBuf);
            else
                break;

            double dfEndAngle = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 51 )
                dfEndAngle = CPLAtof(szLineBuf);
            else
                break;

            bool bCounterClockwise = false;

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

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;
            if( bCounterClockwise )
            {
                dfStartAngle *= -1;
                dfEndAngle *= -1;
            }

            if( fabs(dfEndAngle - dfStartAngle) <= 361.0 )
            {
                OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles(
                    dfCenterX, dfCenterY, dfElevation,
                    dfRadius, dfRadius, 0.0,
                    dfStartAngle, dfEndAngle, 0.0 );

                // If the input was 2D, we assume we want to keep it that way
                if( dfElevation == 0.0 )
                    poArc->flattenTo2D();

                poGC->addGeometryDirectly( poArc );
            }
            else
            {
                // TODO: emit error ?
            }
        }

/* -------------------------------------------------------------------- */
/*      Process an elliptical arc.                                      */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_ELLIPTIC_ARC )
        {
            double dfCenterX = 0.0;

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

            double dfCenterY = 0.0;

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

            double dfMajorX = 0.0;

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

            double dfMajorY = 0.0;

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

            double dfRatio = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 40 )
                dfRatio = CPLAtof(szLineBuf);
            if( dfRatio == 0.0 )
                break;

            double dfStartAngle = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 50 )
                dfStartAngle = CPLAtof(szLineBuf);
            else
                break;

            double dfEndAngle = 0.0;

            if( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) == 51 )
                dfEndAngle = CPLAtof(szLineBuf);
            else
                break;

            bool bCounterClockwise = false;

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

            if( dfStartAngle > dfEndAngle )
                dfEndAngle += 360.0;
            if( bCounterClockwise )
            {
                dfStartAngle *= -1;
                dfEndAngle *= -1;
            }

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

            const double dfRotation =
                -1 * atan2( dfMajorY, dfMajorX ) * 180 / M_PI;

            // The start and end angles are stored as circular angles. However,
            // approximateArcAngles is expecting elliptical angles (what AutoCAD
            // calls "parameters"), so let's transform them.
            dfStartAngle = 180.0 * floor ( ( dfStartAngle + 90 ) / 180 ) +
                    atan( ( 1.0 / dfRatio ) * tan( dfStartAngle * M_PI / 180 ) ) * 180 / M_PI;
            dfEndAngle = 180.0 * floor ( ( dfEndAngle + 90 ) / 180 ) +
                    atan( ( 1.0 / dfRatio ) * tan( dfEndAngle * M_PI / 180 ) ) * 180 / M_PI;

            if( fabs(dfEndAngle - dfStartAngle) <= 361.0 )
            {
                OGRGeometry *poArc = OGRGeometryFactory::approximateArcAngles(
                    dfCenterX, dfCenterY, dfElevation,
                    dfMajorRadius, dfMinorRadius, dfRotation,
                    dfStartAngle, dfEndAngle, 0.0 );

                // If the input was 2D, we assume we want to keep it that way
                if( dfElevation == 0.0 )
                    poArc->flattenTo2D();

                poGC->addGeometryDirectly( poArc );
            }
            else
            {
                // TODO: emit error ?
            }
        }

/* -------------------------------------------------------------------- */
/*      Process an elliptical arc.                                      */
/* -------------------------------------------------------------------- */
        else if( nEdgeType == ET_SPLINE )
        {
            int nDegree = 3;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 94 )
                nDegree = atoi(szLineBuf);
            else
                break;

            // Skip a few things we don't care about
            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) != 73 )
                break;
            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) != 74 )
                break;

            int nKnots = 0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 95 )
                nKnots = atoi(szLineBuf);
            else
                break;

            int nControlPoints = 0;

            if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 96 )
                nControlPoints = atoi(szLineBuf);
            else
                break;

            std::vector<double> adfKnots( 1, 0.0 );

            nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
            if( nCode != 40 )
                break;

            while( nCode == 40 )
            {
                adfKnots.push_back( CPLAtof(szLineBuf) );
                nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
            }

            std::vector<double> adfControlPoints( 1, 0.0 );
            std::vector<double> adfWeights( 1, 0.0 );

            if( nCode != 10 )
                break;

            while( nCode == 10 )
            {
                adfControlPoints.push_back( CPLAtof(szLineBuf) );

                if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 20 )
                {
                    adfControlPoints.push_back( CPLAtof(szLineBuf) );
                }
                else
                    break;

                adfControlPoints.push_back( 0.0 ); // Z coordinate

                // 42 (weights) are optional
                if( (nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf))) == 42 )
                {
                    adfWeights.push_back( CPLAtof(szLineBuf) );
                    nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
                }
            }

            // Skip past the number of fit points
            if( nCode != 97 )
                break;

            // Eat the rest of this section, if present, until the next
            // boundary segment (72) or the conclusion of the boundary data (97)
            nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
            while( nCode > 0 && nCode != 72 && nCode != 97 )
                nCode = poDS->ReadValue(szLineBuf, sizeof(szLineBuf));
            if( nCode > 0 )
                poDS->UnreadValue();

            OGRLineString *poLS = InsertSplineWithChecks( nDegree,
                adfControlPoints, nControlPoints, adfKnots, nKnots,
                adfWeights );

            if( !poLS )
            {
                DXF_LAYER_READER_ERROR();
                return OGRERR_FAILURE;
            }

            poGC->addGeometryDirectly( poLS );
        }

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

    if( nCode < 0 )
    {
        DXF_LAYER_READER_ERROR();
        return OGRERR_FAILURE;
    }

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

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

    return OGRERR_NONE;
}
Esempio n. 6
0
OGRErr OGRMySQLTableLayer::ICreateFeature( OGRFeature *poFeature )

{
    int bNeedComma = FALSE;
    CPLString osCommand;

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */
    osCommand.Printf( "INSERT INTO `%s` (", poFeatureDefn->GetName() );

    if( poFeature->GetGeometryRef() != nullptr )
    {
        osCommand = osCommand + "`" + pszGeomColumn + "` ";
        bNeedComma = TRUE;
    }

    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != nullptr )
    {
        if( bNeedComma )
            osCommand += ", ";

        osCommand = osCommand + "`" + pszFIDColumn + "` ";
        bNeedComma = TRUE;
    }

    for( int i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( !bNeedComma )
            bNeedComma = TRUE;
        else
            osCommand += ", ";

        osCommand = osCommand + "`"
             + poFeatureDefn->GetFieldDefn(i)->GetNameRef() + "`";
    }

    osCommand += ") VALUES (";

    // Set the geometry
    bNeedComma = poFeature->GetGeometryRef() != nullptr;
    if( poFeature->GetGeometryRef() != nullptr)
    {
        char    *pszWKT = nullptr;

        if( poFeature->GetGeometryRef() != nullptr )
        {
            OGRGeometry *poGeom = (OGRGeometry *) poFeature->GetGeometryRef();

            poGeom->closeRings();
            poGeom->flattenTo2D();
            poGeom->exportToWkt( &pszWKT );
        }

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

            osCommand +=
                CPLString().Printf(
                    "%s('%s',%d%s) ",
                    poDS->GetMajorVersion() >= 8 ? "ST_GeomFromText" : "GeometryFromText",
                    pszWKT, nSRSId, pszAxisOrder );

            CPLFree( pszWKT );
        }
        else
            osCommand += "''";
    }

    // Set the FID
    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != nullptr )
    {
        GIntBig nFID = poFeature->GetFID();
        if( !CPL_INT64_FITS_ON_INT32(nFID) &&
            GetMetadataItem(OLMD_FID64) == nullptr )
        {
            CPLString osCommand2;
            osCommand2.Printf(
                     "ALTER TABLE `%s` MODIFY COLUMN `%s` BIGINT UNIQUE NOT NULL AUTO_INCREMENT",
                     poFeatureDefn->GetName(), pszFIDColumn );

            if( mysql_query(poDS->GetConn(), osCommand2 ) )
            {
                poDS->ReportError( osCommand2 );
                return OGRERR_FAILURE;
            }

            // make sure to attempt to free results of successful queries
            MYSQL_RES *hResult = mysql_store_result( poDS->GetConn() );
            if( hResult != nullptr )
                mysql_free_result( hResult );
            hResult = nullptr;

            SetMetadataItem(OLMD_FID64, "YES");
        }

        if( bNeedComma )
            osCommand += ", ";
        osCommand += CPLString().Printf( CPL_FRMT_GIB, nFID );
        bNeedComma = TRUE;
    }

    for( int i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( bNeedComma )
            osCommand += ", ";
        else
            bNeedComma = TRUE;

        const char *pszStrValue = poFeature->GetFieldAsString(i);

        if( poFeature->IsFieldNull(i) )
        {
            osCommand += "NULL";
        }
        else if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger64
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTBinary )
        {
            // We need to quote and escape string fields.
            osCommand += "'";

            for( int iChar = 0; pszStrValue[iChar] != '\0'; iChar++ )
            {
                if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList
                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger64List
                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList
                    && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0
                    && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() )
                {
                    CPLDebug( "MYSQL",
                              "Truncated %s field value, it was too long.",
                              poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
                    break;
                }

                if( pszStrValue[iChar] == '\\'
                    || pszStrValue[iChar] == '\'' )
                {
                    osCommand += '\\';
                    osCommand += pszStrValue[iChar];
                }
                else
                    osCommand += pszStrValue[iChar];
            }

            osCommand += "'";
        }
        else if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTBinary )
        {
            int binaryCount = 0;
            GByte* binaryData = poFeature->GetFieldAsBinary(i, &binaryCount);
            char* pszHexValue = CPLBinaryToHex( binaryCount, binaryData );

            osCommand += "x'";
            osCommand += pszHexValue;
            osCommand += "'";

            CPLFree( pszHexValue );
        }
        else
        {
            osCommand += pszStrValue;
        }
    }

    osCommand += ")";

    //CPLDebug("MYSQL", "%s", osCommand.c_str());
    int nQueryResult = mysql_query(poDS->GetConn(), osCommand.c_str() );
    const my_ulonglong nFID = mysql_insert_id( poDS->GetConn() );

    if( nQueryResult ){
        int eErrorCode = mysql_errno(poDS->GetConn());
        if (eErrorCode == 1153) {//ER_NET_PACKET_TOO_LARGE)
            poDS->ReportError("CreateFeature failed because the MySQL server " \
                              "cannot read the entire query statement.  Increase " \
                              "the size of statements your server will allow by " \
                              "altering the 'max_allowed_packet' parameter in "\
                              "your MySQL server configuration.");
        }
        else
        {
        CPLDebug("MYSQL","Error number %d", eErrorCode);
            poDS->ReportError(  osCommand.c_str() );
        }

        // make sure to attempt to free results
        MYSQL_RES *hResult = mysql_store_result( poDS->GetConn() );
        if( hResult != nullptr )
            mysql_free_result( hResult );
        hResult = nullptr;

        return OGRERR_FAILURE;
    }

    if( nFID > 0 ) {
        poFeature->SetFID( nFID );
    }

    // make sure to attempt to free results of successful queries
    MYSQL_RES *hResult = mysql_store_result( poDS->GetConn() );
    if( hResult != nullptr )
        mysql_free_result( hResult );
    hResult = nullptr;

    return OGRERR_NONE;
}