Пример #1
0
  /**
   * Get the upper left (northernmost and westernmost) point of the projection.
   *
   * <p>Returns the upper left point (or closest equivalent) of the projection based on the center
   * point and height and width of screen.
   *
   * @return LatLonPoint
   */
  public LatLonPoint getUpperLeft() {
    LatLonPoint tmp = new LatLonPoint.Double();
    double lat, lon;

    // over north pole
    if (overNorthPole()) {
      lat = NORTH_POLE;
      lon = -DATELINE;
    }

    // over south pole
    else if (overSouthPole()) {
      lon = -DATELINE;
      if (overEquator()) {
        // get top center for latitude
        inverse(width / 2, 0, tmp);
        lat = tmp.getRadLat();
      } else {
        // get left top corner for latitude
        inverse(0, 0, tmp);
        lat = tmp.getRadLat();
      }
    }

    // view in northern hemisphere
    else if (tmp.getRadLat() >= 0) {
      // get left top corner for longitude
      inverse(0, 0, tmp);
      lon = tmp.getRadLon();
      // get top center for latitude
      inverse(width / 2, 0, tmp);
      lat = tmp.getRadLat();
    }

    // view in southern hemisphere
    else {
      // get left bottom corner for longitude
      inverse(0, height, tmp);
      lon = tmp.getRadLon();

      if (overEquator()) {
        // get top center (for latitude)
        inverse(width / 2, 0, tmp);
        lat = tmp.getRadLat();
      } else {
        // get left top corner (for latitude)
        inverse(0, 0, tmp);
        lat = tmp.getRadLat();
      }
    }
    tmp.setLatLon(lat, lon, true);
    // Debug.output("ul="+tmp);
    return tmp;
  }
Пример #2
0
  /**
   * Get the lower right (southeast) point of the projection.
   *
   * <p>Returns the lower right point (or closest equivalent) of the projection based on the center
   * point and height and width of screen.
   *
   * <p>This is trivial for most cylindrical projections, but much more complicated for azimuthal
   * projections.
   *
   * @return LatLonPoint
   */
  public LatLonPoint getLowerRight() {
    LatLonPoint tmp = new LatLonPoint.Double();
    double lat, lon;

    // over north pole
    if (overNorthPole()) {
      lon = DATELINE;
      if (overEquator()) {
        // get bottom center for latitude
        inverse(width / 2, height, tmp);
        lat = tmp.getRadLat();
      } else {
        // get bottom right corner for latitude
        inverse(width, height, tmp);
        lat = tmp.getRadLat();
      }
    }

    // over south pole
    else if (overSouthPole()) {
      lat = SOUTH_POLE;
      lon = DATELINE;
    }

    // view in northern hemisphere
    else if (tmp.getRadLat() >= 0f) {
      // get the right top corner for longitude
      inverse(width, 0, tmp);
      lon = tmp.getRadLon();

      if (overEquator()) {
        // get the bottom center (for latitude)
        inverse(width / 2, height, tmp);
        lat = tmp.getRadLat();
      } else {
        // get the right bottom corner (for latitude)
        inverse(width, height, tmp);
        lat = tmp.getRadLat();
      }
    }

    // view in southern hemisphere
    else {
      // get the right bottom corner for longitude
      inverse(width, height, tmp);
      lon = tmp.getRadLon();
      // get bottom center for latitude
      inverse(width / 2, height, tmp);
      lat = tmp.getRadLat();
    }
    tmp.setLatLon(lat, lon, true);
    // Debug.output("lr="+tmp);
    return tmp;
  }
