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; }
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; }
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; }