Beispiel #1
0
QPointF Meshing::addMiddlePoint(int id)
{
    QPointF point(0,0);
    QPolygonF poly = mesh_.at(id);
    if(poly.isEmpty())
        return point;

    if(!poly.isClosed())
        poly << poly.at(0);

    mesh_.removeAt(id);

    for(int i=0;i<poly.size()-1;i++)
        point += poly.at(i);
    point /= (double)(poly.size()-1);

    /*while(!poly.containsPoint(point,Qt::WindingFill)){
        point += QPointF(-50+rand()%100,-50+rand()%100);
    }*/

    for(int i=0;i<poly.size()-1;i++){
        QPolygonF p;
        p << poly.at(i) << poly.at(i+1) << point << poly.at(i);
        mesh_.push_back(p);
    }
    return point;
}
Beispiel #2
0
static void ENP_centroid( const QPolygonF &pX, double &cx, double &cy )
{
  // http://stackoverflow.com/questions/2792443/finding-the-centroid-of-a-polygon/2792459#2792459
  cx = 0;
  cy = 0;

  if ( pX.isEmpty() )
    return;

  double signedArea = 0.0;

  // For all vertices except last
  int i = 0;
  for ( ; i < pX.size() - 1; ++i )
  {
    ENP_centroid_step( pX, cx, cy, signedArea, i, i + 1 );
  }
  // Do last vertex separately to avoid performing an expensive
  // modulus operation in each iteration.
  ENP_centroid_step( pX, cx, cy, signedArea, i, 0 );

  signedArea *= 0.5;
  cx /= ( 6.0 * signedArea );
  cy /= ( 6.0 * signedArea );
}
Beispiel #3
0
void TableTitleView::resizeTitle(float width, float height)
{
	QPolygonF pol;
	pol=box->polygon();

	if(pol.isEmpty())
	{
		pol.append(QPointF(0.0f,0.0f));
		pol.append(QPointF(1.0f,0.0f));
		pol.append(QPointF(1.0f,1.0f));
		pol.append(QPointF(0.0f,1.0f));
	}

	this->resizePolygon(pol, width, height);
	box->setPolygon(pol);

	if(schema_name->text()==" ")
		obj_name->setPos((box->boundingRect().width() - obj_name->boundingRect().width())/2.0f, VERT_SPACING);
	else
	{
		schema_name->setPos((box->boundingRect().width() - (schema_name->boundingRect().width() + obj_name->boundingRect().width()))/2.0f, VERT_SPACING);
		obj_name->setPos(schema_name->pos().x() + schema_name->boundingRect().width(), VERT_SPACING);
		obj_name->setPos(schema_name->pos().x() + schema_name->boundingRect().width(), VERT_SPACING);
	}

	this->bounding_rect.setTopLeft(this->pos());
	this->bounding_rect.setSize(QSizeF(box->boundingRect().width(), box->boundingRect().height()));
}
void DiveCalculatedCeiling::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	// We don't have enougth data to calculate things, quit.
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;
	AbstractProfilePolygonItem::modelDataChanged(topLeft, bottomRight);
	// Add 2 points to close the polygon.
	QPolygonF poly = polygon();
	if (poly.isEmpty())
		return;
	QPointF p1 = poly.first();
	QPointF p2 = poly.last();

	poly.prepend(QPointF(p1.x(), vAxis->posAtValue(0)));
	poly.append(QPointF(p2.x(), vAxis->posAtValue(0)));
	setPolygon(poly);

	QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom());
	pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW));
	pat.setColorAt(1, getColor(CALC_CEILING_DEEP));
	setPen(QPen(QBrush(Qt::NoBrush), 0));
	setBrush(pat);

	gradientFactor->setX(poly.boundingRect().width() / 2 + poly.boundingRect().x());
	DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
	if (plannerModel->isPlanner()) {
		struct diveplan &diveplan = plannerModel->getDiveplan();
		gradientFactor->setText(QString("GF %1/%2").arg(diveplan.gflow).arg(diveplan.gfhigh));
	} else {
		gradientFactor->setText(QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh));
	}
}
void QgsMarkerLineSymbolLayerV2::renderOffsetVertexAlongLine( const QPolygonF &points, int vertex, double distance, QgsSymbolV2RenderContext& context )
{
  if ( points.isEmpty() )
    return;

  QgsRenderContext& rc = context.renderContext();
  double origAngle = mMarker->angle();
  if ( distance == 0 )
  {
    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      bool isRing = false;
      if ( points.first() == points.last() )
        isRing = true;
      double angle = markerAngle( points, isRing, vertex );
      mMarker->setAngle( origAngle + angle * 180 / M_PI );
    }
    mMarker->renderPoint( points[vertex], context.feature(), rc, -1, context.selected() );
    return;
  }

  int pointIncrement = distance > 0 ? 1 : -1;
  QPointF previousPoint = points[vertex];
  int startPoint = distance > 0 ? qMin( vertex + 1, points.count() - 1 ) : qMax( vertex - 1, 0 );
  int endPoint = distance > 0 ? points.count() - 1 : 0;
  double distanceLeft = qAbs( distance );

  for ( int i = startPoint; pointIncrement > 0 ? i <= endPoint : i >= endPoint; i += pointIncrement )
  {
    const QPointF& pt = points[i];

    if ( previousPoint == pt ) // must not be equal!
      continue;

    // create line segment
    MyLine l( previousPoint, pt );

    if ( distanceLeft < l.length() )
    {
      //destination point is in current segment
      QPointF markerPoint = previousPoint + l.diffForInterval( distanceLeft );
      // rotate marker (if desired)
      if ( mRotateMarker )
      {
        mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
      }
      mMarker->renderPoint( markerPoint, context.feature(), rc, -1, context.selected() );
      return;
    }

    distanceLeft -= l.length();
    previousPoint = pt;
  }

  //didn't find point
  return;
}
void testShapedGradientPainterImpl(const QPolygonF &selectionPolygon,
                                   const QString &testName,
                                   const QPolygonF &selectionErasePolygon = QPolygonF())
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);

    QRect imageRect(0,0,300,300);

    KisSelectionSP selection = new KisSelection();
    KisPixelSelectionSP pixelSelection = selection->pixelSelection();

    KisPainter selPainter(pixelSelection);
    selPainter.setFillStyle(KisPainter::FillStyleForegroundColor);
    selPainter.setPaintColor(KoColor(Qt::white, pixelSelection->colorSpace()));
    selPainter.paintPolygon(selectionPolygon);

    if (!selectionErasePolygon.isEmpty()) {
        selPainter.setCompositeOp(COMPOSITE_ERASE);
        selPainter.setPaintColor(KoColor(Qt::white, pixelSelection->colorSpace()));
        selPainter.paintPolygon(selectionErasePolygon);
    }

    selPainter.end();

    pixelSelection->invalidateOutlineCache();

    pixelSelection->convertToQImage(0, imageRect).save("sgt_selection.png");

    QLinearGradient testGradient;
    testGradient.setColorAt(0.0, Qt::white);
    testGradient.setColorAt(0.5, Qt::green);
    testGradient.setColorAt(1.0, Qt::black);
    testGradient.setSpread(QGradient::ReflectSpread);
    QScopedPointer<KoStopGradient> gradient(
        KoStopGradient::fromQGradient(&testGradient));

    KisGradientPainter gc(dev, selection);
    gc.setGradient(gradient.data());
    gc.setGradientShape(KisGradientPainter::GradientShapePolygonal);

    gc.paintGradient(selectionPolygon.boundingRect().topLeft(),
                     selectionPolygon.boundingRect().bottomRight(),
                     KisGradientPainter::GradientRepeatNone,
                     0,
                     false,
                     imageRect.x(),
                     imageRect.y(),
                     imageRect.width(),
                     imageRect.height());

    QVERIFY(TestUtil::checkQImageExternal(dev->convertToQImage(0, imageRect),
                                          "shaped_gradient",
                                          "fill",
                                          testName, 1, 1, 0));
}
QPolygonF polygonFromPath(potrace_path_t *path,
                          int bezierPrecision)
{
  QPolygonF poly;
  if(!path) return poly;

  int n = path->curve.n;
  int *tag = path->curve.tag;
  potrace_dpoint_t (*c)[3] = path->curve.c;
  for(int i = 0; i < n; ++i)
  {
    switch (tag[i])
    {
    case POTRACE_CORNER:
      poly << QPointF(c[i][1].x, c[i][1].y)
           << QPointF(c[i][2].x, c[i][2].y);
      break;
    case POTRACE_CURVETO:
    {
      QPointF pa, pb, pc, pd;
      pa = poly.isEmpty()? QPointF(c[n-1][2].x, c[n-1][2].y) :
                           poly.last();
      pb = QPointF(c[i][0].x, c[i][0].y);
      pc = QPointF(c[i][1].x, c[i][1].y);
      pd = QPointF(c[i][2].x, c[i][2].y);
      for(int i = 1; i <= bezierPrecision; ++i)
      {
        poly << bezier(pa, pb, pc, pd, static_cast<qreal>(i)/bezierPrecision);
      }
    }
      break;
    }
  }

  if(!poly.isEmpty() && poly.first() == poly.last())
  {
    poly.remove(poly.size()-1);
  }

  return poly;
}
Beispiel #8
0
void LineWidthItem::paintContents(QPainter *p) {
  static QPolygonF pp;
  if (pp.isEmpty()) 
    for (double x=10; x<22.1; x+=0.5) 
      pp << QPointF(x, 16-(x-16)-sin(.7*(x-12)));
  p->setPen(QPen(c, lw));
  p->setBrush(Qt::NoBrush);
  if (straight)
    p->drawLine(QLineF(QPointF(10, 22), QPointF(22, 10)));
  else
    p->drawPolyline(pp);
}
/**
 * @brief Function to show the plot
 *
 * @param _plot
 * @param _residualVO
 * @param _points
 * @return QPolygonF
 */
