#include #include #include #include #include "GeometryUtils.h" #include "GeoIndicatorGenerator.h" #include #define TRAINTERVAL 0 #define LONINTERVAL 0 #define RIGHTLEVEL 6 //第2*n行的偏移参数 #define GEOHEIGHT 4 //标准符号高度(mm) #define GEOWIDTH 30 //标准符号宽度(mm) #define SPLITLINE_ADD 0 //分割线额外长度 #define HORANGEL -90 QPen sPen(Qt::black, 0.5, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);// 分割线画笔 //完成符号库映射 GeoIndicatorGenerator::GeoIndicatorGenerator() { libMap.insert(std::pair("岩性符号库.lib", 0)); libMap.insert(std::pair("常用岩性符号.lib", 1)); libMap.insert(std::pair("岩性符号文件夹.lib", 2)); lineType.insert(std::pair("off", 1)); //无分割线 lineType.insert(std::pair("on", 2)); //有分割线 SymbolType.insert(std::pair("Stretch", 1)); //全拉伸 SymbolType.insert(std::pair("Original", 2)); //原样 SymbolType.insert(std::pair("OneStretch", 3)); //单个时拉伸 SymbolType.insert(std::pair("OnlyOne", 4)); //总是单行且不拉伸 reverseType.insert(std::pair("Forward", 1)); //右偏移 reverseType.insert(std::pair("Reverse", 2)); //反向 reverseType.insert(std::pair("InSitu", 3)); //原地绘制 fillType.insert(std::pair("True", 1)); //满 fillType.insert(std::pair("False", 2)); //不满 ifGeoHeight.insert(std::pair("True", 1)); //使用 ifGeoHeight.insert(std::pair("False", 2)); //不使用标准高度 if(!initGeoInf("岩性符号库.lib", libMap["岩性符号库.lib"])) return; //if(!initGeoInf("常用岩性符号.lib", libMap["常用岩性符号.lib"])) return; //if(!initGeoInf("岩性符号文件夹.lib", libMap["岩性符号文件夹.lib"])) return; tempLine += ""; tempLine += ""; } GeoIndicatorGenerator::~GeoIndicatorGenerator() { } //读取符号库信息 bool GeoIndicatorGenerator::initGeoInf(QString libName, int libNum) { QString SLibPath = ::GetConfPath() + GetOilFieldName()+libName; QFile file; file.setFileName(SLibPath); QXmlStreamAttributes attributes; if(!file.open(QIODevice::ReadOnly)) return false; QTextStream stream(&file); QString line; int lineNum = 0; while(!stream.atEnd()) { line = stream.readLine(); lines[libNum] += line; lines[libNum] += "\n"; QString name = "(temp[3], lineNum)); } lineNum++; } file.close(); libStr = lines[libMap[libName]].split(QRegExp("[\r\n]")); return true; } //判断是否是所需符号名称 bool GeoIndicatorGenerator::FindGeoName(QString GName, QXmlStreamReader* reader) { QXmlStreamAttributes attributes; if(reader->isStartElement() && reader->name() == "Symbol") { attributes = reader->attributes(); if(attributes.hasAttribute("Name") && attributes.value("Name").toString() == GName) return true; } return false; } //获取符号的 宽 & 高 & 分隔线类型 & 拉伸类型 & 反向 float * GeoIndicatorGenerator::getWH(QXmlStreamReader* reader) { QXmlStreamAttributes attributes; attributes = reader->attributes(); static float r[10]; if(attributes.hasAttribute("Width")) r[0] = attributes.value("Width").toString().toFloat(); if(attributes.hasAttribute("Height")) r[1] = attributes.value("Height").toString().toFloat(); r[2] = -1; if(attributes.hasAttribute("Line")) { QString tempType = attributes.value("Line").toString(); r[2] = lineType[tempType]; } r[3] = 2; if(attributes.hasAttribute("SymbolType")) { QString tempType = attributes.value("SymbolType").toString(); r[3] = SymbolType[tempType]; } r[4] = 2; if(attributes.hasAttribute("reverseType")) { QString tempType = attributes.value("reverseType").toString(); r[4] = reverseType[tempType]; } r[5] = 2; if(attributes.hasAttribute("Filled")) { QString tempType = attributes.value("Filled").toString(); r[5] = fillType[tempType]; } r[6] = 0; if(attributes.hasAttribute("GeoHeight")) { QString tempType = attributes.value("GeoHeight").toString(); r[6] = ifGeoHeight[tempType]; } return r; } //计算堆叠个数 void GeoIndicatorGenerator::calcLNum(float *wH, QRectF rect, int *wHNum, bool isOne) { int w = rect.width(); int h = rect.height(); wHNum[0] = 1;//横向只绘制一个 float hPix = (wH[1] + LONINTERVAL) * mm; if(hPix <= 0 || isOne) wHNum[1] = 1; else wHNum[1] = h / hPix + 1; } float GeoIndicatorGenerator::seleGeo(QString libName, QString geoName, QPainter *scene, QRectF rect, bool isOne, bool isStech, bool isHorizon, float cm, QColor bkColor) { m_Rect=rect; float rW = m_Rect.width(); mm = cm / 10; float *wH; float resultWH = 0; int wHNum[2] = {1, 1}; if(isHorizon) { float temp = m_Rect.width(); m_Rect.setWidth(m_Rect.height()); m_Rect.setHeight(temp); } bool tempHas = false; QString name = "", Qt::CaseSensitive)) { in = false; break; } } if(!find) return resultWH; } QXmlStreamReader reader(tempLine); reader.addData(tempLine); QString r = reader.readElementText(); bool error = reader.hasError(); scene->setRenderHints(QPainter::HighQualityAntialiasing | QPainter::Antialiasing | QPainter::TextAntialiasing, true);//抗锯齿以平滑 QRectF drawRect; QXmlStreamAttributes attributes; while(!reader.atEnd()) { reader.readNext(); if(!FindGeoName(geoName, &reader)) continue; //已发现所需符号-------------------------------------- wH = getWH(&reader); resultWH = wH[0] * mm * m_Rect.width() / (GEOWIDTH * mm); if(wH[1] <= 0) return resultWH; //纵向高度标准化 if(wH[6] != 2) h_strechRate = GEOHEIGHT / wH[1]; else h_strechRate = 1; wH[1] *= h_strechRate; //背景色填充 if(isHorizon) { scene->translate(m_Rect.x() - m_Rect.y(), m_Rect.y()+m_Rect.x()+m_Rect.width()); scene->rotate(HORANGEL); } if(!isStech) scene->fillRect(QRectF(m_Rect.x(), m_Rect.y(), m_Rect.width(), m_Rect.height()), bkColor); else scene->fillRect(QRectF(m_Rect.x(), m_Rect.y(), resultWH, m_Rect.height()), bkColor); scene->resetTransform(); //绘制边界限定 if(isStech) if(!isHorizon) drawRect = QRectF( m_Rect.x(), m_Rect.y(), wH[0] * mm * m_Rect.width() / (GEOWIDTH * mm), m_Rect.height()); else drawRect = QRectF( m_Rect.x(), m_Rect.y() + (m_Rect.width() - (wH[0] * mm * m_Rect.width() / (GEOWIDTH * mm))), m_Rect.height(), (wH[0] * mm * m_Rect.width() / (GEOWIDTH * mm))/*m_Rect.width()*/); else if(!isHorizon) drawRect = m_Rect; else drawRect = QRectF( m_Rect.x(), m_Rect.y(), m_Rect.height(), m_Rect.width()); scene->setClipRect(drawRect, Qt::IntersectClip); calcLNum(wH, m_Rect, wHNum, isOne); reader.readNext(); while(!(reader.isEndElement() && reader.name() == "Symbol")) { reader.readNext(); if(reader.name() == "DrawItem" && reader.isStartElement()) { attributes = reader.attributes(); QString typeName = attributes.value("Type").toString(); if(typeName == "Polyline") PolylinePainter(&reader, scene, wHNum, wH, isOne, isStech, isHorizon); else if(typeName == "Circle") CirclePainter(&reader, scene, wHNum, wH, isOne, isStech, isHorizon); else if(typeName == "Ellipse") CirclePainter(&reader, scene, wHNum, wH, isOne, isStech, isHorizon); else if(typeName == "Line") LinePainter(&reader, scene, wHNum, wH, isOne, isStech, isHorizon); else if(typeName == "Text") TextPainter(&reader, scene, wHNum, wH, isOne, isStech, isHorizon); else if(typeName == "Arc") ArcPainter(&reader, scene, wHNum, wH, isOne, isStech, isHorizon); else if(typeName == "Polygon") PolygonPainter(&reader, scene, wHNum, wH, isOne, isStech, isHorizon); else if(typeName == "Curve") PolylinePainter(&reader, scene, wHNum, wH, isOne, isStech, isHorizon); else int a = 0; } } break; } scene->setClipRect(drawRect, Qt::NoClip); return resultWH; } void GeoIndicatorGenerator::PolylinePainter(QXmlStreamReader *reader, QPainter *scene, int *wHNum, float *wH, bool isOne, bool isStech, bool isHorizon) { bool ifLine = (wH[2] == 1) ? false : true; //SymbolType="Original" 不画分割线 bool ifStretch = (wH[3] == 1) ? true : false; bool ifOneStrech = (wH[3] == 3) ? true : false; bool ifForward = (wH[4] == 1) ? true : false; //右移绘制 bool ifReverse = (wH[4] == 2) ? true : false; //反向绘制 bool ifOnlyOne = (wH[3] == 4) ? true : false; if(ifOnlyOne) isOne = true; if(ifOneStrech && isOne) ifStretch = true; if(ifStretch) { isOne = false; //因为拉伸,所以不需要居中 ifLine = false; //因为拉伸,所以不需要分割线 wHNum[1] = 1; //纵向拉伸,只需画一个符号 } float centerX = 0; float strechR; //横向边长比例 if(!isStech) strechR = m_Rect.width() / (wH[0] * mm); else strechR = m_Rect.width() / (GEOWIDTH * mm); float strechH = (ifStretch) ? (m_Rect.height() / (wH[1] / h_strechRate * mm)) : h_strechRate; //纵向拉伸比例 reader->readNext(); QPen PolylinePen(Qt::black, 0.2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); int pointNum = 0; QStringList pointList; //非画线段 int noPaintNum = 0; int noPaintList[20]; while(!(reader->isEndElement() && reader->name() == "DrawItem"))//end DrawItem { QXmlStreamAttributes attributes; if(reader->name() == "LinePen") { attributes = reader->attributes(); // if(attributes.hasAttribute("DashStyle") && attributes.value("DashStyle").toString() != "Solid") // QString aa = attributes.hasAttribute("DashStyle"); if(attributes.hasAttribute("Width")) PolylinePen.setWidthF(attributes.value("Width").toString().toFloat() * mm); if(attributes.hasAttribute("Color")) { QString color = attributes.value("Color").toString()/*.toInt()*/; if(color.contains("#")) PolylinePen.setColor(QColor(color)); else PolylinePen.setColor(QColor(color.toInt())); } } if(reader->name() == "noPaint") { noPaintList[noPaintNum++] = pointNum; } if(reader->name() == "Point") { pointList << reader->readElementText().split(','); centerX = centerX + pointList[pointNum * 2].toFloat(); pointNum++; } reader->readNext(); } centerX /= pointNum; //取中心 //计算横向拉伸后的位移增量 float strechV = centerX * strechR; //计算扩张后中心值 strechV -= centerX; //计算偏移量 strechV *= mm; //偏移量转像素量 //计算反向绘制位移增量 float c2c = wH[0] - centerX * 2; float strechV_R = (centerX + c2c) * strechR; strechV_R -= (centerX + c2c); strechV_R *= mm; if(pointNum < 2)return; float x1,y1,x2,y2, wAdd, hAdd; int itemNum = 0; int wN, hN; wN = wHNum[0]; hN = wHNum[1]; bool rightMove = false; //右侧偏移标志 bool reverseMove = false; //反向绘制标志 for(int w = 0; w < wN; w++) { for(int h = 0; h < hN; h++) { rightMove = (h % 2) != 0 ? true : false; rightMove = (ifForward == true) ? rightMove : false; reverseMove = (h % 2) != 0 ? true : false; reverseMove = (ifReverse == true) ? reverseMove : false; for(int i = 0; i < pointNum - 1; i++) { float strechHTemp = strechH; //备份 if(isHorizon) { scene->translate(m_Rect.x() - m_Rect.y(), m_Rect.y()+m_Rect.x()+m_Rect.width()); scene->rotate(HORANGEL); } wAdd = w * (wH[0] + TRAINTERVAL); hAdd = h * (wH[1] + LONINTERVAL); //若本次绘制有超出边界的可能,缩小纵向拉伸比 if((hAdd + wH[1] + LONINTERVAL) * mm > m_Rect.height()) strechH *= (m_Rect.height() / mm - hAdd) / wH[1]; //第2*n行的右偏移量 float moveW = (m_Rect.width() / mm < wH[0]) ? (m_Rect.width() / mm) : wH[0]; moveW = (isStech == false) ? m_Rect.width() / mm : moveW; x1 = pointList[i * 2].toFloat() + wAdd; x1 = rightMove == true ? (x1 + moveW / RIGHTLEVEL) : (x1); y1 = pointList[i * 2 + 1].toFloat() * strechH + hAdd; x1 *= mm; y1 *= mm; x2 = pointList[i * 2 + 2].toFloat() + wAdd; x2 = rightMove == true ? (x2 + moveW / RIGHTLEVEL) : (x2); y2 = pointList[i * 2 + 3].toFloat() * strechH + hAdd; x2 *= mm; y2 *= mm; //单符号,居中 if(isOne) scene->translate(0, (m_Rect.height() - wH[1]*mm) / 2); //分割线绘制 if(!isOne && ifLine) { scene->setPen(sPen); if(isStech) { scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } else { scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } } //移动到横向扩张或缩小后的位置 if(reverseMove) scene->translate(strechV_R + c2c * mm, 0); else scene->translate(strechV, 0); bool ifPaint = true; for(int ni = 0; ni < noPaintNum; ni++){ if(i + 1 == noPaintList[ni]) ifPaint = false; } if(ifPaint){ scene->setPen(PolylinePen); scene->drawLine(m_Rect.x() + x1, m_Rect.y() + y1, m_Rect.x() + x2, m_Rect.y() + y2); } scene->resetTransform(); itemNum++; strechH = strechHTemp; } } } } void GeoIndicatorGenerator::LinePainter(QXmlStreamReader *reader, QPainter *scene, int *wHNum, float *wH, bool isOne, bool isStech, bool isHorizon) { bool ifLine = (wH[2] == 1) ? false : true; //SymbolType="Original" 不画分割线 bool ifStretch = (wH[3] == 1) ? true : false; bool ifOneStrech = (wH[3] == 3) ? true : false; bool ifForward = (wH[4] == 1) ? true : false; bool ifReverse = (wH[4] == 2) ? true : false; //反向绘制 bool ifOnlyOne = (wH[3] == 4) ? true : false; if(ifOnlyOne) isOne = true; if(ifOneStrech && isOne) ifStretch = true; if(ifStretch) { isOne = false; //因为拉伸,所以不需要居中 ifLine = false; //因为拉伸,所以不需要分割线 wHNum[1] = 1; //纵向拉伸,只需画一个符号 } float centerX = 0; float strechR; //横向边长比例 if(!isStech) strechR = m_Rect.width() / (wH[0] * mm); else strechR = m_Rect.width() / (GEOWIDTH * mm); float strechH = (ifStretch == true) ? m_Rect.height() / (wH[1] / h_strechRate * mm) : h_strechRate; //纵向拉伸比例 reader->readNext(); QPen PolylinePen(Qt::black, 0.2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); QStringList pointList; while(!(reader->isEndElement() && reader->name() == "DrawItem"))//end DrawItem { QXmlStreamAttributes attributes; if(reader->name() == "LinePen") { attributes = reader->attributes(); // if(attributes.hasAttribute("DashStyle") && attributes.value("DashStyle").toString() != "Solid") // QString aa = attributes.hasAttribute("DashStyle"); if(attributes.hasAttribute("Width")) PolylinePen.setWidthF(attributes.value("Width").toString().toFloat() * mm); if(attributes.hasAttribute("Color")){ QString color = attributes.value("Color").toString()/*.toInt()*/; if(color.contains("#")) PolylinePen.setColor(QColor(color)); else PolylinePen.setColor(QColor(color.toInt())); } } if(reader->name() == "Point"){ pointList << reader->readElementText().split(','); } reader->readNext(); } centerX = pointList[0].toFloat() + pointList[2].toFloat(); centerX /= 2;//取中心 float strechV = centerX * strechR; //计算扩张后中心值 strechV -= centerX; //计算偏移量 strechV *= mm; //偏移量转像素量 //计算反向绘制位移增量 float c2c = wH[0] - centerX * 2; float strechV_R = (centerX + c2c) * strechR; strechV_R -= (centerX + c2c); strechV_R *= mm; float x1,y1,x2,y2, wAdd, hAdd; int itemNum = 0; int wN = wHNum[0]; int hN = wHNum[1]; bool rightMove = false; //右侧偏移标志 bool reverseMove = false; //反向绘制标志 for(int w = 0; w < wN; w++){ for(int h = 0; h < hN; h++){ if(isHorizon){ scene->translate(m_Rect.x() - m_Rect.y(), m_Rect.y()+m_Rect.x()+m_Rect.width()); scene->rotate(HORANGEL); } rightMove = (h % 2) != 0 ? true : false; rightMove = (ifForward == true) ? rightMove : false; reverseMove = (h % 2) != 0 ? true : false; reverseMove = (ifReverse == true) ? reverseMove : false; wAdd = w * (wH[0] + TRAINTERVAL); hAdd = h * (wH[1] + LONINTERVAL); //若本次绘制有超出边界的可能,缩小纵向拉伸比 if((hAdd + wH[1] + LONINTERVAL) * mm > m_Rect.height()){ strechH *= (m_Rect.height() / mm - hAdd) / wH[1]; } float moveW = (m_Rect.width()/mm < wH[0]) ? m_Rect.width()/mm : wH[0]; moveW = (isStech == false) ? m_Rect.width()/mm : moveW; x1 = pointList[0].toFloat()+wAdd; x1 = rightMove == true ? (x1 + moveW / RIGHTLEVEL) : (x1); y1 = pointList[1].toFloat() * strechH + hAdd; x1 *= mm; y1 *= mm; x2 = pointList[2].toFloat()+wAdd; x2 = rightMove == true ? (x2 + moveW / RIGHTLEVEL) : (x2); y2 = pointList[3].toFloat() * strechH + hAdd; x2 *= mm; y2 *= mm; if(isOne) scene->translate(0, (m_Rect.height() - wH[1]*mm) / 2); if(!isOne && ifLine){ scene->setPen(sPen); if(isStech){ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } else{ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } } //移动到横向扩张或缩小后的位置 if(reverseMove) scene->translate(strechV_R + c2c * mm, 0); else scene->translate(strechV, 0); scene->setPen(PolylinePen); scene->drawLine(m_Rect.x() + x1, m_Rect.y() + y1, m_Rect.x() + x2, m_Rect.y() + y2); //if(!isStech || isOne || m_Rect.width() < wH[0]*mm) scene->resetTransform(); itemNum++; } } } void GeoIndicatorGenerator::CirclePainter( QXmlStreamReader *reader, QPainter *scene, int *wHNum, float *wH, bool isOne, bool isStech, bool isHorizon) { /* 9,0.7 */ bool ifLine = (wH[2] == 1) ? false : true; //SymbolType="Original" 不画分割线 bool ifStretch = (wH[3] == 1) ? true : false; bool ifOneStrech = (wH[3] == 3) ? true : false; bool ifForward = (wH[4] == 1) ? true : false; bool ifReverse = (wH[4] == 2) ? true : false; //反向绘制 bool ifOnlyOne = (wH[3] == 4) ? true : false; if(ifOnlyOne) isOne = true; if(ifOneStrech && isOne) ifStretch = true; if(ifStretch) { isOne = false; //因为拉伸,所以不需要居中 ifLine = false; //因为拉伸,所以不需要分割线 wHNum[1] = 1; //纵向拉伸,只需画一个符号 } float centerX = 0; float strechR; //横向边长比例 if(!isStech) strechR = m_Rect.width() / (wH[0] * mm); else strechR = m_Rect.width() / (GEOWIDTH * mm); float strechH = (ifStretch == true) ? m_Rect.height() / (wH[1] / h_strechRate * mm) : h_strechRate; //纵向拉伸比例 bool ifFilled = false; float radius = 0; float Xradius = -1; float Yradius = -1; float rotatedAngle = 0; QXmlStreamAttributes attributes; attributes = reader->attributes(); if(attributes.hasAttribute("Filled") && attributes.value("Filled").toString() == "True") ifFilled = true; if(attributes.hasAttribute("Radius")) radius = attributes.value("Radius").toString().toFloat(); if(attributes.hasAttribute("XRadius")) Xradius = attributes.value("XRadius").toString().toFloat(); if(attributes.hasAttribute("YRadius")) Yradius = attributes.value("YRadius").toString().toFloat(); if(attributes.hasAttribute("RotatedAngle")) rotatedAngle = attributes.value("RotatedAngle").toString().toFloat(); reader->readNext(); QPen PolylinePen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); QStringList pointList; QColor brushColor; bool hasBrushColor = false; while(!(reader->isEndElement() && reader->name() == "DrawItem")) { if(reader->name() == "Brush" && !hasBrushColor) { attributes = reader->attributes(); QString color = attributes.value("Color").toString(); if(color.contains("#")) brushColor = QColor(color); else brushColor = QColor(color.toInt()); hasBrushColor = true; } else if(reader->name() == "LinePen") { attributes = reader->attributes(); // if(attributes.hasAttribute("DashStyle") && attributes.value("DashStyle").toString() != "Solid") // QString aa = attributes.hasAttribute("DashStyle"); if(attributes.hasAttribute("Width")) PolylinePen.setWidthF(attributes.value("Width").toString().toFloat() * mm); if(attributes.hasAttribute("Color")){ QString color = attributes.value("Color").toString()/*.toInt()*/; if(color.contains("#")) PolylinePen.setColor(QColor(color)); else PolylinePen.setColor(QColor(color.toInt())); } } else if(reader->name() == "Point") pointList << reader->readElementText().split(','); else QString aa = reader->name().toString(); reader->readNext(); } centerX = pointList[0].toFloat(); //取中心 float strechV = centerX * strechR; //计算扩张后中心值 strechV -= centerX; //计算偏移量 strechV *= mm; //偏移量转像素量 //计算反向绘制位移增量 float c2c = wH[0] - centerX * 2; float strechV_R = (centerX + c2c) * strechR; strechV_R -= (centerX + c2c); strechV_R *= mm; float wAdd, hAdd; int itemNum = 0; int wN = wHNum[0]; int hN = wHNum[1]; bool rightMove = false; //右侧偏移标志 bool reverseMove = false; //反向绘制标志 for(int w = 0; w < wN; w++){ for(int h = 0; h < hN; h++){ if(isHorizon){ scene->translate(m_Rect.x() - m_Rect.y(), m_Rect.y()+m_Rect.x()+m_Rect.width()); scene->rotate(HORANGEL); } rightMove = (h % 2) != 0 ? true : false; rightMove = (ifForward == true) ? rightMove : false; reverseMove = (h % 2) != 0 ? true : false; reverseMove = (ifReverse == true) ? reverseMove : false; wAdd = w * (wH[0] + TRAINTERVAL); hAdd = h * (wH[1] + LONINTERVAL); //若本次绘制有超出边界的可能,缩小纵向拉伸比 if((hAdd + wH[1] + LONINTERVAL) * mm > m_Rect.height()){ strechH *= (m_Rect.height() / mm - hAdd) / wH[1]; } if(Xradius <= 0 && Yradius <= 0){ Xradius = radius; Yradius = radius; } if(isOne) scene->translate(0, (m_Rect.height() - wH[1] * mm) / 2); if(!isOne && ifLine){ scene->setPen(sPen); if(isStech){ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } else{ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } } //移动到横向扩张或缩小后的位置 if(reverseMove) scene->translate(strechV_R + c2c * mm, 0); else scene->translate(strechV, 0); qreal oX = pointList[0].toFloat() + wAdd; qreal oY = pointList[1].toFloat() * strechH + hAdd; float moveW = (m_Rect.width()/mm < wH[0]) ? m_Rect.width()/mm : wH[0]; moveW = (isStech == false) ? m_Rect.width()/mm : moveW; if(rightMove) oX += moveW / RIGHTLEVEL; oX *= mm; oY *= mm; oX += m_Rect.x(); oY += m_Rect.y(); scene->translate(oX, oY); scene->rotate(rotatedAngle); scene->setPen(PolylinePen); if(ifFilled) scene->setBrush(QBrush(brushColor)); else scene->setBrush(Qt::NoBrush); scene->drawEllipse(QRectF(-Xradius * mm, -Yradius * mm, Xradius * 2 * mm, Yradius * 2 * mm)); scene->resetTransform(); itemNum++; } } } void GeoIndicatorGenerator::TextPainter(QXmlStreamReader *reader, QPainter *scene, int *wHNum, float *wH, bool isOne, bool isStech, bool isHorizon) { /* 15,1.5 */ bool ifLine = (wH[2] == 1) ? false : true; //SymbolType="Original" 不画分割线 bool ifStretch = (wH[3] == 1) ? true : false; bool ifOneStrech = (wH[3] == 3) ? true : false; bool ifForward = (wH[4] == 1) ? true : false; bool ifReverse = (wH[4] == 2) ? true : false; //反向绘制 bool ifOnlyOne = (wH[3] == 4) ? true : false; if(ifOnlyOne) isOne = true; if(ifOneStrech && isOne) ifStretch = true; if(ifStretch) { isOne = false; //因为拉伸,所以不需要居中 ifLine = false; //因为拉伸,所以不需要分割线 wHNum[1] = 1; //纵向拉伸,只需画一个符号 } float centerX = 0; float strechR; //横向边长比例 if(!isStech) strechR = m_Rect.width() / (wH[0] * mm); else strechR = m_Rect.width() / (GEOWIDTH * mm); float strechH = (ifStretch == true) ? m_Rect.height() / (wH[1] / h_strechRate * mm) : h_strechRate; //纵向拉伸比例 QColor brushColor; bool hasBrushColor = false; float Rangle; float Size = 0; QString Text, Name, ifBold, ifItalic, ifUnderLine; ifBold = "false"; ifItalic = "false"; ifUnderLine = "false"; QStringList pointList; QXmlStreamAttributes attributes; attributes = reader->attributes(); if(attributes.hasAttribute("RotatedAngle")) Rangle = attributes.value("RotatedAngle").toString().toFloat(); if(attributes.hasAttribute("Text")) Text = attributes.value("Text").toString(); reader->readNext(); while(!(reader->isEndElement() && reader->name() == "DrawItem")) { if(reader->name() == "Brush" && !hasBrushColor) { attributes = reader->attributes(); QString color = attributes.value("Color").toString(); if(color.contains("#")) brushColor = QColor(color); else brushColor = QColor(color.toInt()); hasBrushColor = true; } else if(reader->name() == "TextFont") { attributes = reader->attributes(); if(attributes.hasAttribute("Name")) Name = attributes.value("Name").toString(); if(attributes.hasAttribute("Size")) Size = attributes.value("Size").toString().toFloat(); if(attributes.hasAttribute("Bold")) ifBold = attributes.value("Bold").toString(); if(attributes.hasAttribute("Italic")) ifItalic = attributes.value("Italic").toString(); if(attributes.hasAttribute("UnderLine")) ifUnderLine = attributes.value("UnderLine").toString(); } else if(reader->name() == "Point") { pointList << reader->readElementText().split(','); } else { QString aa = reader->name().toString(); } reader->readNext(); } centerX = pointList[0].toFloat(); //取中心 float strechV = centerX * strechR; //计算扩张后中心值 strechV -= centerX; //计算偏移量 strechV *= mm; //偏移量转像素量 //计算反向绘制位移增量 float c2c = wH[0] - centerX * 2; float strechV_R = (centerX + c2c) * strechR; strechV_R -= (centerX + c2c); strechV_R *= mm; float wAdd, hAdd; int itemNum = 0; int wN = wHNum[0]; int hN = wHNum[1]; bool rightMove = false; //右侧偏移标志 bool reverseMove = false; //反向绘制标志 for(int w = 0; w < wN; w++){ for(int h = 0; h < hN; h++){ if(isHorizon){ scene->translate(m_Rect.x() - m_Rect.y(), m_Rect.y()+m_Rect.x()+m_Rect.width()); scene->rotate(HORANGEL); } rightMove = (h % 2) != 0 ? true : false; rightMove = (ifForward == true) ? rightMove : false; reverseMove = (h % 2) != 0 ? true : false; reverseMove = (ifReverse == true) ? reverseMove : false; wAdd = w * (wH[0] + TRAINTERVAL); hAdd = h * (wH[1] + LONINTERVAL); //若本次绘制有超出边界的可能,缩小纵向拉伸比 if((hAdd + wH[1] + LONINTERVAL) * mm > m_Rect.height()){ strechH *= (m_Rect.height() / mm - hAdd) / wH[1]; } QFont font(Name, Size, QFont::Bold, true); float psize = mm * 0.5; if(psize < 1) psize = 1; font.setPointSize(Size * psize); if(ifItalic == "true") font.setItalic(true); // 斜体 else font.setItalic(false); if(ifUnderLine == "true") font.setUnderline(true); // 下划线 else font.setUnderline(false); if(ifBold == "true") font.setBold(true); // 下划线 else font.setBold(false); if(isOne) scene->translate(0, (m_Rect.height() - wH[1] * mm) / 2); if(!isOne && ifLine){ scene->setPen(sPen); if(isStech){ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } else{ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } } //移动到横向扩张或缩小后的位置 if(reverseMove) scene->translate(strechV_R + c2c * mm, 0); else scene->translate(strechV, 0); qreal X = pointList[0].toFloat() + wAdd; qreal Y = pointList[1].toFloat() * strechH + hAdd; float moveW = (m_Rect.width() / mm < wH[0]) ? m_Rect.width() / mm : wH[0]; moveW = (isStech == false) ? m_Rect.width()/mm : moveW; if(rightMove) X += moveW / RIGHTLEVEL; X *= mm; Y *= mm; scene->translate(m_Rect.x() + X, m_Rect.y() + Y); scene->rotate(Rangle); scene->setFont(font); scene->setPen(brushColor); scene->drawText(-10, -10, 20, 20, Qt::AlignCenter, Text); scene->resetTransform(); itemNum++; } } } void GeoIndicatorGenerator::ArcPainter( QXmlStreamReader *reader, QPainter *scene, int *wHNum, float *wH, bool isOne, bool isStech, bool isHorizon) { /* 9.292982,0.8986088 */ bool ifLine = (wH[2] == 1) ? false : true; //SymbolType="Original" 不画分割线 bool ifStretch = (wH[3] == 1) ? true : false; bool ifOneStrech = (wH[3] == 3) ? true : false; bool ifForward = (wH[4] == 1) ? true : false; bool ifReverse = (wH[4] == 2) ? true : false; //反向绘制 bool ifOnlyOne = (wH[3] == 4) ? true : false; if(ifOnlyOne) isOne = true; if(ifOneStrech && isOne) ifStretch = true; if(ifStretch) { isOne = false; //因为拉伸,所以不需要居中 ifLine = false; //因为拉伸,所以不需要分割线 wHNum[1] = 1; //纵向拉伸,只需画一个符号 } float centerX = 0; float strechR; //横向边长比例 if(!isStech) strechR = m_Rect.width() / (wH[0] * mm); else strechR = m_Rect.width() / (GEOWIDTH * mm); float strechH = (ifStretch == true) ? m_Rect.height() / (wH[1] / h_strechRate * mm) : h_strechRate; //纵向拉伸比例 bool ifFilled = true; float Xradius, Yradius; float Sangle, Eangle, Rangle; QXmlStreamAttributes attributes; attributes = reader->attributes(); if(attributes.hasAttribute("Filled") && attributes.value("Filled").toString() != "True") ifFilled = false; if(attributes.hasAttribute("XRadius")) Xradius = attributes.value("XRadius").toString().toFloat(); if(attributes.hasAttribute("YRadius")) Yradius = attributes.value("YRadius").toString().toFloat(); if(attributes.hasAttribute("StartAngle")) Sangle = attributes.value("StartAngle").toString().toFloat(); if(attributes.hasAttribute("EndAngle")) Eangle = attributes.value("EndAngle").toString().toFloat(); if(attributes.hasAttribute("RotatedAngle")) Rangle = attributes.value("RotatedAngle").toString().toFloat(); reader->readNext(); QPen PolylinePen(Qt::black, 0.1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); QStringList pointList; QColor brushColor; bool hasBrushColor = false; while(!(reader->isEndElement() && reader->name() == "DrawItem"))//end DrawItem { if(reader->name() == "Brush" && !hasBrushColor) { attributes = reader->attributes(); QString color = attributes.value("Color").toString(); if(color.contains("#")) brushColor = QColor(color); else brushColor = QColor(color.toInt()); hasBrushColor = true; } else if(reader->name() == "LinePen") { attributes = reader->attributes(); // if(attributes.hasAttribute("DashStyle") && attributes.value("DashStyle").toString() != "Solid") // QString aa = attributes.hasAttribute("DashStyle"); if(attributes.hasAttribute("Width")) PolylinePen.setWidthF(attributes.value("Width").toString().toFloat() * mm); if(attributes.hasAttribute("Color")){ QString color = attributes.value("Color").toString(); if(color.contains("#")) PolylinePen.setColor(QColor(color)); else PolylinePen.setColor(QColor(color.toInt())); } } else if(reader->name() == "Point") { pointList << reader->readElementText().split(','); } else { QString aa = reader->name().toString(); } reader->readNext(); } centerX = pointList[0].toFloat(); //取中心 float strechV = centerX * strechR; //计算扩张后中心值 strechV -= centerX; //计算偏移量 strechV *= mm; //偏移量转像素量 //计算反向绘制位移增量 float c2c = wH[0] - centerX * 2; float strechV_R = (centerX + c2c) * strechR; strechV_R -= (centerX + c2c); strechV_R *= mm; float wAdd, hAdd; int itemNum = 0; int wN = wHNum[0]; int hN = wHNum[1]; bool rightMove = false; //右侧偏移标志 bool reverseMove = false; //反向绘制标志 for(int w = 0; w < wN; w++){ for(int h = 0; h < hN; h++){ if(isHorizon){ scene->translate(m_Rect.x() - m_Rect.y(), m_Rect.y()+m_Rect.x()+m_Rect.width()); scene->rotate(HORANGEL); } rightMove = (h % 2) != 0 ? true : false; rightMove = (ifForward == true) ? rightMove : false; reverseMove = (h % 2) != 0 ? true : false; reverseMove = (ifReverse == true) ? reverseMove : false; wAdd = w * (wH[0] + TRAINTERVAL); hAdd = h * (wH[1] + LONINTERVAL); //若本次绘制有超出边界的可能,缩小纵向拉伸比 if((hAdd + wH[1] + LONINTERVAL) * mm > m_Rect.height()){ strechH *= (m_Rect.height() / mm - hAdd) / wH[1]; } if(isOne) scene->translate(0, (m_Rect.height() - wH[1] * mm) / 2); if(!isOne && ifLine){ scene->setPen(sPen); if(isStech){ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } else{ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } } //移动到横向扩张或缩小后的位置 if(reverseMove) scene->translate(strechV_R + c2c * mm, 0); else scene->translate(strechV, 0); qreal oX = pointList[0].toFloat() + wAdd; qreal oY = pointList[1].toFloat() * strechH + hAdd; float moveW = (m_Rect.width()/mm < wH[0]) ? m_Rect.width()/mm : wH[0]; moveW = (isStech == false) ? m_Rect.width()/mm : moveW; if(rightMove) oX += moveW / RIGHTLEVEL; oX *= mm; oY *= mm; oX += m_Rect.x(); oY += m_Rect.y(); scene->translate(oX, oY); scene->rotate(Rangle); scene->setPen(PolylinePen); if(ifFilled) scene->setBrush(QBrush(brushColor)); else scene->setBrush(Qt::NoBrush); scene->setRenderHint(QPainter::Antialiasing, true); scene->drawArc(QRectF(-Xradius * mm, -Yradius * mm, Xradius * 2 * mm, Yradius * 2 * mm), 16*Sangle, 16*Eangle); scene->resetTransform(); itemNum++; } } } void GeoIndicatorGenerator::PolygonPainter( QXmlStreamReader *reader, QPainter *scene, int *wHNum, float *wH, bool isOne, bool isStech, bool isHorizon) { /* 6,0.2 4,0.5 4,1.5 6,1.8 8,1.5 8,0.5 */ bool ifLine = (wH[2] == 1) ? false : true; //SymbolType="Original" 不画分割线 bool ifStretch = (wH[3] == 1) ? true : false; bool ifOneStrech = (wH[3] == 3) ? true : false; bool ifForward = (wH[4] == 1) ? true : false; bool ifReverse = (wH[4] == 2) ? true : false; //反向绘制 bool filled = (wH[5] == 1) ? true : false; bool ifOnlyOne = (wH[3] == 4) ? true : false; if(ifOnlyOne) isOne = true; if(filled) ifStretch = true; //全填满,则纵向拉伸 if(ifOneStrech && isOne) ifStretch = true; if(ifStretch) { isOne = false; //因为拉伸,所以不需要居中 ifLine = false; //因为拉伸,所以不需要分割线 wHNum[1] = 1; //纵向拉伸,只需画一个符号 } float centerX = 0; float strechR; //横向边长比例 if(!isStech) strechR = m_Rect.width() / (wH[0] * mm); else strechR = m_Rect.width() / (GEOWIDTH * mm); float strechA = (filled == true) ? m_Rect.width() / (GEOWIDTH * mm) : 1; //横向拉伸比例 float strechH = (ifStretch == true) ? m_Rect.height() / (wH[1] / h_strechRate * mm) : h_strechRate; //纵向拉伸比例 bool ifFilled = true; QColor brushColor; bool hasBrushColor = false; QXmlStreamAttributes attributes; attributes = reader->attributes(); if(attributes.hasAttribute("Filled") && attributes.value("Filled").toString() != "True") ifFilled = false; reader->readNext(); QPen PolylinePen(Qt::black, 0.1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); int pointNum = 0; QStringList pointList; while(!(reader->isEndElement() && reader->name() == "DrawItem"))//end DrawItem { if(reader->name() == "Brush" && !hasBrushColor) { attributes = reader->attributes(); QString color = attributes.value("Color").toString()/*.toInt()*/; if(color.contains("#")) brushColor = QColor(color); else brushColor = QColor(color.toInt()); hasBrushColor = true; } else if(reader->name() == "LinePen") { attributes = reader->attributes(); // if(attributes.hasAttribute("DashStyle") && attributes.value("DashStyle").toString() != "Solid") // QString aa = attributes.hasAttribute("DashStyle"); if(attributes.hasAttribute("Width")) PolylinePen.setWidthF(attributes.value("Width").toString().toFloat() * mm); if(attributes.hasAttribute("Color")){ QString color = attributes.value("Color").toString()/*.toInt()*/; if(color.contains("#")) PolylinePen.setColor(QColor(color)); else PolylinePen.setColor(QColor(color.toInt())); } } else if(reader->name() == "Point") { pointList << reader->readElementText().split(','); centerX = centerX + pointList[pointNum * 2].toFloat(); pointNum++; } else { QString aa = reader->name().toString(); } reader->readNext(); } centerX /= pointNum; //取中心 float strechV = centerX * strechR; //计算扩张后中心值 strechV -= centerX; //计算偏移量 strechV *= mm; //偏移量转像素量 //计算反向绘制位移增量 float c2c = wH[0] - centerX * 2; float strechV_R = (centerX + c2c) * strechR; strechV_R -= (centerX + c2c); strechV_R *= mm; float wAdd, hAdd; int itemNum = 0; int wN = wHNum[0]; int hN = wHNum[1]; bool rightMove = false; //右侧偏移标志 bool reverseMove = false; //反向绘制标志 for(int w = 0; w < wN; w++){ for(int h = 0; h < hN; h++){ if(isHorizon){ scene->translate(m_Rect.x() - m_Rect.y(), m_Rect.y()+m_Rect.x()+m_Rect.width()); scene->rotate(HORANGEL); } rightMove = (h % 2) != 0 ? true : false; rightMove = (ifForward == true) ? rightMove : false; reverseMove = (h % 2) != 0 ? true : false; reverseMove = (ifReverse == true) ? reverseMove : false; wAdd = w * (wH[0]+TRAINTERVAL); hAdd = h * (wH[1]+LONINTERVAL); //若本次绘制有超出边界的可能,缩小纵向拉伸比 if((hAdd + wH[1] + LONINTERVAL) * mm > m_Rect.height()){ strechH *= (m_Rect.height() / mm - hAdd) / wH[1]; } // 绘制多边形 QPolygonF polygon; if(rightMove){ float moveW = (m_Rect.width() / mm < wH[0]) ? m_Rect.width() / mm : wH[0]; moveW = (isStech == false) ? m_Rect.width() / mm : moveW; for(int i = 0; i < pointNum; i++) polygon << QPointF( m_Rect.x() + (pointList[i*2].toFloat() + wAdd + moveW / RIGHTLEVEL) * mm, m_Rect.y() + (pointList[i * 2 + 1].toFloat() * strechH + hAdd) * mm ); } else for(int i = 0; i < pointNum; i++){ polygon << QPointF( m_Rect.x() + (pointList[i * 2].toFloat() * strechA + wAdd) * mm, m_Rect.y() + (pointList[i * 2 + 1].toFloat() * strechH + hAdd) * mm ); } scene->setPen(PolylinePen); if(ifFilled) scene->setBrush(QBrush(QColor(brushColor))); else scene->setBrush(Qt::NoBrush); if(isOne) scene->translate(0, (m_Rect.height() - wH[1] * mm) / 2); if(!isOne && ifLine){ scene->setPen(sPen); if(isStech){ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + wH[0] * mm * strechR + SPLITLINE_ADD, m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } else{ scene->drawLine(m_Rect.x(), m_Rect.y() + hAdd * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + hAdd * mm); scene->drawLine(m_Rect.x(), m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm, m_Rect.x() + m_Rect.width() + SPLITLINE_ADD,m_Rect.y() + (hAdd + wH[1] + LONINTERVAL) * mm); } } //移动到横向扩张或缩小后的位置 if(!filled){ if(reverseMove) scene->translate(strechV_R + c2c * mm, 0); else scene->translate(strechV, 0); } scene->drawPolygon(polygon); //if(!isStech || isOne) scene->resetTransform(); itemNum++; } } }