Exemplo n.º 1
0
  /**
   * Compute the bounding screen extent of a rotated rectangle.
   *
   * @param rect Rectangle to rotate.
   * @param x X coordinate of the rotation point.
   * @param y Y coordinate of the rotation point.
   * @param rotation Rotation angle.
   * @return The smallest rectangle that completely contains {@code rect} when rotated by the
   *     specified angle.
   */
  protected Rectangle computeRotatedScreenExtent(Rectangle rect, int x, int y, Angle rotation) {
    Rectangle r = new Rectangle(rect);

    // Translate the rectangle to the rotation point.
    r.translate(-x, -y);

    // Compute corner points
    Vec4[] corners = {
      new Vec4(r.getMaxX(), r.getMaxY()),
      new Vec4(r.getMaxX(), r.getMinY()),
      new Vec4(r.getMinX(), r.getMaxY()),
      new Vec4(r.getMinX(), r.getMinY())
    };

    // Rotate the rectangle
    Matrix rotationMatrix = Matrix.fromRotationZ(rotation);
    for (int i = 0; i < corners.length; i++) {
      corners[i] = corners[i].transformBy3(rotationMatrix);
    }

    // Find the bounding rectangle of rotated points.
    int minX = Integer.MAX_VALUE;
    int minY = Integer.MAX_VALUE;
    int maxX = -Integer.MAX_VALUE;
    int maxY = -Integer.MAX_VALUE;

    for (Vec4 v : corners) {
      if (v.x > maxX) maxX = (int) v.x;

      if (v.x < minX) minX = (int) v.x;

      if (v.y > maxY) maxY = (int) v.y;

      if (v.y < minY) minY = (int) v.y;
    }

    // Set bounds and translate the rectangle back to where it started.
    r.setBounds(minX, minY, maxX - minX, maxY - minY);
    r.translate(x, y);

    return r;
  }
 @Override
 protected void applyModelviewTransform(DrawContext dc, SurfaceTileDrawContext sdc) {
   // Apply the geographic to surface tile coordinate transform.
   Matrix modelview = sdc.getModelviewMatrix();
   dc.getGL().glMultMatrixd(modelview.toArray(new double[16], 0, false), 0);
 }
Exemplo n.º 3
0
  /**
   * Compute the label's screen position from its geographic position.
   *
   * @param dc Current draw context.
   */
  protected void computeGeometry(DrawContext dc) {
    // Project the label position onto the viewport
    Position pos = this.getPosition();
    if (pos == null) return;

    this.placePoint = dc.computeTerrainPoint(pos.getLatitude(), pos.getLongitude(), 0);
    this.screenPlacePoint = dc.getView().project(this.placePoint);

    this.eyeDistance = this.placePoint.distanceTo3(dc.getView().getEyePoint());

    boolean orientationReversed = false;
    if (this.orientationPosition != null) {
      // Project the orientation point onto the screen
      Vec4 orientationPlacePoint =
          dc.computeTerrainPoint(
              this.orientationPosition.getLatitude(), this.orientationPosition.getLongitude(), 0);
      Vec4 orientationScreenPoint = dc.getView().project(orientationPlacePoint);

      this.rotation = this.computeRotation(this.screenPlacePoint, orientationScreenPoint);

      // The orientation is reversed if the orientation point falls to the right of the screen
      // point. Text is
      // never drawn upside down, so when the orientation is reversed the text flips vertically to
      // keep the text
      // right side up.
      orientationReversed = (orientationScreenPoint.x <= this.screenPlacePoint.x);
    }

    this.computeBoundsIfNeeded(dc);

    Offset offset = this.getOffset();
    Point2D offsetPoint =
        offset.computeOffset(this.bounds.getWidth(), this.bounds.getHeight(), null, null);

    // If a rotation is applied to the text, then rotate the offset as well. An offset in the x
    // direction
    // will move the text along the orientation line, and a offset in the y direction will move the
    // text
    // perpendicular to the orientation line.
    if (this.rotation != null) {
      double dy = offsetPoint.getY();

      // If the orientation is reversed we need to adjust the vertical offset to compensate for the
      // flipped
      // text. For example, if the offset normally aligns the top of the text with the place point
      // then without
      // this adjustment the bottom of the text would align with the place point when the
      // orientation is
      // reversed.
      if (orientationReversed) {
        dy = -(dy + this.bounds.getHeight());
      }

      Vec4 pOffset = new Vec4(offsetPoint.getX(), dy);
      Matrix rot = Matrix.fromRotationZ(this.rotation.multiply(-1));

      pOffset = pOffset.transformBy3(rot);

      offsetPoint = new Point((int) pOffset.getX(), (int) pOffset.getY());
    }

    int x = (int) (this.screenPlacePoint.x + offsetPoint.getX());
    int y = (int) (this.screenPlacePoint.y - offsetPoint.getY());

    this.screenPoint = new Point(x, y);
    this.screenExtent = this.computeTextExtent(x, y, this.rotation);
  }
