1818#include " qgsmaplayerregistry.h"
1919#include " qgsrubberband.h"
2020#include " qgsvectorlayer.h"
21+ #include < QDoubleSpinBox>
22+ #include < QGraphicsProxyWidget>
2123#include < QMouseEvent>
2224
23- QgsMapToolOffsetCurve::QgsMapToolOffsetCurve ( QgsMapCanvas* canvas ): QgsMapToolEdit( canvas ), mRubberBand( 0 ), mOriginalGeometry( 0 ), mGeometryModified( false ), mDistanceItem( 0 )
25+ QgsMapToolOffsetCurve::QgsMapToolOffsetCurve ( QgsMapCanvas* canvas ): QgsMapToolEdit( canvas ), mRubberBand( 0 ),
26+ mOriginalGeometry( 0 ), mGeometryModified( false ), mDistanceItem( 0 ), mDistanceSpinBox( 0 )
2427{
2528}
2629
2730QgsMapToolOffsetCurve::~QgsMapToolOffsetCurve ()
2831{
2932 deleteRubberBandAndGeometry ();
33+ deleteDistanceItem ();
3034}
3135
3236void QgsMapToolOffsetCurve::canvasPressEvent ( QMouseEvent * e )
@@ -57,15 +61,20 @@ void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent * e )
5761 {
5862 mOriginalGeometry = createOriginGeometry ( vl, snapResult, fet );
5963 mRubberBand = createRubberBand ();
60- mRubberBand ->setToGeometry ( mOriginalGeometry , layer );
64+ if ( mRubberBand )
65+ {
66+ mRubberBand ->setToGeometry ( mOriginalGeometry , layer );
67+ }
6168 mModifiedFeature = fet.id ();
69+ createDistanceItem ();
6270 }
6371 }
6472 }
6573}
6674
6775void QgsMapToolOffsetCurve::canvasReleaseEvent ( QMouseEvent * e )
6876{
77+ Q_UNUSED ( e );
6978 QgsVectorLayer* vlayer = currentVectorLayer ();
7079 if ( !vlayer || !mGeometryModified )
7180 {
@@ -96,11 +105,28 @@ void QgsMapToolOffsetCurve::canvasReleaseEvent( QMouseEvent * e )
96105 vlayer->destroyEditCommand ();
97106 }
98107
99- delete mRubberBand ;
100- mRubberBand = 0 ;
108+ deleteRubberBandAndGeometry () ;
109+ deleteDistanceItem () ;
101110 mCanvas ->refresh ();
102111}
103112
113+ void QgsMapToolOffsetCurve::placeOffsetCurveToValue ()
114+ {
115+ if ( mOriginalGeometry && mRubberBand && mRubberBand ->numberOfVertices () > 0 )
116+ {
117+ // is rubber band left or right of original geometry
118+ double leftOf = 0 ;
119+ const QgsPoint* firstPoint = mRubberBand ->getPoint ( 0 );
120+ if ( firstPoint )
121+ {
122+ QgsPoint minDistPoint;
123+ int beforeVertex;
124+ mOriginalGeometry ->closestSegmentWithContext ( *firstPoint, minDistPoint, beforeVertex, &leftOf );
125+ }
126+ setOffsetForRubberBand ( mDistanceSpinBox ->value (), leftOf < 0 );
127+ }
128+ }
129+
104130void QgsMapToolOffsetCurve::canvasMoveEvent ( QMouseEvent * e )
105131{
106132 if ( !mOriginalGeometry || !mRubberBand )
@@ -114,6 +140,12 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
114140 return ;
115141 }
116142
143+ if ( mDistanceItem )
144+ {
145+ mDistanceItem ->show ();
146+ mDistanceItem ->setPos ( e->posF () + QPointF ( 10 , 10 ) );
147+ }
148+
117149 mGeometryModified = true ;
118150
119151 // get offset from current position rectangular to feature
@@ -122,19 +154,13 @@ void QgsMapToolOffsetCurve::canvasMoveEvent( QMouseEvent * e )
122154 int beforeVertex;
123155 double leftOf;
124156 double offset = sqrt ( mOriginalGeometry ->closestSegmentWithContext ( layerCoords, minDistPoint, beforeVertex, &leftOf ) );
125- // qWarning( QString::number( offset ).toLocal8Bit().data() );
126157
127158 // create offset geometry using geos
128- QgsGeometry geomCopy ( * mOriginalGeometry );
129- GEOSGeometry* geosGeom = geomCopy. asGeos ();
130- if ( geosGeom )
159+ setOffsetForRubberBand ( offset, leftOf < 0 );
160+
161+ if ( mDistanceSpinBox )
131162 {
132- GEOSGeometry* offsetGeom = GEOSSingleSidedBuffer ( geosGeom, offset, 8 , 1 , 1 , ( leftOf < 0 ) ? 1 : 0 );
133- if ( offsetGeom )
134- {
135- mModifiedGeometry .fromGeos ( offsetGeom );
136- mRubberBand ->setToGeometry ( &mModifiedGeometry , layer );
137- }
163+ mDistanceSpinBox ->setValue ( offset );
138164 }
139165}
140166
@@ -182,19 +208,35 @@ QgsGeometry* QgsMapToolOffsetCurve::createOriginGeometry( QgsVectorLayer* vl, co
182208 }
183209}
184210
185- QGraphicsProxyWidget* QgsMapToolOffsetCurve::createDistanceItem ()
211+ void QgsMapToolOffsetCurve::createDistanceItem ()
186212{
187213 if ( !mCanvas )
188214 {
189- return 0 ;
215+ return ;
190216 }
191217
192- QGraphicsProxyWidget* pw = new QGraphicsProxyWidget ();
193- // Embed double spin box
194- QDoubleSpinBox* sb = new QDoubleSpinBox ();
195- pw->setWidget ( sb );
218+ deleteDistanceItem ();
196219
197- return pw;
220+ mDistanceItem = new QGraphicsProxyWidget ();
221+ mDistanceSpinBox = new QDoubleSpinBox ();
222+ mDistanceSpinBox ->setMaximum ( 99999999 );
223+ mDistanceSpinBox ->setDecimals ( 2 );
224+ mDistanceItem ->setWidget ( mDistanceSpinBox );
225+ mCanvas ->scene ()->addItem ( mDistanceItem );
226+ mDistanceSpinBox ->grabKeyboard ();
227+ mDistanceItem ->hide ();
228+ QObject::connect ( mDistanceSpinBox , SIGNAL ( editingFinished () ), this , SLOT ( placeOffsetCurveToValue () ) );
229+ }
230+
231+ void QgsMapToolOffsetCurve::deleteDistanceItem ()
232+ {
233+ if ( mDistanceSpinBox )
234+ {
235+ mDistanceSpinBox ->releaseKeyboard ();
236+ }
237+ delete mDistanceItem ;
238+ mDistanceItem = 0 ;
239+ mDistanceSpinBox = 0 ;
198240}
199241
200242void QgsMapToolOffsetCurve::deleteRubberBandAndGeometry ()
@@ -204,3 +246,30 @@ void QgsMapToolOffsetCurve::deleteRubberBandAndGeometry()
204246 delete mOriginalGeometry ;
205247 mOriginalGeometry = 0 ;
206248}
249+
250+ void QgsMapToolOffsetCurve::setOffsetForRubberBand ( double offset, bool leftSide )
251+ {
252+ if ( !mRubberBand || !mOriginalGeometry )
253+ {
254+ return ;
255+ }
256+
257+ QgsVectorLayer* sourceLayer = dynamic_cast <QgsVectorLayer*>( QgsMapLayerRegistry::instance ()->mapLayer ( mSourceLayerId ) );
258+ if ( !sourceLayer )
259+ {
260+ return ;
261+ }
262+
263+
264+ QgsGeometry geomCopy ( *mOriginalGeometry );
265+ GEOSGeometry* geosGeom = geomCopy.asGeos ();
266+ if ( geosGeom )
267+ {
268+ GEOSGeometry* offsetGeom = GEOSSingleSidedBuffer ( geosGeom, offset, 8 , 1 , 1 , leftSide ? 1 : 0 );
269+ if ( offsetGeom )
270+ {
271+ mModifiedGeometry .fromGeos ( offsetGeom );
272+ mRubberBand ->setToGeometry ( &mModifiedGeometry , sourceLayer );
273+ }
274+ }
275+ }
0 commit comments