gwaldron / osgearth

3D Maps for OpenSceneGraph / C++14
https://www.pelicanmapping.com/home-1/opensource
Other
1.51k stars 780 forks source link

Annotations do not render #2640

Open icenaive opened 3 weeks ago

icenaive commented 3 weeks ago

osgEarth Version (required):3.5,qt5.12

Description of the problem:annotation can not render.

I am using osg to add a two-dimensional map function on the qt platform. I am developing the function of using the mouse to click on the map to add labels. However, I found that after using qinputdialog to input text, the label text cannot be rendered, but if I write the label text You can add text annotations in the code without using Qt's dialog box for input.

What you have tried:

I tried to use non-blocking dialog boxes, lineedit and other components, but they had no effect. I tried to use the slot function to process it in the widget instead of the guieventhandeler, but it still had no effect. Later, I added the annotation first and then modified it by inputting the text. method to solve it, but the modification was not successful. However, through the code gettext, I found that the text had been modified but was not rendered. I suspected that there was a conflict in the rendering logic and I didn't know how to modify it. I hope to get an answer.

I have modified it using the method provided in the osg3.5 documentation,setsmallfeaturecullingPixelsize,setdefaultfboid. Etc not works。

Screenshot, code block, or data file that will help reproduce the issue:

bool AnnotationHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::osg::View* view = aa.asView();

if (!view || !_mapNode || !_viewer) {
    qDebug() << "view or mapnode ptr is nullptr";
    return false;
}

if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {
    if (!_isMousePressed) {
        _isMousePressed = true;
        double x = ea.getX();
        double y = ea.getY();
        osgEarth::GeoPoint mapPoint;
        osg::Vec3d worldCoords;
    }

    if (em->screenToWorld(x, y, view, worldCoords)) {
        mapPoint.fromWorld(_mapNode->getMapSRS(), worldCoords);
        createTextInput(mapPoint);
    }

    return true;
}

if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {
    _isMousePressed = false;
}

return false;
}

void AnnotationHandler::addAnnotationText(const osgEarth::GeoPoint& mapPoint, const std::string& labelText) {
    if (labelText.empty()) {
        return;
    }
}

void AnnotationHandler::addAnnotationText(const osgEarth::GeoPoint& mapPoint, const std::string& labelText) {
    if (labelText.empty()) {
        return;
    }

    osgEarth::Style placeStyle;
    osgEarth::TextSymbol* textSymbol = placeStyle.getOrCreateSymbol<osgEarth::TextSymbol>();

    if (textSymbol == nullptr) {
        qDebug() << "placeStyle get textSymbol failed";
        return;
    }

    textSymbol->alignment() = osgEarth::TextSymbol::ALIGN_CENTER_BOTTOM;
    textSymbol->encoding() = osgEarth::TextSymbol::ENCODING_UTF8;
    textSymbol->font() = "simsun.ttc";
    textSymbol->size() = 16.0f;
    textSymbol->fill()->color() = osgEarth::Color::Yellow;
    textSymbol->halo()->color() = osgEarth::Color::Black;

    osgEarth::GeoPoint adjustedPoint = mapPoint;
    adjustedPoint.alt() += 20.0;

    qDebug() << "loc x:" << adjustedPoint.x() << ", y:" << adjustedPoint.y() << ", z:" << adjustedPoint.z();

    osgEarth::PlaceNode* place = new osgEarth::PlaceNode(adjustedPoint, "test", placeStyle);

    if (place == nullptr) {
        qDebug() << "place get ptr failed";
        return;
    }

    _mapNode->addChild(place);
    _viewer->frame();
}

void AnnotationHandler::createTextInput(const osgEarth::GeoPoint& mapPoint) {
    bool ok = true;
    QString text = "Test";

    qDebug() << "loc x:" << mapPoint.x() << ", y:" << mapPoint.y() << ", z:" << mapPoint.z();

    // text = QInputDialog::getText(nullptr, "输入标注内容", "输入标注的文本内容", QLineEdit::Normal, "", &ok);

    qDebug() << "获取的文本是:" << text << ", is_ok:" << ok;

    if (ok && !text.isEmpty()) {
        std::string labelText = text.toUtf8().constData();
        qDebug() << "get text std: " << QString::fromStdString(labelText);
        addAnnotationText(mapPoint, labelText);
    }
}

if i not use qinputdialog it works。

gwaldron commented 1 week ago

Hi, did you ever figure this out? I'm afraid we don't have much Qt experience on this end so we are relying on others to help you.

My only guess would be: after the click, instead of immediately trying to open a Qt dialog from inside the event handler, queue up the request and open your dialog from the main Qt loop. Maybe there is a problem launching a dialog from the OSG event traversal.

Let us know if you find a solution.