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;
  }
Пример #2
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;
    }
  public static Sector union(Iterable<? extends Sector> sectors) {
    if (sectors == null) {
      throw new IllegalArgumentException("Sector List Is Null");
    }

    Angle minLat = Angle.POS90;
    Angle maxLat = Angle.NEG90;
    Angle minLon = Angle.POS180;
    Angle maxLon = Angle.NEG180;

    for (Sector s : sectors) {
      if (s == null) {
        continue;
      }

      for (LatLon p : s) {
        if (p.getLatitude().degrees < minLat.degrees) {
          minLat = p.getLatitude();
        }
        if (p.getLatitude().degrees > maxLat.degrees) {
          maxLat = p.getLatitude();
        }
        if (p.getLongitude().degrees < minLon.degrees) {
          minLon = p.getLongitude();
        }
        if (p.getLongitude().degrees > maxLon.degrees) {
          maxLon = p.getLongitude();
        }
      }
    }

    return new Sector(minLat, maxLat, minLon, maxLon);
  }
  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();
  }
Пример #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());
 }
Пример #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++;
    }
  }
  /**
   * Determines whether a latitude/longitude position is within the sector. The sector's angles are
   * assumed to be normalized to +/- 90 degrees latitude and +/- 180 degrees longitude. The result
   * of the operation is undefined if they are not.
   *
   * @param latLon the position to test, with angles normalized to +/- &#960 latitude and +/- 2&#960
   *     longitude.
   * @return <code>true</code> if the position is within the sector, <code>false</code> otherwise.
   * @throws IllegalArgumentException if <code>latlon</code> is null.
   */
  public final boolean contains(LatLon latLon) {
    if (latLon == null) {
      throw new IllegalArgumentException("LatLon Is Null");
    }

    return this.contains(latLon.getLatitude(), latLon.getLongitude());
  }
Пример #8
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));
  }
  public static Sector boundingSector(Iterable<? extends LatLon> locations) {
    if (locations == null) {
      throw new IllegalArgumentException("Positions List Is Null");
    }

    if (!locations.iterator().hasNext()) {
      return EMPTY_SECTOR; // TODO: should be returning null
    }
    double minLat = Angle.POS90.getDegrees();
    double minLon = Angle.POS180.getDegrees();
    double maxLat = Angle.NEG90.getDegrees();
    double maxLon = Angle.NEG180.getDegrees();

    for (LatLon p : locations) {
      double lat = p.getLatitude().getDegrees();
      if (lat < minLat) {
        minLat = lat;
      }
      if (lat > maxLat) {
        maxLat = lat;
      }

      double lon = p.getLongitude().getDegrees();
      if (lon < minLon) {
        minLon = lon;
      }
      if (lon > maxLon) {
        maxLon = lon;
      }
    }

    return Sector.fromDegrees(minLat, maxLat, minLon, maxLon);
  }
    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());
    }
Пример #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);
  }
Пример #12
0
 @Test
 public void testAntipodalPointsA() {
   LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442);
   double azimuthRadians = Math.toRadians(-90.0);
   double distanceRadians = Math.toRadians(180.0);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Antipodal points A (lat)", -53.0902505, end.getLatitude().degrees, THRESHOLD);
   assertEquals("Antipodal points A (lon)", -67.1064558, end.getLongitude().degrees, THRESHOLD);
 }
Пример #13
0
 @Test
 public void testTrivialAzimuthA() {
   LatLon begin = LatLon.fromDegrees(0.0, 0.0);
   double azimuthRadians = Math.toRadians(90.0);
   double distanceRadians = Math.toRadians(0.0);
   LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Trivial Azimuth A (lat)", 0.0, end.getLatitude().degrees, THRESHOLD);
   assertEquals("Trivial Azimuth A (lon)", 0.0, end.getLongitude().degrees, THRESHOLD);
 }
Пример #14
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;
 }
