Skip to content

Commit

Permalink
highlight identified feature using real feature shape
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed Jan 12, 2014
1 parent d59ab80 commit a18b4a3
Show file tree
Hide file tree
Showing 15 changed files with 294 additions and 62 deletions.
6 changes: 6 additions & 0 deletions python/core/qgsfeaturestore.sip
Expand Up @@ -28,6 +28,12 @@ class QgsFeatureStore
/** Set crs */
void setCrs( const QgsCoordinateReferenceSystem& crs );

/** Add feature. Feature's fields will be set to pointer to the store fields.
* @param feature
* @note added in 2.1
*/
void addFeature ( const QgsFeature& feature );

/** Get features list reference */
QgsFeatureList& features();

Expand Down
4 changes: 4 additions & 0 deletions python/core/qgsrectangle.sip
Expand Up @@ -58,6 +58,10 @@ class QgsRectangle
QgsPoint center() const;
//! Scale the rectangle around its center point
void scale( double, const QgsPoint *c = 0 );
void scale( double scaleFactor, double centerX, double centerY );
/** Get rectangle enlarged by buffer.
* @note added in 2.1 */
QgsRectangle buffer( double width );
//! Expand the rectangle to support zoom out scaling
//! return the intersection with the given rectangle
QgsRectangle intersect( const QgsRectangle *rect ) const;
Expand Down
6 changes: 6 additions & 0 deletions python/core/symbology-ng/qgsfillsymbollayerv2.sip
Expand Up @@ -40,6 +40,12 @@ class QgsSimpleFillSymbolLayerV2 : QgsFillSymbolLayerV2
QColor borderColor() const;
void setBorderColor( QColor borderColor );

virtual QColor outlineColor() const;
virtual void setOutlineColor( const QColor& color );

virtual QColor fillColor() const;
virtual void setFillColor( const QColor& color );

Qt::PenStyle borderStyle() const;
void setBorderStyle( Qt::PenStyle borderStyle );

Expand Down
6 changes: 6 additions & 0 deletions python/core/symbology-ng/qgsmarkersymbollayerv2.sip
Expand Up @@ -42,6 +42,12 @@ class QgsSimpleMarkerSymbolLayerV2 : QgsMarkerSymbolLayerV2
double outlineWidth() const;
void setOutlineWidth( double w );

virtual QColor outlineColor() const;
virtual void setOutlineColor( const QColor& color );

virtual QColor fillColor() const;
virtual void setFillColor( const QColor& color );

QgsSymbolV2::OutputUnit outlineWidthUnit() const;
void setOutlineWidthUnit( QgsSymbolV2::OutputUnit u );

Expand Down
4 changes: 4 additions & 0 deletions python/core/symbology-ng/qgssymbollayerv2.sip
Expand Up @@ -63,6 +63,10 @@ class QgsSymbolLayerV2
// not necessarily supported by all symbol layers...
virtual void setColor( const QColor& color );
virtual QColor color() const;
virtual void setOutlineColor( const QColor& color );
virtual QColor outlineColor() const;
virtual void setFillColor( const QColor& color );
virtual QColor fillColor() const;

virtual ~QgsSymbolLayerV2();

Expand Down
16 changes: 13 additions & 3 deletions src/app/qgsidentifyresultsdialog.cpp
Expand Up @@ -1172,14 +1172,24 @@ void QgsIdentifyResultsDialog::highlightFeature( QTreeWidgetItem *item )
if ( !featItem->feature().geometry() || featItem->feature().geometry()->wkbType() == QGis::WKBUnknown )
return;

QgsHighlight *h = new QgsHighlight( mCanvas, featItem->feature().geometry(), layer );
if ( h )
if ( vlayer )
{
h->setWidth( 2 );
QgsHighlight *h = new QgsHighlight( mCanvas, featItem->feature(), vlayer );
h->setColor( Qt::red );
h->show();
mHighlights.insert( featItem, h );
}
else
{
QgsHighlight *h = new QgsHighlight( mCanvas, featItem->feature().geometry(), layer );
if ( h )
{
h->setWidth( 2 );
h->setColor( Qt::red );
h->show();
mHighlights.insert( featItem, h );
}
}
}