Пример #3
0
  /**
   * Calculate point along edge of hemisphere (using center point and current azimuth).
   *
   * <p>This is invoked for points that aren't visible in the current hemisphere.
   *
   * @param p Point2D
   * @return Point2D p
   */
  private Point2D edge_point(Point2D p, double current_azimuth) {
    double c = HEMISPHERE_EDGE;
    LatLonPoint tmpll =
        GreatCircle.sphericalBetween(centerY, centerX, c /*-epsilon*/, current_azimuth);
    double phi = tmpll.getRadLat();
    double lambda = tmpll.getRadLon();

    double kPrime = 1f / Math.cos(c);
    double cosPhi = Math.cos(phi);
    double sinPhi = Math.sin(phi);
    double lambdaMinusCtrLon = lambda - centerY;
    double cosLambdaMinusCtrLon = Math.cos(lambdaMinusCtrLon);
    double sinLambdaMinusCtrLon = Math.sin(lambdaMinusCtrLon);

    double x = (scaled_radius * kPrime * cosPhi * sinLambdaMinusCtrLon) + wx;
    double y =
        hy
            - (scaled_radius
                * kPrime
                * (cosCtrLat * sinPhi - sinCtrLat * cosPhi * cosLambdaMinusCtrLon));
    p.setLocation(x, y);
    return p;
  }
