void deleteSegment (SegmentTree * st, int n, Coord Y1, Coord Y2) { Coord discriminant; if (st->nodes[n].left >= Y1 && st->nodes[n].right <= Y2) { assert (st->nodes[n].covered); --st->nodes[n].covered; } else { assert (n < st->size / 2); discriminant = st->nodes[n * 2 + 1 /*right */ ].left; if (Y1 < discriminant) { deleteSegment (st, n * 2, Y1, Y2); } if (discriminant < Y2) { deleteSegment (st, n * 2 + 1, Y1, Y2); } } /* fixup area */ st->nodes[n].area = (st->nodes[n].covered > 0) ? (st->nodes[n].right - st->nodes[n].left) : (n >= st->size / 2) ? 0 : st->nodes[n * 2].area + st->nodes[n * 2 + 1].area; }
/* --------------------------------------------------------------------------- * Compute the area of the union of the given rectangles. * O(N ln N) time. */ double ComputeUnionArea (BoxListType *boxlist) { BoxType **rectLeft, **rectRight; Cardinal i, j; LocationList yCoords; SegmentTree segtree; Coord lastX; double area = 0.0; if (boxlist->BoxN == 0) return 0.0; /* create sorted list of Y coordinates */ yCoords = createSortedYList (boxlist); /* now create empty segment tree */ segtree = createSegmentTree (yCoords.p, yCoords.size); free (yCoords.p); /* create sorted list of left and right X coordinates of rectangles */ rectLeft = (BoxType **)calloc (boxlist->BoxN, sizeof (*rectLeft)); rectRight = (BoxType **)calloc (boxlist->BoxN, sizeof (*rectRight)); for (i = 0; i < boxlist->BoxN; i++) { assert (boxlist->Box[i].X1 <= boxlist->Box[i].X2); assert (boxlist->Box[i].Y1 <= boxlist->Box[i].Y2); rectLeft[i] = rectRight[i] = &boxlist->Box[i]; } qsort (rectLeft, boxlist->BoxN, sizeof (*rectLeft), compareleft); qsort (rectRight, boxlist->BoxN, sizeof (*rectRight), compareright); /* sweep through x segments from left to right */ i = j = 0; lastX = rectLeft[0]->X1; while (j < boxlist->BoxN) { assert (i <= boxlist->BoxN); /* i will step through rectLeft, j will through rectRight */ if (i == boxlist->BoxN || rectRight[j]->X2 < rectLeft[i]->X1) { /* right edge of rectangle */ BoxType *b = rectRight[j++]; /* check lastX */ if (b->X2 != lastX) { assert (lastX < b->X2); area += (double) (b->X2 - lastX) * segtree.nodes[1].area; lastX = b->X2; } /* remove a segment from the segment tree. */ deleteSegment (&segtree, 1, b->Y1, b->Y2); } else { /* left edge of rectangle */ BoxType *b = rectLeft[i++]; /* check lastX */ if (b->X1 != lastX) { assert (lastX < b->X1); area += (double) (b->X1 - lastX) * segtree.nodes[1].area; lastX = b->X1; } /* add a segment from the segment tree. */ insertSegment (&segtree, 1, b->Y1, b->Y2); } } free (rectLeft); free (rectRight); free (segtree.nodes); return area * 0.0001; }
RouteView::RouteView(QObject* parent ) { m_parent = parent; config = Configuration::instance(); //sql.setConfig(config); //headers << "" << "Item" << "Name" << "1 way" << "Next" << "Prev" << "Dir" << "Seq" << "RSeq" << "StartDate" << "EndDate"; mainWindow* myParent = qobject_cast<mainWindow*>(m_parent); ui = myParent->ui->tblRouteView; connect(ui->verticalHeader(), SIGNAL(sectionCountChanged(int,int)), this, SLOT(Resize(int,int))); //ui->setColumnCount(headers.count()); //ui->setHorizontalHeaderLabels(headers); ui->resizeColumnsToContents(); ui->setAlternatingRowColors(true); ui->setColumnWidth(0,25); //m_myParent = myParent; ui->setSelectionBehavior(QAbstractItemView::SelectRows ); ui->setSelectionMode( QAbstractItemView::SingleSelection ); //create contextmenu copyAction = new QAction(tr("&Copy"), this); copyAction->setStatusTip(tr("Copy Table Location")); copyAction->setShortcut(tr("Ctrl+C")); connect(copyAction, SIGNAL(triggered()), this, SLOT(aCopy())); pasteAction = new QAction(tr("&Paste"), this); pasteAction->setStatusTip(tr("Paste")); pasteAction->setShortcut(tr("Ctrl+V")); connect(pasteAction, SIGNAL(triggered()), this, SLOT(aPaste())); reSequenceAction = new QAction(tr("&Start route here"), this); reSequenceAction->setStatusTip(tr("Start route at this segment")); reSequenceAction->setShortcut(tr("Alt_Ctrl+S")); connect(reSequenceAction, SIGNAL(triggered()), this, SLOT(reSequenceRoute())); startTerminalStartAct = new QAction(tr("Start at start"), this); startTerminalStartAct->setStatusTip(tr("Start terminal is at start of segment")); connect(startTerminalStartAct, SIGNAL(triggered()), this, SLOT(StartRoute_S())); startTerminalEndAct = new QAction(tr("Start at end"), this); startTerminalEndAct->setStatusTip(tr("Start terminal is at end of segment")); connect(startTerminalEndAct, SIGNAL(triggered()), this, SLOT(StartRoute_E())); endTerminalStartAct = new QAction(tr("End terminal at start"), this); endTerminalStartAct->setStatusTip(tr("End terminal is at start of segment")); connect(endTerminalStartAct, SIGNAL(triggered()), this, SLOT(EndRoute_S())); endTerminalEndAct = new QAction(tr("End terminal at end"), this); endTerminalEndAct->setStatusTip(tr("End terminal is at end of segment")); connect(endTerminalEndAct,SIGNAL(triggered()), this, SLOT(EndRoute_E())); deleteSegmentAct = new QAction(tr("Remove from route"), this); deleteSegmentAct->setStatusTip(tr("Delete the segment from the route")); connect(deleteSegmentAct, SIGNAL(triggered()), this, SLOT(deleteSegment())); unDeleteSegmentAct = new QAction(tr("Undo delete of segment"), this); unDeleteSegmentAct->setStatusTip(tr("Don't delete the segment from the route")); connect(unDeleteSegmentAct, SIGNAL(triggered()), this, SLOT(unDeleteSegment())); selectSegmentAct = new QAction(tr("Select segment"),this); selectSegmentAct->setToolTip(tr("Select segment on map.")); connect(selectSegmentAct, SIGNAL(triggered()), this, SLOT(on_selectSegment_triggered())); editSegmentAct = new QAction(tr("Edit segment"), this); editSegmentAct->setStatusTip(tr("Edit this segment's properties")); connect(editSegmentAct, SIGNAL(triggered(bool)), this, SLOT(editSegment())); ui->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui, SIGNAL(customContextMenuRequested( const QPoint& )), this, SLOT(tablev_customContextMenu( const QPoint& ))); sourceModel = new RouteViewTableModel(route, name, QDate::fromString(startDate, "yyyy/MM/dd"), QDate::fromString(endDate, "yyyy/MM/dd"), segmentInfoList); saveChangesAct = new QAction(tr("Commit changes"),this); saveChangesAct->setStatusTip(tr("Save any uncommitted changes")); //connect(saveChangesAct, SIGNAL(triggered()), sourceModel, SLOT(commitChanges())); connect(saveChangesAct, SIGNAL(triggered(bool)), this, SLOT(commitChanges())); myParent->proxyModel = proxymodel = new RouteViewSortProxyModel(this); myParent->proxyModel->setSourceModel(sourceModel); ui->setModel(myParent->proxyModel); connect(this, SIGNAL(sendRows(int, int)), sourceModel, SLOT(getRows(int,int))); //connect(ui, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(itemChanged(QTableWidgetItem*))); //connect(ui, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(handleSelectionChanged(QTableWidgetItem *))); connect(ui, SIGNAL(clicked(QModelIndex)), this, SLOT(itemSelectionChanged(QModelIndex))); connect(sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), ui, SLOT(dataChanged(QModelIndex,QModelIndex))); //connect(myParent->saveChangesAct, SIGNAL(triggered()), sourceModel, SLOT(commitChanges())); connect(webViewBridge::instance(), SIGNAL(segmentSelected(qint32,qint32)), this, SLOT(on_segmentSelected(int,int))); myParent->ui->tabWidget->setTabText(0, "Route Segments"); startTerminal = NULL; startSegment = -1; endSegment = -1; }