void QgsIdentifyResultsDialog::zoomToFeature()
Expand Down
15 changes: 15 additions & 0 deletions src/core/qgsfeaturestore.cpp
Expand Up @@ -37,3 +37,18 @@ QgsFeatureStore::~QgsFeatureStore( )
{
}

void QgsFeatureStore::setFields( const QgsFields & fields )
{
mFields = fields;
foreach ( QgsFeature feature, mFeatures )
{
feature.setFields( &mFields );
}
}

void QgsFeatureStore::addFeature( const QgsFeature& feature )
{
QgsFeature f( feature );
f.setFields( &mFields );
mFeatures.append( f );
}
10 changes: 8 additions & 2 deletions src/core/qgsfeaturestore.h
Expand Up @@ -45,15 +45,21 @@ class CORE_EXPORT QgsFeatureStore
/** Get fields list */
QgsFields& fields() { return mFields; }

/** Set fields */
void setFields( const QgsFields & fields ) { mFields = fields; }
/** Set fields. Resets feauters fields to pointer to new internal fields. */
void setFields( const QgsFields & fields );

/** Get crs */
QgsCoordinateReferenceSystem crs() const { return mCrs; }

/** Set crs */
void setCrs( const QgsCoordinateReferenceSystem& crs ) { mCrs = crs; }

/** Add feature. Feature's fields will be set to pointer to the store fields.
* @param feature
* @note added in 2.1
*/
void addFeature( const QgsFeature& feature );

/** Get features list reference */
QgsFeatureList& features() { return mFeatures; }

Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsrectangle.cpp
Expand Up @@ -122,6 +122,11 @@ void QgsRectangle::scale( double scaleFactor, double centerX, double centerY )
ymax = centerY + newHeight / 2.0;
}

QgsRectangle QgsRectangle::buffer( double width )
{
return QgsRectangle( xmin - width, ymin - width, xmax + width, ymax + width );
}