Пример #4
0
  /**
   * Add a point at a certain point in the polygon coordinate list. If the position is less than
   * zero, the point will be the starting point. If the position is greater than the list of current
   * points, the point will be added to the end of the poly. This method is convenient because it
   * lets you define the GrabPoint object to use for the node, in case you need a special type of
   * GrabPoint.
   *
   * @return the index for the point in the polygon, starting with 0.
   */
  public int addPoint(GrabPoint gp, int position) {

    if (gp == null) {
      return -1;
    }

    int x = gp.getX();
    int y = gp.getY();

    int renderType = poly.getRenderType();
    boolean rads = (poly.getUnits() == OMGraphic.RADIANS);

    if (renderType == OMGraphic.RENDERTYPE_LATLON) {
      Debug.message("eomg", "EditableOMPoly: adding point to lat/lon poly");

      if (projection != null) {

        double[] ll = poly.getLatLonArray();
        int actualPosition = (position == Integer.MAX_VALUE ? ll.length : position * 2);

        LatLonPoint llpnt = projection.inverse(x, y, new LatLonPoint.Double());

        if (Debug.debugging("eomp")) {
          Debug.output(
              "EditableOMPoly: adding point to lat/lon poly at "
                  + x
                  + ", "
                  + y
                  + ": "
                  + llpnt
                  + ", at the end of ");

          for (int j = 0; j < ll.length; j += 2) {
            Debug.output(ll[j] + ", " + ll[j + 1]);
          }
        }

        double[] newll = new double[ll.length + 2];

        double newlat;
        double newlon;

        if (rads) {
          newlat = llpnt.getRadLat();
          newlon = llpnt.getRadLon();
        } else {
          newlat = llpnt.getY();
          newlon = llpnt.getX();
        }

        if (actualPosition >= ll.length) {
          // Put the new points at the end
          if (ll.length != 0) {
            System.arraycopy(ll, 0, newll, 0, ll.length);
          }

          newll[ll.length] = newlat;
          newll[ll.length + 1] = newlon;

          position = ll.length / 2;

        } else if (actualPosition <= 0) {
          // Put the new point at the beginning
          System.arraycopy(ll, 0, newll, 2, ll.length);
          newll[0] = newlat;
          newll[1] = newlon;
          position = 0;
        } else {
          // actualPosition because there are 2 floats for
          // every
          // position.
          newll[actualPosition] = newlat;
          newll[actualPosition + 1] = newlon;
          System.arraycopy(ll, 0, newll, 0, actualPosition);
          System.arraycopy(
              ll, actualPosition, newll, actualPosition + 2, ll.length - actualPosition);
        }
        poly.setLocation((double[]) newll, poly.getUnits());
      }
    } else if (renderType == OMGraphic.RENDERTYPE_XY) {
      // Grab the projected endpoints
      Debug.message("eomg", "EditableOMPoly: adding point to x/y poly");
      int currentLength = poly.xs.length;
      int[] newxs = new int[currentLength + 1];
      int[] newys = new int[currentLength + 1];

      if (position >= currentLength) {
        // Put the new points at the end
        System.arraycopy(poly.xs, 0, newxs, 0, currentLength);
        System.arraycopy(poly.ys, 0, newys, 0, currentLength);
        newxs[currentLength] = x;
        newys[currentLength] = y;

        position = currentLength;

      } else if (position <= 0) {
        // Put the new points at the beginning
        System.arraycopy(poly.xs, 0, newxs, 1, currentLength);
        System.arraycopy(poly.ys, 0, newys, 1, currentLength);
        newxs[0] = x;
        newys[0] = y;

        position = 0;

      } else {
        newxs[position] = x;
        newys[position] = y;

        System.arraycopy(poly.xs, 0, newxs, 0, position);
        System.arraycopy(poly.xs, position, newxs, position + 1, currentLength - position);

        System.arraycopy(poly.ys, 0, newys, 0, position);
        System.arraycopy(poly.ys, position, newys, position + 1, currentLength - position);
      }

      poly.setLocation(newxs, newys);

    } else {
      // Rendertype is offset...
      // Grab the projected endpoints
      Debug.message("eomg", "EditableOMPoly: adding point to offset poly");
      int currentLength = poly.xs.length;
      int[] newxs = new int[currentLength + 1];
      int[] newys = new int[currentLength + 1];

      if (position >= currentLength) {
        // Put the new points at the end
        position = currentLength;

        System.arraycopy(poly.xs, 0, newxs, 0, currentLength);
        System.arraycopy(poly.ys, 0, newys, 0, currentLength);

      } else if (position <= 0) {
        // Put the new points at the beginning
        position = 0;

        System.arraycopy(poly.xs, 0, newxs, 1, currentLength);
        System.arraycopy(poly.ys, 0, newys, 1, currentLength);

      } else {

        System.arraycopy(poly.xs, 0, newxs, 0, position);
        System.arraycopy(poly.xs, position, newxs, position + 1, currentLength - position);

        System.arraycopy(poly.ys, 0, newys, 0, position);
        System.arraycopy(poly.ys, position, newys, position + 1, currentLength - position);
      }

      int offsetX;
      int offsetY;

      if (gpo.getX() == -1 && gpo.getY() == -1) {
        offsetX = projection.getWidth() / 2;
        offsetY = projection.getHeight() / 2;
      } else {
        offsetX = gpo.getX();
        offsetY = gpo.getY();
      }

      if (poly.coordMode == OMPoly.COORDMODE_ORIGIN || position == 0) { // cover
        // the
        // first
        // point

        newxs[position] = x - offsetX;
        newys[position] = y - offsetY;
      } else { // CMode Previous offset deltas
        newxs[position] = x - offsetX - newxs[position - 1];
        newys[position] = y - offsetY - newys[position - 1];
      }

      if (position == 0) {
        // Could call projection.getCenter() but that might
        // break if/when we make other projection
        // libraries/paradigms active.
        LatLonPoint llpnt = projection.inverse(offsetX, offsetY, new LatLonPoint.Double());

        if (rads) {
          poly.lat = llpnt.getRadLat();
          poly.lon = llpnt.getRadLon();
        } else {
          poly.lat = llpnt.getY();
          poly.lon = llpnt.getX();
        }
      }

      poly.setLocation(poly.lat, poly.lon, poly.getUnits(), newxs, newys);
    }

    // Need to reset the arrowhead when an end point is added,
    // removing it from the shape when the point gets added.
    // Otherwise, you end up with a arrowhead at each junction of
    // the polygon.
    OMArrowHead omah = poly.getArrowHead();
    poly.setArrowHead(null);

    // Reset the arrowhead so it will get drawn on the new
    // segment.
    poly.setArrowHead(omah);
    polyGrabPoints.add(position, gp);

    if (gpo != null) {
      gpo.addGrabPoint(gp);
    }

    // This is the standard call that needs to be made here, the
    // arrowhead changes are around this.
    poly.regenerate(projection);
    gp.generate(projection);

    return position;
  }
