예제 #1
0
	LinkedPool * add_pool_(SizeT block_size, SizeT block_num) {
		ImpactLnkPoolBuilder<alloc_t> bldr(block_size, block_num);
		LinkedPool * pool;
		bldr.set_target(pool);
		bldr.create();
		bldr.initiate();
		return pool;
	}
/*!
  \brief Returns the screen coordinate of the current \l pointToConvert,
  within the bounds of \a screenWidth and \a screenHeight.

  If the point is off the screen, attempts to find the closest point on the
  screen (e.g. on the edge) to the point.
 */
QPointF CoordinateConversionController::screenCoordinate() const
{
  // attempt to get the target point as a screen coordinate
  QPointF res(-1.0, -1.0);
  if (m_sceneView)
    res = m_sceneView->locationToScreen(m_pointToConvert).screenPoint();
  else if (m_mapView)
    res = m_mapView->locationToScreen(m_pointToConvert);
  else
    return res;

  // get the extents of the screen (padded to ensure we are within the visible area)
  constexpr double padding = 1.0;
  const double screenWidth = m_sceneView ? m_sceneView->widthInPixels() - padding : m_mapView->widthInPixels() - padding;
  const double screenHeight = m_sceneView ? m_sceneView->heightInPixels() - padding : m_mapView->heightInPixels() - padding;

  // if we did not recieve a valid screen coordinate
  if (res.x() == 0.0 && res.y() == 0.0)
  {
    // lambda to search for a valid geographic position for the top of the screen (e.g. to account for the horizon)
    auto findValidTopPoint = [this, screenHeight](double x)
    {
      Point validTopPoint;
      double lastValidY = screenHeight;
      double testMinY = 1.0;
      for (int attempt = 0; attempt < 16; ++attempt)
      {
        double testY = testMinY + ((lastValidY - testMinY) * 0.5);
        auto newRes =  m_sceneView ? m_sceneView->screenToBaseSurface(x, testY) : m_mapView->screenToLocation(x, testY);
        if (newRes.isValid() && !newRes.isEmpty())
        {
          validTopPoint = newRes;
          if (std::abs(lastValidY - testY) < 1.0)
            break;

          lastValidY = testY;
        }
        else
        {
          testMinY = testY;
        }
      }

      return validTopPoint;
    };

    // otherwise build a polyline describing the extent of the screen
    Point topLeft = m_sceneView ? m_sceneView->screenToBaseSurface(padding, padding) : m_mapView->screenToLocation(padding, padding);
    if (topLeft.isEmpty() || !topLeft.isValid())
      topLeft = findValidTopPoint(padding);

    Point topRight = m_sceneView ? m_sceneView->screenToBaseSurface(screenWidth, padding) : m_mapView->screenToLocation(screenWidth, padding);
    if (topRight.isEmpty() || !topRight.isValid())
      findValidTopPoint(screenWidth);

    Point lowerLeft = m_sceneView ? m_sceneView->screenToBaseSurface(padding, screenHeight) : m_mapView->screenToLocation(padding, screenHeight);
    Point lowerRight = m_sceneView ? m_sceneView->screenToBaseSurface(screenWidth, screenHeight) : m_mapView->screenToLocation(screenWidth, screenHeight);

    PolylineBuilder bldr(topLeft.spatialReference());
    bldr.addPoint(topLeft);
    bldr.addPoint(topRight);
    bldr.addPoint(lowerRight);
    bldr.addPoint(lowerLeft);
    bldr.addPoint(topLeft);
    const Polyline viewBoundary = bldr.toPolyline();
    // obtain the point on the view boundary polyline which is closest to the target point
    Point projected = GeometryEngine::instance()->project(m_pointToConvert, topLeft.spatialReference());
    const ProximityResult nearestCoordinateResult = GeometryEngine::instance()->nearestCoordinate(viewBoundary, projected);

    res = m_sceneView ? m_sceneView->locationToScreen(nearestCoordinateResult.coordinate()).screenPoint() :
                        m_mapView->locationToScreen(nearestCoordinateResult.coordinate());
  }

  // ensure the returned point is within the bounds of the visible screen
  if (res.x() < 0.0)
    res.setX(0.0);
  else if (res.x() > screenWidth)
    res.setX(screenWidth);

  if (res.y() < 0.0)
    res.setY(0.0);
  else if (res.y() > screenHeight)
    res.setY(screenHeight);

  return res;
}