public int countImagesInSector(Sector sector, int levelNumber) {
    if (sector == null) {
      String msg = Logging.getMessage("nullValue.SectorIsNull");
      Logging.logger().severe(msg);
      throw new IllegalArgumentException(msg);
    }

    Level targetLevel = this.levels.getLastLevel();
    if (levelNumber >= 0) {
      for (int i = levelNumber; i < this.getLevels().getLastLevel().getLevelNumber(); i++) {
        if (this.levels.isLevelEmpty(i)) continue;

        targetLevel = this.levels.getLevel(i);
        break;
      }
    }

    // Collect all the tiles intersecting the input sector.
    LatLon delta = targetLevel.getTileDelta();
    Angle latOrigin = this.levels.getTileOrigin().getLatitude();
    Angle lonOrigin = this.levels.getTileOrigin().getLongitude();
    final int nwRow = Tile.computeRow(delta.getLatitude(), sector.getMaxLatitude(), latOrigin);
    final int nwCol = Tile.computeColumn(delta.getLongitude(), sector.getMinLongitude(), lonOrigin);
    final int seRow = Tile.computeRow(delta.getLatitude(), sector.getMinLatitude(), latOrigin);
    final int seCol = Tile.computeColumn(delta.getLongitude(), sector.getMaxLongitude(), lonOrigin);

    int numRows = nwRow - seRow + 1;
    int numCols = seCol - nwCol + 1;

    return numRows * numCols;
  }
    private void adjustDateLineCrossingPoints() {
      ArrayList<LatLon> corners = new ArrayList<LatLon>(Arrays.asList(sw, se, nw, ne));
      if (!LatLon.locationsCrossDateLine(corners)) return;

      double lonSign = 0;
      for (LatLon corner : corners) {
        if (Math.abs(corner.getLongitude().degrees) != 180)
          lonSign = Math.signum(corner.getLongitude().degrees);
      }

      if (lonSign == 0) return;

      if (Math.abs(sw.getLongitude().degrees) == 180
          && Math.signum(sw.getLongitude().degrees) != lonSign)
        sw = new Position(sw.getLatitude(), sw.getLongitude().multiply(-1), sw.getElevation());
      if (Math.abs(se.getLongitude().degrees) == 180
          && Math.signum(se.getLongitude().degrees) != lonSign)
        se = new Position(se.getLatitude(), se.getLongitude().multiply(-1), se.getElevation());
      if (Math.abs(nw.getLongitude().degrees) == 180
          && Math.signum(nw.getLongitude().degrees) != lonSign)
        nw = new Position(nw.getLatitude(), nw.getLongitude().multiply(-1), nw.getElevation());
      if (Math.abs(ne.getLongitude().degrees) == 180
          && Math.signum(ne.getLongitude().degrees) != lonSign)
        ne = new Position(ne.getLatitude(), ne.getLongitude().multiply(-1), ne.getElevation());
    }
  private void drawTileIDs(DrawContext dc, ArrayList<MercatorTextureTile> tiles) {
    java.awt.Rectangle viewport = dc.getView().getViewport();
    if (this.textRenderer == null) {
      this.textRenderer = new TextRenderer(java.awt.Font.decode("Arial-Plain-13"), true, true);
      this.textRenderer.setUseVertexArrays(false);
    }

    dc.getGL().glDisable(GL.GL_DEPTH_TEST);
    dc.getGL().glDisable(GL.GL_BLEND);
    dc.getGL().glDisable(GL.GL_TEXTURE_2D);

    this.textRenderer.setColor(java.awt.Color.YELLOW);
    this.textRenderer.beginRendering(viewport.width, viewport.height);
    for (MercatorTextureTile tile : tiles) {
      String tileLabel = tile.getLabel();

      if (tile.getFallbackTile() != null) tileLabel += "/" + tile.getFallbackTile().getLabel();

      LatLon ll = tile.getSector().getCentroid();
      Vec4 pt =
          dc.getGlobe()
              .computePointFromPosition(
                  ll.getLatitude(),
                  ll.getLongitude(),
                  dc.getGlobe().getElevation(ll.getLatitude(), ll.getLongitude()));
      pt = dc.getView().project(pt);
      this.textRenderer.draw(tileLabel, (int) pt.x, (int) pt.y);
    }
    this.textRenderer.endRendering();
  }