Пример #15
0
 @Test
 public void testAntipodalPointsB() {
   LatLon begin = LatLon.fromDegrees(-12.0, 87.0);
   double azimuthRadians = Math.toRadians(-90.0);
   double distanceRadians = Math.toRadians(180.0);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Antipodal points B (lat)", 12.0, end.getLatitude().degrees, THRESHOLD);
   assertEquals("Antipodal points B (lon)", -93.0, end.getLongitude().degrees, THRESHOLD);
 }
Пример #16
0
 @Test
 public void testKnownPointsB() {
   LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442);
   double azimuthRadians = Math.toRadians(-68.4055227);
   double distanceRadians = Math.toRadians(10.53630354);
   LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Known points B (lat)", 56.9679782407693, end.getLatitude().degrees, THRESHOLD);
   assertEquals(
       "Known points B (lon)", 95.78434282105843, end.getLongitude().degrees, THRESHOLD);
 }
Пример #17
0
 @Test
 public void testKnownPointsA() {
   LatLon begin = LatLon.fromDegrees(-53.0902505, -67.1064558);
   double azimuthRadians = Math.toRadians(15.2204311);
   double distanceRadians = Math.toRadians(88.7560694);
   LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Known points A (lat)", 32.55251684755035, end.getLatitude().degrees, THRESHOLD);
   assertEquals(
       "Known points A (lon)", -40.62266365697857, end.getLongitude().degrees, THRESHOLD);
 }
  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;
  }
Пример #19
0
 @Test
 public void testKnownPointsB() {
   LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442);
   double azimuthRadians = Math.toRadians(-68.4055227);
   double distanceRadians = Math.toRadians(10.53630354);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals("Known points B (lat)", 55.7426290038835, end.getLatitude().degrees, THRESHOLD);
   assertEquals(
       "Known points B (lon)", 95.313127193979270, end.getLongitude().degrees, THRESHOLD);
 }
  public static Sector[] splitBoundingSectors(Iterable<? extends LatLon> locations) {
    if (locations == null) {
      throw new IllegalArgumentException("Location In List Is Null");
    }

    if (!locations.iterator().hasNext()) {
      return null;
    }

    double minLat = Angle.POS90.getDegrees();
    double minLon = Angle.POS180.getDegrees();
    double maxLat = Angle.NEG90.getDegrees();
    double maxLon = Angle.NEG180.getDegrees();

    LatLon lastLocation = null;

    for (LatLon ll : locations) {
      double lat = ll.getLatitude().getDegrees();
      if (lat < minLat) {
        minLat = lat;
      }
      if (lat > maxLat) {
        maxLat = lat;
      }

      double lon = ll.getLongitude().getDegrees();
      if (lon >= 0 && lon < minLon) {
        minLon = lon;
      }
      if (lon <= 0 && lon > maxLon) {
        maxLon = lon;
      }

      if (lastLocation != null) {
        double lastLon = lastLocation.getLongitude().getDegrees();
        if (Math.signum(lon) != Math.signum(lastLon)) {
          if (Math.abs(lon - lastLon) < 180) {
            // Crossing the zero longitude line too
            maxLon = 0;
            minLon = 0;
          }
        }
      }
      lastLocation = ll;
    }

    if (minLat == maxLat && minLon == maxLon) {
      return null;
    }

    return new Sector[] {
      Sector.fromDegrees(minLat, maxLat, minLon, 180), // Sector on eastern hemisphere.
      Sector.fromDegrees(minLat, maxLat, -180, maxLon) // Sector on western hemisphere.
    };
  }
Пример #21
0
 @Test
 public void testKnownPointsA() {
   LatLon begin = LatLon.fromDegrees(-53.0902505, -67.1064558);
   double azimuthRadians = Math.toRadians(15.2204311);
   double distanceRadians = Math.toRadians(-88.7560694);
   LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals(
       "Known points A (lat)", -36.63477988750917, end.getLatitude().degrees, THRESHOLD);
   assertEquals(
       "Known points A (lon)", 131.98550742812412, end.getLongitude().degrees, THRESHOLD);
 }