QPolygonF ResidualTabHelper::showPlot(QwtPlot * _plot, SolverResidualVO * _residualVO,
                                 QPolygonF _points)
{
    if (_points.isEmpty())
         _points  << QPointF(0,0) ;

    int _iteration = _residualVO->getIteration();
    _points << QPointF(50+_iteration,100+_iteration );
    _curve->setSamples(_points);
    _curve->attach(_plot );
    _plot->replot();
    _plot->show();
    return _points;
}
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
{
  if ( points.isEmpty() )
    return;

  QgsRenderContext& rc = context.renderContext();

  double origAngle = mMarker->angle();
  int i, maxCount;
  bool isRing = false;

  if ( placement == FirstVertex )
  {
    i = 0;
    maxCount = 1;
  }
  else if ( placement == LastVertex )
  {
    i = points.count() - 1;
    maxCount = points.count();
  }
  else
  {
    i = 0;
    maxCount = points.count();
    if ( points.first() == points.last() )
      isRing = true;
  }

  for ( ; i < maxCount; ++i )
  {
    if ( isRing && placement == Vertex && i == points.count() - 1 )
    {
      continue; // don't draw the last marker - it has been drawn already
    }
    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      double angle = markerAngle( points, isRing, i );
      mMarker->setAngle( origAngle + angle * 180 / M_PI );
    }

    mMarker->renderPoint( points.at( i ), context.feature(), rc, -1, context.selected() );
  }

  // restore original rotation
  mMarker->setAngle( origAngle );
}
Beispiel #11
0
void TestConnection::testRouteSimple()
{
    MockCanvas canvas;
    KShapeManager manager(&canvas);

    KShape shape1;
    shape1.setPosition(30, 50);
    shape1.setSize(100, 200);
    manager.addShape(&shape1);

    KShapeConnection connection;
    connection.setStartPoint(&shape1, 0);
    connection.setEndPoint(150, 300);

    QPolygonF path = manager.routeConnection(&connection);
    QVERIFY(!path.isEmpty());
    // TODO need to start at start and end at end
}
Beispiel #12
0
QString QTikzPicturePrivate::toTikzPath(const QPolygonF & polygon) const
{
    if (polygon.isEmpty()) return QString();

    const int end = polygon.size() - polygon.isClosed() ? 1 : 0;

    QString path;
    for (int i = 0; i < end; ++i) {
        if (i == 0) {
            path = toCoord(polygon[i]);
        } else if (i == end - 1) {
            path += " -- cycle";
        } else {
            path += " -- " + toCoord(polygon[i]);
        }
    }

    return path;
}
Beispiel #13
0
/**
 * Extends or shrinks a line segment in such a way that if you draw perpendicular
 * lines through its endpoints, the given polygon would be squeezed between these
 * two perpendiculars.  This ensures that the resulting line segment intersects
 * all the polygon edges it can possibly intersect.
 */