Exemplo n.º 4
0
    protected Vec4 getSurfacePoint(LatLon latlon, double elevation) {
      Vec4 point = null;

      SceneController sc = this.getApp().getWwd().getSceneController();
      Globe globe = this.getApp().getWwd().getModel().getGlobe();

      if (sc.getTerrain() != null) {
        point =
            sc.getTerrain()
                .getSurfacePoint(
                    latlon.getLatitude(),
                    latlon.getLongitude(),
                    elevation * sc.getVerticalExaggeration());
      }

      if (point == null) {
        double e = globe.getElevation(latlon.getLatitude(), latlon.getLongitude());
        point =
            globe.computePointFromPosition(
                latlon.getLatitude(),
                latlon.getLongitude(),
                (e + elevation) * sc.getVerticalExaggeration());
      }

      return point;
    }
Exemplo n.º 5
0
 protected Vec4 getPoint(LatLon latlon, double elevation) {
   SceneController sc = this.getApp().getWwd().getSceneController();
   Globe globe = this.getApp().getWwd().getModel().getGlobe();
   double e = globe.getElevation(latlon.getLatitude(), latlon.getLongitude());
   return globe.computePointFromPosition(
       latlon.getLatitude(),
       latlon.getLongitude(),
       (e + elevation) * sc.getVerticalExaggeration());
 }
Exemplo n.º 6
0
  protected void assembleVertexControlPoints(DrawContext dc) {
    Terrain terrain = dc.getTerrain();
    ExtrudedPolygon polygon = this.getPolygon();

    Position refPos = polygon.getReferencePosition();
    Vec4 refPoint = terrain.getSurfacePoint(refPos.getLatitude(), refPos.getLongitude(), 0);

    int altitudeMode = polygon.getAltitudeMode();
    double height = polygon.getHeight();

    Vec4 vaa = null;
    double vaaLength = 0; // used to compute independent length of each cap vertex
    double vaLength = 0;

    int i = 0;
    for (LatLon location : polygon.getOuterBoundary()) {
      Vec4 vert;

      // Compute the top/cap point.
      if (altitudeMode == WorldWind.CONSTANT || !(location instanceof Position)) {
        if (vaa == null) {
          // Compute the vector lengths of the top and bottom points at the reference position.
          vaa = refPoint.multiply3(height / refPoint.getLength3());
          vaaLength = vaa.getLength3();
          vaLength = refPoint.getLength3();
        }

        // Compute the bottom point, which is on the terrain.
        vert = terrain.getSurfacePoint(location.getLatitude(), location.getLongitude(), 0);

        double delta = vaLength - vert.dot3(refPoint) / vaLength;
        vert = vert.add3(vaa.multiply3(1d + delta / vaaLength));
      } else if (altitudeMode == WorldWind.RELATIVE_TO_GROUND) {
        vert =
            terrain.getSurfacePoint(
                location.getLatitude(),
                location.getLongitude(),
                ((Position) location).getAltitude());
      } else // WorldWind.ABSOLUTE
      {
        vert =
            terrain
                .getGlobe()
                .computePointFromPosition(
                    location.getLatitude(),
                    location.getLongitude(),
                    ((Position) location).getAltitude() * terrain.getVerticalExaggeration());
      }

      Position vertexPosition = this.wwd.getModel().getGlobe().computePositionFromPoint(vert);

      this.controlPoints.add(
          new ControlPointMarker(
              MOVE_VERTEX_ACTION, vertexPosition, vert, this.vertexControlAttributes, i));
      i++;
    }
  }
Exemplo n.º 7
0
  protected void movePolygon(Point previousMousePoint, Point mousePoint) {
    // Intersect a ray through each mouse point, with a geoid passing through the reference
    // elevation.
    // If either ray fails to intersect the geoid, then ignore this event. Use the difference
    // between the two
    // intersected positions to move the control point's location.

    View view = this.wwd.getView();
    Globe globe = this.wwd.getModel().getGlobe();

    Position refPos = this.polygon.getReferencePosition();
    if (refPos == null) return;

    Line ray = view.computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY());
    Line previousRay =
        view.computeRayFromScreenPoint(previousMousePoint.getX(), previousMousePoint.getY());

    Vec4 vec = AirspaceEditorUtil.intersectGlobeAt(this.wwd, refPos.getElevation(), ray);
    Vec4 previousVec =
        AirspaceEditorUtil.intersectGlobeAt(this.wwd, refPos.getElevation(), previousRay);

    if (vec == null || previousVec == null) {
      return;
    }

    Position pos = globe.computePositionFromPoint(vec);
    Position previousPos = globe.computePositionFromPoint(previousVec);
    LatLon change = pos.subtract(previousPos);

    this.polygon.move(new Position(change.getLatitude(), change.getLongitude(), 0.0));
  }
