diff --git a/.gitignore b/.gitignore index 740cefa..ebdc0a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .* !.gitignore *.user +build diff --git a/IndoorMapEditor.pro b/IndoorMapEditor.pro index 0259102..ad74453 100644 --- a/IndoorMapEditor.pro +++ b/IndoorMapEditor.pro @@ -40,7 +40,6 @@ SOURCES += main.cpp\ core/room.cpp \ gui/propviewroom.cpp \ core/feature.cpp \ - core/polygonfeature.cpp HEADERS += mainwindow.h \ core/building.h \ @@ -72,7 +71,6 @@ HEADERS += mainwindow.h \ core/room.h \ gui/propviewroom.h \ core/feature.h \ - core/polygonfeature.h FORMS += mainwindow.ui diff --git a/README.md b/README.md index 8cbdfb8..c46e2b9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,48 @@ -This is a simple editor for creating and editing indoor maps.\ -The data can be used in my [indoor3D](https://github.com/wolfwind521/indoor3D) project for visualization. +# 最近要落地 室内商场的三维展示 场景 ,于是在github上一顿找,没有找到好的。最符合的要求就是: -Now it can only export a json file by my own definition, but it will support the GeoJson format in the future. -More instructions are coming on the way. \ No newline at end of file +## indoor3D +### 基于原生js的以及比较低版本的three.js +https://github.com/wolfwind521/indoor3D + +### 它有配套的编辑器:基于qt5的c++ +https://github.com/wolfwind521/IndoorMapEditor + +## 它们也有各种衍生: + +### Angular版本的 也是早期node版本的 +https://github.com/tangerren/Indoor-Map +https://github.com/tangerren/Indoor-Map-Draw +未开发完成,也挺久的了 + +### 在展示的部分 增加了 shapefile格式 +https://github.com/tommy2gis/indoor3D +同样也是原生的,也挺久的了 + +## 采坑记录 +本方案是基于 wolfwind521/indoor3D 的一套 + +### 更新代码 [本项目master分支] +代码直接拉取后 发现了问题,因为是很早之前的代码了,使用的是qt5.x的版本 +我用的是maco15.1.1 arm的m1 ,原则上从codex和sdk都不太兼容 +所以使用最新的qt6.x,然后codex也是最新的,当然项目indoor3D函数也根据最新的qt6.x方式更改了,即目前看到的最新版本 +打包编译运行都可以了。 但是app很脆弱很容易崩亏。 + +### 匹配环境[本项目qt5.x分支] +所以想是不是更改代码或者本身项目升级就会出现问题,因为c++的程序嘛,对底层内存的控制不同cpu运算字符了,可能会有区别。 +就用x86的笔记本,虚拟了macos14.x版本的系统,安装了qt5.x的版本 codex 10的sdk +就是本项目qt5.x分支部分代码。 +同样打包编译运行都可以了。 但是app还是很脆弱很容易崩亏。 + +### 崩溃思考 +不管使用哪种方式,打开app后,新建项目随便新增编辑就会崩溃 +或者载入现有json数据文件,出来看不到商铺,编辑也会崩溃 +### 待优化 +如果有人熟悉qt的UI部分,看了报错信息,还是挺难调试的 +### 操作使用 +如果有人知道操作方法,也请issues告知大家 + +# 重构 three.js geojson +本人是tvt.js的作者:https://github.com/hawk86104/three-vue-tres +所以想在插件商场落地这个场景,看了数据结构后,还是想用通用的geojson格式的配置文件,通过tvt的底子来展示三维场景 +编辑器部分将使用通用的geojson编辑器 +已完成 详见 https://www.icegl.cn/tvtstore/networkLinkTopology.html diff --git a/core/building.cpp b/core/building.cpp index 1dcdb9e..319d6c9 100644 --- a/core/building.cpp +++ b/core/building.cpp @@ -191,8 +191,11 @@ bool Building::save(QJsonObject &jsonObject) const floorArray.append(floorObject); } } - qSort(tmpList); - foreach(int id, tmpList){ + // qSqrt(tmpList); + QList sqrtList; + std::transform(tmpList.begin(), tmpList.end(), std::back_inserter(sqrtList), + [](int value) { return qSqrt(value); }); + foreach(int id, sqrtList){ floorsId += QString::number(id) + ","; } @@ -296,7 +299,7 @@ void Building::setTel(const QString &tel){ } } -void Building::transformFeature(const QMatrix &matrix){ +void Building::transformFeature(const QTransform &matrix){ PolygonFeature::transformFeature(matrix); QList children = this->childItems(); diff --git a/core/building.h b/core/building.h index 1675235..b8de509 100644 --- a/core/building.h +++ b/core/building.h @@ -53,7 +53,7 @@ class Building : public PolygonFeature QVector getFloors(); Floor *getFloorById(int id); - virtual void transformFeature(const QMatrix &matrix); + virtual void transformFeature(const QTransform &matrix); private slots: void updateFloorIds(int oldId, int newId); diff --git a/core/feature.cpp b/core/feature.cpp index 70c0e0d..9e4cb7e 100644 --- a/core/feature.cpp +++ b/core/feature.cpp @@ -1,6 +1,8 @@ #include "feature.h" #include #include +#include +#include Feature::Feature(QGraphicsItem *parent) : QGraphicsObject(parent), m_type("0") @@ -22,7 +24,9 @@ const QString &Feature::brief() const int Feature::generateId(){ //利用时间生成6位id, 小概率生成同样id... - m_id = QDateTime::currentDateTime().toTime_t() % 1000000 + qrand()% 100000 + 1000000; + // m_id = QDateTime::currentDateTime().toTime_t() % 1000000 + qrand()% 100000 + 1000000; + // m_id = QDateTime::currentDateTime().toSecsSinceEpoch() % 1000000 + std::rand() % 100000 + 1000000; + m_id = QDateTime::currentDateTime().toSecsSinceEpoch() % 1000000 + QRandomGenerator::global()->bounded(100000) + 1000000; return m_id; } @@ -99,6 +103,10 @@ bool Feature::load(const QJsonObject &jsonObject) setObjectName( jsonObject["Name"].toString() ); m_enName = jsonObject["Name_en"].toString(); m_brief = jsonObject["Brief"].toString(); + + QTextStream out(stdout); + out << jsonObject["Name"].toString() << Qt::endl; + const QJsonArray & jsonArray = jsonObject["Center"].toArray(); if(jsonArray.size() == 2){ m_center = QPointF(jsonArray[0].toDouble(), -jsonArray[1].toDouble()); @@ -124,7 +132,7 @@ void Feature::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q } -void Feature::transformFeature(const QMatrix &matrix){ +void Feature::transformFeature(const QTransform &matrix){ m_center = matrix.map(m_center); emit centerChanged(m_center); } diff --git a/core/feature.h b/core/feature.h index bd8b08f..9b6ab55 100644 --- a/core/feature.h +++ b/core/feature.h @@ -46,7 +46,7 @@ class Feature : public QGraphicsObject virtual bool load(const QJsonObject & jsonObject); virtual bool save(QJsonObject & jsonObject) const; - virtual void transformFeature(const QMatrix &matrix); + virtual void transformFeature(const QTransform &matrix); virtual int generateId(); signals: void nameChanged(const QString & name); diff --git a/core/floor.cpp b/core/floor.cpp index 5b1fc1e..6bebd0b 100644 --- a/core/floor.cpp +++ b/core/floor.cpp @@ -135,7 +135,7 @@ QList Floor::getRooms() const{ } -void Floor::transformFeature(const QMatrix &mat) +void Floor::transformFeature(const QTransform &mat) { PolygonFeature::transformFeature(mat); diff --git a/core/floor.h b/core/floor.h index c982e37..c70e788 100644 --- a/core/floor.h +++ b/core/floor.h @@ -26,7 +26,7 @@ class Floor : public PolygonFeature static void resetMaxFloorId(); //transform - virtual void transformFeature(const QMatrix &matrix); + virtual void transformFeature(const QTransform &matrix); virtual int generateId(); signals: void heightChanged( double height ); diff --git a/core/polygonfeature.cpp b/core/polygonfeature.cpp index 482fe74..840c446 100644 --- a/core/polygonfeature.cpp +++ b/core/polygonfeature.cpp @@ -234,7 +234,7 @@ QPointF PolygonFeature::computeMainDir(){ return QPointF(double(obb.get_dir(0)[0]), double(obb.get_dir(0)[1])); } -void PolygonFeature::transformFeature(const QMatrix &matrix){ +void PolygonFeature::transformFeature(const QTransform &matrix){ Feature::transformFeature(matrix); m_outline = matrix.map(m_outline); computeArea(); diff --git a/core/polygonfeature.h b/core/polygonfeature.h index 753a0b2..954e66e 100644 --- a/core/polygonfeature.h +++ b/core/polygonfeature.h @@ -6,7 +6,6 @@ #include #include #include - class PolygonFeature : public Feature { Q_OBJECT @@ -62,7 +61,7 @@ class PolygonFeature : public Feature virtual bool load(const QJsonObject & jsonObject); virtual bool save(QJsonObject & jsonObject) const; - virtual void transformFeature(const QMatrix &matrix); + virtual void transformFeature(const QTransform &matrix); protected: double m_frontAngle; diff --git a/core/scene.cpp b/core/scene.cpp index 33020dc..9c61b0d 100644 --- a/core/scene.cpp +++ b/core/scene.cpp @@ -293,7 +293,7 @@ QList Scene::findMapFeature(const QString &name){ QList > Scene::findAllRepeat(){ QList > result; - QHash hash; + QMultiHash hash; if(m_building != NULL){ const QVector & floors = m_building->getFloors(); Floor* floor; @@ -304,7 +304,8 @@ QList > Scene::findAllRepeat(){ foreach (room, rooms) { QString name = room->objectName(); if(name.compare("非开放区域") && name.compare("中空") && name.compare("空铺")){ - hash.insertMulti(room->objectName(), room); + // hash.insertMulti(room->objectName(), room); + hash.insert(room->objectName(), room); } } @@ -333,7 +334,7 @@ void Scene::selectMapFeature(Feature *feature){ } } -void Scene::transformMap(const QMatrix &mat) +void Scene::transformMap(const QTransform &mat) { if(m_curFloor != NULL){//rotate current floor m_curFloor->transformFeature(mat); @@ -345,7 +346,7 @@ void Scene::transformMap(const QMatrix &mat) void Scene::addScale(double s) { m_scaleNum ++; double scale = (s*m_curScale + m_curScale*(m_scaleNum-1))/m_scaleNum; //相对于初始的平均缩放 - QMatrix mat; + QTransform mat; scale /= m_curScale; //相对于上一次的缩放 mat.scale(scale, scale); m_building->transformFeature(mat); diff --git a/core/scene.h b/core/scene.h index 38c7461..b110056 100644 --- a/core/scene.h +++ b/core/scene.h @@ -64,7 +64,7 @@ class Scene : public QGraphicsScene QList > findAllRepeat(); - void transformMap(const QMatrix &matrix); + void transformMap(const QTransform &matrix); void addScale(double s); void clearSelectedLayers(); void setSelectedLayer(Feature *feature); diff --git a/gui/documentview.cpp b/gui/documentview.cpp index a9aef06..b6a6a07 100644 --- a/gui/documentview.cpp +++ b/gui/documentview.cpp @@ -143,7 +143,8 @@ void DocumentView::printScene(QPrinter *printer){ QVector floors = m_scene->building()->getFloors(); m_scene->showFloor(floors[page-1]->id()); QRectF newRect = rect.united(m_scene->currentFloor()->boundingRect()); //unite the building rect with the floor rect - m_scene->render(&painter, printer->pageRect(), newRect, Qt::KeepAspectRatio); + // m_scene->render(&painter, printer->pageRect(), newRect, Qt::KeepAspectRatio); + m_scene->render(&painter, printer->pageRect(QPrinter::Millimeter), newRect, Qt::KeepAspectRatio); firstPage = false; } painter.end(); @@ -286,7 +287,8 @@ void DocumentView::keyReleaseEvent(QKeyEvent *event){ void DocumentView::wheelEvent(QWheelEvent *event){ if(m_ctrlKeyPressed){ - int numDegrees = event->delta() / 8; + // int numDegrees = event->delta() / 8; + int numDegrees = event->angleDelta().y() / 8; int numSteps = numDegrees / 15; zoom(numSteps); }else{ @@ -305,9 +307,10 @@ void DocumentView::zoomOut(int step){ void DocumentView::zoom(int step){ m_zoom += step; float scale = qPow(2.0, m_zoom / 50.0); - QMatrix matrix; + QTransform matrix; matrix.scale(scale, scale); - this->setMatrix(matrix); + // this->setMatrix(matrix); + this->setTransform(matrix); } void DocumentView::mousePressEvent(QMouseEvent *event){ @@ -318,7 +321,7 @@ void DocumentView::mousePressEvent(QMouseEvent *event){ void DocumentView::fitView(){ fitInView(m_scene->currentFloor()->boundingRect(),Qt::KeepAspectRatio); - qreal dx = matrix().m11(); + qreal dx = transform().m11(); m_zoom = qLn(dx)/qLn(2.0) * 50.0; } @@ -328,7 +331,7 @@ void DocumentView::onRotate(){ int angle = QInputDialog::getInt(this, tr("旋转地图"), tr("顺时针角度(0~360):"), 0, 0, 360, 1, &ok); if (ok){ - QMatrix mat; + QTransform mat; mat.rotate(angle); m_scene->transformMap(mat); } @@ -343,7 +346,7 @@ void DocumentView::onFlip(){ QString item = QInputDialog::getItem(this, tr("对称翻转"), tr("选择对称方向"), items, 0, false, &ok); if (ok && !item.isEmpty()){ - QMatrix mat; + QTransform mat; if(!item.compare(item1)){ mat.scale(-1, 1); }else if(!item.compare(item2)){ diff --git a/mainwindow.cpp b/mainwindow.cpp index 68ba4da..52bf696 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -33,6 +33,8 @@ #include #include #endif +#include + #pragma execution_character_set("utf-8") @@ -47,7 +49,8 @@ MainWindow::MainWindow(QWidget *parent) : m_searchResultIter(m_searchResults) { ui->setupUi(this); - qsrand(time(0)); + // srand(time(0)); + arc4random(); m_sceneTreeView = new QTreeView(ui->dockTreeWidget); ui->verticalLayout->insertWidget(0,m_sceneTreeView); diff --git a/tool/splittool.cpp b/tool/splittool.cpp index e9cd223..79c36be 100644 --- a/tool/splittool.cpp +++ b/tool/splittool.cpp @@ -154,7 +154,7 @@ bool Split::intersect(QPointF &crossPoint, const QPoint &polyPoint1, const QPoin QLineF l1(polyPoint1, polyPoint2); QLineF l2(linePoint1, linePoint2); - return l1.intersect(l2, &crossPoint) == QLineF::BoundedIntersection; + return l1.intersects(l2, &crossPoint) == QLineF::BoundedIntersection; } bool Split::isBetween(const QPoint &p0, const QPoint &p1, const QPoint &p2) {