QLineF
PageLayout::extendToCover(QLineF const& line, QPolygonF const& poly)
{
	if (poly.isEmpty()) {
		return line;
	}

	// Project every vertex of the polygon onto the line and take extremas.

	double min = NumericTraits<double>::max();
	double max = NumericTraits<double>::min();
	ToLineProjector const projector(line);

	BOOST_FOREACH(QPointF const& pt, poly) {
		double const scalar = projector.projectionScalar(pt);
		if (scalar < min) {
			min = scalar;
		}
		if (scalar > max) {
			max = scalar;
		}
	}
Beispiel #14
0
// Check whether a point is on the border
static bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p)
{
    // null border doesn't contain points
    if (border.isEmpty())
        return false;

    QPointF p1 = border.at(0);
    QPointF p2;

    for (int i = 1; i < border.size(); ++i) {
        p2 = border.at(i);
        if (areCollinear(p, p1, p2)
                // Once we know that the points are collinear we
                // only need to check one of the coordinates
                && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ?
                        withinRange(p.x(), p1.x(), p2.x()) :
                        withinRange(p.y(), p1.y(), p2.y()))) {
            return true;
        }
        p1 = p2;
    }
    return false;
}
static QList<QPolygonF> splitToPolygons(const QList<QPointF> &line)
{
    QList<QPolygonF> results;
    QPolygonF polygon;
    foreach (const QPointF &pt, line)
    {
//        if (!QIG::isNullValue(pt.y())) // y为时间轴或者深度轴
//        {
//            polygon.append(pt);
//        }
//        else if (!polygon.isEmpty())
//        {
//            results.append(polygon);
//            polygon.clear();
//        }
    }

    if (!polygon.isEmpty())
    {
        results.append(polygon);
    }

    return results;
}
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
{
  if ( points.isEmpty() )
    return;

  QgsRenderContext& rc = context.renderContext();

  double origAngle = mMarker->angle();
  double angle;
  int i, maxCount;
  bool isRing = false;

  if ( placement == FirstVertex )
  {
    i = 0;
    maxCount = 1;
  }
  else if ( placement == LastVertex )
  {
    i = points.count() - 1;
    maxCount = points.count();
  }
  else
  {
    i = 0;
    maxCount = points.count();
    if ( points.first() == points.last() )
      isRing = true;
  }

  for ( ; i < maxCount; ++i )
  {
    const QPointF& pt = points[i];

    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      if ( i == 0 )
      {
        if ( !isRing )
        {
          // use first segment's angle
          const QPointF& nextPt = points[i+1];
          if ( pt == nextPt )
            continue;
          angle = MyLine( pt, nextPt ).angle();
        }
        else
        {
          // closed ring: use average angle between first and last segment
          const QPointF& prevPt = points[points.count() - 2];
          const QPointF& nextPt = points[1];
          if ( prevPt == pt || nextPt == pt )
            continue;

          angle = _averageAngle( prevPt, pt, nextPt );
        }
      }
      else if ( i == points.count() - 1 )
      {
        if ( !isRing )
        {
          // use last segment's angle
          const QPointF& prevPt = points[i-1];
          if ( pt == prevPt )
            continue;
          angle = MyLine( prevPt, pt ).angle();
        }
        else
        {
          // don't draw the last marker - it has been drawn already
          continue;
        }
      }
      else
      {
        // use average angle
        const QPointF& prevPt = points[i-1];
        const QPointF& nextPt = points[i+1];
        if ( prevPt == pt || nextPt == pt )
          continue;

        angle = _averageAngle( prevPt, pt, nextPt );
      }
      mMarker->setAngle( origAngle + angle * 180 / M_PI );
    }

    mMarker->renderPoint( points.at( i ), context.feature(), rc, -1, context.selected() );
  }

  // restore original rotation
  mMarker->setAngle( origAngle );
}
Beispiel #17
0
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;
    }
}
Beispiel #18
0
void Meshing::splitDiag()
{
    for(int id=0;id<mesh_.size();id++){
        QPolygonF poly = mesh_.at(id);
        if(poly.isEmpty())
            continue;

        if(!poly.isClosed())
            poly << poly.at(0);

        if(poly.size()<=4)
            continue;

        QStringList polyID;
        for(int k=0;k<poly.size();k++)
            polyID << findID(poly.at(k));

        /*for(int i=0;i<poly.size()-2;i++){
            QPointF p = (poly.at(i) + poly.at(i+2))/2.0;
            if(poly.containsPoint(p,Qt::WindingFill)){
                QPolygonF p1,p2;
                for(int k=i;k<i+3;k++){
                    p1 << poly.at(k);
                }
                p1 << poly.at(i);
                for(int k=i+3;k<=poly.size()-1;k++){
                    p2 << poly.at(k);
                }
                for(int k=0;k<i;k++){
                    p2 << poly.at(k);
                }
                p2 << poly.at(i);
                mesh_.push_back(p1);
                mesh_.push_back(p2);
                mesh_.removeAt(id);
                splitDiag();
                return;
            }
        }*/

        //qDebug() << "Split poly" << polyID;
        for(int i=0;i<poly.size()-1;i++){
            for(int j=i+2;j<poly.size()-(i==0?2:1);j++){
                //qDebug() << "Try to split along" << findID(poly.at(i)) << findID(poly.at(j));
                QLineF line(poly.at(i),poly.at(j));
                QPointF middle = (poly.at(i)+poly.at(j))/2.0;
                if(!poly.containsPoint(middle,Qt::WindingFill))
                    continue;
                if(!intersects(poly,line)){
                    QPolygonF p1,p2;
                    //QStringList poly1id,poly2id;

                    for(int k=i;k<=j;k++){
                        p1 << poly.at(k);
                        //poly1id << findID(poly.at(k));
                    }
                    p1 << poly.at(i);
                    //poly1id << findID(poly.at(i));
                    for(int k=j;k<poly.size()-1;k++){
                        p2 << poly.at(k);
                        //poly2id << findID(poly.at(k));
                    }
                    for(int k=0;k<=i;k++){
                        p2 << poly.at(k);
                        //poly2id << findID(poly.at(k));
                    }
                    p2 << poly.at(j);
                    //poly2id << findID(poly.at(j));
                    //qDebug() << poly.size() << QPair<int,QString>(i,findID(poly.at(i))) << QPair<int,QString>(j,findID(poly.at(j))) << p1.size() << p2.size();
                    //qDebug() << "Poly1" << poly1id;
                    //qDebug() << "Poly2" << poly2id;
                    mesh_.push_back(p1);
                    mesh_.push_back(p2);
                    mesh_.removeAt(id);
                    splitDiag();
                    return;
                }
            }
        }
        //qDebug() << "Can't split poly " << polyID;
    }
}
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
{
  if ( points.isEmpty() )
    return;

  QgsRenderContext& rc = context.renderContext();

  double origAngle = mMarker->angle();
  int i, maxCount;
  bool isRing = false;

  double offsetAlongLine = mOffsetAlongLine;
  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET_ALONG_LINE ) )
  {
    context.setOriginalValueVariable( mOffsetAlongLine );
    offsetAlongLine = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET_ALONG_LINE, context, mOffsetAlongLine ).toDouble();
  }
  if ( offsetAlongLine != 0 )
  {
    //scale offset along line
    offsetAlongLine = QgsSymbolLayerV2Utils::convertToPainterUnits( rc, offsetAlongLine, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
  }

  if ( offsetAlongLine == 0 && context.renderContext().geometry()
       && context.renderContext().geometry()->hasCurvedSegments() && ( placement == Vertex || placement == CurvePoint ) )
  {
    const QgsCoordinateTransform* ct = context.renderContext().coordinateTransform();
    const QgsMapToPixel& mtp = context.renderContext().mapToPixel();

    QgsVertexId vId;
    QgsPointV2 vPoint;
    double x, y, z;
    QPointF mapPoint;
    while ( context.renderContext().geometry()->nextVertex( vId, vPoint ) )
    {
      if (( placement == Vertex && vId.type == QgsVertexId::SegmentVertex )
          || ( placement == CurvePoint && vId.type == QgsVertexId::CurveVertex ) )
      {
        //transform
        x = vPoint.x(), y = vPoint.y(); z = vPoint.z();
        if ( ct )
        {
          ct->transformInPlace( x, y, z );
        }
        mapPoint.setX( x ); mapPoint.setY( y );
        mtp.transformInPlace( mapPoint.rx(), mapPoint.ry() );
        if ( mRotateMarker )
        {
          double angle = context.renderContext().geometry()->vertexAngle( vId );
          mMarker->setAngle( angle * 180 / M_PI );
        }
        mMarker->renderPoint( mapPoint, context.feature(), rc, -1, context.selected() );
      }
    }
    return;
  }

  if ( placement == FirstVertex )
  {
    i = 0;
    maxCount = 1;
  }
  else if ( placement == LastVertex )
  {
    i = points.count() - 1;
    maxCount = points.count();
  }
  else if ( placement == Vertex )
  {
    i = 0;
    maxCount = points.count();
    if ( points.first() == points.last() )
      isRing = true;
  }
  else
  {
    return;
  }

  if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
  {
    double distance;
    distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
    renderOffsetVertexAlongLine( points, i, distance, context );
    // restore original rotation
    mMarker->setAngle( origAngle );
    return;
  }

  for ( ; i < maxCount; ++i )
  {
    if ( isRing && placement == Vertex && i == points.count() - 1 )
    {
      continue; // don't draw the last marker - it has been drawn already
    }
    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      double angle = markerAngle( points, isRing, i );
      mMarker->setAngle( origAngle + angle * 180 / M_PI );
    }

    mMarker->renderPoint( points.at( i ), context.feature(), rc, -1, context.selected() );
  }

  // restore original rotation
  mMarker->setAngle( origAngle );
}
void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
  if ( points.isEmpty() )
    return;

  QPointF lastPt = points[0];
  double lengthLeft = 0; // how much is left until next marker
  bool first = mOffsetAlongLine ? false : true; //only draw marker at first vertex when no offset along line is set

  QgsRenderContext& rc = context.renderContext();
  double interval = mInterval;

  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_INTERVAL ) )
  {
    context.setOriginalValueVariable( mInterval );
    interval = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_INTERVAL, context, mInterval ).toDouble();
  }
  if ( interval <= 0 )
  {
    interval = 0.1;
  }
  double offsetAlongLine = mOffsetAlongLine;
  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET_ALONG_LINE ) )
  {
    context.setOriginalValueVariable( mOffsetAlongLine );
    offsetAlongLine = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET_ALONG_LINE, context, mOffsetAlongLine ).toDouble();
  }

  double painterUnitInterval = QgsSymbolLayerV2Utils::convertToPainterUnits( rc, interval, mIntervalUnit, mIntervalMapUnitScale );
  lengthLeft = painterUnitInterval - QgsSymbolLayerV2Utils::convertToPainterUnits( rc, offsetAlongLine, mIntervalUnit, mIntervalMapUnitScale );

  for ( int i = 1; i < points.count(); ++i )
  {
    const QPointF& pt = points[i];

    if ( lastPt == pt ) // must not be equal!
      continue;

    // for each line, find out dx and dy, and length
    MyLine l( lastPt, pt );
    QPointF diff = l.diffForInterval( painterUnitInterval );

    // if there's some length left from previous line
    // use only the rest for the first point in new line segment
    double c = 1 - lengthLeft / painterUnitInterval;

    lengthLeft += l.length();

    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      mMarker->setLineAngle( l.angle() * 180 / M_PI );
    }

    // draw first marker
    if ( first )
    {
      mMarker->renderPoint( lastPt, context.feature(), rc, -1, context.selected() );
      first = false;
    }

    // while we're not at the end of line segment, draw!
    while ( lengthLeft > painterUnitInterval )
    {
      // "c" is 1 for regular point or in interval (0,1] for begin of line segment
      lastPt += c * diff;
      lengthLeft -= painterUnitInterval;
      mMarker->renderPoint( lastPt, context.feature(), rc, -1, context.selected() );
      c = 1; // reset c (if wasn't 1 already)
    }

    lastPt = pt;
  }
}
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
{
  if ( points.isEmpty() )
    return;

  QgsRenderContext& rc = context.renderContext();

  double origAngle = mMarker->angle();
  int i, maxCount;
  bool isRing = false;

  double offsetAlongLine = mOffsetAlongLine;
  QgsExpression* offsetAlongLineExpression = expression( "offset_along_line" );
  if ( offsetAlongLineExpression )
  {
    offsetAlongLine = offsetAlongLineExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }
  if ( offsetAlongLine != 0 )
  {
    //scale offset along line
    offsetAlongLine *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( rc, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
  }

  if ( placement == FirstVertex )
  {
    i = 0;
    maxCount = 1;
  }
  else if ( placement == LastVertex )
  {
    i = points.count() - 1;
    maxCount = points.count();
  }
  else
  {
    i = 0;
    maxCount = points.count();
    if ( points.first() == points.last() )
      isRing = true;
  }

  if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
  {
    double distance;
    distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
    renderOffsetVertexAlongLine( points, i, distance, context );
    // restore original rotation
    mMarker->setAngle( origAngle );
    return;
  }

  for ( ; i < maxCount; ++i )
  {
    if ( isRing && placement == Vertex && i == points.count() - 1 )
    {
      continue; // don't draw the last marker - it has been drawn already
    }
    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      double angle = markerAngle( points, isRing, i );
      mMarker->setAngle( origAngle + angle * 180 / M_PI );
    }

    mMarker->renderPoint( points.at( i ), context.feature(), rc, -1, context.selected() );
  }

  // restore original rotation
  mMarker->setAngle( origAngle );
}
Beispiel #22
0
void _PolyClipper::clipPolyline(const QPolygonF& poly)
{
  // exit if fewer than 2 points in polygon
  if ( poly.size() < 2 )
    return;

  // output goes here
  QPolygonF pout;

  QPolygonF::const_iterator polyiter = poly.begin();
  QPointF lastpt = *polyiter;
  polyiter++;

  for( ; polyiter != poly.end(); ++polyiter )
    {
      QPointF p1 = lastpt;
      QPointF p2 = *polyiter;

      bool plotline = _clipper.clipLine(p1, p2);
      if( plotline )
        {
          if( pout.isEmpty() )
            {
              // add first line
              pout << p1;
              if( ! smallDelta(p1, p2) )
                pout << p2;
            }
          else
            {
              if( p1 == pout.last() )
                {
                  if( ! smallDelta(p1, p2) )
                    // extend polyline
                    pout << p2;
                }
              else
                {
                  // paint existing line
                  if( pout.size() >= 2 )
                    emitPolyline(pout);

                  // start new line
                  pout.clear();
                  pout << p1;
                  if( ! smallDelta(p1, p2) )
                    pout << p2;
                }
            }
        }
      else
        {
          // line isn't in region, so ignore results from clip function

          // paint existing line
          if( pout.size() >= 2 )
            emitPolyline(pout);

          // cleanup
          pout.clear();
        }


      lastpt = *polyiter;
    }

  if( pout.size() >= 2 )
    emitPolyline(pout);
}
Beispiel #23
0
QgsConstWkbPtr QgsClipper::clippedLineWKB( QgsConstWkbPtr& wkbPtr, const QgsRectangle& clipExtent, QPolygonF& line )
{
  QgsWKBTypes::Type wkbType = wkbPtr.readHeader();

  int nPoints;
  wkbPtr >> nPoints;

  int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );

  if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() )
  {
    QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) );
    return QgsConstWkbPtr( nullptr, 0 );
  }

  double p0x, p0y, p1x = 0.0, p1y = 0.0; //original coordinates
  double p1x_c, p1y_c; //clipped end coordinates
  double lastClipX = 0.0, lastClipY = 0.0; //last successfully clipped coords

  QPolygonF pts;
  wkbPtr -= sizeof( unsigned int );
  wkbPtr >> pts;
  nPoints = pts.size();

  line.clear();
  line.reserve( nPoints + 1 );

  QPointF *ptr = pts.data();

  for ( int i = 0; i < nPoints; ++i, ++ptr )
  {
    if ( i == 0 )
    {
      p1x = ptr->rx();
      p1y = ptr->ry();
      continue;
    }
    else
    {
      p0x = p1x;
      p0y = p1y;

      p1x = ptr->rx();
      p1y = ptr->ry();

      p1x_c = p1x;
      p1y_c = p1y;
      if ( clipLineSegment( clipExtent.xMinimum(), clipExtent.xMaximum(), clipExtent.yMinimum(), clipExtent.yMaximum(),
                            p0x, p0y, p1x_c,  p1y_c ) )
      {
        bool newLine = !line.isEmpty() && ( !qgsDoubleNear( p0x, lastClipX ) || !qgsDoubleNear( p0y, lastClipY ) );
        if ( newLine )
        {
          //add edge points to connect old and new line
          connectSeparatedLines( lastClipX, lastClipY, p0x, p0y, clipExtent, line );
        }
        if ( line.size() < 1 || newLine )
        {
          //add first point
          line << QPointF( p0x, p0y );
        }

        //add second point
        lastClipX = p1x_c;
        lastClipY = p1y_c;
        line << QPointF( p1x_c,  p1y_c );
      }
    }
  }
  return wkbPtr;
}
void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
  if ( points.isEmpty() )
    return;

  QPointF lastPt = points[0];
  double lengthLeft = 0; // how much is left until next marker
  bool first = true;
  double origAngle = mMarker->angle();

  double painterUnitInterval = context.outputLineWidth( mInterval > 0 ? mInterval : 0.1 );

  QgsRenderContext& rc = context.renderContext();

  for ( int i = 1; i < points.count(); ++i )
  {
    const QPointF& pt = points[i];

    if ( lastPt == pt ) // must not be equal!
      continue;

    // for each line, find out dx and dy, and length
    MyLine l( lastPt, pt );
    QPointF diff = l.diffForInterval( painterUnitInterval );

    // if there's some length left from previous line
    // use only the rest for the first point in new line segment
    double c = 1 - lengthLeft / painterUnitInterval;

    lengthLeft += l.length();

    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
    }

    // draw first marker
    if ( first )
    {
      mMarker->renderPoint( lastPt, rc, -1, context.selected() );
      first = false;
    }

    // while we're not at the end of line segment, draw!
    while ( lengthLeft > painterUnitInterval )
    {
      // "c" is 1 for regular point or in interval (0,1] for begin of line segment
      lastPt += c * diff;
      lengthLeft -= painterUnitInterval;
      mMarker->renderPoint( lastPt, rc, -1, context.selected() );
      c = 1; // reset c (if wasn't 1 already)
    }

    lastPt = pt;
  }

  // restore original rotation
  mMarker->setAngle( origAngle );

}
void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
  if ( points.isEmpty() )
    return;

  QPointF lastPt = points[0];
  double lengthLeft = 0; // how much is left until next marker
  bool first = mOffsetAlongLine ? false : true; //only draw marker at first vertex when no offset along line is set
  double origAngle = mMarker->angle();

  QgsRenderContext& rc = context.renderContext();
  double interval = mInterval;

  QgsExpression* intervalExpression = expression( "interval" );
  if ( intervalExpression )
  {
    interval = intervalExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }
  if ( interval <= 0 )
  {
    interval = 0.1;
  }
  double offsetAlongLine = mOffsetAlongLine;
  QgsExpression* offsetAlongLineExpression = expression( "offset_along_line" );
  if ( offsetAlongLineExpression )
  {
    offsetAlongLine = offsetAlongLineExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }

  double painterUnitInterval = interval * QgsSymbolLayerV2Utils::lineWidthScaleFactor( rc, mIntervalUnit, mIntervalMapUnitScale );
  lengthLeft = painterUnitInterval - offsetAlongLine * QgsSymbolLayerV2Utils::lineWidthScaleFactor( rc, mIntervalUnit, mIntervalMapUnitScale );

  for ( int i = 1; i < points.count(); ++i )
  {
    const QPointF& pt = points[i];

    if ( lastPt == pt ) // must not be equal!
      continue;

    // for each line, find out dx and dy, and length
    MyLine l( lastPt, pt );
    QPointF diff = l.diffForInterval( painterUnitInterval );

    // if there's some length left from previous line
    // use only the rest for the first point in new line segment
    double c = 1 - lengthLeft / painterUnitInterval;

    lengthLeft += l.length();

    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
    }

    // draw first marker
    if ( first )
    {
      mMarker->renderPoint( lastPt, context.feature(), rc, -1, context.selected() );
      first = false;
    }

    // while we're not at the end of line segment, draw!
    while ( lengthLeft > painterUnitInterval )
    {
      // "c" is 1 for regular point or in interval (0,1] for begin of line segment
      lastPt += c * diff;
      lengthLeft -= painterUnitInterval;
      mMarker->renderPoint( lastPt, context.feature(), rc, -1, context.selected() );
      c = 1; // reset c (if wasn't 1 already)
    }

    lastPt = pt;
  }

  // restore original rotation
  mMarker->setAngle( origAngle );

}
Beispiel #26
0
void GpxLayer::load(const QString &filename)
{
    QFile file(filename);
    if (file.open(QIODevice::ReadOnly)) {
        QXmlStreamReader xml(&file);

        QPolygonF points;
        QList<float> elev;
        QList<int> time;

        QString tag, tag2;
        QString name;
        QPointF pos;
        while (!xml.atEnd()) {
            xml.readNext();
            if (xml.isStartElement()) {
                if (xml.name() == "trkpt") {
                    tag = "trkpt";
                    float lat = xml.attributes().value("lat").toString().toFloat();
                    float lon = xml.attributes().value("lon").toString().toFloat();

                    points << QPointF(Projection::lon2rawx(lon), Projection::lat2rawy(lat));
                } else if (xml.name() == "ele") {
                    tag2 = "ele";
                } else if (xml.name() == "time") {
                    tag2 = "time";
                } else if (xml.name() == "wpt") {
                    tag = "wpt";
                    float lat = xml.attributes().value("lat").toString().toFloat();
                    float lon = xml.attributes().value("lon").toString().toFloat();

                    pos = QPointF(lon, lat);
                } else if (xml.name() == "name") {
                    tag2 = "name";
                } else if (xml.name() == "trk" ||
                           xml.name() == "trkseg") {
                } else {
                    tag2.clear();
                }
            } else if (xml.isEndElement()) {
                if (xml.name() == "trkseg") {
                    if (!points.isEmpty()) {
                        m_track << points;
                        m_track << QPointF();
                    }
                    points.clear();
                    elev.clear();
                    time.clear();
                } else if (xml.name() == "wpt") {
                    //addMarker(pos, name);
                    name.clear();
                }
            } else if (xml.isCharacters() && !xml.isWhitespace()) {
                if (tag == "trkpt") {
                    if (tag2 == "ele") {
                        elev << xml.text().toString().toFloat();
                    } else if (tag2 == "time") {
                        QDateTime dt = QDateTime::fromString(xml.text().toString(), Qt::ISODate);
                        time << dt.toTime_t();
                    }
                } else if (tag == "wpt") {
                    if (tag2 == "name") {
                        name = xml.text().toString();
                    }
                }
            }
        }
        zoom(0);
    }
}
Beispiel #27
0
void BarDiagram::BarDiagramType::paintBars( PaintContext* ctx, const QModelIndex& index, const QRectF& bar, qreal maxDepth )
{
    PainterSaver painterSaver( ctx->painter() );

    //Pending Michel: configure threeDBrush settings - shadowColor etc...
    QBrush indexBrush( diagram()->brush( index ) );
    QPen indexPen( diagram()->pen( index ) );

    ctx->painter()->setRenderHint( QPainter::Antialiasing, diagram()->antiAliasing() );
    ThreeDBarAttributes threeDAttrs = diagram()->threeDBarAttributes( index );
    if ( threeDAttrs.isEnabled() ) {
        indexBrush = threeDAttrs.threeDBrush( indexBrush, bar );
    }
    ctx->painter()->setBrush( indexBrush );
    ctx->painter()->setPen( PrintingParameters::scalePen( indexPen ) );

    if ( threeDAttrs.isEnabled() ) {
        if ( maxDepth ) {
            threeDAttrs.setDepth( -maxDepth );
        }
        //fixme adjust the painting to reasonable depth value
        const qreal usedDepth = threeDAttrs.depth() * ( type() == BarDiagram::Normal ? 0.25 : 1.0 );

        const QRectF isoRect = bar.translated( usedDepth, -usedDepth );
        // we need to find out if the height is negative
        // and in this case paint it up and down
        QPolygonF topPoints;
        if ( isoRect.height() < 0 ) {
            if ( !( type() == BarDiagram::Stacked && index.column() != 0 ) ) {
                // fix it when several negative stacked values
                topPoints << isoRect.bottomLeft() << isoRect.bottomRight()
                          << bar.bottomRight() << bar.bottomLeft();
            }
        } else {
            reverseMapper().addRect( index.row(), index.column(), isoRect );
            ctx->painter()->drawRect( isoRect );
            if ( !( type() == BarDiagram::Percent && isoRect.height() == 0 ) ) {
                topPoints << bar.topLeft() << bar.topRight() << isoRect.topRight() << isoRect.topLeft();
            }
        }

        bool noClippingForTop = false;
        if ( !topPoints.isEmpty() ) {
            // Draw the top, if at least one of the top's points is
            // either inside or near at the edge of the coordinate plane:
            bool drawIt = false;
            bool hasPointOutside = false;
            const QRectF r( ctx->rectangle().adjusted( 0, -1, 1, 0 ) );
            Q_FOREACH( QPointF pt, topPoints ) {
                if ( r.contains( pt ) ) {
                    drawIt = true;
                } else {
                    hasPointOutside = true;
                }
            }
            if ( drawIt ) {
                const PainterSaver p( ctx->painter() );
                noClippingForTop = hasPointOutside && ctx->painter()->hasClipping();
                if ( noClippingForTop ) {
                    ctx->painter()->setClipping( false );
                }
                reverseMapper().addPolygon( index.row(), index.column(), topPoints );
                ctx->painter()->drawPolygon( topPoints );
            }
        }

        if ( bar.height() != 0 ) {
            const PainterSaver p( ctx->painter() );
            if ( noClippingForTop ) {
                ctx->painter()->setClipping( false );
            }
            QPolygonF sidePoints;
            sidePoints << bar.topRight() << isoRect.topRight()
                       << isoRect.bottomRight() << bar.bottomRight();
            reverseMapper().addPolygon( index.row(), index.column(), sidePoints );
            ctx->painter()->drawPolygon( sidePoints );
        }
    }
Beispiel #28
0
void assertPolygonIsClosed(QPolygonF polygon)
{
  ASSERT_RETURN(polygon.isEmpty() || polygon.first() == polygon.last());
}