void Grid::drawVerticalLines(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) const {
  QVector<QLineF> lines;
  for (int x = minimalXCoordinate(); x <= maximalXCoordinate(); x++) {
    bool started = false;
    int startY;
    for (int y = minimalYCoordinate(x); y <= maximalYCoordinate(x); y++) {
      if (!started && isValidCoordinate(x, y)) {
        started = true;
        startY = y;
      }
      if (started && !isValidCoordinate(x, y + 1)) {
        started = false;
        lines.push_back(QLineF(getFieldPosition(x, startY), getFieldPosition(x, y)));
      }
    }
  }
  painter->drawLines(lines);
}
void Grid::drawRightDiagonalLines(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) const {
  QVector<QLineF> lines;
  for (int sum = minimalXCoordinate() + minimalYCoordinate(); sum < maximalXCoordinate() + maximalYCoordinate(); sum++) {
    bool started = false;
    int startX;
    for (int x = minimalXCoordinate(); x <= maximalXCoordinate(); x++) {
      if (!started && isValidCoordinate(x, sum -x)) {
        started = true;
        startX = x;
      }
      if (started && !isValidCoordinate(x + 1, sum - x - 1)) {
        started = false;
        QPointF startPoint = getFieldPosition(startX, sum - startX);
        QPointF endPoint = getFieldPosition(x, sum - x);
        lines.push_back(QLineF(startPoint, endPoint));
      }
    }
  }
  painter->drawLines(lines);
}
void Grid::drawHandicapSpots(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) const {
  painter->setBrush(Qt::black);
  QList<QPair<int,int> > points = getHandicapCoordinates();

  QPair<int, int> point;
  foreach(point, points)
    {
      if (isValidCoordinate(point.first, point.second))
      painter->drawEllipse(getFieldPosition(point.first, point.second),
          s_handicapSpotRadius , s_handicapSpotRadius);
    }
}
void Grid::drawFieldsShape(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) const {
  QTransform transform = painter->transform();
  for (int x = minimalXCoordinate(); x <= maximalXCoordinate(); x++) {
    for (int y = minimalYCoordinate(x); y <= maximalYCoordinate(x); y++) {
      if (isValidCoordinate(x, y)) {
        painter->setTransform(transform);
        painter->translate(getFieldPosition(x, y));
        painter->drawPath(getPath());
      }
    }
  }
}
    StatusWith<NearStage::CoveredInterval*> //
    GeoNear2DSphereStage::nextInterval(OperationContext* txn,
                                       WorkingSet* workingSet,
                                       Collection* collection) {

        // The search is finished if we searched at least once and all the way to the edge
        if (_currBounds.getInner() >= 0 && _currBounds.getOuter() == _fullBounds.getOuter()) {
            return StatusWith<CoveredInterval*>(NULL);
        }

        //
        // Setup the next interval
        //

        const NearStats* stats = getNearStats();

        if (!stats->intervalStats.empty()) {

            const IntervalStats& lastIntervalStats = stats->intervalStats.back();

            // TODO: Generally we want small numbers of results fast, then larger numbers later
            if (lastIntervalStats.numResultsBuffered < 300)
                _boundsIncrement *= 2;
            else if (lastIntervalStats.numResultsBuffered > 600)
                _boundsIncrement /= 2;
        }

        R2Annulus nextBounds(_currBounds.center(),
                             _currBounds.getOuter(),
                             min(_currBounds.getOuter() + _boundsIncrement,
                                 _fullBounds.getOuter()));
        
        bool isLastInterval = (nextBounds.getOuter() == _fullBounds.getOuter());
        _currBounds = nextBounds;

        //
        // Setup the covering region and stages for this interval
        //

        IndexScanParams scanParams;
        scanParams.descriptor = _s2Index;
        scanParams.direction = 1;
        // We use a filter on the key.  The filter rejects keys that don't intersect with the
        // annulus.  An object that is in the annulus might have a key that's not in it and a key
        // that's in it.  As such we can't just look at one key per object.
        //
        // This does force us to do our own deduping of results, though.
        scanParams.doNotDedup = true;
        scanParams.bounds = _nearParams.baseBounds;

        // Because the planner doesn't yet set up 2D index bounds, do it ourselves here
        const string s2Field = _nearParams.nearQuery.field;
        const int s2FieldPosition = getFieldPosition(_s2Index, s2Field);
        scanParams.bounds.fields[s2FieldPosition].intervals.clear();
        OrderedIntervalList* coveredIntervals = &scanParams.bounds.fields[s2FieldPosition];

        TwoDSphereKeyInRegionExpression* keyMatcher = 
            new TwoDSphereKeyInRegionExpression(_currBounds, s2Field);

        ExpressionMapping::cover2dsphere(keyMatcher->getRegion(),
                                         _s2Index->infoObj(),
                                         coveredIntervals);

        // IndexScan owns the hash matcher
        IndexScan* scan = new IndexScanWithMatch(txn, scanParams, workingSet, keyMatcher);

        // FetchStage owns index scan
        FetchStage* fetcher(new FetchStage(workingSet, scan, _nearParams.filter, collection));

        return StatusWith<CoveredInterval*>(new CoveredInterval(fetcher,
                                                                true,
                                                                nextBounds.getInner(),
                                                                nextBounds.getOuter(),
                                                                isLastInterval));
    }