Exemplo n.º 8
0
  public void printInfo(boolean printCoordinates) {
    System.out.printf(
        "%d, %s: %d parts, %d points",
        this.getRecordNumber(),
        this.getShapeType(),
        this.getNumberOfParts(),
        this.getNumberOfPoints());
    for (Map.Entry<String, Object> a : this.getAttributes().getEntries()) {
      if (a.getKey() != null) System.out.printf(", %s", a.getKey());
      if (a.getValue() != null) System.out.printf(", %s", a.getValue());
    }
    System.out.println();

    System.out.print("\tAttributes: ");
    for (Map.Entry<String, Object> entry : this.getAttributes().getEntries()) {
      System.out.printf("%s = %s, ", entry.getKey(), entry.getValue());
    }
    System.out.println();

    if (!printCoordinates) return;

    VecBuffer vb = this.getPointBuffer(0);
    for (LatLon ll : vb.getLocations()) {
      System.out.printf("\t%f, %f\n", ll.getLatitude().degrees, ll.getLongitude().degrees);
    }
  }
    public void doActionOnButton3() {
      //            Sector sector = Sector.fromDegrees( 44d, 46d, -123.3d, -123.2d );

      ArrayList<LatLon> latlons = new ArrayList<LatLon>();

      latlons.add(LatLon.fromDegrees(45.50d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.51d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.52d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.53d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.54d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.55d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.56d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.57d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.58d, -123.3d));
      //            latlons.add( LatLon.fromDegrees( 45.59d, -123.3d ) );
      latlons.add(LatLon.fromDegrees(45.60d, -123.3d));

      ElevationModel model = this.wwd.getModel().getGlobe().getElevationModel();

      StringBuffer sb = new StringBuffer();
      for (LatLon ll : latlons) {
        double e = model.getElevation(ll.getLatitude(), ll.getLongitude());
        sb.append("\n").append(e);
      }

      Logging.logger().info(sb.toString());
    }
Exemplo n.º 10
0
  public void flyToLatLon(LatLon latlon, double zoom) {
    Globe globe = canvas.getModel().getGlobe();
    Position position =
        new Position(latlon, globe.getElevation(latlon.getLatitude(), latlon.getLongitude()));

    flyToPosition(position, zoom);
  }
