QCAD 代码片段
引用块对象的递归加载
引用块对象绘制统一返回圆。
//RBlockReferenceEntity.cpp
void RBlockReferenceEntity::exportEntity(RExporter& e, bool preview, bool forceSelected) const {
e.setBrush(Qt::NoBrush);
//绘制一个半径为1,圆心为对象位置的circle
e.exportCircle(RCircle(data.getPosition().x,data.getPosition().y,1));
}
引用块对象包围盒的计算。
//RBlockReferenceData.cpp
QList<RBox> RBlockReferenceData::getBoundingBoxes(bool ignoreEmpty) const {
QList<RBox>* bbs;
if (ignoreEmpty) {
bbs = &boundingBoxes;
}
else {
bbs = &boundingBoxesIgnoreEmpty;
}
if (!bbs->isEmpty()) {
return *bbs;
}
if (document == NULL) {
return QList<RBox>();
}
RCircle r(position.x,position.y,1);
bbs->append(r.getBoundingBox());
return *bbs;
}
引用块对象几何数据的获取。
//RBlockReferenceData.cpp
QList<QSharedPointer<RShape> > RBlockReferenceData::getShapes(const RBox& queryBox, bool ignoreComplex, bool segment) const {
Q_UNUSED(segment)
return QList<QSharedPointer<RShape> >() <<
QSharedPointer<RShape>(new RCircle(position.x,position.y,1));
}
限制递归深度为1。
//全局查找修改
static int recursionDepth = 0;
recursionDepth++;
if (recursionDepth>1) {
recursionDepth--;
return;
}
主题的加载
主题的加载,只加载css文件即可。
//library.js
function applyTheme() {
var theme = RSettings.getValue("Theme/ThemeName", undefined);
if (!isNull(theme)) {
var path = "themes/" + theme + "/";
qApp.styleSheet = "";
// load stylesheet.css, stylesheet_[win|macos|linux].css:
var found = false;
var systemId = RS.getSystemId();
if (systemId==="osx") systemId = "macos";
var postfixes = ["", "_" + systemId];
for (var i=0; i<postfixes.length; i++) {
var postfix = postfixes[i];
var fn = path + "stylesheet" + postfix + ".css";
//qDebug("trying to load theme stylesheet: ", fn);
if (new QFileInfo(fn).exists()) {
var css = readTextFile(fn);
// if (css.contains("RequiresPlugin:true")) {
// // only load theme if plugin loaded:
// var pluginId = theme.toUpperCase() + "STYLE";
// if (!RPluginLoader.hasPlugin(pluginId)) {
// qWarning("Theme not loaded: ", theme);
// qWarning("Theme plugin not found:", pluginId);
// return;
// }
// }
//css = css.replace(/url\\(/g, "url(" + path);
// qDebug(css);
qApp.styleSheet = qApp.styleSheet + "\\n" + css;
found = true;
}
}
// if (!found) {
// if (theme!=="Default") {
// qWarning("Cannot open theme: ", theme);
// }
// }
}
}
删减不必要的Js插件
Js
插件一部分放在安装目录下,一部分编译成插件放在安装目录下的插件目录中。
删减插件中js
脚本,只需从\\src\\scripts\\scripts_release.qrc
删除即可。
\\src\\scripts\\scripts_release.qrc
:为release
版本下加载的插件。
\\src\\scripts\\scripts.qrc
:为完整版本下加载的插件。
删减不必要程序配置选项的内容
【编辑】->【程序选项】/【绘制选项】
将Js脚本中的一下代码注释掉即可:
//示例:Exploade.js注释掉`getPreferencesCategory`函数即可。
// Explode.getPreferencesCategory = function() {
// return [qsTr("Extensions"), qsTr("Explode")];
// };
目标图层与原图层分开
RLayer添加字段及函数
//RLayer.h
bool getLyType() const
{
return lyType;
}
void setLyType(bool value)
{
lyType = value;
}
private:
bool lyType;
Js环境可调用
Js环境下可调用,需要封装转换一下,如果对象涉及到智能指针,需要转换两次。示例,REcma*.h&cpp 和REcmaSharedPointer*.h&cpp
。
//REcmaLayer.h & REcmaSharedPointerLayer.h
static QScriptValue getLyType(QScriptContext* context, QScriptEngine* engine);
static QScriptValue setLyType(QScriptContext* context, QScriptEngine* engine);
//REcmaLayer.cpp & REcmaSharedPointerLayer.cpp
REcmaHelper::registerFunction(&engine, proto, getLyType, "getLyType");
REcmaHelper::registerFunction(&engine, proto, setLyType, "setLyType");
QScriptValue REcmaLayer::getLyType(QScriptContext *context, QScriptEngine *engine)
{
//REcmaHelper::functionStart("REcmaLayer::getLyType", context, engine);
//qDebug() << "ECMAScript WRAPPER: REcmaLayer::getLyType";
//QCoreApplication::processEvents();
QScriptValue result = engine->undefinedValue();
// public function: can be called from ECMA wrapper of ECMA shell:
RLayer* self =
getSelf("getLyType", context);
//Q_ASSERT(self!=NULL);
if (self==NULL) {
return REcmaHelper::throwError("self is NULL", context);
}
if( context->argumentCount() ==
0
){
// prepare arguments:
// end of arguments
// call C++ function:
// return type 'bool'
bool cppResult =
self->getLyType();
// return type: bool
// standard Type
result = QScriptValue(cppResult);
} else
{
return REcmaHelper::throwError("Wrong number/types of arguments for RLayer.getLyType().",
context);
}
//REcmaHelper::functionEnd("REcmaLayer::getLyType", context, engine);
return result;
}
QScriptValue REcmaLayer::setLyType(QScriptContext *context, QScriptEngine *engine)
{
//REcmaHelper::functionStart("REcmaLayer::setLyType", context, engine);
//qDebug() << "ECMAScript WRAPPER: REcmaLayer::setLyType";
//QCoreApplication::processEvents();
QScriptValue result = engine->undefinedValue();
// public function: can be called from ECMA wrapper of ECMA shell:
RLayer* self =
getSelf("setLyType", context);
//Q_ASSERT(self!=NULL);
if (self==NULL) {
return REcmaHelper::throwError("self is NULL", context);
}
if( context->argumentCount() ==
1 && (
context->argument(0).isBool()
) /* type: bool */
){
// prepare arguments:
// argument isStandardType
bool
a0 =
(bool)
context->argument( 0 ).
toBool();
// end of arguments
// call C++ function:
// return type 'void'
self->setLyType(a0);
} else
{
return REcmaHelper::throwError("Wrong number/types of arguments for RLayer.setLyType().",
context);
}
//REcmaHelper::functionEnd("REcmaLayer::setLyType", context, engine);
return result;
}
修改图层列表Js脚本
\\scripts\\Widgets\\LayerList\\LayerList.js
//添加一个目标图层List控件,并初始化
var layerListDest = new RLayerListQt(layout,RLayerListQt.Type.Dest);
layerListDest.objectName = "DestLayerList";
layout.addWidget(layerListDest,1,0);
layout.addStretch();
WidgetFactory.initList(layerListDest, "LayerList");
//设置事件处理函数,条目选择事件处理函数
layerListDest.itemSelectionChanged.connect(function() {
var action = RGuiAction.getByScriptFile("scripts/Layer/RemoveLayer/RemoveLayer.js");
if (isNull(action)) {
return;
}
var list = layerList.selectedItems();
if (list.length === 0) {
return;
}
var item = list[0];
if (isNull(item)) {
return;
}
// protected layers:
if (item.text() === "0" || item.data(Qt.UserRole)===true) {
action.setEnabledOverride(false, 0);
} else {
action.setEnabledOverride(true, 1);
}
});
图层数目发生改变时,通过判断前面设置的字段来区分。
//`\\scripts\\Widgets\\LayerList\\LayerList.js`
RLayerListQt.prototype.updateLayers = function(documentInterface, previousLayerId) {
this.di = documentInterface;
var layer;
var pos = this.verticalScrollBar().sliderPosition;
this.clear();
if (isNull(documentInterface)) {
return;
}
var doc = documentInterface.getDocument();
var result = doc.queryAllLayers();
for ( var i = 0; i < result.length; ++i) {
var id = result[i];
layer = doc.queryLayer(id);
if (layer.isNull()) {
continue;
}
//图层区分
if(this.lyType==RLayerListQt.Type.Src && layer.getLyType()==false){
this.addLayerItem(layer);
}
if(this.lyType==RLayerListQt.Type.Dest && layer.getLyType()==true){
this.addLayerItem(layer);
}
}
this.sortItems();
layer = doc.queryCurrentLayer();
if (!layer.isNull()) {
var items = this.findItems(layer.getName(), Qt.MatchExactly);
if (items.length !== 0) {
this.blockSignals(true);
this.setCurrentItem(items[0]);
this.blockSignals(false);
}
}
this.verticalScrollBar().sliderPosition = pos;
};
加载dxf中文乱码
dxf文件为文本文件,中文编码可能是utf-8编码,也有可能是GBK编码。QCAD使用Qt开发环境,字符串统一按照utf-8编码解码,
所以解析dxf文件时对字符串首先按照utf-8转码,如果转码失败则按照GBK转码。
//RDxfImporter.cpp
QString decode(const std::string& str) {
//GBK UTF-8->Unicode
QByteArray data=QByteArray::fromStdString(str);
QTextCodec::ConverterState state;
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QString str_tmp=codec->toUnicode(data.constData(),data.size(),&state);
if(state.invalidChars>0){
str_tmp=QTextCodec::codecForName("GBK")->toUnicode(data);
}else{
str_tmp=data;
}
return RDxfServices::parseUnicode(str_tmp);
}
//示例,可能出现乱码的地方需要调用一下
void RDxfImporter::addLayer(const DL_LayerData& data) {
QString layerName = decode(data.name.c_str());
}
void RDxfImporter::addLinetype(const DL_LinetypeData& data) {
QString name = decode(data.name.c_str());
QString description = decode(data.description.c_str());
}
void RDxfImporter::addBlock(const DL_BlockData& data) {
QString blockName = decode(data.name.c_str());
}
...
...
...
重建空间索引
1.文本字体的设置统一设置为 “Arial”。
2. 多线程处理对象的包围盒。
//RDocument.cpp
void RDocument::rebuildSpatialIndex() {
clearSpatialIndices();
QSet<REntity::Id> result = storage.queryAllEntities(false, true);
QList<int> allIds;
QList<QList<RBox> > allBbs;
QMap<RBlock::Id, QList<int> > allIdsByBlock;
QMap<RBlock::Id, QList<QList<RBox> > > allBbsByBlock;
QList<RIdBox > entities;
QSetIterator<REntity::Id> j(result);
while (j.hasNext()) {
QSharedPointer<REntity> entity = storage.queryEntityDirect(j.next());
if (entity.isNull()) {
continue;
}
if (entity->isUndone()) {
continue;
}
entity->update();
int id=entity->getId();
int blockId= entity->getBlockId();
if(RS::EntityText==entity->getType()){
RTextBasedEntity* txtEntity=(RTextBasedEntity*)(entity.data());
// QString fontName=txtEntity->getFontName();
// RFont*font=RFontList::get(fontName);
// if(font==NULL){
// continue;
// }
txtEntity->setFontName("Arial");
}
if(RS::EntityBlockRef==entity->getType()){
continue;
// QSharedPointer<RBlockReferenceEntity> blockRef = entity.dynamicCast<RBlockReferenceEntity>();
// if (blockRef.isNull()) {
// continue;
// }
// QVariant v = blockRef->getCustomProperty("", "block");
// if (!v.isValid()) {
// continue;
// }
// QString blockName = v.toString();
// RBlock::Id refblockId = getBlockId(blockName);
// if (refblockId==RBlock::INVALID_ID) {
// continue;
// }
// blockRef->setReferencedBlockId(refblockId);
}
entity->update();
entities.append(RIdBox(id,blockId,QList<RBox>(),entity));
}
QFuture<void>future= QtConcurrent::map(entities,&RDocument::buildSpatialIndex);
future.waitForFinished();
foreach (auto entity, entities) {
if (disableSpatialIndicesByBlock) {
allIds.append(entity.id);
allBbs.append(entity.box);
}
else {
RBlock::Id blockId = entity.blockId;
if (!allIdsByBlock.contains(blockId)) {
allIdsByBlock.insert(blockId, QList<int>());
}
allIdsByBlock[blockId].append(entity.id);
if (!allBbsByBlock.contains(blockId)) {
allBbsByBlock.insert(blockId, QList<QList<RBox> >());
}
allBbsByBlock[blockId].append(entity.box);
}
}
// QSetIterator<REntity::Id> i(result);
// while (i.hasNext()) {
// QSharedPointer<REntity> entity = storage.queryEntityDirect(i.next());
// if (entity.isNull()) {
// continue;
// }
// if (entity->isUndone()) {
// continue;
// }
// entity->update();
// RObject::Id entityId = entity->getId();
// QList<RBox> bbs = entity->getBoundingBoxes(true);
// if (disableSpatialIndicesByBlock) {
// allIds.append(entityId);
// allBbs.append(bbs);
// }
// else {
// RBlock::Id blockId = entity->getBlockId();
// if (!allIdsByBlock.contains(blockId)) {
// allIdsByBlock.insert(blockId, QList<int>());
// }
// allIdsByBlock[blockId].append(entityId);
// if (!allBbsByBlock.contains(blockId)) {
// allBbsByBlock.insert(blockId, QList<QList<RBox> >());
// }
// allBbsByBlock[blockId].append(bbs);
// }
// }
if (!disableSpatialIndicesByBlock) {
QList<RBlock::Id> blockIds = queryAllBlocks().toList();
for (int i=0; i<blockIds.length(); i++) {
RBlock::Id blockId = blockIds[i];
RSpatialIndex* si = getSpatialIndexForBlock(blockId);
// remove entries without bounding boxes:
for (int i=allIdsByBlock[blockId].length()-1; i>=0 && !allIdsByBlock[blockId].isEmpty(); i--) {
if (allBbsByBlock[blockId][i].isEmpty()) {
allIdsByBlock[blockId].removeAt(i);
allBbsByBlock[blockId].removeAt(i);
}
}
si->bulkLoad(allIdsByBlock[blockId], allBbsByBlock[blockId]);
// for (int i=0; i<allIdsByBlock[blockId].length(); i++) {
// si->addToIndex(allIdsByBlock[blockId][i], allBbsByBlock[blockId][i]);
// }
}
}
else {
spatialIndex.bulkLoad(allIds, allBbs);
}
// clear cached bounding box:
storage.update();
}
国际化中文翻译
ts
文件夹下,有成对的*.ts
和*.qm
文件。示例:qcadextensions_zh_CN.ts
和qcadextensions_zh_CN.qm
是插件
/src/support/examples/extensions
插件的翻译文件。
对于支持国际化的插件,需要在项目.pro
文件中添加如下内容:
//src/support/examples/extensions/extensions.pro
include( ../../../shared_ts.pri )
同时插件初始化时,加载对应的*.ts
文件。
//src/support/examples/extensions/RExtensionsPlugin.h
void ExtensionsPlugin::initTranslations()
{
RSettings::loadTranslations("qcadextensions", QStringList() << ":ts");
}
翻译宏标记
1.cpp 文件
QObject::tr("None")
2.js 文件
qsTr("None");
生成ts
文件
QtCreator
菜单【工具】->【外部->【Qt语言家】->【更新翻译】,更新翻译后,会在ts
文件夹下生成对应的ts
文件。
生成qm
文件
利用Qt语言家
(Linguist)打开ts
文件,翻译后发布后,生成对应的qm文件,国际化支持完成。
图层列表和块列表标志图标显示
自定义一个RListWidgetDelegate
类,继承自QStyledItemDelegate
,需要重载paint
函数,根据Item
数据来自定义Item
外观,实现图层列表和块列表显示标志图标。
//RListWidget.h
class RListWidgetDelegate:public QStyledItemDelegate
{
Q_OBJECT
public:
RListWidgetDelegate(QObject *parent):
QStyledItemDelegate(parent){
}
virtual ~RListWidgetDelegate(){}
// QAbstractItemDelegate interface
public:
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
重载paint
函数,绘制图标。
//RListWidget.cpp
void RListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyledItemDelegate::paint(painter, option, index);
QRect rect = option.rect; // 目标矩形
rect.adjust(2,2,-2,-2); // 缩小一圈,留出空白间隔
//Qt::UserRole+1,2,3保存图层的颜色值
int r = index.data(Qt::UserRole+1).toInt();
int g = index.data(Qt::UserRole+2).toInt();
int b = index.data(Qt::UserRole+3).toInt();
{
//绘制图层颜色图标
QColor clr(r,g,b);
QRect dst = rect;
dst.setLeft(rect.right()-60);
QRect area(0,0,20,10);
area.moveCenter(dst.center());
painter->fillRect(area,clr);
QPen pen(Qt::black);
painter->setPen(pen);
painter->drawRect(area);
}
//Qt::UserRole+4保存块图标
QString filesvg=index.data(Qt::UserRole+4).toString();
QFileInfo fileInfo(filesvg);
//绘制块图标
if(option.state & QStyle::State_Selected){
if(fileInfo.isFile())
{
QRect dst = rect;
dst.setLeft(rect.right()-120);
QRect area(0,0,18,18);
area.moveCenter(dst.center());
QPixmap pixmapPic(filesvg);
painter->drawPixmap(area, pixmapPic);
}
}
}
设置RListWidget
控件的委托外观类。
//RListWidget.cpp
RListWidget::RListWidget(QWidget* parent) :
QListWidget(parent), itemPressed(NULL), iconOffset(0) {
//#ifdef Q_OS_MAC
// iconOffset = 7;
//#else
// iconOffset = 0;
//#endif
this->setItemDelegate(new RListWidgetDelegate(this));
installEventFilter(new REventFilter(QEvent::KeyPress, true));
installEventFilter(new REventFilter(QEvent::KeyRelease, true));
}
图层列表标志图标数据的设置。
//scripts\\Widgets\\LayerList\\LayerList.js
RLayerListQt.prototype.addLayerItem=function(layer){
var item = new QListWidgetItem(layer.getName(), this);
var iconName = autoIconPath(this.basePath
+ "/layerstatus_%1%2.svg".arg(Number(layer.isFrozen()))
.arg(Number(layer.isLocked())));
item.setIcon(new QIcon(iconName));
//
//var icon = RColor.getIcon(layer.getColor(), new QSize(20,10));
//item.setIcon(icon);
//
item.setData(Qt.UserRole+1,layer.getColor().red());
item.setData(Qt.UserRole+2,layer.getColor().green());
item.setData(Qt.UserRole+3,layer.getColor().blue());
item.setData(Qt.UserRole+4,this.basePath +"/EditLayer.svg");
if (layer.isProtected()) {
item.setData(Qt.UserRole, true);
}
this.addItem(item);
}
块列表标志图标的设置
//scripts\\Widgets\\BlockList\\BlockList.js
RBlockListQt.prototype.createBlockItem = function(block) {
var item = new QTreeWidgetItem();
var name = block.getName();
var flags = new Qt.ItemFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled);
item.setFlags(flags);
var title = RBlockListQt.getBlockTitle(block);
// count the blockReferences
var doc = this.di.getDocument();
var blockId=doc.getBlockId(name);
var ids=doc.queryBlockReferences(blockId);
if(ids.length>0 && blockId != 5){
//title= sprintf("%s [ %d ]",title,ids.length);
item.setData(BlockList.colName,Qt.UserRole+2,ids.length);
}
item.setText(BlockList.colName, title);
item.setData(BlockList.colName, Qt.UserRole, name);
this.updateItemIcons(item, block);
var dirpath=sprintf("%s/images",RSettings.getApplicationPath());
var dir=new QDir();
if(dir.exists(dirpath))dir.mkpath(dirpath);
var fileName=sprintf("%s/%s.png",dirpath,name);
item.setData(BlockList.colName, Qt.UserRole+1, fileName);
return item;
};
自定义属性读取与写入
自定义属性的读取,属性以字符串的方式保存,如:“property=value”。
//RDxfImporter.cpp
void RDxfImporter::importXData(QSharedPointer<REntity> entity)
{
QStringList pJson;
QString str;
QPair<int,QVariant>p;
foreach (const QString &group, xData.keys()) {
QList<QPair<int, QVariant>> properties=xData.value(group);
for(int i=0;i<properties.size();++i){
p=properties.at(i);
str=p.second.toString();
if(str.contains('=')){
pJson=str.split("=");
if(pJson.length()>1){
entity->setProperty(RPropertyTypeId(group,pJson[0]),pJson[1]);
//qDebug()<<"group:"<<group<<"; key:"<<pJson[0]<<"; value:"<<pJson[1];
//设置自定义属性的属性,显示标签,以及可选项列表
QJsonObject field=getFieldAttri(group,pJson[0]);
RPropertyAttributes proAttr;
proAttr.setOption(RPropertyAttributes::Custom,true);
proAttr.setLabel(field.value("dataName").toString());
QString dic=field.value("dictionary").toString();
if(dic.length()>1){
QStringList items=dic.split(";");
QSet<QString>choices;
for(int i=0;i<items.count();i++){
QString item=items.at(i);
if(item.length()>1){
QStringList choice=item.split(",");
choices.insert(choice[1]);
}
}
if(choices.count()>0)
proAttr.setChoices(choices);
}
QString viewType=field.value("viewType").toString();
if(viewType=="MultLineTextBox")
proAttr.setRichText(true);
else if(viewType=="NumberTextBox")
proAttr.setOption(RPropertyAttributes::Integer,true);
entity->setCustomPropertyAttributes(group,pJson[0],proAttr);
//import to customtables;
document->addCustomTables(group,entity->getId());
//qDebug()<<"group:"<<group<<";entity:"<<entity->getId();
}
}
}
}
}
自定义属性的写入
//RDxfExporter.cpp
void RDxfExporter::writeCustomProperties(const REntity& p)
{
QMap<QString, QVariantMap>customProperties=p.getCustomProperties();
QString kv;
foreach (QString title, customProperties.keys()) {
QVariantMap properties=customProperties.value(title);
dw->dxfString(1001, (const char*)RDxfExporter::escapeUnicode(title));
foreach (const QString key, properties.keys()) {
QVariant value=properties.value(key);
kv=QString("%1=%2").arg(key,value.toString());
dw->dxfString(1000,(const char*)RDxfExporter::escapeUnicode(kv));
}
}
// dxf.writeDictionaryEntry();
}
数据库使用
目标图层的保存
//NewFile.js 331
if(isOpen){
//初始化数据库
FileDB.initDb();
var ids=LayerTypeTablePeer.getItems();
for(var i=0;i<ids.length;++i){
//这里是获取副本
var layer=document.queryLayer(ids[i].name);
if(!isNull(layer)){
//获取引用
layer=document.queryLayerDirect(layer.getId());
layer.setLyType(true);
}else{
LayerTypeTablePeer.doDeleteById(ids[i].name);
}
}
//
ids=document.queryAllLayers();
//通知图层改变信号
appWin.notifyLayerListeners(documentInterface,ids);
}
目标图层的设置
//FilterEditor.js 184
var op=undefined;
var layer=undefined;
layer=doc.queryLayer(text);
if(isNull(layer)){
layer = new RLayer(doc, text, false, false, clr, ltId, lw);
layer.setLyType(true);
op = new RModifyObjectOperation(layer);
di.applyOperation(op);
}else{
//获取图层引用,并修改其属性,注意不是副本
layer=doc.queryLayerDirect(layer.getId());
layer=layer.data();
layer.setLyType(true);
}
//保存目标图层
var layerType=new LayerTypeTable(layer.getName());
layerType.save();
//设置为当前图层
di.setCurrentLayer(layer);
坐标转换
仿射变换
//RCoordsParamSettingWidget.cpp
void RCoordsParamSettingWidget::AffineTransform(double &x, double &y)
{
double x1=x,y1=y;
double dx=ui->leDX_2->text().toDouble();
double dy=ui->leDY_2->text().toDouble();
double angle=ui->leRX_2->text().toDouble();
angle*= DEG_TO_RAD;
double m=ui->lem_2->text().toDouble();
x=dx+(m)*(cos(angle)*x1-sin(angle)*y1);
y=dy+(m)*(sin(angle)*x1+cos(angle)*y1);
}
仿射变换改变实体形状
//RAffineTransImpl.cpp 194
void RAffineTransImpl::btnApplyClicked()
{
if(_result.count()>0){
emit calcResult(_result);
}
double rotation=ui->angleLineEdit->text().toDouble()*DEG_TO_RAD;
double scale=ui->scaleLineEdit->text().toDouble();
double x = ui->dXLineEdit->text().toDouble();
double y = ui->dYLineEdit->text().toDouble();
double a = scale * cos(rotation);
double b = scale * sin(rotation);
QTransform *transform=new QTransform(a,b,x,-b,a,y,0,0,1);
RDocumentInterface*di=RMainWindow::getDocumentInterfaceStatic();
RDocument&doc=di->getDocument();
QSet<REntity::Id>ids=doc.querySelectedEntities();
if(ids.count()<1){
QMessageBox::information(this,"提示","请选择变换的实体!");
}
RAddObjectsOperation*op=new RAddObjectsOperation();
QSet<REntity::Id>::const_iterator it;
for (it=ids.constBegin(); it!=ids.constEnd(); it++) {
REntity::Id id=*it;
QSharedPointer<REntity> entity=doc.queryEntity(id);
RShape*shape=entity->castToShape();
QSharedPointer<RShape>pShape=shape->getTransformed(transform->transposed());
QSharedPointer<REntity>e=RCommonFunc::shapeToEntity(doc,pShape);
e->copyAttributesFrom(entity->clone());
op->deleteObject(entity);
op->addObject(e,false);
}
di->applyOperation(op);
}
投影坐标转换为经纬度
//RCoordinateTransImpl.cpp
void RCoordinateTransImpl::coordTransform(double &x, double &y, double &z)
{
int trans_type=parasetting->getTransType();
//是否需要进行放射变换
if(trans_type==1)
parasetting->AffineTransform(x,y);
pj_transform(pjsrc,pjdest,1,1,&x,&y,&z);
x*=RAD_TO_DEG;
y*=RAD_TO_DEG;
}
对选择的实体进行坐标转换
//RCoordinateTransImpl.cpp
RMainWindowQt *app= RMainWindowQt::getMainWindow();
RDocumentInterface*di =app->getDocumentInterface();
if(di){
RDocument&doc=di->getDocument();
QSet<REntity::Id>ids= doc.querySelectedEntities();
QSet<REntity::Id>::const_iterator it;
QSharedPointer<REntity> entity;
for(it=ids.constBegin();it!=ids.constEnd();it++){
REntity::Id id=*it;
entity=doc.queryEntityDirect(id);
RBox box=entity->getBoundingBox();
RVector v=box.getCenter();
double x=v.x,y=v.y,z=0.0;
coordTransform(x,y,z);
entity->setProperty(RPropertyTypeId("app","lon"),x);
entity->setProperty(RPropertyTypeId("app","lat"),y);
}
QMessageBox::information(this,"提示",QString("%1条数据转换完毕。").arg(ids.count()),
QMessageBox::StandardButton::Ok);
}
数据导出Excel
sheet
//RExportExcelImpl.cpp
void RExportExcelImpl::exportSheet(QJsonObject dataObj)
{
RDocument*doc=appWin->getDocument();
QXlsx::Workbook* workBook= xlsx.workbook();
QJsonArray fields=dataObj.value("dataFields").toArray();
QString group=dataObj.value("emCode").toString();
QString sheetName=dataObj.value("emName").toString();
QString dataType=dataObj.value("objectType").toString();
QSet<REntity::Id>ids=doc->getCustomTableValues(group);
if(ids.count()<1)
return;
sheetName=QString("%1(%2)").arg(sheetName).arg(ids.count());
QXlsx::Worksheet* workSheet=static_cast<QXlsx::Worksheet*>(workBook->addSheet(sheetName));
int col;
if(dataType=="POINT"){
col=1;
workSheet->write(1,col++,"序号");
workSheet->write(1,col++,"系统编号");
workSheet->write(1,col++,"创建时间");
workSheet->write(1,col++,"解状态");
workSheet->write(1,col++,"经度");
workSheet->write(1,col++,"纬度");
workSheet->write(1,col++,"高程");
workSheet->write(1,col++,"城建坐标N");
workSheet->write(1,col++,"城建坐标E");
workSheet->write(1,col++,"城建坐标H");
for(int i=0;i<fields.count();++i){
QJsonObject field=fields.at(i).toObject();
workSheet->write(1,col++,field.value("dataName").toString());
}
int row=2;
QSet<REntity::Id>::const_iterator it;
QSharedPointer<REntity> entity;
for(it=ids.constBegin();it!=ids.constEnd();it++){
REntity::Id id=*it;
entity=doc->queryEntityDirect(id);
col=1;
workSheet->write(row,col++,row-1);
QString uuid=entity->getCustomProperty(group,"uuid").toString();
workSheet->write(row,col++,uuid);
workSheet->write(row,col++,QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
//解状态
workSheet->write(row,col++," ");
QString lon="-1",lat="-1";
lon=entity->getCustomProperty("app","lon").toString();
lat=entity->getCustomProperty("app","lat").toString();
//经度
workSheet->write(row,col++,lon);
//纬度
workSheet->write(row,col++,lat);
//高程
workSheet->write(row,col++," ");
//平面坐标
RBox box=entity->getBoundingBox();
RVector v= box.getCenter();
workSheet->write(row,col++,v.y);
workSheet->write(row,col++,v.x);
workSheet->write(row,col++,v.z);
//写入动态字段
for(int i=0;i<fields.count();++i){
QJsonObject field=fields.at(i).toObject();
QString title=field.value("dataCode").toString();
QString value=entity->getCustomProperty(group,title).toString();
workSheet->write(row,col++,value);
}
row++;
}
}
else if(dataType=="LINE"){
col=1;
workSheet->write(1,col++,"序号");
workSheet->write(1,col++,"系统编号");
workSheet->write(1,col++,"管线长度");
workSheet->write(1,col++,"压力级别");
workSheet->write(1,col++,"创建时间");
workSheet->write(1,col++,"起点编号");
workSheet->write(1,col++,"起点经度");
workSheet->write(1,col++,"起点纬度");
workSheet->write(1,col++,"起点高程");
workSheet->write(1,col++,"终点编号");
workSheet->write(1,col++,"终点经度");
workSheet->write(1,col++,"终点纬度");
workSheet->write(1,col++,"终点高程");
workSheet->write(1,col++,"起点城建坐标N");
workSheet->write(1,col++,"起点城建坐标E");
workSheet->write(1,col++,"起点城建坐标H");
workSheet->write(1,col++,"终点城建坐标N");
workSheet->write(1,col++,"终点城建坐标E");
workSheet->write(1,col++,"终点城建坐标H");
for(int i=0;i<fields.count();++i){
QJsonObject field=fields.at(i).toObject();
workSheet->write(1,col++,field.value("dataName").toString());
}
int row=2;
QSet<REntity::Id>::const_iterator it;
QSharedPointer<REntity> entity;
for(it=ids.constBegin();it!=ids.constEnd();it++){
REntity::Id id=*it;
entity=doc->queryEntityDirect(id);
col=1;
workSheet->write(row,col++,row-1);
QString uuid=entity->getCustomProperty(group,"uuid").toString();
workSheet->write(row,col++,uuid);
QSharedPointer<RLineEntity>line= entity.dynamicCast<RLineEntity>();
QString length="-1";
if(line->isValid()){
length=QString("%1").arg(line->getLength());
}
workSheet->write(row,col++,length);
//压力级别
QString value=entity->getCustomProperty(group,"pressureRange").toString();
workSheet->write(row,col++,value);
//qDebug()<<"压力级别:"<<value;
//创建时间
workSheet->write(row,col++,QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
//起点编号
REntity::Id start_id =entity->getCustomProperty(group,"start").toInt();
QSharedPointer<REntity>start_entity=doc->queryEntityDirect(start_id);
value="-1";
QString lon="-1",lat="-1";
if(!start_entity.isNull()&&start_entity->isValid()){
QString start_group=start_entity->getCustomProperty("app","group").toString();
value=start_entity->getCustomProperty(start_group,"uuid").toString();
lon=start_entity->getCustomProperty("app","lon").toString();
lat=start_entity->getCustomProperty("app","lat").toString();
}
//!起点
workSheet->write(row,col++,value);
//经度
workSheet->write(row,col++,lon);
//纬度
workSheet->write(row,col++,lat);
//高程
workSheet->write(row,col++," ");
REntity::Id end_id=entity->getCustomProperty(group,"end").toInt();
QSharedPointer<REntity>end_entity=doc->queryEntityDirect(end_id);
value="-1";
if(!end_entity.isNull()&& end_entity->isValid()){
QString end_group=end_entity->getCustomProperty("app","group").toString();
value=end_entity->getCustomProperty(end_group,"uuid").toString();
lon=end_entity->getCustomProperty("app","lon").toString();
lat=end_entity->getCustomProperty("app","lat").toString();
}
//!终点
workSheet->write(row,col++,value);
//经度
workSheet->write(row,col++,lon);
//纬度
workSheet->write(row,col++,lat);
//高程
workSheet->write(row,col++," ");
//平面坐标
RVector v;
if(line->isValid()){
v= line->getStartPoint();
}
workSheet->write(row,col++,v.y);
workSheet->write(row,col++,v.x);
workSheet->write(row,col++,v.z);
if(line->isValid()){
v= line->getEndPoint();
}
workSheet->write(row,col++,v.y);
workSheet->write(row,col++,v.x);
workSheet->write(row,col++,v.z);
//写入动态字段
for(int i=0;i<fields.count();++i){
QJsonObject field=fields.at(i).toObject();
QString title=field.value("dataCode").toString();
value=entity->getCustomProperty(group,title).toString();
workSheet->write(row,col++,value);
}
row++;
}
}
暂无评论内容