/*! * \brief TextAnnotation::duplicate * Duplicates the shape. */ void TextAnnotation::duplicate() { TextAnnotation *pTextAnnotation = new TextAnnotation("", mpGraphicsView); pTextAnnotation->updateShape(this); QPointF gridStep(mpGraphicsView->mCoOrdinateSystem.getHorizontalGridStep() * 5, mpGraphicsView->mCoOrdinateSystem.getVerticalGridStep() * 5); pTextAnnotation->setOrigin(mOrigin + gridStep); pTextAnnotation->initializeTransformation(); pTextAnnotation->drawCornerItems(); pTextAnnotation->setCornerItemsActiveOrPassive(); pTextAnnotation->update(); mpGraphicsView->getModelWidget()->getUndoStack()->push(new AddShapeCommand(pTextAnnotation)); mpGraphicsView->getModelWidget()->getLibraryTreeItem()->emitShapeAdded(pTextAnnotation, mpGraphicsView); setSelected(false); pTextAnnotation->setSelected(true); }
osg::Node* BuildTextOperator::operator()(const FeatureList& features, const TextSymbol* symbol, const FilterContext& context) { if (!symbol) return 0; std::set< std::string > labelNames; bool removeDuplicateLabels = symbol->removeDuplicateLabels().isSet() ? symbol->removeDuplicateLabels().get() : false; osg::Geode* result = new osg::Geode; for (FeatureList::const_iterator itr = features.begin(); itr != features.end(); ++itr) { Feature* feature = itr->get(); if (!feature->getGeometry()) continue; std::string text; //If the feature is a TextAnnotation, just get the value from it TextAnnotation* annotation = dynamic_cast<TextAnnotation*>(feature); if (annotation) { text = annotation->text(); } else if (symbol->content().isSet()) { //Get the text from the specified content and referenced attributes std::string content = symbol->content().value(); text = parseAttributes(feature, content, symbol->contentAttributeDelimiter().value()); } else if (symbol->attribute().isSet()) { //Get the text from the specified attribute std::string attr = symbol->attribute().value(); text = feature->getAttr(attr); } if (text.empty()) continue; //See if there is a duplicate name if (removeDuplicateLabels && labelNames.find(text) != labelNames.end()) continue; bool rotateToScreen = symbol->rotateToScreen().isSet() ? symbol->rotateToScreen().value() : false; // find the centroid osg::Vec3d position; osg::Quat orientation; GeometryIterator gi( feature->getGeometry() ); while( gi.hasMore() ) { Geometry* geom = gi.next(); TextSymbol::LinePlacement linePlacement = symbol->linePlacement().isSet() ? symbol->linePlacement().get() : TextSymbol::LINEPLACEMENT_ALONG_LINE; if (geom->getType() == Symbology::Geometry::TYPE_LINESTRING && linePlacement == TextSymbol::LINEPLACEMENT_ALONG_LINE) { //Compute the "middle" of the line string LineString* lineString = static_cast<LineString*>(geom); double length = lineString->getLength(); double center = length / 2.0; osg::Vec3d start, end; if (lineString->getSegment(center, start, end)) { TextSymbol::LineOrientation lineOrientation = symbol->lineOrientation().isSet() ? symbol->lineOrientation().get() : TextSymbol::LINEORIENTATION_HORIZONTAL; position = (end + start) / 2.0; //We don't want to orient the text at all if we are rotating to the screen if (!rotateToScreen && lineOrientation != TextSymbol::LINEORIENTATION_HORIZONTAL) { osg::Vec3d dir = (end-start); dir.normalize(); if (lineOrientation == TextSymbol::LINEORIENTATION_PERPENDICULAR) { osg::Vec3d up(0,0,1); const SpatialReference* srs = context.profile()->getSRS(); if (srs && context.isGeocentric() && srs->getEllipsoid()) { osg::Vec3d w = context.toWorld( position ); up = srs->getEllipsoid()->computeLocalUpVector(w.x(), w.y(), w.z()); } dir = up ^ dir; } orientation.makeRotate(osg::Vec3d(1,0,0), dir); } } else { //Fall back on using the center position = lineString->getBounds().center(); } } else { position = geom->getBounds().center(); } } osgText::Text* t = new osgText::Text(); t->setText( text ); std::string font = "fonts/arial.ttf"; if (symbol->font().isSet() && !symbol->font().get().empty()) { font = symbol->font().value(); } t->setFont( font ); t->setAutoRotateToScreen( rotateToScreen ); TextSymbol::SizeMode sizeMode = symbol->sizeMode().isSet() ? symbol->sizeMode().get() : TextSymbol::SIZEMODE_SCREEN; if (sizeMode == TextSymbol::SIZEMODE_SCREEN) { t->setCharacterSizeMode( osgText::TextBase::SCREEN_COORDS ); } else if (sizeMode == TextSymbol::SIZEMODE_OBJECT) { t->setCharacterSizeMode( osgText::TextBase::OBJECT_COORDS ); } float size = symbol->size().isSet() ? symbol->size().get() : 32.0f; t->setCharacterSize( size ); //t->setCharacterSizeMode( osgText::TextBase::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT ); //t->setCharacterSize( 300000.0f ); t->setPosition( position ); t->setRotation( orientation); t->setAlignment( osgText::TextBase::CENTER_CENTER ); t->getOrCreateStateSet()->setAttributeAndModes( new osg::Depth(osg::Depth::ALWAYS), osg::StateAttribute::ON ); t->getOrCreateStateSet()->setRenderBinDetails( 99999, "RenderBin" ); // apply styling as appropriate: osg::Vec4f textColor = symbol->fill()->color(); osg::Vec4f haloColor = symbol->halo()->color(); t->setColor( textColor ); t->setBackdropColor( haloColor ); t->setBackdropType( osgText::Text::OUTLINE ); if ( context.isGeocentric() ) { // install a cluster culler t->setCullCallback( new CullPlaneCallback( position * context.inverseReferenceFrame() ) ); } result->addDrawable( t ); if (removeDuplicateLabels) labelNames.insert(text); } return result; }
bool ModelValidator::isValid(const TextAnnotation& textAnnotation, bool allowDefaults/* = false*/) { RETURN_IF_STR_EMPTY(textAnnotation.GetText(), "Annotation Text"); if (textAnnotation.GetConnectorPoints() != NULL) { RETURN_IF_NOT_VALID1(*textAnnotation.GetConnectorPoints(), allowDefaults, "Text connection points are invalid"); if (textAnnotation.GetConnectorPoints()->GetSpatialCoordinateCollection().size() > 2) RETURN_WITH_ERROR("No more than two text connection points are allowed"); } if (!allowDefaults) { RETURN_IF_STR_EMPTY(textAnnotation.GetFont(), "Font"); RETURN_IF_STR_EMPTY(textAnnotation.GetFontColor(), "Font Color"); RETURN_IF_STR_EMPTY(textAnnotation.GetFontEffect(), "Font Effect"); RETURN_IF_STR_EMPTY(textAnnotation.GetFontSize(), "Font Size"); RETURN_IF_STR_EMPTY(textAnnotation.GetFontStyle(), "Font Style"); RETURN_IF_STR_EMPTY(textAnnotation.GetFontOpacity(), "Font Opacity"); RETURN_IF_STR_EMPTY(textAnnotation.GetTextJustify(), "Text Justify"); } return true; }
/*! * \brief TextAnnotation::duplicate * Creates a duplicate of this object. */ void TextAnnotation::duplicate() { TextAnnotation *pTextAnnotation = new TextAnnotation("", false, mpGraphicsView); QPointF gridStep(mpGraphicsView->getCoOrdinateSystem()->getHorizontalGridStep(), mpGraphicsView->getCoOrdinateSystem()->getVerticalGridStep()); pTextAnnotation->setOrigin(mOrigin + gridStep); pTextAnnotation->setRotationAngle(mRotation); pTextAnnotation->initializeTransformation(); pTextAnnotation->setLineColor(getLineColor()); pTextAnnotation->setFillColor(getFillColor()); pTextAnnotation->setLinePattern(getLinePattern()); pTextAnnotation->setFillPattern(getFillPattern()); pTextAnnotation->setLineThickness(getLineThickness()); pTextAnnotation->setExtents(getExtents()); pTextAnnotation->setTextString(getTextString()); pTextAnnotation->setFontSize(getFontSize()); pTextAnnotation->setFontName(getFontName()); pTextAnnotation->setTextStyles(getTextStyles()); pTextAnnotation->setTextHorizontalAlignment(getTextHorizontalAlignment()); pTextAnnotation->drawCornerItems(); pTextAnnotation->setCornerItemsPassive(); pTextAnnotation->update(); mpGraphicsView->addClassAnnotation(); mpGraphicsView->setCanAddClassAnnotation(true); }