SocketError SocketImpl::GetLastError(SocketHandle handle, SocketError* error) { int code = GetLastErrorCode(handle, error); if (code < 0) return SocketError_Internal; return TranslateWSAErrorToSocketError(code); }
std::string System::GetLastErrorMessage() { #ifdef _WIN32 DWORD code = GetLastErrorCode(); LPTSTR msg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, // no source buffer needed code, // error code for this message 0, // default language ID (LPTSTR)&msg, // allocated by fcn 0, // minimum size of buffer (va_list *)NULL); // no inserts return msg; #else return strerror(GetLastErrorCode()); #endif }
SocketState SocketImpl::Connect(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error) { SocketState state = Connect(handle, address, error); if (state == SocketState_Connecting) { // http://developerweb.net/viewtopic.php?id=3196 fd_set localSet; FD_ZERO(&localSet); FD_SET(handle, &localSet); timeval tv; tv.tv_sec = static_cast<long>(msTimeout / 1000ULL); tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL); int ret = select(0, nullptr, &localSet, &localSet, (msTimeout > 0) ? &tv : nullptr); if (ret > 0) { int code = GetLastErrorCode(handle, error); if (code < 0) //< GetLastErrorCode() failed return SocketState_NotConnected; if (code) { if (error) *error = TranslateWSAErrorToSocketError(code); return SocketState_NotConnected; } } else if (ret == 0) { if (error) *error = SocketError_TimedOut; return SocketState_NotConnected; } else { if (error) *error = TranslateWSAErrorToSocketError(WSAGetLastError()); return SocketState_NotConnected; } if (error) *error = SocketError_NoError; state = SocketState_Connected; } return state; }
HWND IRA_Dialog::Create() { bIsModal = false; auto result{ CreateDialogParam(g_hThisDLLInst, MAKEINTRESOURCE(nResourceId), g_RAMainWnd, MsgQueue, reinterpret_cast<LPARAM>(this)) }; if (!result) throw std::system_error{ GetLastErrorCode(), GetLastErrorMsg() }; return result; }
BasicFile::BasicFile(ufL_t bytes, const std::string& path, bool retry){ do{ if (create(path, bytes)) return; if (!retry){ FileException(GetLastErrorCode(), nullptr, path, "Unable to create file.").fire(); } Console::Warning("Unable to create file.", true); Console::println(path); PrintLastError(); Console::println(); Console::println("Re-attempting..."); Console::Pause('w'); }while (true); }
void Acceptor::handleRead() { loop_->assertInLoopThread(); int errorCode = 0; while(true) { InetAddress peerAddr; sockaddr addr = {0}; socket_t newFd = SocketOps::accept(listenFd_, &addr); if(newFd < 0) { errorCode = GetLastErrorCode(); break; } SocketOps::setSocketNoneBlocking(newFd); peerAddr.setSockAddr(addr); if(newConnCallBack_) { newConnCallBack_(newFd, peerAddr); } else { SocketOps::closeSocket(newFd); } } if(!ERR_ACCEPT_RETRIABLE(errorCode)) { LOG_PRINT(LogType_Error, "accept socket failed:%s %s:%d", GetErrorText(errorCode).c_str(), __FUNCTION__, __LINE__); } }
dbiplus::Dataset* BXDatabase::Exec(const char *query, ...) { if (!IsOpen()) { return NULL; } std::string strQuery = query; BXUtils::StringReplace(strQuery, "%s", "%q"); BXUtils::StringReplace(strQuery, "%I64", "%ll"); va_list args; va_start(args, query); char *szSql = sqlite3_vmprintf(strQuery.c_str(), args); va_end(args); std::string strResult; if (szSql) { strResult = szSql; sqlite3_free(szSql); } Dataset* pDataset = m_pDatabase->CreateDataset(); if (pDataset == NULL) { LOG(LOG_LEVEL_ERROR, "Could not create dataset, query %s not executed", strResult.c_str()); return NULL; } int iRetries = MEDIA_DATABSE_LOCK_RETRIES; while (iRetries > 0) { try { pDataset->exec(strResult.c_str()); return pDataset; } catch(dbiplus::DbErrors& e) { if (GetLastErrorCode() == SQLITE_LOCKED || GetLastErrorCode() == SQLITE_BUSY || GetLastErrorCode() == SQLITE_CANTOPEN) { LOG(LOG_LEVEL_DEBUG, "Database was locked, retry. Error = %s, msg= %s", GetLastErrorMessage(), e.getMsg()); SDL_Delay(BXUtils::GetRandInt(10) + 10); iRetries--; // log the last attempt as error if (iRetries == 0) LOG(LOG_LEVEL_ERROR, "Exception caught, could not execute query. Error = %s, msg= %s", GetLastErrorMessage(), e.getMsg()); continue; } else { // Some other error LOG(LOG_LEVEL_ERROR, "Exception caught, could not execute query. Error = %s, msg= %s", GetLastErrorMessage(), e.getMsg()); iRetries = 0; } } } delete pDataset; return NULL; }
int BXDatabase::Insert(const char* query, ...) { if (!IsOpen()) { return MEDIA_DATABASE_ERROR; } //LOG(LOG_LEVEL_DEBUG, "Inserting query for database %d in thread %d", m_pDatabase, pthread_self()); std::string strQuery = query; BXUtils::StringReplace(strQuery, "%s", "%q"); BXUtils::StringReplace(strQuery, "%I64", "%ll"); va_list args; va_start(args, query); char *szSql = sqlite3_vmprintf(strQuery.c_str(), args); va_end(args); std::string strResult; if (szSql) { strResult = szSql; sqlite3_free(szSql); } //LOG(LOG_LEVEL_DEBUG, "Inserting query: %s for database %d in thread %d", strResult.c_str(), m_pDatabase, pthread_self()); Dataset* pDataset = m_pDatabase->CreateDataset(); if (pDataset == NULL) { LOG(LOG_LEVEL_ERROR, "Could not create dataset, query %s not executed", strResult.c_str()); return MEDIA_DATABASE_ERROR; } int iID = MEDIA_DATABASE_ERROR; int iRetries = MEDIA_DATABSE_LOCK_RETRIES; while (iRetries > 0) { try { // In case of the error, exception will be thrown pDataset->exec(strResult.c_str()); iID = (int)sqlite3_last_insert_rowid(m_pDatabase->getHandle()); iRetries = 0; } catch(dbiplus::DbErrors& e) { if (GetLastErrorCode() == SQLITE_LOCKED || GetLastErrorCode() == SQLITE_BUSY || GetLastErrorCode() == SQLITE_CANTOPEN) { LOG(LOG_LEVEL_DEBUG, "Database was locked, retry. Error = %s, msg= %s", GetLastErrorMessage(), e.getMsg()); // Sleep random amount of time SDL_Delay(BXUtils::GetRandInt(10) + 10); iRetries--; // log the last attempt as error if (iRetries == 0) LOG(LOG_LEVEL_ERROR, "Exception caught, could not execute query. Error = %s, msg= %s", GetLastErrorMessage(), e.getMsg()); continue; } else { // Some other error LOG(LOG_LEVEL_ERROR, "Exception caught, could not execute query. Error = %s, msg= %s", GetLastErrorMessage(), e.getMsg()); iRetries = 0; } } } delete pDataset; return iID; }
ESocketErrors FSocketSubsystemBSD::TranslateErrorCode(int32 Code) { // @todo sockets: Windows for some reason doesn't seem to have all of the standard error messages, // but it overrides this function anyway - however, this #if !PLATFORM_HAS_BSD_SOCKET_FEATURE_WINSOCKETS // handle the generic -1 error if (Code == SOCKET_ERROR) { return GetLastErrorCode(); } switch (Code) { case 0: return SE_NO_ERROR; case EINTR: return SE_EINTR; case EBADF: return SE_EBADF; case EACCES: return SE_EACCES; case EFAULT: return SE_EFAULT; case EINVAL: return SE_EINVAL; case EMFILE: return SE_EMFILE; case EWOULDBLOCK: return SE_EWOULDBLOCK; case EINPROGRESS: return SE_EINPROGRESS; case EALREADY: return SE_EALREADY; case ENOTSOCK: return SE_ENOTSOCK; case EDESTADDRREQ: return SE_EDESTADDRREQ; case EMSGSIZE: return SE_EMSGSIZE; case EPROTOTYPE: return SE_EPROTOTYPE; case ENOPROTOOPT: return SE_ENOPROTOOPT; case EPROTONOSUPPORT: return SE_EPROTONOSUPPORT; case ESOCKTNOSUPPORT: return SE_ESOCKTNOSUPPORT; case EOPNOTSUPP: return SE_EOPNOTSUPP; case EPFNOSUPPORT: return SE_EPFNOSUPPORT; case EAFNOSUPPORT: return SE_EAFNOSUPPORT; case EADDRINUSE: return SE_EADDRINUSE; case EADDRNOTAVAIL: return SE_EADDRNOTAVAIL; case ENETDOWN: return SE_ENETDOWN; case ENETUNREACH: return SE_ENETUNREACH; case ENETRESET: return SE_ENETRESET; case ECONNABORTED: return SE_ECONNABORTED; case ECONNRESET: return SE_ECONNRESET; case ENOBUFS: return SE_ENOBUFS; case EISCONN: return SE_EISCONN; case ENOTCONN: return SE_ENOTCONN; case ESHUTDOWN: return SE_ESHUTDOWN; case ETOOMANYREFS: return SE_ETOOMANYREFS; case ETIMEDOUT: return SE_ETIMEDOUT; case ECONNREFUSED: return SE_ECONNREFUSED; case ELOOP: return SE_ELOOP; case ENAMETOOLONG: return SE_ENAMETOOLONG; case EHOSTDOWN: return SE_EHOSTDOWN; case EHOSTUNREACH: return SE_EHOSTUNREACH; case ENOTEMPTY: return SE_ENOTEMPTY; case EUSERS: return SE_EUSERS; case EDQUOT: return SE_EDQUOT; case ESTALE: return SE_ESTALE; case EREMOTE: return SE_EREMOTE; case ENODEV: return SE_NODEV; #if !PLATFORM_HAS_NO_EPROCLIM case EPROCLIM: return SE_EPROCLIM; #endif // case EDISCON: return SE_EDISCON; // case SYSNOTREADY: return SE_SYSNOTREADY; // case VERNOTSUPPORTED: return SE_VERNOTSUPPORTED; // case NOTINITIALISED: return SE_NOTINITIALISED; #if PLATFORM_HAS_BSD_SOCKET_FEATURE_GETHOSTNAME case HOST_NOT_FOUND: return SE_HOST_NOT_FOUND; case TRY_AGAIN: return SE_TRY_AGAIN; case NO_RECOVERY: return SE_NO_RECOVERY; #endif // case NO_DATA: return SE_NO_DATA; // case : return SE_UDP_ERR_PORT_UNREACH; //@TODO Find it's replacement } #endif UE_LOG(LogSockets, Warning, TEXT("Unhandled socket error! Error Code: %d"), Code); check(0); return SE_NO_ERROR; }
void ShowError() { char err[2048]; sprintf(err, "Code: %d, Msg: %s", GetLastErrorCode(), GetLastErrorString()); printf(err); }
OGRFeature *OGRCADLayer::GetFeature( GIntBig nFID ) { if( poCADLayer.getGeometryCount() <= static_cast<size_t>(nFID) || nFID < 0 ) { return nullptr; } OGRFeature *poFeature = nullptr; CADGeometry *poCADGeometry = poCADLayer.getGeometry( static_cast<size_t>(nFID) ); if( nullptr == poCADGeometry || GetLastErrorCode() != CADErrorCodes::SUCCESS ) { CPLError( CE_Failure, CPLE_NotSupported, "Failed to get geometry with ID = " CPL_FRMT_GIB " from layer \"%s\". Libopencad errorcode: %d", nFID, poCADLayer.getName().c_str(), GetLastErrorCode() ); return nullptr; } poFeature = new OGRFeature( poFeatureDefn ); poFeature->SetFID( nFID ); poFeature->SetField( FIELD_NAME_THICKNESS, poCADGeometry->getThickness() ); if( !poCADGeometry->getEED().empty() ) { std::vector<std::string> asGeometryEED = poCADGeometry->getEED(); std::string sEEDAsOneString = ""; for ( std::vector<std::string>::const_iterator iter = asGeometryEED.cbegin(); iter != asGeometryEED.cend(); ++iter ) { sEEDAsOneString += *iter; sEEDAsOneString += ' '; } poFeature->SetField( FIELD_NAME_EXT_DATA, sEEDAsOneString.c_str() ); } RGBColor stRGB = poCADGeometry->getColor(); CPLString sHexColor; sHexColor.Printf("#%02X%02X%02X%02X", stRGB.R, stRGB.G, stRGB.B, 255); poFeature->SetField( FIELD_NAME_COLOR, sHexColor ); CPLString sStyle; sStyle.Printf("PEN(c:%s,w:5px)", sHexColor.c_str()); poFeature->SetStyleString( sStyle ); std::vector< CADAttrib > oBlockAttrs = poCADGeometry->getBlockAttributes(); for( const CADAttrib& oAttrib : oBlockAttrs ) { CPLString osTag = oAttrib.getTag(); auto featureAttrIt = asFeaturesAttributes.find( osTag ); if( featureAttrIt != asFeaturesAttributes.end()) { poFeature->SetField(*featureAttrIt, oAttrib.getTextValue().c_str()); } } switch( poCADGeometry->getType() ) { case CADGeometry::POINT: { CADPoint3D * const poCADPoint = ( CADPoint3D* ) poCADGeometry; CADVector stPositionVector = poCADPoint->getPosition(); poFeature->SetGeometryDirectly( new OGRPoint( stPositionVector.getX(), stPositionVector.getY(), stPositionVector.getZ() ) ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADPoint" ); break; } case CADGeometry::LINE: { CADLine * const poCADLine = ( CADLine* ) poCADGeometry; OGRLineString *poLS = new OGRLineString(); poLS->addPoint( poCADLine->getStart().getPosition().getX(), poCADLine->getStart().getPosition().getY(), poCADLine->getStart().getPosition().getZ() ); poLS->addPoint( poCADLine->getEnd().getPosition().getX(), poCADLine->getEnd().getPosition().getY(), poCADLine->getEnd().getPosition().getZ() ); poFeature->SetGeometryDirectly( poLS ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLine" ); break; } case CADGeometry::SOLID: { CADSolid * const poCADSolid = ( CADSolid* ) poCADGeometry; OGRPolygon * poPoly = new OGRPolygon(); OGRLinearRing * poLR = new OGRLinearRing(); std::vector<CADVector> astSolidCorners = poCADSolid->getCorners(); for( size_t i = 0; i < astSolidCorners.size(); ++i ) { poLR->addPoint( astSolidCorners[i].getX(), astSolidCorners[i].getY(), astSolidCorners[i].getZ()); } poPoly->addRingDirectly( poLR ); poPoly->closeRings(); poFeature->SetGeometryDirectly( poPoly ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADSolid" ); break; } case CADGeometry::CIRCLE: { CADCircle * poCADCircle = static_cast<CADCircle*>(poCADGeometry); OGRCircularString * poCircle = new OGRCircularString(); CADVector stCircleCenter = poCADCircle->getPosition(); OGRPoint oCirclePoint1; oCirclePoint1.setX( stCircleCenter.getX() - poCADCircle->getRadius() ); oCirclePoint1.setY( stCircleCenter.getY() ); oCirclePoint1.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint1 ); OGRPoint oCirclePoint2; oCirclePoint2.setX( stCircleCenter.getX() ); oCirclePoint2.setY( stCircleCenter.getY() + poCADCircle->getRadius() ); oCirclePoint2.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint2 ); OGRPoint oCirclePoint3; oCirclePoint3.setX( stCircleCenter.getX() + poCADCircle->getRadius() ); oCirclePoint3.setY( stCircleCenter.getY() ); oCirclePoint3.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint3 ); OGRPoint oCirclePoint4; oCirclePoint4.setX( stCircleCenter.getX() ); oCirclePoint4.setY( stCircleCenter.getY() - poCADCircle->getRadius() ); oCirclePoint4.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint4 ); // Close the circle poCircle->addPoint( &oCirclePoint1 ); /*NOTE: The alternative way: OGRGeometry *poCircle = OGRGeometryFactory::approximateArcAngles( poCADCircle->getPosition().getX(), poCADCircle->getPosition().getY(), poCADCircle->getPosition().getZ(), poCADCircle->getRadius(), poCADCircle->getRadius(), 0.0, 0.0, 360.0, 0.0 ); */ poFeature->SetGeometryDirectly( poCircle ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADCircle" ); break; } case CADGeometry::ARC: { CADArc * poCADArc = static_cast<CADArc*>(poCADGeometry); OGRCircularString * poCircle = new OGRCircularString(); // Need at least 3 points in arc double dfStartAngle = poCADArc->getStartingAngle() * DEG2RAD; double dfEndAngle = poCADArc->getEndingAngle() * DEG2RAD; double dfMidAngle = (dfEndAngle + dfStartAngle) / 2; CADVector stCircleCenter = poCADArc->getPosition(); OGRPoint oCirclePoint; oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() * cos( dfStartAngle ) ); oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() * sin( dfStartAngle ) ); oCirclePoint.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint ); oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() * cos( dfMidAngle ) ); oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() * sin( dfMidAngle ) ); oCirclePoint.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint ); oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() * cos( dfEndAngle ) ); oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() * sin( dfEndAngle ) ); oCirclePoint.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint ); /*NOTE: alternative way: OGRGeometry * poArc = OGRGeometryFactory::approximateArcAngles( poCADArc->getPosition().getX(), poCADArc->getPosition().getY(), poCADArc->getPosition().getZ(), poCADArc->getRadius(), poCADArc->getRadius(), 0.0, dfStartAngle, dfStartAngle > dfEndAngle ? ( dfEndAngle + 360.0f ) : dfEndAngle, 0.0 ); */ poFeature->SetGeometryDirectly( poCircle ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADArc" ); break; } case CADGeometry::FACE3D: { CADFace3D * const poCADFace = ( CADFace3D* ) poCADGeometry; OGRPolygon * poPoly = new OGRPolygon(); OGRLinearRing * poLR = new OGRLinearRing(); for ( size_t i = 0; i < 3; ++i ) { poLR->addPoint( poCADFace->getCorner( i ).getX(), poCADFace->getCorner( i ).getY(), poCADFace->getCorner( i ).getZ() ); } if ( !(poCADFace->getCorner( 2 ) == poCADFace->getCorner( 3 )) ) { poLR->addPoint( poCADFace->getCorner( 3 ).getX(), poCADFace->getCorner( 3 ).getY(), poCADFace->getCorner( 3 ).getZ() ); } poPoly->addRingDirectly( poLR ); poPoly->closeRings(); poFeature->SetGeometryDirectly( poPoly ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADFace3D" ); break; } case CADGeometry::LWPOLYLINE: { CADLWPolyline * const poCADLWPolyline = ( CADLWPolyline* ) poCADGeometry; poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLWPolyline" ); /* * Excessive check, like in DXF driver. * I tried to make a single-point polyline, but couldn't make it. * Probably this check should be removed. */ if( poCADLWPolyline->getVertexCount() == 1 ) { poFeature->SetGeometryDirectly( new OGRPoint( poCADLWPolyline->getVertex(0).getX(), poCADLWPolyline->getVertex(0).getY(), poCADLWPolyline->getVertex(0).getZ() ) ); break; } /* * If polyline has no arcs, handle it in easy way. */ OGRLineString * poLS = new OGRLineString(); if( poCADLWPolyline->getBulges().empty() ) { for( size_t i = 0; i < poCADLWPolyline->getVertexCount(); ++i ) { CADVector stVertex = poCADLWPolyline->getVertex( i ); poLS->addPoint( stVertex.getX(), stVertex.getY(), stVertex.getZ() ); } poFeature->SetGeometryDirectly( poLS ); break; } /* * Last case - if polyline has mixed arcs and lines. */ bool bLineStringStarted = false; std::vector< double > adfBulges = poCADLWPolyline->getBulges(); const size_t nCount = std::min(adfBulges.size(), poCADLWPolyline->getVertexCount()); for( size_t iCurrentVertex = 0; iCurrentVertex + 1 < nCount; iCurrentVertex++ ) { CADVector stCurrentVertex = poCADLWPolyline->getVertex( iCurrentVertex ); CADVector stNextVertex = poCADLWPolyline->getVertex( iCurrentVertex + 1 ); double dfLength = sqrt( pow( stNextVertex.getX() - stCurrentVertex.getX(), 2 ) + pow( stNextVertex.getY() - stCurrentVertex.getY(), 2 ) ); /* * Handling straight polyline segment. */ if( ( dfLength == 0 ) || ( adfBulges[iCurrentVertex] == 0 ) ) { if( !bLineStringStarted ) { poLS->addPoint( stCurrentVertex.getX(), stCurrentVertex.getY(), stCurrentVertex.getZ() ); bLineStringStarted = true; } poLS->addPoint( stNextVertex.getX(), stNextVertex.getY(), stNextVertex.getZ() ); } else { double dfSegmentBulge = adfBulges[iCurrentVertex]; double dfH = ( dfSegmentBulge * dfLength ) / 2; if( dfH == 0.0 ) dfH = 1.0; // just to avoid a division by zero double dfRadius = ( dfH / 2 ) + ( dfLength * dfLength / ( 8 * dfH ) ); double dfOgrArcRotation = 0, dfOgrArcRadius = fabs( dfRadius ); /* * Set arc's direction and keep bulge positive. */ bool bClockwise = ( dfSegmentBulge < 0 ); if( bClockwise ) dfSegmentBulge *= -1; /* * Get arc's center point. */ double dfSaggita = fabs( dfSegmentBulge * ( dfLength / 2.0 ) ); double dfApo = bClockwise ? -( dfOgrArcRadius - dfSaggita ) : -( dfSaggita - dfOgrArcRadius ); CADVector stVertex; stVertex.setX( stCurrentVertex.getX() - stNextVertex.getX() ); stVertex.setY( stCurrentVertex.getY() - stNextVertex.getY() ); stVertex.setZ( stCurrentVertex.getZ() ); CADVector stMidPoint; stMidPoint.setX( stNextVertex.getX() + 0.5 * stVertex.getX() ); stMidPoint.setY( stNextVertex.getY() + 0.5 * stVertex.getY() ); stMidPoint.setZ( stVertex.getZ() ); CADVector stPperp; stPperp.setX( stVertex.getY() ); stPperp.setY( -stVertex.getX() ); double dfStPperpLength = sqrt( stPperp.getX() * stPperp.getX() + stPperp.getY() * stPperp.getY() ); // TODO: Check that length isnot 0 stPperp.setX( stPperp.getX() / dfStPperpLength ); stPperp.setY( stPperp.getY() / dfStPperpLength ); CADVector stOgrArcCenter; stOgrArcCenter.setX( stMidPoint.getX() + ( stPperp.getX() * dfApo ) ); stOgrArcCenter.setY( stMidPoint.getY() + ( stPperp.getY() * dfApo ) ); /* * Get the line's general vertical direction ( -1 = down, +1 = up ). */ double dfLineDir = stNextVertex.getY() > stCurrentVertex.getY() ? 1.0f : -1.0f; /* * Get arc's starting angle. */ double dfA = atan2( ( stOgrArcCenter.getY() - stCurrentVertex.getY() ), ( stOgrArcCenter.getX() - stCurrentVertex.getX() ) ) * DEG2RAD; if( bClockwise && ( dfLineDir == 1.0 ) ) dfA += ( dfLineDir * 180.0 ); double dfOgrArcStartAngle = dfA > 0.0 ? -( dfA - 180.0 ) : -( dfA + 180.0 ); /* * Get arc's ending angle. */ dfA = atan2( ( stOgrArcCenter.getY() - stNextVertex.getY() ), ( stOgrArcCenter.getX() - stNextVertex.getX() ) ) * DEG2RAD; if( bClockwise && ( dfLineDir == 1.0 ) ) dfA += ( dfLineDir * 180.0 ); double dfOgrArcEndAngle = dfA > 0.0 ? -( dfA - 180.0 ) : -( dfA + 180.0 ); if( !bClockwise && ( dfOgrArcStartAngle < dfOgrArcEndAngle) ) dfOgrArcEndAngle = -180.0 + ( dfLineDir * dfA ); if( bClockwise && ( dfOgrArcStartAngle > dfOgrArcEndAngle ) ) dfOgrArcEndAngle += 360.0; /* * Flip arc's rotation if necessary. */ if( bClockwise && ( dfLineDir == 1.0 ) ) dfOgrArcRotation = dfLineDir * 180.0; /* * Tessellate the arc segment and append to the linestring. */ OGRLineString * poArcpoLS = ( OGRLineString * ) OGRGeometryFactory::approximateArcAngles( stOgrArcCenter.getX(), stOgrArcCenter.getY(), stOgrArcCenter.getZ(), dfOgrArcRadius, dfOgrArcRadius, dfOgrArcRotation, dfOgrArcStartAngle,dfOgrArcEndAngle, 0.0 ); poLS->addSubLineString( poArcpoLS ); delete( poArcpoLS ); } } if( poCADLWPolyline->isClosed() ) { poLS->addPoint( poCADLWPolyline->getVertex(0).getX(), poCADLWPolyline->getVertex(0).getY(), poCADLWPolyline->getVertex(0).getZ() ); } poFeature->SetGeometryDirectly( poLS ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLWPolyline" ); break; } // TODO: Unsupported smooth lines case CADGeometry::POLYLINE3D: { CADPolyline3D * const poCADPolyline3D = ( CADPolyline3D* ) poCADGeometry; OGRLineString * poLS = new OGRLineString(); for( size_t i = 0; i < poCADPolyline3D->getVertexCount(); ++i ) { CADVector stVertex = poCADPolyline3D->getVertex( i ); poLS->addPoint( stVertex.getX(), stVertex.getY(), stVertex.getZ() ); } poFeature->SetGeometryDirectly( poLS ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADPolyline3D" ); break; } case CADGeometry::TEXT: { CADText * const poCADText = ( CADText * ) poCADGeometry; OGRPoint * poPoint = new OGRPoint( poCADText->getPosition().getX(), poCADText->getPosition().getY(), poCADText->getPosition().getZ() ); CPLString sTextValue = CADRecode( poCADText->getTextValue(), nDWGEncoding ); poFeature->SetField( FIELD_NAME_TEXT, sTextValue ); poFeature->SetGeometryDirectly( poPoint ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADText" ); sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(), sHexColor.c_str()); poFeature->SetStyleString( sStyle ); break; } case CADGeometry::MTEXT: { CADMText * const poCADMText = ( CADMText * ) poCADGeometry; OGRPoint * poPoint = new OGRPoint( poCADMText->getPosition().getX(), poCADMText->getPosition().getY(), poCADMText->getPosition().getZ() ); CPLString sTextValue = CADRecode( poCADMText->getTextValue(), nDWGEncoding ); poFeature->SetField( FIELD_NAME_TEXT, sTextValue ); poFeature->SetGeometryDirectly( poPoint ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADMText" ); sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(), sHexColor.c_str()); poFeature->SetStyleString( sStyle ); break; } case CADGeometry::SPLINE: { CADSpline * const poCADSpline = ( CADSpline * ) poCADGeometry; OGRLineString * poLS = new OGRLineString(); // TODO: Interpolate spline as points or curves for( size_t i = 0; i < poCADSpline->getControlPoints().size(); ++i ) { poLS->addPoint( poCADSpline->getControlPoints()[i].getX(), poCADSpline->getControlPoints()[i].getY(), poCADSpline->getControlPoints()[i].getZ() ); } poFeature->SetGeometryDirectly( poLS ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADSpline" ); break; } case CADGeometry::ELLIPSE: { CADEllipse * poCADEllipse = static_cast<CADEllipse*>(poCADGeometry); // FIXME: Start/end angles should be swapped to work exactly as DXF driver. // is it correct? double dfStartAngle = -1 * poCADEllipse->getEndingAngle() * DEG2RAD; double dfEndAngle = -1 * poCADEllipse->getStartingAngle() * DEG2RAD; double dfAxisRatio = poCADEllipse->getAxisRatio(); dfStartAngle = fmod(dfStartAngle, 360.0); dfEndAngle = fmod(dfEndAngle, 360.0); if( dfStartAngle > dfEndAngle ) dfEndAngle += 360.0; CADVector vectPosition = poCADEllipse->getPosition(); CADVector vectSMAxis = poCADEllipse->getSMAxis(); double dfPrimaryRadius, dfSecondaryRadius; double dfRotation; dfPrimaryRadius = sqrt( vectSMAxis.getX() * vectSMAxis.getX() + vectSMAxis.getY() * vectSMAxis.getY() + vectSMAxis.getZ() * vectSMAxis.getZ() ); dfSecondaryRadius = dfAxisRatio * dfPrimaryRadius; dfRotation = -1 * atan2( vectSMAxis.getY(), vectSMAxis.getX() ) * DEG2RAD; OGRGeometry *poEllipse = OGRGeometryFactory::approximateArcAngles( vectPosition.getX(), vectPosition.getY(), vectPosition.getZ(), dfPrimaryRadius, dfSecondaryRadius, dfRotation, dfStartAngle, dfEndAngle, 0.0 ); poFeature->SetGeometryDirectly( poEllipse ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADEllipse" ); break; } case CADGeometry::ATTDEF: { CADAttdef * const poCADAttdef = ( CADAttdef* ) poCADGeometry; OGRPoint * poPoint = new OGRPoint( poCADAttdef->getPosition().getX(), poCADAttdef->getPosition().getY(), poCADAttdef->getPosition().getZ() ); CPLString sTextValue = CADRecode( poCADAttdef->getTag(), nDWGEncoding ); poFeature->SetField( FIELD_NAME_TEXT, sTextValue ); poFeature->SetGeometryDirectly( poPoint ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADAttdef" ); sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(), sHexColor.c_str()); poFeature->SetStyleString( sStyle ); break; } default: { CPLError( CE_Warning, CPLE_NotSupported, "Unhandled feature. Skipping it." ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADUnknown" ); delete poCADGeometry; return poFeature; } } delete poCADGeometry; poFeature->GetGeometryRef()->assignSpatialReference( poSpatialRef ); return poFeature; }