Exemplo n.º 11
0
  /**
   * Sets the vector element at the specified position, as a geographic LatLon. This buffer's
   * logical vector size must be at least 2.
   *
   * @param position the logical vector position.
   * @param ll the geographic location to set.
   * @throws IllegalArgumentException if the position is out of range, if the LatLon is null, or if
   *     this buffer cannot store a LatLon.
   */
  public void putLocation(int position, LatLon ll) {
    if (position < 0 || position >= this.getSize()) {
      String message =
          Logging.getMessage("generic.ArgumentOutOfRange", "position < 0 or position >= size");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    if (ll == null) {
      String message = Logging.getMessage("nullValue.LatLonIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    if (this.coordsPerVec < 2) {
      String message = Logging.getMessage("generic.BufferIncompatible", this);
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    double[] compArray = new double[2];
    compArray[1] = ll.getLatitude().degrees;
    compArray[0] = ll.getLongitude().degrees;

    this.put(position, compArray);
  }
Exemplo n.º 12
0
 protected double computeLocationDistanceDegreesSquared(Sector drawSector, LatLon location) {
   double lonOffset = computeHemisphereOffset(drawSector, location);
   double dLat = location.getLatitude().degrees - drawSector.getCentroid().getLatitude().degrees;
   double dLon =
       location.getLongitude().degrees
           - drawSector.getCentroid().getLongitude().degrees
           + lonOffset;
   return dLat * dLat + dLon * dLon;
 }
  private MercatorTextureTile[][] getTilesInSector(Sector sector, int levelNumber) {
    if (sector == null) {
      String msg = Logging.getMessage("nullValue.SectorIsNull");
      Logging.logger().severe(msg);
      throw new IllegalArgumentException(msg);
    }

    Level targetLevel = this.levels.getLastLevel();
    if (levelNumber >= 0) {
      for (int i = levelNumber; i < this.getLevels().getLastLevel().getLevelNumber(); i++) {
        if (this.levels.isLevelEmpty(i)) continue;

        targetLevel = this.levels.getLevel(i);
        break;
      }
    }

    // Collect all the tiles intersecting the input sector.
    LatLon delta = targetLevel.getTileDelta();
    Angle latOrigin = this.levels.getTileOrigin().getLatitude();
    Angle lonOrigin = this.levels.getTileOrigin().getLongitude();
    final int nwRow = Tile.computeRow(delta.getLatitude(), sector.getMaxLatitude(), latOrigin);
    final int nwCol = Tile.computeColumn(delta.getLongitude(), sector.getMinLongitude(), lonOrigin);
    final int seRow = Tile.computeRow(delta.getLatitude(), sector.getMinLatitude(), latOrigin);
    final int seCol = Tile.computeColumn(delta.getLongitude(), sector.getMaxLongitude(), lonOrigin);

    int numRows = nwRow - seRow + 1;
    int numCols = seCol - nwCol + 1;
    MercatorTextureTile[][] sectorTiles = new MercatorTextureTile[numRows][numCols];

    for (int row = nwRow; row >= seRow; row--) {
      for (int col = nwCol; col <= seCol; col++) {
        TileKey key =
            new TileKey(targetLevel.getLevelNumber(), row, col, targetLevel.getCacheName());
        Sector tileSector = this.levels.computeSectorForKey(key);
        MercatorSector mSector = MercatorSector.fromSector(tileSector); // TODO: check
        sectorTiles[nwRow - row][col - nwCol] =
            new MercatorTextureTile(mSector, targetLevel, row, col);
      }
    }

    return sectorTiles;
  }
Exemplo n.º 14
0
  /**
   * Format angles of latitude and longitude according to the current angle format.
   *
   * <p>The values are formatted using the current {@link #LABEL_LATLON_LAT}, {@link
   * #LABEL_LATLON_LON} and angle format.
   *
   * @param latlon the angles to format.
   * @return a string containing the formatted angles.
   * @throws IllegalArgumentException if <code>latlon</code> is null.
   */
  public String latLon(LatLon latlon) {
    if (latlon == null) {
      String msg = Logging.getMessage("nullValue.LatLonIsNull");
      Logging.logger().severe(msg);
      throw new IllegalArgumentException(msg);
    }

    return String.format(
            "%s %s",
            this.angle(this.getLabel(LABEL_LATLON_LAT), latlon.getLatitude()),
            this.angle(this.getLabel(LABEL_LATLON_LON), latlon.getLongitude()))
        .trim();
  }
Exemplo n.º 15
0
  protected void doMoveAirspaceLaterally(
      WorldWindow wwd, Airspace airspace, Point mousePoint, Point previousMousePoint) {
    // Intersect a ray throuh each mouse point, with a geoid passing through the reference
    // elevation. Since
    // most airspace control points follow a fixed altitude, this will track close to the intended
    // mouse position.
    // If either ray fails to intersect the geoid, then ignore this event. Use the difference
    // between the two
    // intersected positions to move the control point's location.

    if (!(airspace instanceof Movable)) {
      return;
    }

    Movable movable = (Movable) airspace;
    View view = wwd.getView();
    Globe globe = wwd.getModel().getGlobe();

    Position refPos = movable.getReferencePosition();
    if (refPos == null) return;

    // Convert the reference position into a cartesian point. This assumes that the reference
    // elevation is defined
    // by the airspace's lower altitude.
    Vec4 refPoint = null;
    if (airspace.isTerrainConforming()[LOWER_ALTITUDE])
      refPoint = wwd.getSceneController().getTerrain().getSurfacePoint(refPos);
    if (refPoint == null) refPoint = globe.computePointFromPosition(refPos);

    // Convert back to a position.
    refPos = globe.computePositionFromPoint(refPoint);

    Line ray = view.computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY());
    Line previousRay =
        view.computeRayFromScreenPoint(previousMousePoint.getX(), previousMousePoint.getY());

    Vec4 vec = AirspaceEditorUtil.intersectGlobeAt(wwd, refPos.getElevation(), ray);
    Vec4 previousVec = AirspaceEditorUtil.intersectGlobeAt(wwd, refPos.getElevation(), previousRay);

    if (vec == null || previousVec == null) {
      return;
    }

    Position pos = globe.computePositionFromPoint(vec);
    Position previousPos = globe.computePositionFromPoint(previousVec);
    LatLon change = pos.subtract(previousPos);

    movable.move(new Position(change.getLatitude(), change.getLongitude(), 0.0));

    this.fireAirspaceMoved(new AirspaceEditEvent(wwd, airspace, this));
  }
Exemplo n.º 16
0
  public void exportAsXML(XMLStreamWriter xmlWriter) throws IOException, XMLStreamException {
    if (xmlWriter == null) {
      String message = Logging.getMessage("Export.UnsupportedOutputObject");
      Logging.logger().warning(message);
      throw new IllegalArgumentException(message);
    }

    xmlWriter.writeStartElement("Record");

    xmlWriter.writeAttribute("id", Integer.toString(this.getRecordNumber()));
    xmlWriter.writeAttribute(
        "shape", this.getShapeType().substring(this.getShapeType().lastIndexOf("Shape") + 5));
    xmlWriter.writeAttribute("parts", Integer.toString(this.getNumberOfParts()));
    xmlWriter.writeAttribute("points", Integer.toString(this.getNumberOfPoints()));
    xmlWriter.writeCharacters("\n");

    for (Map.Entry<String, Object> a : this.getAttributes().getEntries()) {
      xmlWriter.writeStartElement("Attribute");

      xmlWriter.writeAttribute("name", a.getKey() != null ? a.getKey().toString() : "");
      xmlWriter.writeAttribute("value", a.getValue() != null ? a.getValue().toString() : "");

      xmlWriter.writeEndElement(); // Attribute
      xmlWriter.writeCharacters("\n");
    }

    if (this.getNumberOfParts() > 0) {
      VecBuffer vb = this.getPointBuffer(0);
      for (LatLon ll : vb.getLocations()) {
        xmlWriter.writeStartElement("Point");
        xmlWriter.writeAttribute("x", Double.toString(ll.getLatitude().degrees));
        xmlWriter.writeAttribute("y", Double.toString(ll.getLongitude().degrees));
        xmlWriter.writeEndElement(); // Point
        xmlWriter.writeCharacters("\n");
      }
    }

    // TODO: export record-type specific fields

    xmlWriter.writeEndElement(); // Record
  }
Exemplo n.º 17
0
    protected void initializePolygon(WorldWindow wwd, Polygon polygon, boolean fitShapeToViewport) {
      // Creates a rectangle in the center of the viewport. Attempts to guess at a reasonable size
      // and height.

      Position position = ShapeUtils.getNewShapePosition(wwd);
      Angle heading = ShapeUtils.getNewShapeHeading(wwd, true);
      double sizeInMeters =
          fitShapeToViewport ? ShapeUtils.getViewportScaleFactor(wwd) : DEFAULT_SHAPE_SIZE_METERS;

      java.util.List<LatLon> locations =
          ShapeUtils.createSquareInViewport(wwd, position, heading, sizeInMeters);

      double maxElevation = -Double.MAX_VALUE;
      Globe globe = wwd.getModel().getGlobe();

      for (LatLon ll : locations) {
        double e = globe.getElevation(ll.getLatitude(), ll.getLongitude());
        if (e > maxElevation) maxElevation = e;
      }

      polygon.setAltitudes(0.0, maxElevation + sizeInMeters);
      polygon.setTerrainConforming(true, false);
      polygon.setLocations(locations);
    }
 protected boolean isPathCrossingAPole(LatLon p1, LatLon p2) {
   return Math.abs(p1.getLongitude().degrees - p2.getLongitude().degrees) > 20
       && Math.abs(p1.getLatitude().degrees - 90 * Math.signum(p1.getLatitude().degrees)) < 10;
 }
Exemplo n.º 19
0
  /**
   * Subdivide a list of positions so that no segment is longer then the provided maxLength. Only
   * the positions between start and start + count - 1 will be processed.
   *
   * <p>If needed, new intermediate positions will be created along lines that follow the given
   * pathType - one of Polyline.LINEAR, Polyline.RHUMB_LINE or Polyline.GREAT_CIRCLE. All position
   * elevations will be either at the terrain surface if followTerrain is true, or interpolated
   * according to the original elevations.
   *
   * @param globe the globe to draw elevations and points from.
   * @param positions the original position list
   * @param maxLength the maximum length for one segment.
   * @param followTerrain true if the positions should be on the terrain surface.
   * @param pathType the type of path to use in between two positions.
   * @param start the first position indice in the original list.
   * @param count how many positions from the original list have to be processed and returned.
   * @return a list of positions with no segment longer then maxLength and elevations following
   *     terrain or not.
   */
  protected static ArrayList<? extends Position> subdividePositions(
      Globe globe,
      ArrayList<? extends Position> positions,
      double maxLength,
      boolean followTerrain,
      String pathType,
      int start,
      int count) {
    if (positions == null || positions.size() < start + count) return positions;

    ArrayList<Position> newPositions = new ArrayList<Position>();
    // Add first position
    Position pos1 = positions.get(start);
    if (followTerrain)
      newPositions.add(
          new Position(pos1, globe.getElevation(pos1.getLatitude(), pos1.getLongitude())));
    else newPositions.add(pos1);
    for (int i = 1; i < count; i++) {
      Position pos2 = positions.get(start + i);
      double arcLengthRadians = LatLon.greatCircleDistance(pos1, pos2).radians;
      double arcLength = arcLengthRadians * globe.getRadiusAt(LatLon.interpolate(.5, pos1, pos2));
      if (arcLength > maxLength) {
        // if necessary subdivide segment at regular intervals smaller then maxLength
        Angle segmentAzimuth = null;
        Angle segmentDistance = null;
        int steps = (int) Math.ceil(arcLength / maxLength); // number of intervals - at least two
        for (int j = 1; j < steps; j++) {
          float s = (float) j / steps;
          LatLon destLatLon;
          if (pathType.equals(AVKey.LINEAR)) {
            destLatLon = LatLon.interpolate(s, pos1, pos2);
          } else if (pathType.equals(AVKey.RHUMB_LINE)) {
            if (segmentAzimuth == null) {
              segmentAzimuth = LatLon.rhumbAzimuth(pos1, pos2);
              segmentDistance = LatLon.rhumbDistance(pos1, pos2);
            }
            destLatLon =
                LatLon.rhumbEndPosition(pos1, segmentAzimuth.radians, s * segmentDistance.radians);
          } else // GREAT_CIRCLE
          {
            if (segmentAzimuth == null) {
              segmentAzimuth = LatLon.greatCircleAzimuth(pos1, pos2);
              segmentDistance = LatLon.greatCircleDistance(pos1, pos2);
            }
            destLatLon =
                LatLon.greatCircleEndPosition(
                    pos1, segmentAzimuth.radians, s * segmentDistance.radians);
          }
          // Set elevation
          double elevation;
          if (followTerrain)
            elevation = globe.getElevation(destLatLon.getLatitude(), destLatLon.getLongitude());
          else elevation = pos1.elevation * (1 - s) + pos2.elevation * s;
          // Add new position
          newPositions.add(new Position(destLatLon, elevation));
        }
      }
      // Finally add the segment end position
      if (followTerrain)
        newPositions.add(
            new Position(pos2, globe.getElevation(pos2.getLatitude(), pos2.getLongitude())));
      else newPositions.add(pos2);
      // Prepare for next segment
      pos1 = pos2;
    }
    return newPositions;
  }
Exemplo n.º 20
0
  protected void drawIcon(DrawContext dc) {
    if (this.getIconFilePath() == null) return;

    GL gl = dc.getGL();
    OGLStackHandler ogsh = new OGLStackHandler();

    try {
      // Initialize texture if necessary
      Texture iconTexture = dc.getTextureCache().getTexture(this.getIconFilePath());
      if (iconTexture == null) {
        this.initializeTexture(dc);
        iconTexture = dc.getTextureCache().getTexture(this.getIconFilePath());
        if (iconTexture == null) {
          String msg = Logging.getMessage("generic.ImageReadFailed");
          Logging.logger().finer(msg);
          return;
        }
      }
      gl.glDisable(GL.GL_DEPTH_TEST);

      double width = this.getScaledIconWidth();
      double height = this.getScaledIconHeight();

      // Load a parallel projection with xy dimensions (viewportWidth, viewportHeight)
      // into the GL projection matrix.
      java.awt.Rectangle viewport = dc.getView().getViewport();
      ogsh.pushProjectionIdentity(gl);
      double maxwh = width > height ? width : height;
      gl.glOrtho(0d, viewport.width, 0d, viewport.height, -0.6 * maxwh, 0.6 * maxwh);

      // Translate and scale
      ogsh.pushModelviewIdentity(gl);
      double scale = this.computeScale(viewport);
      Vec4 locationSW = this.computeLocation(viewport, scale);
      gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z());
      // Scale to 0..1 space
      gl.glScaled(scale, scale, 1);
      gl.glScaled(width, height, 1d);

      if (!dc.isPickingMode()) {
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

        // Draw background color behind the map
        gl.glColor4ub(
            (byte) this.backColor.getRed(),
            (byte) this.backColor.getGreen(),
            (byte) this.backColor.getBlue(),
            (byte) (this.backColor.getAlpha() * this.getOpacity()));
        dc.drawUnitQuad();

        // Draw world map icon
        gl.glColor4d(1d, 1d, 1d, this.getOpacity());
        gl.glEnable(GL.GL_TEXTURE_2D);
        iconTexture.bind();

        TextureCoords texCoords = iconTexture.getImageTexCoords();
        dc.drawUnitQuad(texCoords);
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
        gl.glDisable(GL.GL_TEXTURE_2D);

        // Draw crosshair for current location
        gl.glLoadIdentity();
        gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z());
        // Scale to width x height space
        gl.glScaled(scale, scale, 1);
        // Set color
        float[] colorRGB = this.color.getRGBColorComponents(null);
        gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity());

        // Draw crosshair
        Position groundPos = this.computeGroundPosition(dc, dc.getView());
        if (groundPos != null) {
          int x = (int) (width * (groundPos.getLongitude().degrees + 180) / 360);
          int y = (int) (height * (groundPos.getLatitude().degrees + 90) / 180);
          int w = 10; // cross branch length
          // Draw
          gl.glBegin(GL.GL_LINE_STRIP);
          gl.glVertex3d(x - w, y, 0);
          gl.glVertex3d(x + w + 1, y, 0);
          gl.glEnd();
          gl.glBegin(GL.GL_LINE_STRIP);
          gl.glVertex3d(x, y - w, 0);
          gl.glVertex3d(x, y + w + 1, 0);
          gl.glEnd();
        }

        // Draw view footprint in map icon space
        if (this.showFootprint) {
          this.footPrintPositions = this.computeViewFootPrint(dc, 32);
          if (this.footPrintPositions != null) {
            gl.glBegin(GL.GL_LINE_STRIP);
            LatLon p1 = this.footPrintPositions.get(0);
            for (LatLon p2 : this.footPrintPositions) {
              int x = (int) (width * (p2.getLongitude().degrees + 180) / 360);
              int y = (int) (height * (p2.getLatitude().degrees + 90) / 180);
              // Draw
              if (LatLon.locationsCrossDateline(p1, p2)) {
                int y1 = (int) (height * (p1.getLatitude().degrees + 90) / 180);
                gl.glVertex3d(x < width / 2 ? width : 0, (y1 + y) / 2, 0);
                gl.glEnd();
                gl.glBegin(GL.GL_LINE_STRIP);
                gl.glVertex3d(x < width / 2 ? 0 : width, (y1 + y) / 2, 0);
              }
              gl.glVertex3d(x, y, 0);
              p1 = p2;
            }
            gl.glEnd();
          }
        }
        // Draw 1px border around and inside the map
        gl.glBegin(GL.GL_LINE_STRIP);
        gl.glVertex3d(0, 0, 0);
        gl.glVertex3d(width, 0, 0);
        gl.glVertex3d(width, height - 1, 0);
        gl.glVertex3d(0, height - 1, 0);
        gl.glVertex3d(0, 0, 0);
        gl.glEnd();
      } else {
        // Picking
        this.pickSupport.clearPickList();
        this.pickSupport.beginPicking(dc);
        // Where in the world are we picking ?
        Position pickPosition =
            computePickPosition(
                dc, locationSW, new Dimension((int) (width * scale), (int) (height * scale)));
        Color color = dc.getUniquePickColor();
        int colorCode = color.getRGB();
        this.pickSupport.addPickableObject(colorCode, this, pickPosition, false);
        gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());
        dc.drawUnitQuad();
        this.pickSupport.endPicking(dc);
        this.pickSupport.resolvePick(dc, dc.getPickPoint(), this);
      }
    } finally {
      dc.restoreDefaultDepthTesting();
      dc.restoreDefaultCurrentColor();
      if (dc.isPickingMode()) dc.restoreDefaultBlending();
      ogsh.pop(gl);
    }
  }
Exemplo n.º 21
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;
  }