Exemplo n.º 4
0
  protected int computeCartesianPolygon(
      Globe globe,
      List<? extends LatLon> locations,
      List<Boolean> edgeFlags,
      Vec4[] points,
      Boolean[] edgeFlagArray,
      Matrix[] transform) {
    if (globe == null) {
      String message = Logging.getMessage("nullValue.GlobeIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (locations == null) {
      String message = "nullValue.LocationsIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (points == null) {
      String message = "nullValue.LocationsIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (points.length < (1 + locations.size())) {
      String message =
          Logging.getMessage(
              "generic.ArrayInvalidLength", "points.length < " + (1 + locations.size()));
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (transform == null) {
      String message = "nullValue.TransformIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (transform.length < 1) {
      String message = Logging.getMessage("generic.ArrayInvalidLength", "transform.length < 1");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    // Allocate space to hold the list of locations and location vertices.
    int locationCount = locations.size();

    // Compute the cartesian points for each location.
    for (int i = 0; i < locationCount; i++) {
      LatLon ll = locations.get(i);
      points[i] = globe.computePointFromPosition(ll.getLatitude(), ll.getLongitude(), 0.0);

      if (edgeFlagArray != null) edgeFlagArray[i] = (edgeFlags != null) ? edgeFlags.get(i) : true;
    }

    // Compute the average of the cartesian points.
    Vec4 centerPoint = Vec4.computeAveragePoint(Arrays.asList(points));

    // Test whether the polygon is closed. If it is not closed, repeat the first vertex.
    if (!points[0].equals(points[locationCount - 1])) {
      points[locationCount] = points[0];
      if (edgeFlagArray != null) edgeFlagArray[locationCount] = edgeFlagArray[0];

      locationCount++;
    }

    // Compute a transform that will map the cartesian points to a local coordinate system centered
    // at the average
    // of the points and oriented with the globe surface.
    Position centerPos = globe.computePositionFromPoint(centerPoint);
    Matrix tx = globe.computeSurfaceOrientationAtPosition(centerPos);
    Matrix txInv = tx.getInverse();
    // Map the cartesian points to a local coordinate space.
    for (int i = 0; i < locationCount; i++) {
      points[i] = points[i].transformBy4(txInv);
    }

    transform[0] = tx;

    return locationCount;
  }
  /**
   * Indicates the transform matrix applied to this document.
   *
   * @return Transform matrix.
   */
  protected Matrix getMatrix() {
    // If the matrix has already been computed then just return the cached value.
    if (this.matrix != null) return this.matrix;

    Matrix m = Matrix.IDENTITY;

    if (this.heading != null)
      m = m.multiply(Matrix.fromRotationZ(Angle.POS360.subtract(this.heading)));

    if (this.pitch != null) m = m.multiply(Matrix.fromRotationX(this.pitch));

    if (this.roll != null) m = m.multiply(Matrix.fromRotationY(this.roll));

    // Apply scaling factor to convert file units to meters.
    double scale = this.getScale();
    m = m.multiply(Matrix.fromScale(scale));

    if (this.modelScale != null) m = m.multiply(Matrix.fromScale(this.modelScale));

    this.matrix = m;
    return m;
  }