Пример #5
0
  /**
   * Take the current location of the GrabPoints, and modify the location parameters of the OMPoly
   * with them. Called when you want the graphic to change according to the grab points.
   */
  public void setGrabPoints() {
    int i;
    GrabPoint gb; // just to use a temp marker
    LatLonPoint llp = new LatLonPoint.Double();
    int renderType = poly.getRenderType();

    if (renderType == OMGraphic.RENDERTYPE_LATLON) {
      if (projection != null) {
        double[] radCoords = new double[polyGrabPoints.size() * 2];

        // OK, this code resets the location of every point slightly to
        // the inverse location of the grab points. So if you grab one
        // node and move it, all of the precise values of each node
        // actually changes. As we go through the array of grab points,
        // we can check the corresponding projected location of the
        // current node and it matches the grab point, just use the
        // current poly value.
        double[] currentCoords = poly.getLatLonArray();
        Point2D testPoint = new Point2D.Double();
        for (i = 0; i < polyGrabPoints.size(); i++) {
          gb = (GrabPoint) polyGrabPoints.get(i);

          boolean useGrabPointLocation = true;
          try {
            double radLat = currentCoords[i * 2];
            double lat = Math.toDegrees(radLat);
            double radLon = currentCoords[i * 2 + 1];
            double lon = Math.toDegrees(radLon);
            testPoint = projection.forward(lat, lon, testPoint);

            if (testPoint.getX() == gb.getX() && testPoint.getY() == gb.getY()) {
              // The projected location of the current node is the
              // same as the grab point, use that location.
              radCoords[2 * i] = radLat;
              radCoords[2 * i + 1] = radLon;
              useGrabPointLocation = false;
            }

          } catch (Exception e) {
            // If anything goes wrong, don't worry about it, just
            // use the
            // projected inverse of grab point
          }

          if (useGrabPointLocation) {
            projection.inverse(gb.getX(), gb.getY(), llp);
            radCoords[2 * i] = llp.getRadLat();
            radCoords[2 * i + 1] = llp.getRadLon();
          }
        }

        poly.setLocation(radCoords, OMGraphic.RADIANS);
      } else {
        Debug.message(
            "eomg",
            "EditableOMPoly.setGrabPoints: projection is null, can't figure out LATLON points for poly.");
      }
    } else if (renderType == OMGraphic.RENDERTYPE_OFFSET) {
      // Do the offset point.
      if (projection != null) {

        projection.inverse(gpo.getX(), gpo.getY(), llp);

      } else {
        Debug.message(
            "eomg",
            "EditableOMPoly.setGrabPoints: projection is null, can't figure out LATLON points for poly offset.");
      }
    }

    if (renderType == OMGraphic.RENDERTYPE_XY || renderType == OMGraphic.RENDERTYPE_OFFSET) {

      int[] ints = new int[polyGrabPoints.size() * 2];
      if (renderType == OMGraphic.RENDERTYPE_OFFSET && gpo != null) {
        // If offset rendertype, the x-y have to be offset
        // distances, not screen pixel locations. For the
        // polygon, you also need to take into account that
        // the ints can represent 2 different things: distance
        // from the origin (Offset) or distance from the
        // previous point. Need to check with the poly to
        // find out which to do.
        GrabPoint previous = gpo;

        for (i = 0; i < polyGrabPoints.size(); i++) {
          gb = (GrabPoint) polyGrabPoints.get(i);

          if (poly.coordMode == OMPoly.COORDMODE_PREVIOUS) {

            ints[2 * i] = gb.getX() - previous.getX();
            ints[2 * i + 1] = gb.getY() - previous.getY();

            previous = gb;

          } else {
            ints[2 * i] = gb.getX() - gpo.getX();
            ints[2 * i + 1] = gb.getY() - gpo.getY();
          }
        }

        double newlat = llp.getRadLat();
        double newlon = llp.getRadLon();

        poly.setLocation(newlat, newlon, OMGraphic.RADIANS, ints);

      } else {

        for (i = 0; i < polyGrabPoints.size(); i++) {
          gb = (GrabPoint) polyGrabPoints.get(i);

          ints[2 * i] = gb.getX();
          ints[2 * i + 1] = gb.getY();
        }

        poly.setLocation(ints);
      }
    }
  }