QgsRectangle QgsRectangle::intersect( const QgsRectangle * rect ) const
{
QgsRectangle intersection = QgsRectangle();
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgsrectangle.h
Expand Up @@ -82,6 +82,9 @@ class CORE_EXPORT QgsRectangle
//! Scale the rectangle around its center point
void scale( double scaleFactor, const QgsPoint *c = 0 );
void scale( double scaleFactor, double centerX, double centerY );
/** Get rectangle enlarged by buffer.
* @note added in 2.1 */
QgsRectangle buffer( double width );
//! return the intersection with the given rectangle
QgsRectangle intersect( const QgsRectangle *rect ) const;
//! returns true when rectangle intersects with other rectangle
Expand Down
14 changes: 14 additions & 0 deletions src/core/symbology-ng/qgsfillsymbollayerv2.h
Expand Up @@ -65,6 +65,20 @@ class CORE_EXPORT QgsSimpleFillSymbolLayerV2 : public QgsFillSymbolLayerV2
QColor borderColor() const { return mBorderColor; }
void setBorderColor( QColor borderColor ) { mBorderColor = borderColor; }

/** Get outline color.
* @note added in 2.1 */
QColor outlineColor() const { return borderColor(); }
/** Set outline color.
* @note added in 2.1 */
void setOutlineColor( const QColor& color ) { setBorderColor( color ); }

/** Get fill color.
* @note added in 2.1 */
QColor fillColor() const { return color(); }
/** Set fill color.
* @note added in 2.1 */
void setFillColor( const QColor& color ) { setColor( color ); }

Qt::PenStyle borderStyle() const { return mBorderStyle; }
void setBorderStyle( Qt::PenStyle borderStyle ) { mBorderStyle = borderStyle; }

Expand Down
16 changes: 16 additions & 0 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.h
Expand Up @@ -48,6 +48,8 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2

// implemented from base classes



QString layerType() const;

void startRender( QgsSymbolV2RenderContext& context );
Expand All @@ -73,6 +75,20 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
Qt::PenStyle outlineStyle() const { return mOutlineStyle; }
void setOutlineStyle( Qt::PenStyle outlineStyle ) { mOutlineStyle = outlineStyle; }

/** Get outline color.
* @note added in 2.1 */
QColor outlineColor() const { return borderColor(); }
/** Set outline color.
* @note added in 2.1 */
void setOutlineColor( const QColor& color ) { setBorderColor( color ); }

/** Get fill color.
* @note added in 2.1 */
QColor fillColor() const { return color(); }
/** Set fill color.
* @note added in 2.1 */
void setFillColor( const QColor& color ) { setColor( color ); }

double outlineWidth() const { return mOutlineWidth; }
void setOutlineWidth( double w ) { mOutlineWidth = w; }

Expand Down
14 changes: 13 additions & 1 deletion src/core/symbology-ng/qgssymbollayerv2.h
Expand Up @@ -47,8 +47,20 @@ class CORE_EXPORT QgsSymbolLayerV2
public:

// not necessarily supported by all symbol layers...
virtual void setColor( const QColor& color ) { mColor = color; }
virtual QColor color() const { return mColor; }
virtual void setColor( const QColor& color ) { mColor = color; }
/** Set outline color. Supported by marker and fill layers.
* @note added in 2.1 */
virtual void setOutlineColor( const QColor& color ) { Q_UNUSED( color ); }
/** Get outline color. Supported by marker and fill layers.
* @note added in 2.1 */
virtual QColor outlineColor() const { return QColor(); }
/** Set fill color. Supported by marker and fill layers.
* @note added in 2.1 */
virtual void setFillColor( const QColor& color ) { Q_UNUSED( color ); }
/** Get fill color. Supported by marker and fill layers.
* @note added in 2.1 */
virtual QColor fillColor() const { return QColor(); }

virtual ~QgsSymbolLayerV2() { removeDataDefinedProperties(); }

Expand Down

11 comments on commit a18b4a3

@haubourg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Radim, could you explain qhat the commit does? I remember we founded generalisation for identify highlight because it was extremely slow for big features and sometimes led to crash.. Could your commit reintroduce that?
Thanks for your lights
Régis

@blazek
Copy link
Member Author

@blazek blazek commented on a18b4a3 Jan 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The highlight was originally using a rectangle, simple line or simple polygon ignoring feature symbology. The commit renders highlighted features using current renderer with additional highlight symbol layer over each original symbol layer so that the whole current appearance of the feature including all markers, patterns etc. is highlighted.

"Real shape" in comment was meant for symbology not for geometry. It is true however, that original geometry simplification in QgsHighlight::paintPolygon() is not used anymore. OTOH, rendering is done using standard renderer with all its tricks (cut by extent, simplification...) so I believe that it may not crash (because the same methods are used to render the layer itself). It may be slower (of course, rendering of true symbology may be slower if it is complex) but it should not become so slow to make it unusable because, as said, the same algorithm is used to render the whole layer.

Could you please test with your data and computer?

@timlinux
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me the selection post Radim's patch is working very nice and quickly even for layers with quite complex polygons.

@haubourg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Radim, will test when osgeo4w builds gets it. I have some huge 400 000 vertices polygons full of rings and islands for that ( crazy dataset... )
Régis

@haubourg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi I tested today, and it works well and fast. Not sure if it is a problem, but I was amazed when I zoomed out.. identified object appears clipped to the old extent.. Not totally sure this is good from a user point of view the real object is not shown entirely. By myself, conscious of the performance gain, I do accept that behaviour. Maybe should we request user comments on this?

@timlinux
Copy link
Member

@timlinux timlinux commented on a18b4a3 Jan 14, 2014 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@blazek
Copy link
Member Author

@blazek blazek commented on a18b4a3 Jan 14, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zoom out: I know about it. I'll fix that.

@blazek
Copy link
Member Author

@blazek blazek commented on a18b4a3 Jan 16, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have fixed the clip on zoom out.

BTW, the highlight is painted 10 times when mouse enters or leaves map canvas, that may be additional source of possible slowness.

@blazek
Copy link
Member Author

@blazek blazek commented on a18b4a3 Jan 27, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @slarosa pointed out, new highlight covers features in other layer. It is because the feature is rendered with all its symbol layers + highlight layer above each. That covers all other features. The reason for rendering all original symbol layers is that otherwise the lower symbol layers become visible if the highlight is only transparent (lower transparent highlight layers are visible).

I'll try to fix that using blending modes.

@blazek
Copy link
Member Author

@blazek blazek commented on a18b4a3 Feb 9, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be fixed in b05c93c.

@slarosa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

Please sign in to comment.