Пример #22
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();
  }
  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));
  }
Пример #24
0
 @Test
 public void testTrivialAzimuthB() {
   LatLon begin = LatLon.fromDegrees(0.0, 0.0);
   double azimuthRadians = Math.toRadians(90.0);
   double distanceRadians = Math.toRadians(360.0);
   LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians);
   assertEquals(
       "Trivial Azimuth B (lat)", 2.204291436880279e-14, end.getLatitude().degrees, THRESHOLD);
   assertEquals(
       "Trivial Azimuth B (lon)",
       -96.67061650574995,
       end.getLongitude().degrees,
       1e-1); // Custom threshold
 }
  /**
   * Determines whether this sector intersects the specified geographic line segment. The line
   * segment is specified by a begin location and an end location. The locations are are assumed to
   * be connected by a linear path in geographic space. This returns true if any location along that
   * linear path intersects this sector, including the begin and end locations.
   *
   * @param begin the line segment begin location.
   * @param end the line segment end location.
   * @return true <code>true</code> if this sector intersects the line segment, otherwise <code>
   *     false</code>.
   * @throws IllegalArgumentException if either the begin location or the end location is null.
   */
  public boolean intersectsSegment(LatLon begin, LatLon end) {
    if (begin == null) {
      throw new IllegalArgumentException("Begin Is Null");
    }

    if (end == null) {
      throw new IllegalArgumentException("End Is Null");
    }

    Vec4 segmentBegin = new Vec4(begin.getLongitude().degrees, begin.getLatitude().degrees, 0);
    Vec4 segmentEnd = new Vec4(end.getLongitude().degrees, end.getLatitude().degrees, 0);
    Vec4 tmp = segmentEnd.subtract3(segmentBegin);
    Vec4 segmentCenter = segmentBegin.add3(segmentEnd).divide3(2);
    Vec4 segmentDirection = tmp.normalize3();
    double segmentExtent = tmp.getLength3() / 2.0;

    LatLon centroid = this.getCentroid();
    Vec4 boxCenter = new Vec4(centroid.getLongitude().degrees, centroid.getLatitude().degrees, 0);
    double boxExtentX = this.getDeltaLonDegrees() / 2.0;
    double boxExtentY = this.getDeltaLatDegrees() / 2.0;

    Vec4 diff = segmentCenter.subtract3(boxCenter);

    if (Math.abs(diff.x) > (boxExtentX + segmentExtent * Math.abs(segmentDirection.x))) {
      return false;
    }

    if (Math.abs(diff.y) > (boxExtentY + segmentExtent * Math.abs(segmentDirection.y))) {
      return false;
    }

    //noinspection SuspiciousNameCombination
    Vec4 segmentPerp = new Vec4(segmentDirection.y, -segmentDirection.x, 0);

    return Math.abs(segmentPerp.dot3(diff))
        <= (boxExtentX * Math.abs(segmentPerp.x) + boxExtentY * Math.abs(segmentPerp.y));
  }
  public static Sector boundingSector(LatLon pA, LatLon pB) {
    if (pA == null || pB == null) {
      throw new IllegalArgumentException("Positions List Is Null");
    }

    double minLat = pA.getLatitude().degrees;
    double minLon = pA.getLongitude().degrees;
    double maxLat = pA.getLatitude().degrees;
    double maxLon = pA.getLongitude().degrees;

    if (pB.getLatitude().degrees < minLat) {
      minLat = pB.getLatitude().degrees;
    } else if (pB.getLatitude().degrees > maxLat) {
      maxLat = pB.getLatitude().degrees;
    }

    if (pB.getLongitude().degrees < minLon) {
      minLon = pB.getLongitude().degrees;
    } else if (pB.getLongitude().degrees > maxLon) {
      maxLon = pB.getLongitude().degrees;
    }

    return Sector.fromDegrees(minLat, maxLat, minLon, maxLon);
  }
Пример #27
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);
    }
Пример #28
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;
  }
Пример #29
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;
  }
Пример #30
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);
    }
  }