void QgsMarkerLineSymbolLayerV2::renderPolylineCentral( const QPolygonF& points, QgsSymbolV2RenderContext& context ) { if ( points.size() > 0 ) { // calc length qreal length = 0; QPolygonF::const_iterator it = points.constBegin(); QPointF last = *it; for ( ++it; it != points.constEnd(); ++it ) { length += sqrt(( last.x() - it->x() ) * ( last.x() - it->x() ) + ( last.y() - it->y() ) * ( last.y() - it->y() ) ); last = *it; } // find the segment where the central point lies it = points.constBegin(); last = *it; qreal last_at = 0, next_at = 0; QPointF next; int segment = 0; for ( ++it; it != points.constEnd(); ++it ) { next = *it; next_at += sqrt(( last.x() - it->x() ) * ( last.x() - it->x() ) + ( last.y() - it->y() ) * ( last.y() - it->y() ) ); if ( next_at >= length / 2 ) break; // we have reached the center last = *it; last_at = next_at; segment++; } // find out the central point on segment MyLine l( last, next ); // for line angle qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at ); QPointF pt = last + ( next - last ) * k; // draw the marker double origAngle = mMarker->angle(); if ( mRotateMarker ) mMarker->setAngle( origAngle + l.angle() * 180 / M_PI ); mMarker->renderPoint( pt, context.feature(), context.renderContext(), -1, context.selected() ); if ( mRotateMarker ) mMarker->setAngle( origAngle ); } }
void ClipPainterPrivate::clipPolyObject ( const QPolygonF & polygon, QVector<QPolygonF> & clippedPolyObjects, bool isClosed ) { // mDebug() << "ClipPainter enabled." ; // Only create a new polyObject as soon as we know for sure that // the current point is on the screen. QPolygonF clippedPolyObject = QPolygonF(); const QVector<QPointF>::const_iterator itStartPoint = polygon.constBegin(); const QVector<QPointF>::const_iterator itEndPoint = polygon.constEnd(); QVector<QPointF>::const_iterator itPoint = itStartPoint; // We use a while loop to be able to cover linestrings as well as linear rings: // Linear rings require to tessellate the path from the last node to the first node // which isn't really convenient to achieve with a for loop ... bool processingLastNode = false; while ( itPoint != itEndPoint ) { m_currentPoint = (*itPoint); // mDebug() << "m_currentPoint.x()" << m_currentPoint.x() << "m_currentPOint.y()" << m_currentPoint.y(); // Figure out the sector of the current point. m_currentSector = sector( m_currentPoint ); // Initialize the variables related to the previous point. if ( itPoint == itStartPoint && processingLastNode == false ) { if ( isClosed ) { m_previousPoint = polygon.last(); // Figure out the sector of the previous point. m_previousSector = sector( m_previousPoint ); } else { m_previousSector = m_currentSector; } } // If the current point reaches a new sector, take care of clipping. if ( m_currentSector != m_previousSector ) { if ( m_currentSector == 4 || m_previousSector == 4 ) { // In this case the current or the previous point is visible on the // screen but not both. Hence we only need to clip once and require // only one interpolation for both cases. clipOnce( clippedPolyObject, clippedPolyObjects, isClosed ); } else { // This case mostly deals with lines that reach from one // sector that is located off screen to another one that // is located off screen. In this situation the line // can get clipped once, twice, or not at all. clipMultiple( clippedPolyObject, clippedPolyObjects, isClosed ); } m_previousSector = m_currentSector; } // If the current point is onscreen, just add it to our final polygon. if ( m_currentSector == 4 ) { clippedPolyObject << m_currentPoint; #ifdef MARBLE_DEBUG ++(m_debugNodeCount); #endif } m_previousPoint = m_currentPoint; // Now let's handle the case where we have a (closed) polygon and where the // last point of the polyline is outside the viewport and the start point // is inside the viewport. This needs special treatment if ( processingLastNode ) { break; } ++itPoint; if ( itPoint == itEndPoint && isClosed ) { itPoint = itStartPoint; processingLastNode = true; } } // Only add the pointer if there's node data available. if ( !clippedPolyObject.isEmpty() ) { clippedPolyObjects << clippedPolyObject; } }