Пример #1
0
//交差点削除、接続単路も削除、なしなら無視
void Map::deleteIntsec(int intsecId)
{
    MAP_INTSECMAP_IT    imi;
    Intsec*             pIntsec;
    INTSEC_ROADMAP_IT   irmi;
    Road*               pRoad;
    vector<int>         deleteRoadId;
    int                 i;

//  qDebug("Map::deleteIntsec %d", intsecId);
    imi = _intsecMap.find(intsecId);
    if (imi == _intsecMap.end())
        return;
    pIntsec = imi->second;

    //単路削除時に接続情報を消すので後でまとめて実行
    pRoad = pIntsec->nextRoad(&irmi, true);
    while (pRoad != NULL)
    {
        deleteRoadId.push_back(pRoad->getRoadId());
        pRoad = pIntsec->nextRoad(&irmi);
    }
    for (i=0; i < (int)deleteRoadId.size(); i++)
        deleteRoad(deleteRoadId[i]);

    delete pIntsec;
    _intsecMap.erase(imi);
}
Пример #2
0
//単路付け換え、付け換え後単路返却、構造的変換なので注意、既存単路不可
Road* Map::replaceRoad(Intsec* pIntsec, Intsec* pIntsecNew, Intsec* pIntsecCon)
{
    bool            already;
    Road*           pRoad;
    Road*           pRoadNew;

    pRoad = pIntsec->getRoad(pIntsecCon->getIntsecId());
    Q_ASSERT(pRoad!=NULL);
    pRoadNew = createRoad(pIntsecCon, pIntsecNew, &already);
    Q_ASSERT(!already);
    pRoadNew->copyLane(pRoad);
    if (pIntsecCon->getFirstIntsecIdCon() == pIntsec->getIntsecId())
        pIntsecCon->setFirstIntsecIdCon(pIntsecNew->getIntsecId());
    deleteRoad(pRoad->getRoadId());
    return pRoadNew;
}
Пример #3
0
//ドロップイベント
void MapFrame::dropEvent(QDropEvent *event)
{
    Intsec*         pIntsec;
    Intsec*         pIntsecDrop;
    Intsec*         pIntsecReplCon;
    Map*            pMap = app.getMap();
    double          x, y;
    bool            already;
    Road*           pRoad;

    //自ドラッグ判定、ドラッグ開始で弾かれるようだが念のため
    if (!event->mimeData()->hasFormat(ITEM_MINETYPE) || (event->source() != this))
    {
        event->ignore();
        return;
    }

    //スクロール以外なら交差点取得、必ずあるはずだが念のため
    if (_dragType != scroll)
    {
//      qDebug("drop %d", _intsecIdDrag);
        pIntsec = pMap->getIntsec(_intsecIdDrag);
        if (pIntsec == NULL)
        {
            event->ignore();
            return;
        }

        //単路ドラッグ位置設定
        if (_dragType == intsec ||_dragType == road || _dragType == roadRepl)
        {
            _dragRoadX = event->pos().x() - _offsetDragX;
            _dragRoadY = event->pos().y() - _offsetDragY;
        }

        //交差点移動
        if (_dragType == intsec)
        {
            x = getMapX(event->pos().x() - _offsetDragX);
            y = getMapY(event->pos().y() - _offsetDragY);
            if      (x < APP_POS_MIN || y < APP_POS_MIN )
                QMessageBox::critical(this, tr(TITLE), tr("最大位置が小さすぎます。"));
            else if (x > APP_POS_MAX || y > APP_POS_MAX )
                QMessageBox::critical(this, tr(TITLE), tr("最大位置が大きすぎます。"));
            else
                pIntsec->setMapPos(x, y, pIntsec->getMapPosZ());
//          pMap->debugTrace();
        }

        //単路作成
        else if (_dragType == road)
        {
            pIntsecDrop = getIntsecAt(_dragRoadX, _dragRoadY);
            if (pIntsecDrop != NULL && pIntsecDrop->getIntsecId() != _intsecIdDrag)
            {
                pRoad = pMap->createRoad(pIntsec, pIntsecDrop, &already);
                if (already)
                    QMessageBox::warning(this, tr(TITLE), tr("既に単路があります。"));
                else
                {
                    if (!app.getMainWindow()->isLane2())
                        pRoad->setLane4();
                    changeShowSelect(_intsecIdDrag, pIntsecDrop->getIntsecId(), pRoad->getRoadId());
                }
//              pMap->debugTrace();
            }
        }

        //単路入れ替え、先頭接続先交差点ID変更、タイミング注意
        else if (_dragType == roadRepl)
        {
            pIntsecDrop = getIntsecAt(_dragRoadX, _dragRoadY);
            if (pIntsecDrop != NULL && pIntsecDrop->getIntsecId() != _intsecIdDrag
                                    && pIntsecDrop->getIntsecId() != _intsecIdReplCon)
            {
                pIntsecReplCon = pMap->getIntsec(_intsecIdReplCon);
                Q_ASSERT(pIntsecReplCon!=NULL);
                if (pMap->getRoad(_intsecIdReplCon, pIntsecDrop->getIntsecId()) != NULL)
                    QMessageBox::warning(this, tr(TITLE), tr("既に単路があります。"));
                else
                {
                    pRoad = pMap->replaceRoad(pIntsec, pIntsecDrop, pIntsecReplCon);
                    if (_intsecIdDrag == _intsecIdSelect)
                        changeShowSelect(pIntsecDrop->getIntsecId(), _intsecIdDest, pRoad->getRoadId());
                    else
                        changeShowSelect(_intsecIdSelect, pIntsecDrop->getIntsecId(), pRoad->getRoadId());
                }
            }
        }
    }

    //ドロップ終了、再描画はドラッグ処理で実行
    event->accept();
}
Пример #4
0
//描画
void MapFrame::paint(QPainter* pp)
{
    Map*                pMap = app.getMap();
    QRect               rectSource, rectDest;
    double              viewBackMagni;
    MAP_INTSECMAP_IT    imi;
    Intsec*             pIntsec;
    stringstream        ss;
    int                 viewX, viewY;
    MAP_ROADMAP_IT      rmi;
    Road*               pRoad;
    DrawLineType        drawLineType;

    //塗りつぶし、ドラッグ画面用
    pp->fillRect(0, 0, width(), height(), Qt::gray);

    //背景描画
    if (app.getBackImage() && !_backPixmap.isNull())
    {
        viewBackMagni = app.getBackMagni() * app.getViewMagni();    // view / back
        rectDest.setCoords(0, 0, width(), height());
        rectSource.setLeft(  (int)((double)(app.getViewMapX() - app.getBackMapX()) / app.getBackMagni()));
        rectSource.setBottom(_backPixmap.size().height() -
                             (int)((double)(app.getViewMapY() - app.getBackMapY()) / app.getBackMagni()));
        rectSource.setRight( rectSource.left()   + (int)((double)width() / viewBackMagni));
        rectSource.setTop(  rectSource.bottom() - (int)((double)height() / viewBackMagni));
        pp->drawPixmap(rectDest, _backPixmap, rectSource);
    }

    //全単路描画
    pMap = app.getMap();
    pRoad = pMap->nextRoad(&rmi, true);
    while (pRoad != NULL)
    {
        if (pRoad->getRoadId() == _roadIdSelect)
        {
            if (_dragType == roadRepl)
            {
//                  qDebug("MapFrame::paint drag road replace selected");
                drawLineType = selectedDark;
            }
            else
                drawLineType = selected;
        }
        else
            drawLineType = normal;
        if (_dragType == intsec)
        {
//              qDebug("MapFrame::paint drag intsec road");
            if (pRoad->getIntsec(ROAD_IT_SMALL)->getIntsecId() == _intsecIdDrag ||
                pRoad->getIntsec(ROAD_IT_LARGE)->getIntsecId() == _intsecIdDrag )
            {
//                  qDebug("MapFrame::paint drag intsec road selected");
                drawLineType = selectedDark;
            }
        }
//          qDebug("MapFrame::paint road (%d,%d) drag %d lineType:%d",
//                 pRoad->getIntsec(ROAD_IT_SMALL)->getIntsecId(),
//                 pRoad->getIntsec(ROAD_IT_LARGE)->getIntsecId(), _intsecIdDrag, drawLineType);
        if (isViewArea(pRoad->getIntsec(ROAD_IT_SMALL)) || isViewArea(pRoad->getIntsec(ROAD_IT_LARGE)))
            drawLine(pp, getViewX(pRoad->getIntsec(ROAD_IT_SMALL)->getMapPosX()),
                         getViewY(pRoad->getIntsec(ROAD_IT_SMALL)->getMapPosY()),
                         getViewX(pRoad->getIntsec(ROAD_IT_LARGE)->getMapPosX()),
                         getViewY(pRoad->getIntsec(ROAD_IT_LARGE)->getMapPosY()),
                         drawLineType, pRoad->isLaneOver4(), pRoad->isError());
        pRoad = pMap->nextRoad(&rmi);
    }

    //交差点ID描画、広域表示では点描画
    if (app.getShowId())
    {
        pIntsec = pMap->nextIntsec(&imi, true);
        while (pIntsec != NULL)
        {
            if (isViewArea(pIntsec))
            {
                if (app.getMainWindow()->getEditMode() != MainWindow::large)
                {
                    ss.str("");
                    ss << pIntsec->getIntsecId();
                    viewX = getViewX(pIntsec->getMapPosX()) + INTSEC_LABELSIZE_H + 2;
                    viewY = getViewY(pIntsec->getMapPosY()) + INTSEC_LABELSIZE_H + 2;
                    pp->setPen(QColor("#FFFFFF"));
                    pp->drawText(viewX - 1, viewY + 1, ss.str().c_str());
                    pp->drawText(viewX - 1, viewY - 1, ss.str().c_str());
                    pp->drawText(viewX + 1, viewY - 1, ss.str().c_str());
                    pp->drawText(viewX + 1, viewY + 1, ss.str().c_str());
                    pp->setPen(QColor("#0000FF"));
                    pp->drawText(viewX,     viewY,     ss.str().c_str());
                }
                else
                {
                    viewX = getViewX(pIntsec->getMapPosX()) - 2;
                    viewY = getViewY(pIntsec->getMapPosY()) - 2;
                    QString colorName;
                    if (pIntsec->getIntsecId() == _intsecIdSelect)
                    {
                        if (pIntsec->isError())
                            colorName = "#FF00FF";
                        else
                            colorName = "#0000FF";
                    }
                    else
                    {
                        if (pIntsec->isError())
                            colorName = "#FF0000";
                        else
                            colorName = "#000000";
                    }
                    //何故かこうしないと描けない
                    QBrush brush(QColor(colorName.toStdString().c_str()));
                    pp->setPen(QColor(colorName));
                    pp->fillRect(viewX, viewY, 4, 4, brush);
                    pp->drawRect(viewX, viewY, 4, 4);
                }
            }
            pIntsec = pMap->nextIntsec(&imi);
        }
    }
}
Пример #5
0
//マウス開放イベント
void MapFrame::mouseReleaseEvent(QMouseEvent *event)
{
    Map*        pMap = app.getMap();
    Intsec*     pIntsec;
    Road*       pRoad;
    bool        roadSelected;
    int         intsecIdSmall, intsecIdLarge, intsecIdNew;
    double      x, y;

    //右ボタンクリック/ドラッグならクリック、このチェックはいらないようだが念のため
//  qDebug("MapFrame::mouseReleaseEvent");
    if (event->button()!=Qt::LeftButton || !_clickDrag)
        return;
//  qDebug("MapFrame::mouseReleaseEvent click");
    _clickDrag = false;

    //交差点選択あり、交差点以外は NULL
    pIntsec = getIntsecAt(_clickDragX, _clickDragY);
    if (pIntsec != NULL)
    {
        changeShowSelect(pIntsec->getIntsecId(), MAP_NOID, MAP_NOID);
        showStatus(event->pos().x(), event->pos().y(), pIntsec->getIntsecId());

        //交差点モードなら編集画面
        if (app.getMainWindow()->getEditMode() == MainWindow::intsec)
        {
            IntsecDialog id(this);
//          qDebug("MapFrame::mouseReleaseEvent intsec dialog (%d, %d)", _intsecDialogX, _intsecDialogY);
            id.init(pIntsec);
            if (_intsecDialogX != DIALOG_NOPOS)
                id.move(_intsecDialogX, _intsecDialogY);
            if (id.exec() == QDialog::Accepted)
            {
                if (id.isDelete())
                {
                    pMap->deleteIntsec(pIntsec->getIntsecId());
                    changeShowSelect(MAP_NOID, MAP_NOID, MAP_NOID, true);
                }
                else
                {
                    if (id.isCenter())
                    {
                        app.setViewMap(app.getViewMapX() - pIntsec->getMapPosX(),
                                       app.getViewMapY() - pIntsec->getMapPosY());
                        if (app.getBackImage())
                            app.setBackMap(app.getBackMapX() - pIntsec->getMapPosX(),
                                           app.getBackMapY() - pIntsec->getMapPosY());
                        pMap->setCenter(pIntsec->getMapPosX(), pIntsec->getMapPosY(), 0);
                    }
                    //ID が変わったらマップで入れ替え、再選択
                    intsecIdNew = id.getIntsecId();
                    if (intsecIdNew != pIntsec->getIntsecId())
                    {
                        pIntsec = pMap->changeIntsecId(pIntsec, intsecIdNew);
                        changeShowSelect(intsecIdNew, MAP_NOID, MAP_NOID, true);
                    }
                    showIntsec(pIntsec);        //全体再描画は遅いので先に書いとく
                }
                repaintAll(true);
            }
//          qDebug("MapFrame::mouseReleaseEvent intsec dialog (%d, %d)", id.x(), id.y());
            _intsecDialogX = id.x();
            _intsecDialogY = id.y();
        }

        //単路/単路付け替えモードならモード切り替え(メインウィンドウから)
        else if (app.getMainWindow()->getEditMode() == MainWindow::road    ||
                 app.getMainWindow()->getEditMode() == MainWindow::roadRepl)
            app.getMainWindow()->setEditMode(MainWindow::intsec);
    }

    //交差点選択なし
    else
    {
        //単路選択あり
        pRoad = getRoadAt(_clickDragX, _clickDragY);
        if (pRoad != NULL)
        {
            roadSelected = false;
            if (pRoad->getRoadId() == _roadIdSelect)
                roadSelected = true;
            intsecIdSmall = pRoad->getIntsec(ROAD_IT_SMALL)->getIntsecId();
            intsecIdLarge = pRoad->getIntsec(ROAD_IT_LARGE)->getIntsecId();
            if (intsecIdLarge == _intsecIdSelect)
                changeShowSelect(intsecIdLarge, intsecIdSmall, pRoad->getRoadId());
            else
                changeShowSelect(intsecIdSmall, intsecIdLarge, pRoad->getRoadId());
            showStatus(event->pos().x(), event->pos().y(), MAP_NOID);

            //交差点モードならモード切り替え(メインウィンドウから)
            if (app.getMainWindow()->getEditMode() == MainWindow::intsec)
                app.getMainWindow()->setEditMode(MainWindow::road);

            //単路モードなら編集画面、単路付け替えモードでも選択済みなら編集画面
            else if (app.getMainWindow()->getEditMode() == MainWindow::road                   ||
                    (app.getMainWindow()->getEditMode() == MainWindow::roadRepl && roadSelected))
            {
                RoadDialog	rd(this);
                rd.init(pRoad);
                if (_roadDialogX != DIALOG_NOPOS)
                    rd.move(_roadDialogX, _roadDialogY);
                if (rd.exec() == QDialog::Accepted)
                {
                    if (rd.isDelete())
                    {
                        pMap->deleteRoad(pRoad->getRoadId());
                        changeShowSelect(MAP_NOID, MAP_NOID, MAP_NOID, true);
                    }
                    else if (rd.isDelIntsec())
                    {
                        Intsec* intsec1 = pRoad->getIntsec(ROAD_IT_SMALL);
                        Intsec* intsec2 = pRoad->getIntsec(ROAD_IT_LARGE);
                        pMap->deleteRoad(pRoad->getRoadId());
                        pMap->deleteIntsec(intsec1->getIntsecId());
                        pMap->deleteIntsec(intsec2->getIntsecId());
                        changeShowSelect(MAP_NOID, MAP_NOID, MAP_NOID, true);
                    }
                    repaintAll(true);
                }
                _roadDialogX = rd.x();
                _roadDialogY = rd.y();
            }
        }

        //単路選択なし
        else
        {
            //交差点モードなら交差点新規作成、選択変更とエラーチェックと表示、ここは全体再描画なし
            if (app.getMainWindow()->getEditMode() == MainWindow::intsec)
            {
                pIntsec = pMap->createIntsec();
                x = getMapX(_clickDragX);
                y = getMapY(_clickDragY);
                if (pIntsec == NULL)
                    QMessageBox::critical(this, tr(TITLE), tr("最大交差点IDが大きすぎます。"));
                if      (x < APP_POS_MIN || y < APP_POS_MIN )
                    QMessageBox::critical(this, tr(TITLE), tr("最大位置が小さすぎます。"));
                else if (x > APP_POS_MAX || y > APP_POS_MAX )
                    QMessageBox::critical(this, tr(TITLE), tr("最大位置が大きすぎます。"));
                else
                {
                    pIntsec->setMapPos(x, y, 0);
                    changeShowSelect(pIntsec->getIntsecId(), _intsecIdDest, _roadIdSelect);
                    // showStatus なしでも変わるが念のため
                    showStatus(event->pos().x(), event->pos().y(), pIntsec->getIntsecId());
                    pIntsec->checkError();
                    showIntsec(pIntsec);
//                  app.getMap()->debugTrace();
                }
            }
        }
    }
}