コード例 #1
0
  /**
   * This method draws the line. Note - highly optimized to handle long paths, proceed with care.
   * Should be fine up to 10K points.
   */
  @Override
  protected void draw(final Canvas canvas, final MapView mapView, final boolean shadow) {

    if (shadow) {
      return;
    }

    if (this.mPoints.size() < 2) {
      // nothing to paint
      return;
    }

    final Projection pj = mapView.getProjection();

    // precompute new points to the intermediate projection.
    final int size = this.mPoints.size();

    while (this.mPointsPrecomputed < size) {
      final Point pt = this.mPoints.get(this.mPointsPrecomputed);
      pj.toMapPixelsProjected(pt.x, pt.y, pt);

      this.mPointsPrecomputed++;
    }

    Point screenPoint0 = null; // points on screen
    Point screenPoint1 = null;
    Point projectedPoint0; // points from the points list
    Point projectedPoint1;

    // clipping rectangle in the intermediate projection, to avoid performing projection.
    final Rect clipBounds = pj.fromPixelsToProjected(pj.getScreenRect());

    mPath.rewind();
    projectedPoint0 = this.mPoints.get(size - 1);
    mLineBounds.set(projectedPoint0.x, projectedPoint0.y, projectedPoint0.x, projectedPoint0.y);

    for (int i = size - 2; i >= 0; i--) {
      // compute next points
      projectedPoint1 = this.mPoints.get(i);
      mLineBounds.union(projectedPoint1.x, projectedPoint1.y);

      if (!Rect.intersects(clipBounds, mLineBounds)) {
        // skip this line, move to next point
        projectedPoint0 = projectedPoint1;
        screenPoint0 = null;
        continue;
      }

      // the starting point may be not calculated, because previous segment was out of clip
      // bounds
      if (screenPoint0 == null) {
        screenPoint0 = pj.toMapPixelsTranslated(projectedPoint0, this.mTempPoint1);
        mPath.moveTo(screenPoint0.x, screenPoint0.y);
      }

      screenPoint1 = pj.toMapPixelsTranslated(projectedPoint1, this.mTempPoint2);

      // skip this point, too close to previous point
      if (Math.abs(screenPoint1.x - screenPoint0.x) + Math.abs(screenPoint1.y - screenPoint0.y)
          <= 1) {
        continue;
      }

      mPath.lineTo(screenPoint1.x, screenPoint1.y);

      // update starting point to next position
      projectedPoint0 = projectedPoint1;
      screenPoint0.x = screenPoint1.x;
      screenPoint0.y = screenPoint1.y;
      mLineBounds.set(projectedPoint0.x, projectedPoint0.y, projectedPoint0.x, projectedPoint0.y);
    }

    canvas.drawPath(mPath, this.mPaint);
  }