From 4d23bf4d5f94564383b4189040635d2282b9b464 Mon Sep 17 00:00:00 2001 From: Petros Koutsolampros Date: Sun, 27 Jan 2019 05:14:57 +0000 Subject: [PATCH 1/3] Spin out a new type of map for Traces That allows for also storing the time of each step in the path --- depthmapX/GraphDoc.cpp | 14 +- depthmapX/dialogs/ColourScaleDlg.cpp | 14 ++ depthmapX/mainwindow.cpp | 94 +++++++- depthmapX/views/depthmapview/depthmapview.cpp | 15 +- depthmapX/views/glview/glview.cpp | 14 ++ depthmapX/views/glview/glview.h | 1 + salalib/mgraph.cpp | 205 ++++++++++++++++-- salalib/mgraph.h | 65 +++++- salalib/nagent.cpp | 16 +- salalib/nagent.h | 4 +- salalib/salalib.pro | 6 +- salalib/shapemap.h | 2 +- salalib/tracemap.cpp | 65 ++++++ salalib/tracemap.h | 34 +++ 14 files changed, 517 insertions(+), 32 deletions(-) create mode 100644 salalib/tracemap.cpp create mode 100644 salalib/tracemap.h diff --git a/depthmapX/GraphDoc.cpp b/depthmapX/GraphDoc.cpp index 8caf3b3b..85a123f9 100644 --- a/depthmapX/GraphDoc.cpp +++ b/depthmapX/GraphDoc.cpp @@ -168,6 +168,9 @@ void QGraphDoc::UpdateMainframestatus() else if ((state & MetaGraph::DATAMAPS) && m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { n = (int) m_meta_graph->getDisplayedDataMap().getShapeCount(); } + else if ((state & MetaGraph::TRACEMAPS) && m_meta_graph->getViewClass() & MetaGraph::VIEWTRACES) { + n = (int) m_meta_graph->getDisplayedTraceMap().getShapeCount(); + } // either showing or constructing the VGA graph else if ((state & MetaGraph::POINTMAPS) && m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { n = (int) m_meta_graph->getDisplayedPointMap().getFilledPointCount(); @@ -1612,6 +1615,9 @@ void QGraphDoc::OnEditClear() else if (m_meta_graph->viewingProcessedShapes()) { modified = m_meta_graph->getDisplayedDataMap().removeSelected(); } + else if (m_meta_graph->viewingProcessedShapes()) { + modified = m_meta_graph->getDisplayedTraceMap().removeSelected(); + } if(modified) { modifiedFlag = true; @@ -2152,6 +2158,9 @@ void QGraphDoc::OnUpdateColumn() else if (vc & MetaGraph::VIEWDATA) { shapemap = &(m_meta_graph->getDisplayedDataMap()); } + else if (vc & MetaGraph::VIEWTRACES) { + shapemap = &(m_meta_graph->getDisplayedTraceMap()); + } if (ReplaceColumnContents(pointmap,shapemap,col)) { m_meta_graph->setDisplayedAttribute(col); @@ -2242,6 +2251,9 @@ void QGraphDoc::OnEditQuery() else if (vc & MetaGraph::VIEWDATA) { shapemap = &(m_meta_graph->getDisplayedDataMap()); } + else if (vc & MetaGraph::VIEWTRACES) { + shapemap = &(m_meta_graph->getDisplayedTraceMap()); + } if (SelectByQuery(pointmap,shapemap)) { SetRedrawFlag(VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); @@ -2321,7 +2333,7 @@ bool QGraphDoc::SelectByQuery(PointMap *pointmap, ShapeMap *shapemap) void QGraphDoc::OnEditSelectToLayer() { - if ((m_meta_graph->getViewClass() & (MetaGraph::VIEWAXIAL|MetaGraph::VIEWDATA)) + if ((m_meta_graph->getViewClass() & (MetaGraph::VIEWAXIAL|MetaGraph::VIEWDATA|MetaGraph::VIEWTRACES)) && m_meta_graph->isSelected()) { CRenameObjectDlg dlg("Layer"); // note, without specifying existing layer name, this defaults to "New layer" behaviour diff --git a/depthmapX/dialogs/ColourScaleDlg.cpp b/depthmapX/dialogs/ColourScaleDlg.cpp index 8dd9c724..c6ce99de 100644 --- a/depthmapX/dialogs/ColourScaleDlg.cpp +++ b/depthmapX/dialogs/ColourScaleDlg.cpp @@ -332,6 +332,16 @@ void CColourScaleDlg::MyUpdateData(bool dir, bool apply_to_all) map.getPolygonDisplay(show_lines,show_fill,show_centroids); m_show_lines = show_lines; m_show_fill = show_fill; m_show_centroids = show_centroids; } + else if (graph->getViewClass() & MetaGraph::VIEWTRACES) { + ShapeMap& map = graph->getDisplayedTraceMap(); + m_display_min = map.getDisplayMinValue(); + m_display_max = map.getDisplayMaxValue(); + m_displayparams = map.getDisplayParams(); + m_color = m_displayparams.colorscale; + bool show_lines = m_show_lines, show_fill = m_show_fill, show_centroids = m_show_centroids; + map.getPolygonDisplay(show_lines,show_fill,show_centroids); + m_show_lines = show_lines; m_show_fill = show_fill; m_show_centroids = show_centroids; + } for (size_t i = 0; i < m_color_type_map.size(); i++) { if (m_color == m_color_type_map[i]) { c_color_type->setCurrentIndex(i); @@ -364,6 +374,10 @@ void CColourScaleDlg::MyUpdateData(bool dir, bool apply_to_all) graph->getDisplayedDataMap().setDisplayParams( m_displayparams, apply_to_all ); graph->getDisplayedDataMap().setPolygonDisplay(m_show_lines,m_show_fill,m_show_centroids); } + else if (graph->getViewClass() & MetaGraph::VIEWTRACES) { + graph->getDisplayedTraceMap().setDisplayParams( m_displayparams, apply_to_all ); + graph->getDisplayedTraceMap().setPolygonDisplay(m_show_lines,m_show_fill,m_show_centroids); + } } m_viewDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP); } diff --git a/depthmapX/mainwindow.cpp b/depthmapX/mainwindow.cpp index 33472ff2..702e5751 100644 --- a/depthmapX/mainwindow.cpp +++ b/depthmapX/mainwindow.cpp @@ -1341,6 +1341,21 @@ void MainWindow::OnSelchangingTree(QTreeWidgetItem* hItem, int col) } remenu = true; break; + case 3: + if (graph->getViewClass() & MetaGraph::VIEWTRACES) { + if (graph->getDisplayedTraceMapRef() == entry.m_cat) { + graph->setViewClass(MetaGraph::SHOWHIDETRACES); + } + else { + graph->setDisplayedTraceMapRef(entry.m_cat); + } + } + else { + graph->setDisplayedTraceMapRef(entry.m_cat); + graph->setViewClass(MetaGraph::SHOWTRACESTOP); + } + remenu = true; + break; case 4: // slightly different for this one break; @@ -1365,6 +1380,10 @@ void MainWindow::OnSelchangingTree(QTreeWidgetItem* hItem, int col) graph->getDataMaps()[entry.m_cat].setEditable(m_indexWidget->isItemSetEditable(hItem)); update = true; } + if (entry.m_type == 3) { + graph->getTraceMaps()[entry.m_cat].setEditable(m_indexWidget->isItemSetEditable(hItem)); + update = true; + } if (update) { // Depending on if the map is displayed you may have to redraw -- I'm just going to redraw *anyway* // (it may be worth switching it to topmost when they do click here) @@ -1381,6 +1400,10 @@ void MainWindow::OnSelchangingTree(QTreeWidgetItem* hItem, int col) update = true; graph->getDataMaps()[entry.m_cat].setLayerVisible(entry.m_subcat, m_indexWidget->isItemSetVisible(hItem)); } + else if (entry.m_type == 3) { + update = true; + graph->getTraceMaps()[entry.m_cat].setLayerVisible(entry.m_subcat, m_indexWidget->isItemSetVisible(hItem)); + } if (update) { m_treeDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_TABLE ); OnFocusGraph(m_treeDoc, QGraphDoc::CONTROLS_CHANGEATTRIBUTE); @@ -1452,6 +1475,16 @@ void MainWindow::SetGraphTreeChecks() m_backgraph = key; } break; + case 3: + if (viewclass & MetaGraph::VIEWTRACES && graph->getDisplayedTraceMapRef() == entry.m_cat) { + checkstyle = 5; + m_topgraph = key; + } + else if (viewclass & MetaGraph::VIEWBACKTRACES && graph->getDisplayedTraceMapRef() == entry.m_cat) { + checkstyle = 6; + m_backgraph = key; + } + break; } if(checkstyle == 5) @@ -1486,6 +1519,9 @@ void MainWindow::SetGraphTreeChecks() case 2: editable = graph->getDataMaps()[entry.m_cat].isEditable() ? MetaGraph::EDITABLE_ON : MetaGraph::EDITABLE_OFF; break; + case 3: + editable = graph->getTraceMaps()[entry.m_cat].isEditable() ? MetaGraph::EDITABLE_ON : MetaGraph::EDITABLE_OFF; + break; } switch (editable) { case MetaGraph::NOT_EDITABLE: @@ -1509,6 +1545,9 @@ void MainWindow::SetGraphTreeChecks() else if (entry.m_type == 2) { show = graph->getDataMaps()[entry.m_cat].isLayerVisible(entry.m_subcat); } + else if (entry.m_type == 3) { + show = graph->getTraceMaps()[entry.m_cat].isLayerVisible(entry.m_subcat); + } if (show) { m_indexWidget->setItemVisibility(key, Qt::Checked); } @@ -1545,7 +1584,7 @@ void MainWindow::ClearGraphTree() { m_attribute_locked.clear(); - for (int i = 2; i >= 0; i--) { + for (int i = 3; i >= 0; i--) { if (m_treeroots[i]) { m_treeroots[i] = NULL; } @@ -1659,6 +1698,44 @@ void MainWindow::MakeGraphTree() m_treeroots[2] = NULL; } + + if (state & MetaGraph::TRACEMAPS) { + if (!m_treeroots[3]) { + QTreeWidgetItem* hItem = m_indexWidget->addNewItem(tr("Trace Maps")); + hItem->setIcon(0, m_tree_icon[2]); + ItemTreeEntry entry(3,-1,-1); + m_treegraphmap[hItem] = entry; + m_treeroots[3] = hItem; + } + for (size_t i = 0; i < m_treeDoc->m_meta_graph->getTraceMaps().size(); i++) { + QString name = QString(m_treeDoc->m_meta_graph->getTraceMaps()[i].getName().c_str()); + QTreeWidgetItem* hItem = m_indexWidget->addNewItem(name, m_treeroots[3]); + m_indexWidget->setItemVisibility(hItem, Qt::Unchecked); + m_indexWidget->setItemEditability(hItem, Qt::Unchecked); + ItemTreeEntry entry(3,(short)i,-1); + m_treegraphmap[hItem] = entry; + + AttributeTable& table = m_treeDoc->m_meta_graph->getTraceMaps()[i].getAttributeTable(); + if(table.getLayerCount() > 1) { + for (int j = 0; j < table.getLayerCount(); j++) { + QString name = QString(table.getLayerName(j).c_str()); + QTreeWidgetItem* hNewItem = m_indexWidget->addNewItem(name, hItem); + m_indexWidget->setItemVisibility(hNewItem, Qt::Unchecked); + ItemTreeEntry entry(3,(short)i,j); + m_treegraphmap.insert(std::make_pair(hNewItem,entry)); + } + } + } + } + else if (m_treeroots[3]) { + m_treeroots[3]->removeChild(m_treeroots[3]); + auto iter = m_treegraphmap.find(m_treeroots[3]); + if(iter != m_treegraphmap.end()) { + m_treegraphmap.erase(iter); + } + m_treeroots[3] = NULL; + } + SetGraphTreeChecks(); } @@ -2178,7 +2255,7 @@ void MainWindow::RedoPlotViewMenu(QGraphDoc* pDoc) in_FocusGraph = true; // this will be used to distinguish between viewing VGA and axial maps - int view_class = pDoc->m_meta_graph->getViewClass() & (MetaGraph::VIEWVGA | MetaGraph::VIEWAXIAL | MetaGraph::VIEWDATA); + int view_class = pDoc->m_meta_graph->getViewClass() & (MetaGraph::VIEWVGA | MetaGraph::VIEWAXIAL | MetaGraph::VIEWDATA | MetaGraph::VIEWTRACES); int curr_j = 0; { @@ -2224,6 +2301,19 @@ void MainWindow::RedoPlotViewMenu(QGraphDoc* pDoc) } } } + else if (view_class == MetaGraph::VIEWTRACES) { + // using attribute tables is very, very simple... + const ShapeMap& map = pDoc->m_meta_graph->getDisplayedTraceMap(); + const AttributeTable& table = map.getAttributeTable(); + m_view_map_entries.insert(std::make_pair(0, "Ref Number")); + curr_j = 0; + for (int i = 0; i < table.getColumnCount(); i++) { + m_view_map_entries.insert(std::make_pair(i+1, table.getColumnName(i))); + if (map.getDisplayedAttribute() == i) { + curr_j = i + 1; + } + } + } } } diff --git a/depthmapX/views/depthmapview/depthmapview.cpp b/depthmapX/views/depthmapview/depthmapview.cpp index c4caf498..d002cd97 100644 --- a/depthmapX/views/depthmapview/depthmapview.cpp +++ b/depthmapX/views/depthmapview/depthmapview.cpp @@ -396,7 +396,7 @@ void QDepthmapView::paintEvent(QPaintEvent *) rect = QRect(0, 0, width(), height()); m_redraw = true; - if (!m_viewport_set && state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS)) { + if (!m_viewport_set && state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS | MetaGraph::TRACEMAPS)) { InitViewport(rect, &m_pDoc); } if (m_redraw_all) { @@ -417,7 +417,7 @@ void QDepthmapView::paintEvent(QPaintEvent *) m_internal_redraw = false; // if redraw signalled: - if (m_redraw && (state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS)) && m_viewport_set) { + if (m_redraw && (state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS | MetaGraph::TRACEMAPS)) && m_viewport_set) { // note that the redraw rect is dependent on the cleared portion above // note you *must* check *state* before drawing, you cannot rely on view_class as it can be set up before the layer is ready to draw: @@ -434,6 +434,9 @@ void QDepthmapView::paintEvent(QPaintEvent *) if (state & MetaGraph::DATAMAPS && (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWBACKDATA | MetaGraph::VIEWDATA))) { m_pDoc.m_meta_graph->getDisplayedDataMap().makeViewportShapes( LogicalViewport(rect, &m_pDoc) ); } + if (state & MetaGraph::TRACEMAPS && (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWBACKTRACES | MetaGraph::VIEWTRACES))) { + m_pDoc.m_meta_graph->getDisplayedTraceMap().makeViewportShapes( LogicalViewport(rect, &m_pDoc) ); + } if (state & MetaGraph::LINEDATA) { m_pDoc.m_meta_graph->makeViewportShapes( LogicalViewport(rect, &m_pDoc) ); } @@ -449,7 +452,7 @@ void QDepthmapView::paintEvent(QPaintEvent *) } // If the meta graph (at least) contains a DXF, draw it: - if (m_continue_drawing && (state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS)) && m_viewport_set) + if (m_continue_drawing && (state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS | MetaGraph::TRACEMAPS)) && m_viewport_set) { if (Output(&pDC, &m_pDoc, true)) { @@ -1738,6 +1741,9 @@ void QDepthmapView::OutputEPS( std::ofstream& stream, QGraphDoc *pDoc, bool incl if (state & MetaGraph::DATAMAPS) { pDoc->m_meta_graph->getDisplayedDataMap().makeViewportShapes( logicalviewport ); } + if (state & MetaGraph::TRACEMAPS) { + pDoc->m_meta_graph->getDisplayedTraceMap().makeViewportShapes( logicalviewport ); + } if (state & MetaGraph::LINEDATA) { pDoc->m_meta_graph->makeViewportShapes( logicalviewport ); } @@ -2373,6 +2379,9 @@ void QDepthmapView::OnEditCopy() if (state & MetaGraph::DATAMAPS && (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWBACKDATA | MetaGraph::VIEWDATA))) { m_pDoc.m_meta_graph->getDisplayedDataMap().makeViewportShapes( LogicalViewport(rectin, &m_pDoc) ); } + if (state & MetaGraph::TRACEMAPS && (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWBACKTRACES | MetaGraph::VIEWTRACES))) { + m_pDoc.m_meta_graph->getDisplayedTraceMap().makeViewportShapes( LogicalViewport(rectin, &m_pDoc) ); + } if (state & MetaGraph::LINEDATA) { m_pDoc.m_meta_graph->makeViewportShapes( LogicalViewport(rectin, &m_pDoc) ); } diff --git a/depthmapX/views/glview/glview.cpp b/depthmapX/views/glview/glview.cpp index f8a3b162..87c06e86 100644 --- a/depthmapX/views/glview/glview.cpp +++ b/depthmapX/views/glview/glview.cpp @@ -64,6 +64,9 @@ GLView::GLView(QGraphDoc &pDoc, m_visibleDataMap.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedDataMap()); } + if(m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWTRACES) { + m_visibleTraceMap.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedTraceMap()); + } m_dragLine.setStrokeColour(m_foreground); m_selectionRect.setStrokeColour(m_background); @@ -84,6 +87,7 @@ GLView::~GLView() m_visiblePointMap.cleanup(); m_visibleShapeGraph.cleanup(); m_visibleDataMap.cleanup(); + m_visibleTraceMap.cleanup(); doneCurrent(); m_settings.writeSetting(SettingTag::depthmapViewSize, size()); } @@ -110,6 +114,7 @@ void GLView::initializeGL() m_visiblePointMap.initializeGL(m_core); m_visibleShapeGraph.initializeGL(m_core); m_visibleDataMap.initializeGL(m_core); + m_visibleTraceMap.initializeGL(m_core); if(m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { m_visiblePointMap.loadGLObjectsRequiringGLContext(m_pDoc.m_meta_graph->getDisplayedPointMap()); @@ -145,6 +150,11 @@ void GLView::paintGL() m_visibleDataMap.updateGL(m_core); } + if(m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWTRACES) { + m_visibleTraceMap.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedTraceMap()); + m_visibleTraceMap.updateGL(m_core); + } + if(m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { m_visiblePointMap.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedPointMap()); m_visiblePointMap.updateGL(m_core); @@ -169,6 +179,10 @@ void GLView::paintGL() m_visibleDataMap.paintGL(m_mProj, m_mView, m_mModel); } + if(m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWTRACES) { + m_visibleTraceMap.paintGL(m_mProj, m_mView, m_mModel); + } + m_visibleDrawingLines.paintGL(m_mProj, m_mView, m_mModel); if(m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { diff --git a/depthmapX/views/glview/glview.h b/depthmapX/views/glview/glview.h index 413c8f57..b3bee0bc 100644 --- a/depthmapX/views/glview/glview.h +++ b/depthmapX/views/glview/glview.h @@ -100,6 +100,7 @@ class GLView : public MapView, protected QOpenGLFunctions GLLinesUniform m_visibleDrawingLines; GLPointMap m_visiblePointMap; GLShapeMap m_visibleDataMap; + GLShapeMap m_visibleTraceMap; QPoint m_mouseLastPos; float m_eyePosX; diff --git a/salalib/mgraph.cpp b/salalib/mgraph.cpp index 86cc35eb..0e0edcfb 100644 --- a/salalib/mgraph.cpp +++ b/salalib/mgraph.cpp @@ -99,6 +99,9 @@ QtRegion MetaGraph::getBoundingBox() const if (bounds.atZero() && ((getState() & MetaGraph::DATAMAPS) == MetaGraph::DATAMAPS)) { bounds = getDisplayedDataMap().getRegion(); } + if (bounds.atZero() && ((getState() & MetaGraph::TRACEMAPS) == MetaGraph::TRACEMAPS)) { + bounds = getDisplayedTraceMap().getRegion(); + } return bounds; } @@ -113,6 +116,8 @@ bool MetaGraph::setViewClass(int command) return false; if ((command & (SHOWHIDESHAPE | SHOWSHAPETOP)) && (~m_state & DATAMAPS)) return false; + if ((command & (SHOWHIDETRACES | SHOWTRACESTOP)) && (~m_state & TRACEMAPS)) + return false; switch (command) { case SHOWHIDEVGA: if (m_view_class & (VIEWVGA | VIEWBACKVGA)) { @@ -123,9 +128,12 @@ bool MetaGraph::setViewClass(int command) else if (m_view_class & VIEWBACKDATA) { m_view_class ^= (VIEWDATA | VIEWBACKDATA); } + else if (m_view_class & VIEWBACKTRACES) { + m_view_class ^= (VIEWTRACES | VIEWBACKTRACES); + } } - else if (m_view_class & (VIEWAXIAL | VIEWDATA)) { - m_view_class &= ~(VIEWBACKAXIAL | VIEWBACKDATA); + else if (m_view_class & (VIEWAXIAL | VIEWDATA | VIEWTRACES)) { + m_view_class &= ~(VIEWBACKAXIAL | VIEWBACKDATA | VIEWBACKTRACES); m_view_class |= VIEWBACKVGA; } else { @@ -141,9 +149,12 @@ bool MetaGraph::setViewClass(int command) else if (m_view_class & VIEWBACKDATA) { m_view_class ^= (VIEWDATA | VIEWBACKDATA); } + else if (m_view_class & VIEWBACKTRACES) { + m_view_class ^= (VIEWTRACES | VIEWBACKTRACES); + } } - else if (m_view_class & (VIEWVGA | VIEWDATA)) { - m_view_class &= ~(VIEWBACKVGA | VIEWBACKDATA); + else if (m_view_class & (VIEWVGA | VIEWDATA | VIEWTRACES)) { + m_view_class &= ~(VIEWBACKVGA | VIEWBACKDATA | VIEWBACKTRACES); m_view_class |= VIEWBACKAXIAL; } else { @@ -159,15 +170,39 @@ bool MetaGraph::setViewClass(int command) else if (m_view_class & VIEWBACKAXIAL) { m_view_class ^= (VIEWAXIAL | VIEWBACKAXIAL); } + else if (m_view_class & VIEWBACKTRACES) { + m_view_class ^= (VIEWTRACES | VIEWBACKTRACES); + } } - else if (m_view_class & (VIEWVGA | VIEWAXIAL)) { - m_view_class &= ~(VIEWBACKVGA | VIEWBACKAXIAL); + else if (m_view_class & (VIEWVGA | VIEWAXIAL | VIEWTRACES)) { + m_view_class &= ~(VIEWBACKVGA | VIEWBACKAXIAL | VIEWBACKTRACES); m_view_class |= VIEWBACKDATA; } else { m_view_class |= VIEWDATA; } break; + case SHOWHIDETRACES: + if (m_view_class & (VIEWTRACES | VIEWBACKTRACES)) { + m_view_class &= ~(VIEWTRACES | VIEWBACKTRACES); + if (m_view_class & VIEWBACKVGA) { + m_view_class ^= (VIEWVGA | VIEWBACKVGA); + } + else if (m_view_class & VIEWBACKAXIAL) { + m_view_class ^= (VIEWAXIAL | VIEWBACKAXIAL); + } + else if (m_view_class & VIEWBACKDATA) { + m_view_class ^= (VIEWDATA | VIEWBACKDATA); + } + } + else if (m_view_class & (VIEWVGA | VIEWAXIAL | VIEWDATA)) { + m_view_class &= ~(VIEWBACKVGA | VIEWBACKAXIAL | VIEWBACKDATA); + m_view_class |= VIEWBACKTRACES; + } + else { + m_view_class |= VIEWTRACES; + } + break; case SHOWVGATOP: if (m_view_class & VIEWAXIAL) { m_view_class = VIEWBACKAXIAL | VIEWVGA; @@ -175,8 +210,11 @@ bool MetaGraph::setViewClass(int command) else if (m_view_class & VIEWDATA) { m_view_class = VIEWBACKDATA | VIEWVGA; } + else if (m_view_class & VIEWTRACES) { + m_view_class = VIEWBACKTRACES | VIEWVGA; + } else { - m_view_class = VIEWVGA | (m_view_class & (VIEWBACKAXIAL | VIEWBACKDATA)); + m_view_class = VIEWVGA | (m_view_class & (VIEWBACKAXIAL | VIEWBACKDATA | VIEWBACKTRACES)); } break; case SHOWAXIALTOP: @@ -186,8 +224,11 @@ bool MetaGraph::setViewClass(int command) else if (m_view_class & VIEWDATA) { m_view_class = VIEWBACKDATA | VIEWAXIAL; } + else if (m_view_class & VIEWTRACES) { + m_view_class = VIEWBACKTRACES | VIEWAXIAL; + } else { - m_view_class = VIEWAXIAL | (m_view_class & (VIEWBACKVGA | VIEWBACKDATA)); + m_view_class = VIEWAXIAL | (m_view_class & (VIEWBACKVGA | VIEWBACKDATA | VIEWBACKTRACES)); } break; case SHOWSHAPETOP: @@ -197,8 +238,25 @@ bool MetaGraph::setViewClass(int command) else if (m_view_class & VIEWAXIAL) { m_view_class = VIEWBACKAXIAL | VIEWDATA; } + else if (m_view_class & VIEWTRACES) { + m_view_class = VIEWBACKTRACES | VIEWDATA; + } else { - m_view_class = VIEWDATA | (m_view_class & (VIEWBACKVGA | VIEWBACKAXIAL)); + m_view_class = VIEWDATA | (m_view_class & (VIEWBACKVGA | VIEWBACKAXIAL | VIEWBACKTRACES)); + } + break; + case SHOWTRACESTOP: + if (m_view_class & VIEWVGA) { + m_view_class = VIEWBACKVGA | VIEWTRACES; + } + else if (m_view_class & VIEWAXIAL) { + m_view_class = VIEWBACKAXIAL | VIEWTRACES; + } + else if (m_view_class & VIEWDATA) { + m_view_class = VIEWBACKDATA | VIEWTRACES; + } + else { + m_view_class = VIEWTRACES | (m_view_class & (VIEWBACKVGA | VIEWBACKAXIAL | VIEWBACKDATA)); } break; } @@ -219,6 +277,9 @@ double MetaGraph::getLocationValue(const Point2f& point) else if (viewingProcessedShapes()) { val = getDisplayedDataMap().getLocationValue(point); } + else if (viewingProcessedTraces()) { + val = getDisplayedTraceMap().getLocationValue(point); + } return val; } @@ -377,6 +438,9 @@ bool MetaGraph::isEditableMap() else if (m_view_class & VIEWDATA) { return getDisplayedDataMap().isEditable(); } + else if (m_view_class & VIEWTRACES) { + return getDisplayedDataMap().isEditable(); + } // still to do: allow editing of drawing layers return false; } @@ -390,6 +454,9 @@ ShapeMap& MetaGraph::getEditableMap() else if (m_view_class & VIEWDATA) { map = &(getDisplayedDataMap()); } + else if (m_view_class & VIEWTRACES) { + map = &(getDisplayedDataMap()); + } else { // still to do: allow editing of drawing layers } @@ -477,6 +544,21 @@ bool MetaGraph::moveSelShape(const Line& line) map.clearSel(); } } + else if (m_view_class & VIEWTRACES) { + TraceMap& map = getDisplayedTraceMap(); + if (!map.isEditable()) { + return false; + } + if (map.getSelCount() > 1) { + return false; + } + // note, selection sets currently store rowids not uids, but moveShape sensibly works off uid: + int rowid = *map.getSelSet().begin(); + retvar = map.moveShape(map.getIndex(rowid),line); + if (retvar) { + map.clearSel(); + } + } return retvar; } @@ -543,6 +625,9 @@ int MetaGraph::makeIsovistPath(Communicator *communicator, double fov, bool simp else if (viewclass == VIEWDATA) { map = &getDisplayedDataMap(); } + else if (viewclass == VIEWTRACES) { + map = &getDisplayedDataMap(); + } else { return 0; } @@ -742,6 +827,13 @@ void MetaGraph::removeDisplayedMap() m_state &= ~DATAMAPS; } break; + case VIEWTRACES: + removeTraceMap(ref); + if (m_traceMaps.empty()) { + setViewClass(SHOWHIDETRACES); + m_state &= ~TRACEMAPS; + } + break; } } @@ -1946,13 +2038,20 @@ void MetaGraph::runAgentEngine(Communicator *comm) if(m_agent_engine.m_record_trails) { std::string mapName = "Agent Trails"; int count = 1; - while(std::find_if(std::begin(m_dataMaps), std::end(m_dataMaps), - [&] (ShapeMap const& m) {return m.getName() == mapName; }) != m_dataMaps.end()) { + while(std::find_if(std::begin(m_traceMaps), std::end(m_traceMaps), + [&] (ShapeMap const& m) {return m.getName() == mapName; }) != m_traceMaps.end()) { mapName = "Agent Trails " + std::to_string(count); count++; } - m_dataMaps.push_back(m_agent_engine.getTrailsAsMap(mapName)); - m_state |= DATAMAPS; + m_traceMaps.push_back(m_agent_engine.getTrailsAsMap(mapName)); + m_state |= TRACEMAPS; +// setViewClass(SHOWTRACESTOP); +// setDisplayedTraceMapRef(m_traceMaps.size() -1); + +// SetUpdateFlag(NEW_TABLE); +// SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH, NEW_DATA); +// m_dataMaps.push_back(m_agent_engine.getTrailsAsMap(mapName)); +// m_state |= DATAMAPS; } if (m_agent_engine.m_gatelayer != -1) { @@ -2031,6 +2130,9 @@ int MetaGraph::getDisplayedMapRef() const case VIEWDATA: ref = getDisplayedDataMapRef(); break; + case VIEWTRACES: + ref = getDisplayedTraceMapRef(); + break; } return ref; } @@ -2047,6 +2149,8 @@ int MetaGraph::getDisplayedMapType() return getDisplayedShapeGraph().getMapType(); case VIEWDATA: return getDisplayedDataMap().getMapType(); + case VIEWTRACES: + return getDisplayedTraceMap().getMapType(); } return ShapeMap::EMPTYMAP; } @@ -2089,6 +2193,9 @@ int MetaGraph::isEditable() const case VIEWDATA: editable = getDisplayedDataMap().isEditable() ? EDITABLE_ON : EDITABLE_OFF; break; + case VIEWTRACES: + editable = getDisplayedTraceMap().isEditable() ? EDITABLE_ON : EDITABLE_OFF; + break; } return editable; } @@ -2106,6 +2213,9 @@ bool MetaGraph::canUndo() const case VIEWDATA: canundo = getDisplayedDataMap().canUndo(); break; + case VIEWTRACES: + canundo = getDisplayedTraceMap().canUndo(); + break; } return canundo; } @@ -2122,6 +2232,9 @@ void MetaGraph::undo() case VIEWDATA: getDisplayedDataMap().undo(); break; + case VIEWTRACES: + getDisplayedTraceMap().undo(); + break; } } @@ -2140,6 +2253,9 @@ int MetaGraph::addAttribute(const std::string& name) case VIEWDATA: col = getDisplayedDataMap().addAttribute(name); break; + case VIEWTRACES: + col = getDisplayedTraceMap().addAttribute(name); + break; } return col; } @@ -2156,6 +2272,9 @@ void MetaGraph::removeAttribute(int col) case VIEWDATA: getDisplayedDataMap().removeAttribute(col); break; + case VIEWTRACES: + getDisplayedTraceMap().removeAttribute(col); + break; } } @@ -2177,6 +2296,9 @@ int MetaGraph::getDisplayedAttribute() const case VIEWDATA: col = getDisplayedDataMap().getDisplayedAttribute(); break; + case VIEWTRACES: + col = getDisplayedTraceMap().getDisplayedAttribute(); + break; } return col; } @@ -2197,6 +2319,10 @@ void MetaGraph::setDisplayedAttribute(int col) getDisplayedDataMap().overrideDisplayedAttribute(-2); getDisplayedDataMap().setDisplayedAttribute(col); break; + case VIEWTRACES: + getDisplayedTraceMap().overrideDisplayedAttribute(-2); + getDisplayedTraceMap().setDisplayedAttribute(col); + break; } } @@ -2218,6 +2344,9 @@ AttributeTable& MetaGraph::getAttributeTable(int type, int layer) case VIEWDATA: tab = (layer == -1) ? &(getDisplayedDataMap().getAttributeTable()) : &(m_dataMaps[layer].getAttributeTable()); break; + case VIEWTRACES: + tab = (layer == -1) ? &(getDisplayedTraceMap().getAttributeTable()) : &(m_traceMaps[layer].getAttributeTable()); + break; } return *tab; } @@ -2238,6 +2367,9 @@ const AttributeTable& MetaGraph::getAttributeTable(int type, int layer) const case VIEWDATA: tab = layer == -1 ? &(getDisplayedDataMap().getAttributeTable()) : &(m_dataMaps[layer].getAttributeTable()); break; + case VIEWTRACES: + tab = layer == -1 ? &(getDisplayedTraceMap().getAttributeTable()) : &(m_traceMaps[layer].getAttributeTable()); + break; } return *tab; } @@ -2667,6 +2799,53 @@ bool MetaGraph::writeDataMaps( std::ofstream& stream, int version, bool displaye } +bool MetaGraph::readTraceMaps(std::istream& stream, int version ) +{ + m_traceMaps.clear(); // empty existing data + // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems + unsigned int displayed_map; + stream.read((char *)&displayed_map,sizeof(displayed_map)); + m_displayed_tracemap = size_t(displayed_map); + // read maps + // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems + unsigned int count = 0; + stream.read((char *) &count, sizeof(count)); + + for (size_t j = 0; j < size_t(count); j++) { + m_traceMaps.emplace_back(); + m_traceMaps.back().read(stream,version); + } + return true; +} + +bool MetaGraph::writeTraceMaps( std::ofstream& stream, int version, bool displayedmaponly ) +{ + if (!displayedmaponly) { + // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems + unsigned int displayed_map = (unsigned int)(m_displayed_tracemap); + stream.write((char *)&displayed_map,sizeof(displayed_map)); + // write maps + // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems + unsigned int count = (unsigned int) m_traceMaps.size(); + stream.write((char *) &count, sizeof(count)); + for (size_t j = 0; j < count; j++) { + m_traceMaps[j].write(stream,version); + } + } + else { + unsigned int dummy; + // displayed map is 0 + dummy = 0; + stream.write((char *)&dummy,sizeof(dummy)); + // count is 1 + dummy = 1; + stream.write((char *)&dummy,sizeof(dummy)); + // write map: + m_traceMaps[m_displayed_tracemap].write(stream,version); + } + return true; +} + bool MetaGraph::readShapeGraphs(std::istream& stream, int version ) { m_shapeGraphs.clear(); // empty existing data diff --git a/salalib/mgraph.h b/salalib/mgraph.h index 1c78e997..dae40de9 100644 --- a/salalib/mgraph.h +++ b/salalib/mgraph.h @@ -23,6 +23,7 @@ #include "salalib/displayparams.h" #include "salalib/fileproperties.h" #include "salalib/importtypedefs.h" +#include "salalib/tracemap.h" // still call paftl: #include "salalib/attributes.h" @@ -70,7 +71,7 @@ class MetaGraph : public FileProperties enum { ADD = 0x0001, REPLACE = 0x0002, CAT = 0x0010, DXF = 0x0020, NTF = 0x0040, RT1 = 0x0080, GML = 0x0100 }; enum { NONE = 0x0000, POINTMAPS = 0x0002, LINEDATA = 0x0004, - ANGULARGRAPH = 0x0010, DATAMAPS = 0x0020, AXIALLINES = 0x0040, SHAPEGRAPHS = 0x0100, + ANGULARGRAPH = 0x0010, DATAMAPS = 0x0020, AXIALLINES = 0x0040, SHAPEGRAPHS = 0x0100, TRACEMAPS = 0x0200, BUGGY = 0x8000 }; enum { NOT_EDITABLE = 0, EDITABLE_OFF = 1, EDITABLE_ON = 2 }; protected: @@ -87,6 +88,8 @@ class MetaGraph : public FileProperties std::vector> m_shapeGraphs; int m_displayed_shapegraph = -1; + std::vector m_traceMaps; + public: MetaGraph(std::string name = ""); ~MetaGraph(); @@ -235,6 +238,25 @@ class MetaGraph : public FileProperties m_displayed_datamap = map; } + + size_t m_displayed_tracemap = -1; + TraceMap& getDisplayedTraceMap() + { return m_traceMaps[m_displayed_tracemap]; } + const TraceMap& getDisplayedTraceMap() const + { return m_traceMaps[m_displayed_tracemap]; } + size_t getDisplayedTraceMapRef() const + { return m_displayed_tracemap; } + + void removeTraceMap(int i) + { if (m_displayed_tracemap >= i) m_displayed_tracemap--; m_traceMaps.erase(m_traceMaps.begin() + i); } + + void setDisplayedTraceMapRef(size_t map) + { + if (m_displayed_tracemap != -1 && m_displayed_tracemap != map) + m_traceMaps[m_displayed_tracemap].clearSel(); + m_displayed_tracemap = map; + } + template size_t getMapRef(std::vector& maps, const std::string& name) const { @@ -277,6 +299,12 @@ class MetaGraph : public FileProperties bool readDataMaps(std::istream &stream, int version ); bool writeDataMaps( std::ofstream& stream, int version, bool displayedmaponly = false ); + std::vector& getTraceMaps() + { return m_traceMaps; } + + bool readTraceMaps(std::istream &stream, int version ); + bool writeTraceMaps( std::ofstream& stream, int version, bool displayedmaponly = false ); + // int getDisplayedMapType(); bool hasVisibleDrawingLayers(); @@ -325,9 +353,10 @@ class MetaGraph : public FileProperties protected: int m_view_class; public: - enum { SHOWHIDEVGA = 0x0100, SHOWVGATOP = 0x0200, SHOWHIDEAXIAL = 0x0400, SHOWAXIALTOP = 0x0800, SHOWHIDESHAPE = 0x1000, SHOWSHAPETOP = 0x2000 }; + enum { SHOWHIDEVGA = 0x0100, SHOWVGATOP = 0x0200, SHOWHIDEAXIAL = 0x0400, SHOWAXIALTOP = 0x0800, SHOWHIDESHAPE = 0x1000, SHOWSHAPETOP = 0x2000, + SHOWHIDETRACES = 0x4000, SHOWTRACESTOP = 0x8000 }; enum { VIEWNONE = 0x00, VIEWVGA = 0x01, VIEWBACKVGA = 0x02, VIEWAXIAL = 0x04, VIEWBACKAXIAL = 0x08, - VIEWDATA = 0x20, VIEWBACKDATA = 0x40, VIEWFRONT = 0x25 }; + VIEWDATA = 0x20, VIEWBACKDATA = 0x40, VIEWTRACES = 0x80, VIEWBACKTRACES = 0x100, VIEWFRONT = 0xA5 }; // int getViewClass() { return m_view_class; } @@ -335,13 +364,15 @@ class MetaGraph : public FileProperties bool viewingNone() { return (m_view_class == VIEWNONE); } bool viewingProcessed() - { return ((m_view_class & (VIEWAXIAL | VIEWDATA)) || (m_view_class & VIEWVGA && getDisplayedPointMap().isProcessed())); } + { return ((m_view_class & (VIEWAXIAL | VIEWDATA | VIEWTRACES)) || (m_view_class & VIEWVGA && getDisplayedPointMap().isProcessed())); } bool viewingShapes() - { return (m_view_class & (VIEWAXIAL | VIEWDATA)) != 0; } + { return (m_view_class & (VIEWAXIAL | VIEWDATA | VIEWTRACES)) != 0; } bool viewingProcessedLines() { return ((m_view_class & VIEWAXIAL) == VIEWAXIAL); } bool viewingProcessedShapes() { return ((m_view_class & VIEWDATA) == VIEWDATA); } + bool viewingProcessedTraces() + { return ((m_view_class & VIEWTRACES) == VIEWTRACES); } bool viewingProcessedPoints() { return ((m_view_class & VIEWVGA) && getDisplayedPointMap().isProcessed()); } bool viewingUnprocessedPoints() @@ -360,6 +391,8 @@ class MetaGraph : public FileProperties return getDisplayedShapeGraph().isSelected(); else if (m_view_class & VIEWDATA) return getDisplayedDataMap().isSelected(); + else if (m_view_class & VIEWTRACES) + return getDisplayedTraceMap().isSelected(); else return false; } @@ -368,6 +401,8 @@ class MetaGraph : public FileProperties return getDisplayedShapeGraph().setCurSel(r, add); else if (m_view_class & VIEWDATA) return getDisplayedDataMap().setCurSel( r, add ); + else if (m_view_class & VIEWTRACES) + return getDisplayedTraceMap().setCurSel( r, add ); else if (m_view_class & VIEWVGA) return getDisplayedPointMap().setCurSel( r, add ); else if (m_state & POINTMAPS && !getDisplayedPointMap().isProcessed()) // this is a default select application @@ -386,6 +421,8 @@ class MetaGraph : public FileProperties return getDisplayedShapeGraph().clearSel(); else if (m_view_class & VIEWDATA) return getDisplayedDataMap().clearSel(); + else if (m_view_class & VIEWTRACES) + return getDisplayedTraceMap().clearSel(); else return false; } @@ -395,8 +432,10 @@ class MetaGraph : public FileProperties return getDisplayedPointMap().getSelCount(); else if (m_view_class & VIEWAXIAL) return (int) getDisplayedShapeGraph().getSelCount(); - else if (m_view_class & VIEWDATA) + else if (m_view_class & VIEWDATA) return (int) getDisplayedDataMap().getSelCount(); + else if (m_view_class & VIEWTRACES) + return (int) getDisplayedTraceMap().getSelCount(); else return 0; } @@ -406,8 +445,10 @@ class MetaGraph : public FileProperties return (float)getDisplayedPointMap().getAttributeTable().getSelAvg(); else if (m_view_class & VIEWAXIAL) return (float)getDisplayedShapeGraph().getAttributeTable().getSelAvg(); - else if (m_view_class & VIEWDATA) + else if (m_view_class & VIEWDATA) return (float)getDisplayedDataMap().getAttributeTable().getSelAvg(); + else if (m_view_class & VIEWTRACES) + return (float)getDisplayedTraceMap().getAttributeTable().getSelAvg(); else return -1.0f; } @@ -417,8 +458,10 @@ class MetaGraph : public FileProperties return getDisplayedPointMap().getSelBounds(); else if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().getSelBounds(); - else if (m_view_class & VIEWDATA) + else if (m_view_class & VIEWDATA) return getDisplayedDataMap().getSelBounds(); + else if (m_view_class & VIEWTRACES) + return getDisplayedTraceMap().getSelBounds(); else return QtRegion(); } @@ -428,6 +471,8 @@ class MetaGraph : public FileProperties getDisplayedPointMap().setCurSel(selset,add); else if (m_view_class & VIEWAXIAL) getDisplayedShapeGraph().setCurSel(selset,add); + else if (m_view_class & VIEWTRACES) + getDisplayedTraceMap().setCurSel(selset,add); else // if (m_view_class & VIEWDATA) getDisplayedDataMap().setCurSel(selset,add); } std::set& getSelSet() @@ -435,6 +480,8 @@ class MetaGraph : public FileProperties return getDisplayedPointMap().getSelSet(); else if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().getSelSet(); + else if (m_view_class & VIEWTRACES) + return getDisplayedTraceMap().getSelSet(); else // if (m_view_class & VIEWDATA) return getDisplayedDataMap().getSelSet(); } const std::set& getSelSet() const @@ -442,6 +489,8 @@ class MetaGraph : public FileProperties return getDisplayedPointMap().getSelSet(); else if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().getSelSet(); + else if (m_view_class & VIEWTRACES) + return getDisplayedTraceMap().getSelSet(); else // if (m_view_class & VIEWDATA) return getDisplayedDataMap().getSelSet(); } // diff --git a/salalib/nagent.cpp b/salalib/nagent.cpp index 05ba9a22..e0d0261a 100644 --- a/salalib/nagent.cpp +++ b/salalib/nagent.cpp @@ -151,7 +151,7 @@ void AgentEngine::run(Communicator *comm, PointMap *pointmap) pointmap->setDisplayedAttribute(displaycol); } -ShapeMap AgentEngine::getTrailsAsMap(std::string mapName) { +ShapeMap AgentEngine::getTrailsAsShapeMap(std::string mapName) { ShapeMap trailsMap(mapName, ShapeMap::DATAMAP); for (auto &agentSet : agentSets) { // there is currently only one AgentSet. If at any point there are more then @@ -164,6 +164,20 @@ ShapeMap AgentEngine::getTrailsAsMap(std::string mapName) { return (trailsMap); } +TraceMap AgentEngine::getTrailsAsMap(std::string mapName) { + TraceMap trailsMap(mapName); + for (auto &agentSet : agentSets) { + // there is currently only one AgentSet. If at any point there are more then + // this could be amended to put the AgentSet id as a property of the trail + for (auto &trail : agentSet.m_trails) { + trailsMap.makeTrace(trail); + } + } + trailsMap.overrideDisplayedAttribute(-2); + trailsMap.setDisplayedAttribute(-1); + return (trailsMap); +} + /////////////////////////////////////////////////////////////////////////////////////////////// AgentSet::AgentSet() diff --git a/salalib/nagent.h b/salalib/nagent.h index 598a3f0f..58ec8d59 100644 --- a/salalib/nagent.h +++ b/salalib/nagent.h @@ -24,6 +24,7 @@ #include "salalib/point.h" #include "salalib/pointdata.h" #include "salalib/shapemap.h" +#include "salalib/tracemap.h" #include "genlib/pflipper.h" @@ -142,7 +143,8 @@ class AgentEngine public: AgentEngine(); void run(Communicator *comm, PointMap *pointmap); - ShapeMap getTrailsAsMap(std::string mapName = "Agent Trails"); + ShapeMap getTrailsAsShapeMap(std::string mapName = "Agent Trails"); + TraceMap getTrailsAsMap(std::string mapName = "Agent Trails"); }; struct AgentProgram diff --git a/salalib/salalib.pro b/salalib/salalib.pro index 0cc31bc2..2ffff9d0 100644 --- a/salalib/salalib.pro +++ b/salalib/salalib.pro @@ -48,7 +48,8 @@ SOURCES += \ tidylines.cpp \ mapconverter.cpp \ importutils.cpp \ - attributetableindex.cpp + attributetableindex.cpp \ + tracemap.cpp HEADERS += \ attributes.h \ @@ -92,7 +93,8 @@ HEADERS += \ iaxial.h \ isegment.h \ importutils.h \ - importtypedefs.h + importtypedefs.h \ + tracemap.h DISTFILES += \ salascript-tests.txt diff --git a/salalib/shapemap.h b/salalib/shapemap.h index 75318841..cbfc55af 100644 --- a/salalib/shapemap.h +++ b/salalib/shapemap.h @@ -196,7 +196,7 @@ class ShapeMap : public PixelBase // Do not change numeric values! They are saved to file. // Note the Pesh map does auto-overlap of shape-shape (yet...), so can be used for an arbitrary shape map enum { EMPTYMAP = 0x0000, DRAWINGMAP = 0x0001, DATAMAP = 0x0002, POINTMAP = 0x0004, CONVEXMAP = 0x0008, - ALLLINEMAP = 0x0010, AXIALMAP = 0x0020, SEGMENTMAP = 0x0040, PESHMAP = 0x0080, LINEMAP = 0x0070 }; + ALLLINEMAP = 0x0010, AXIALMAP = 0x0020, SEGMENTMAP = 0x0040, PESHMAP = 0x0080, LINEMAP = 0x0070, TRACEMAP = 0x0100 }; enum { COPY_NAME = 0x0001, COPY_GEOMETRY = 0x0002, COPY_ATTRIBUTES = 0x0004, COPY_GRAPH = 0x0008, COPY_ALL = 0x000f }; protected: std::string m_name; diff --git a/salalib/tracemap.cpp b/salalib/tracemap.cpp new file mode 100644 index 00000000..8cb383ce --- /dev/null +++ b/salalib/tracemap.cpp @@ -0,0 +1,65 @@ +// sala - a component of the depthmapX - spatial network analysis platform +// Copyright (C) 2011-2012, Petros Koutsolampros + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "tracemap.h" + +int TraceMap::makeTraceWithRef(const std::vector &trace, int trace_ref, + const std::map &extraAttributes) { + std::vector traceGeometry(trace.size()); + std::vector traceTimes(trace.size()); + int counter = 0; + for (const Event2f &event : trace) { + traceGeometry[counter] = event; + traceTimes[counter] = event.t; + counter++; + } + makePolyShapeWithRef(traceGeometry, true, trace_ref, false, extraAttributes); + m_traceTimes.insert(std::make_pair(trace_ref, traceTimes)); + return trace_ref; +} + +int TraceMap::makeTrace(const std::vector &trace, const std::map &extraAttributes) { + return makeTraceWithRef(trace, getNextShapeKey(), extraAttributes); +} + +bool TraceMap::read( std::istream& stream, int version ) +{ + ShapeMap::read(stream, version, false); + + int count = 0; + stream.read((char *) &count, sizeof(count)); + for (int j = 0; j < count; j++) { + int key; + stream.read((char *) &key, sizeof(key)); + m_traceTimes.insert(std::make_pair(key, dXreadwrite::readVector(stream))); + } + return true; +} + +bool TraceMap::write(std::ofstream &stream, int version) { + ShapeMap::write(stream, version); + + // write trace times + int count = m_traceTimes.size(); + stream.write((char *)&count, sizeof(count)); + for (auto &traceTimes : m_traceTimes) { + int key = traceTimes.first; + stream.write((char *)&key, sizeof(key)); + dXreadwrite::writeVector(stream, traceTimes.second); + } + + return true; +} diff --git a/salalib/tracemap.h b/salalib/tracemap.h new file mode 100644 index 00000000..13f8fcdb --- /dev/null +++ b/salalib/tracemap.h @@ -0,0 +1,34 @@ +// sala - a component of the depthmapX - spatial network analysis platform +// Copyright (C) 2011-2012, Petros Koutsolampros + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include "salalib/shapemap.h"; + +#include "genlib/p2dpoly.h" + +class TraceMap : public ShapeMap { + private: + std::map> m_traceTimes; + + public: + TraceMap(std::string name = std::string()) : ShapeMap(name, ShapeMap::TRACEMAP) {} + int makeTraceWithRef(const std::vector &trace, int trace_ref, + const std::map &extraAttributes = std::map()); + int makeTrace(const std::vector &trace, const std::map &extraAttributes = std::map()); + bool read( std::istream& stream, int version ); + bool write(std::ofstream &stream, int version); +}; From db3732f50826cb0f547db24375204441d85614bd Mon Sep 17 00:00:00 2001 From: Petros Koutsolampros Date: Sun, 27 Jan 2019 13:51:57 +0000 Subject: [PATCH 2/3] Allow exporting the traces in the form they can be read in 3dview --- depthmapX/GraphDoc.cpp | 51 ++++++++++++++++++++++++++++++++++++++++ depthmapX/GraphDoc.h | 1 + depthmapX/mainwindow.cpp | 16 +++++++++++++ depthmapX/mainwindow.h | 2 ++ salalib/nagent.cpp | 13 ++++++---- salalib/nagent.h | 3 ++- salalib/tracemap.cpp | 35 +++++++++++++++++++++------ salalib/tracemap.h | 1 + 8 files changed, 109 insertions(+), 13 deletions(-) diff --git a/depthmapX/GraphDoc.cpp b/depthmapX/GraphDoc.cpp index 85a123f9..8835f71e 100644 --- a/depthmapX/GraphDoc.cpp +++ b/depthmapX/GraphDoc.cpp @@ -887,6 +887,53 @@ void QGraphDoc::OnFileExportLinks() stream.close(); } +void QGraphDoc::OnFileExportTraces() +{ + if (m_communicator) { + QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as another process is running"), QMessageBox::Ok, QMessageBox::Ok); + return; // Locked + } + if (!m_meta_graph->viewingProcessedTraces()) { + QMessageBox::warning(this, tr("Notice"), tr("Sorry, can only export traces maps"), QMessageBox::Ok, QMessageBox::Ok); + return; // No graph to export + } + + QFilePath path(m_opened_name); + QString defaultname = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name); + + QString template_string = tr("Traceset XML file (*.xml)\n"); + + QFileDialog::Options options = 0; + QString selectedFilter; + QString outfile = QFileDialog::getSaveFileName( + 0, tr("Save Output As"), + defaultname, + template_string, + &selectedFilter, + options); + if(outfile.isEmpty()) + { + return; + } + + FILE* fp = fopen(outfile.toLatin1(), "wb"); + fclose(fp); + + QFilePath filepath(outfile); + QString ext = filepath.m_ext; + + std::ofstream stream(outfile.toLatin1()); + if (stream.fail() || stream.bad()) { + QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); + stream.close(); + return; + } + + m_meta_graph->getDisplayedTraceMap().writeTracesToXMLFile(stream); + + stream.close(); +} + void QGraphDoc::OnAxialConnectionsExportAsDot() { if (m_communicator) { @@ -927,6 +974,7 @@ void QGraphDoc::OnAxialConnectionsExportAsDot() if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); + stream.close(); return; } shapeGraph.writeAxialConnectionsAsDotGraph(stream); @@ -974,6 +1022,7 @@ void QGraphDoc::OnAxialConnectionsExportAsPairCSV() if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); + stream.close(); return; } shapeGraph.writeAxialConnectionsAsPairsCSV(stream); @@ -1021,6 +1070,7 @@ void QGraphDoc::OnSegmentConnectionsExportAsPairCSV() if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); + stream.close(); return; } shapeGraph.writeSegmentConnectionsAsPairsCSV(stream); @@ -1078,6 +1128,7 @@ void QGraphDoc::OnPointmapExportConnectionsAsCSV() if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); + stream.close(); return; } pointMap.outputConnectionsAsCSV(stream, ","); diff --git a/depthmapX/GraphDoc.h b/depthmapX/GraphDoc.h index 32a6da1f..fdf08b9a 100644 --- a/depthmapX/GraphDoc.h +++ b/depthmapX/GraphDoc.h @@ -273,6 +273,7 @@ public slots: void OnFileExport(); void OnFileExportMapGeometry(); void OnFileExportLinks(); + void OnFileExportTraces(); void OnAxialConnectionsExportAsDot(); void OnAxialConnectionsExportAsPairCSV(); void OnSegmentConnectionsExportAsPairCSV(); diff --git a/depthmapX/mainwindow.cpp b/depthmapX/mainwindow.cpp index 702e5751..f8ce1390 100644 --- a/depthmapX/mainwindow.cpp +++ b/depthmapX/mainwindow.cpp @@ -383,6 +383,16 @@ void MainWindow::OnFileExportLinks() } } + +void MainWindow::OnFileExportTraces() +{ + QGraphDoc* m_p = activeMapDoc(); + if(m_p) + { + m_p->OnFileExportTraces(); + } +} + void MainWindow::OnAxialConnectionsExportAsDot() { QGraphDoc* m_p = activeMapDoc(); @@ -2646,6 +2656,7 @@ void MainWindow::updateMapMenu() exportAct->setEnabled(true); exportGeometryAct->setEnabled(true); exportLinksAct->setEnabled(true); + exportTracesAct->setEnabled(true); exportAxialConnectionsDotAct->setEnabled(true); exportAxialConnectionsPairAct->setEnabled(true); exportSegmentConnectionsPairAct->setEnabled(true); @@ -2655,6 +2666,7 @@ void MainWindow::updateMapMenu() exportAct->setEnabled(0); exportGeometryAct->setEnabled(false); exportLinksAct->setEnabled(0); + exportTracesAct->setEnabled(false); exportAxialConnectionsDotAct->setEnabled(0); exportAxialConnectionsPairAct->setEnabled(0); exportSegmentConnectionsPairAct->setEnabled(0); @@ -3095,6 +3107,9 @@ void MainWindow::createActions() exportLinksAct->setStatusTip(tr("Export the links of the active map")); connect(exportLinksAct, SIGNAL(triggered()), this, SLOT(OnFileExportLinks())); + exportTracesAct = new QAction(tr("&Export traces..."), this); + connect(exportTracesAct, SIGNAL(triggered()), this, SLOT(OnFileExportTraces())); + exportAxialConnectionsPairAct = new QAction(tr("&Axial Connections as CSV..."), this); exportAxialConnectionsPairAct->setStatusTip(tr("Export a list of line-line intersections")); connect(exportAxialConnectionsPairAct, SIGNAL(triggered()), this, SLOT(OnAxialConnectionsExportAsPairCSV())); @@ -3616,6 +3631,7 @@ void MainWindow::createMenus() exportSubMenu->addAction(exportAct); exportSubMenu->addAction(exportGeometryAct); exportSubMenu->addAction(exportLinksAct); + exportSubMenu->addAction(exportTracesAct); exportSubMenu->addAction(exportAxialConnectionsDotAct); exportSubMenu->addAction(exportAxialConnectionsPairAct); exportSubMenu->addAction(exportSegmentConnectionsPairAct); diff --git a/depthmapX/mainwindow.h b/depthmapX/mainwindow.h index c3acda21..006a4b00 100644 --- a/depthmapX/mainwindow.h +++ b/depthmapX/mainwindow.h @@ -130,6 +130,7 @@ private slots: void OnFileExport(); void OnFileExportMapGeometry(); void OnFileExportLinks(); + void OnFileExportTraces(); void OnAxialConnectionsExportAsDot(); void OnAxialConnectionsExportAsPairCSV(); void OnSegmentConnectionsExportAsPairCSV(); @@ -346,6 +347,7 @@ private slots: QAction *exportAct; QAction *exportGeometryAct; QAction *exportLinksAct; + QAction *exportTracesAct; QAction *exportAxialConnectionsDotAct; QAction *exportAxialConnectionsPairAct; QAction *exportSegmentConnectionsPairAct; diff --git a/salalib/nagent.cpp b/salalib/nagent.cpp index e0d0261a..efdf9df8 100644 --- a/salalib/nagent.cpp +++ b/salalib/nagent.cpp @@ -134,7 +134,7 @@ void AgentEngine::run(Communicator *comm, PointMap *pointmap) } for (auto& agentSet: agentSets) { - agentSet.move(); + agentSet.move(i); } if (comm) { @@ -202,11 +202,12 @@ void AgentSet::init(int agent, int trail_num) } } -void AgentSet::move() +void AgentSet::move(int currentTimeStep) { // go through backwards so remove does not affect later agents for (auto rev_iter = agents.rbegin(); rev_iter != agents.rend(); ++rev_iter) { rev_iter->onMove(); + rev_iter->onUpdateTrail(currentTimeStep); if (rev_iter->getFrame() >= m_lifetime) { agents.erase( std::next(rev_iter).base() ); } @@ -689,6 +690,11 @@ void Agent::onMove() } // done. happy hamster. } +void Agent::onUpdateTrail(double currentTime) { + if (!m_stopped && m_trail_num != -1) { + m_program->m_trails[m_trail_num].push_back(Event2f(m_loc, currentTime)); + } +} void Agent::onDestination() { m_at_destination = true; @@ -725,9 +731,6 @@ void Agent::onStep() else { m_loc = nextloc; } - if (!m_stopped && m_trail_num != -1) { - m_program->m_trails[m_trail_num].push_back(Event2f(m_loc, m_program->m_steps)); - } } bool Agent::diagonalStep() { diff --git a/salalib/nagent.h b/salalib/nagent.h index 58ec8d59..f1d88dae 100644 --- a/salalib/nagent.h +++ b/salalib/nagent.h @@ -204,7 +204,7 @@ struct AgentSet : public AgentProgram double m_release_rate; int m_lifetime; AgentSet(); - void move(); + void move(int currentTimeStep); void init(int agent, int trail_num = -1); }; @@ -280,6 +280,7 @@ class Agent void calcLoS(int directionbin, bool curr); void calcLoS2(int directionbin, bool curr); void onMove(); + void onUpdateTrail(double currentTime); void onTarget(); void onDestination(); void onStep(); diff --git a/salalib/tracemap.cpp b/salalib/tracemap.cpp index 8cb383ce..d990cf75 100644 --- a/salalib/tracemap.cpp +++ b/salalib/tracemap.cpp @@ -35,18 +35,17 @@ int TraceMap::makeTrace(const std::vector &trace, const std::map(stream))); + int key; + stream.read((char *)&key, sizeof(key)); + m_traceTimes.insert(std::make_pair(key, dXreadwrite::readVector(stream))); } - return true; + return true; } bool TraceMap::write(std::ofstream &stream, int version) { @@ -63,3 +62,25 @@ bool TraceMap::write(std::ofstream &stream, int version) { return true; } + +void TraceMap::writeTracesToXMLFile(std::ofstream &stream) { + stream << "" << std::endl; + + stream.precision(12); + for (auto &refShape : m_shapes) { + stream << "" << std::endl; + const auto × = m_traceTimes[refShape.first]; + int counter = 0; + for (Point2f &point : refShape.second.m_points) { + stream << "" << std::endl; + counter++; + } + stream << "" << std::endl; + } + + stream << "" << std::endl; +} diff --git a/salalib/tracemap.h b/salalib/tracemap.h index 13f8fcdb..04d148a3 100644 --- a/salalib/tracemap.h +++ b/salalib/tracemap.h @@ -31,4 +31,5 @@ class TraceMap : public ShapeMap { int makeTrace(const std::vector &trace, const std::map &extraAttributes = std::map()); bool read( std::istream& stream, int version ); bool write(std::ofstream &stream, int version); + void writeTracesToXMLFile(std::ofstream &stream); }; From 8c5fefd717168fbb40513e4fb680852cd5ee70f5 Mon Sep 17 00:00:00 2001 From: Petros Koutsolampros Date: Mon, 25 Mar 2019 12:03:20 +0000 Subject: [PATCH 3/3] Minor fixes after merge --- depthmapX/mainwindow.cpp | 2 +- depthmapXcli/runmethods.cpp | 6 ++++-- salalib/mgraph.cpp | 10 ++-------- salalib/nagent.cpp | 8 ++------ salalib/nagent.h | 4 ++-- 5 files changed, 11 insertions(+), 19 deletions(-) diff --git a/depthmapX/mainwindow.cpp b/depthmapX/mainwindow.cpp index 9132de86..f2fe1cf8 100644 --- a/depthmapX/mainwindow.cpp +++ b/depthmapX/mainwindow.cpp @@ -1724,7 +1724,7 @@ void MainWindow::MakeGraphTree() ItemTreeEntry entry(3,(short)i,-1); m_treegraphmap[hItem] = entry; - LayerManagerImpl layers = m_treeDoc->m_meta_graph->getDataMaps()[i].getLayers(); + LayerManagerImpl layers = m_treeDoc->m_meta_graph->getTraceMaps()[i].getLayers(); if(layers.getNumLayers() > 1) { for (int j = 0; j < layers.getNumLayers(); j++) { QString name = QString(layers.getLayerName(j).c_str()); diff --git a/depthmapXcli/runmethods.cpp b/depthmapXcli/runmethods.cpp index f8ec2247..d15c4d64 100644 --- a/depthmapXcli/runmethods.cpp +++ b/depthmapXcli/runmethods.cpp @@ -534,7 +534,8 @@ namespace dm_runmethods case AgentParser::OutputType::TRAILS: { std::ofstream trailStream(cmdP.getOuputFile().c_str()); - ShapeMap trailMap = eng.getTrailsAsMap(); + ShapeMap trailMap("Agent Trails"); + eng.insertTrailsInMap(trailMap); DO_TIMED("Writing trails", mgraph->writeMapShapesAsCat(trailMap, trailStream)) break; } @@ -560,7 +561,8 @@ namespace dm_runmethods if(std::find(resultTypes.begin(), resultTypes.end(), AgentParser::OutputType::TRAILS) != resultTypes.end()) { std::string outFile = cmdP.getOuputFile() + "_trails.cat"; std::ofstream trailStream(outFile.c_str()); - ShapeMap trailMap = eng.getTrailsAsMap(); + ShapeMap trailMap("Agent Trails"); + eng.insertTrailsInMap(trailMap); DO_TIMED("Writing trails", mgraph->writeMapShapesAsCat(trailMap, trailStream)) } } diff --git a/salalib/mgraph.cpp b/salalib/mgraph.cpp index 922f192c..e3d818af 100644 --- a/salalib/mgraph.cpp +++ b/salalib/mgraph.cpp @@ -2075,15 +2075,9 @@ void MetaGraph::runAgentEngine(Communicator *comm) mapName = "Agent Trails " + std::to_string(count); count++; } - m_traceMaps.push_back(m_agent_engine.getTrailsAsMap(mapName)); + m_traceMaps.push_back(mapName); + m_agent_engine.insertTrailsInMap(m_traceMaps.back()); m_state |= TRACEMAPS; -// setViewClass(SHOWTRACESTOP); -// setDisplayedTraceMapRef(m_traceMaps.size() -1); - -// SetUpdateFlag(NEW_TABLE); -// SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH, NEW_DATA); -// m_dataMaps.push_back(m_agent_engine.getTrailsAsMap(mapName)); -// m_state |= DATAMAPS; } if (m_agent_engine.m_gatelayer != -1) { diff --git a/salalib/nagent.cpp b/salalib/nagent.cpp index 1f0fb451..d5bca48d 100644 --- a/salalib/nagent.cpp +++ b/salalib/nagent.cpp @@ -152,8 +152,7 @@ void AgentEngine::run(Communicator *comm, PointMap *pointmap) pointmap->setDisplayedAttribute(displaycol); } -ShapeMap AgentEngine::getTrailsAsShapeMap(std::string mapName) { - ShapeMap trailsMap(mapName, ShapeMap::DATAMAP); +void AgentEngine::insertTrailsInMap(ShapeMap& trailsMap) { for (auto &agentSet : agentSets) { // there is currently only one AgentSet. If at any point there are more then // this could be amended to put the AgentSet id as a property of the trail @@ -162,11 +161,9 @@ ShapeMap AgentEngine::getTrailsAsShapeMap(std::string mapName) { trailsMap.makePolyShape(trailGeometry, true, false); } } - return (trailsMap); } -TraceMap AgentEngine::getTrailsAsMap(std::string mapName) { - TraceMap trailsMap(mapName); +void AgentEngine::insertTrailsInMap(TraceMap& trailsMap) { for (auto &agentSet : agentSets) { // there is currently only one AgentSet. If at any point there are more then // this could be amended to put the AgentSet id as a property of the trail @@ -176,7 +173,6 @@ TraceMap AgentEngine::getTrailsAsMap(std::string mapName) { } trailsMap.overrideDisplayedAttribute(-2); trailsMap.setDisplayedAttribute(-1); - return (trailsMap); } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/salalib/nagent.h b/salalib/nagent.h index f1d88dae..ba71c6d2 100644 --- a/salalib/nagent.h +++ b/salalib/nagent.h @@ -143,8 +143,8 @@ class AgentEngine public: AgentEngine(); void run(Communicator *comm, PointMap *pointmap); - ShapeMap getTrailsAsShapeMap(std::string mapName = "Agent Trails"); - TraceMap getTrailsAsMap(std::string mapName = "Agent Trails"); + void insertTrailsInMap(ShapeMap& trailMap); + void insertTrailsInMap(TraceMap& trailMap); }; struct AgentProgram