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;
  }
  /**
   * Causes the View attached to the specified WorldWindow to animate to the specified sector. The
   * View starts animating at its current location and stops when the sector fills the window.
   *
   * @param wwd the WorldWindow who's View animates.
   * @param sector the sector to go to.
   * @throws IllegalArgumentException if either the <code>wwd</code> or the <code>sector</code> are
   *     <code>null</code>.
   */
  public static void goTo(WorldWindow wwd, Sector sector) {
    if (wwd == null) {
      String message = Logging.getMessage("nullValue.WorldWindow");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

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

    // Create a bounding box for the specified sector in order to estimate its size in model
    // coordinates.
    Box extent =
        Sector.computeBoundingBox(
            wwd.getModel().getGlobe(), wwd.getSceneController().getVerticalExaggeration(), sector);

    // Estimate the distance between the center position and the eye position that is necessary to
    // cause the sector to
    // fill a viewport with the specified field of view. Note that we change the distance between
    // the center and eye
    // position here, and leave the field of view constant.
    Angle fov = wwd.getView().getFieldOfView();
    double zoom = extent.getRadius() / fov.cosHalfAngle() / fov.tanHalfAngle();

    // Configure OrbitView to look at the center of the sector from our estimated distance. This
    // causes OrbitView to
    // animate to the specified position over several seconds. To affect this change immediately use
    // the following:
    // ((OrbitView) wwd.getView()).setCenterPosition(new Position(sector.getCentroid(), 0d));
    // ((OrbitView) wwd.getView()).setZoom(zoom);
    wwd.getView().goTo(new Position(sector.getCentroid(), 0d), zoom);
  }
  public static void main(String[] args) {
    String testDataLocation = "testData/HighResolutionTerrain/";
    HashMap<String, Sector> sectors = new HashMap<String, Sector>();
    sectors.put(
        testDataLocation + "HRTOutputTest01.txt", Sector.fromDegrees(37.8, 38.3, -120, -119.3));
    sectors.put(
        testDataLocation + "HRTOutputTest02.txt",
        Sector.fromDegrees(32.34767, 32.77991, 70.88239, 71.47658));
    sectors.put(
        testDataLocation + "HRTOutputTest03.txt",
        Sector.fromDegrees(32.37825, 71.21130, 32.50050, 71.37926));

    try {
      if (args.length > 0 && args[0].equals("-generateTestData")) {
        for (Map.Entry<String, Sector> sector : sectors.entrySet()) {
          String filePath = sector.getKey();

          generateReferenceValues(filePath, sector.getValue());
        }
      }

      for (Map.Entry<String, Sector> sector : sectors.entrySet()) {
        String filePath = sector.getKey();

        ArrayList<Position> referencePositions = readReferencePositions(filePath);
        ArrayList<Position> computedPositions = computeElevations(referencePositions);
        testPositions(filePath, referencePositions, computedPositions);
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }
  }
 public static String makeSectorDescription(Sector sector) {
   return String.format(
       "S %7.4f\u00B0 W %7.4f\u00B0 N %7.4f\u00B0 E %7.4f\u00B0",
       sector.getMinLatitude().degrees,
       sector.getMinLongitude().degrees,
       sector.getMaxLatitude().degrees,
       sector.getMaxLongitude().degrees);
 }
  public static MeshCoords createMeshCoords(Sector sector) {
    double aspect = sector.getDeltaLonDegrees() / sector.getDeltaLatDegrees();

    float width = 100.0f;
    float height = (float) (width * aspect);

    return new MeshCoords(0f, 0f, height, width);
  }
 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 static AffineTransform createTransform(Sector source, MeshCoords destination) {
   java.awt.geom.AffineTransform transform = new java.awt.geom.AffineTransform();
   transform.translate(destination.left, destination.bottom);
   transform.scale(
       (destination.right - destination.left) / source.getDeltaLonDegrees(),
       (destination.top - destination.bottom) / source.getDeltaLatDegrees());
   transform.translate(-source.getMinLongitude().degrees, -source.getMinLatitude().degrees);
   return transform;
 }
  protected Angle computeIconRadius(DrawContext dc, double regionPixelSize, Sector drawSector) {
    double minCosLat =
        Math.min(drawSector.getMinLatitude().cos(), drawSector.getMaxLatitude().cos());
    if (minCosLat < 0.001) return Angle.POS180;

    Rectangle2D iconDimension = this.computeDrawDimension(regionPixelSize); // Meter
    double dLat = iconDimension.getHeight() / dc.getGlobe().getRadius();
    double dLon = iconDimension.getWidth() / dc.getGlobe().getRadius() / minCosLat;
    return Angle.fromRadians(Math.sqrt(dLat * dLat + dLon * dLon) / 2);
  }
  @Override
  public void doDefaultAction(final IGlobeApplication application) {
    if (isEnabled()) {
      final Sector sector = getExtent();

      final double altitude = application.calculateAltitudeForZooming(sector);
      application.goTo(
          new Position(sector.getCentroid(), 0), Angle.ZERO, Angle.fromDegrees(75), altitude);
    }
  }
  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.
    };
  }
 private Sector intersects(Sector a, Sector b) {
   if (null != a && null != b) {
     Sector overlap = a.intersection(b);
     if (overlap != null
         && overlap.getDeltaLon().degrees > 0d
         && overlap.getDeltaLat().degrees > 0d) {
       return overlap;
     }
   }
   return null;
 }
  public Sector(Sector sector) {
    if (sector == null) {
      throw new IllegalArgumentException("Sector Is Null");
    }

    this.minLatitude = new Angle(sector.getMinLatitude());
    this.maxLatitude = new Angle(sector.getMaxLatitude());
    this.minLongitude = new Angle(sector.getMinLongitude());
    this.maxLongitude = new Angle(sector.getMaxLongitude());
    this.deltaLat = Angle.fromDegrees(this.maxLatitude.degrees - this.minLatitude.degrees);
    this.deltaLon = Angle.fromDegrees(this.maxLongitude.degrees - this.minLongitude.degrees);
  }
  /**
   * Determines whether this sector intersects any one of the sectors in the specified iterable.
   * This returns true if at least one of the sectors is non-null and intersects this sector.
   *
   * @param sectors the sectors to test for intersection.
   * @return true if at least one of the sectors is non-null and intersects this sector, otherwise
   *     false.
   * @throws java.lang.IllegalArgumentException if the iterable is null.
   */
  public boolean intersectsAny(Iterable<? extends Sector> sectors) {
    if (sectors == null) {
      throw new IllegalArgumentException("SectorListIsNull");
    }

    for (Sector s : sectors) {
      if (s != null && s.intersects(this)) {
        return true;
      }
    }

    return false;
  }
  public boolean isSameSector(Iterable<? extends LatLon> corners) {
    if (corners == null) {
      throw new IllegalArgumentException("Locations List Is Null");
    }

    if (!isSector(corners)) {
      return false;
    }

    Sector s = Sector.boundingSector(corners);

    return s.equals(this);
  }
    public void createRenderables() {
      this.gridElements = new ArrayList<GridElement>();
      double gridStep = this.size / 10;
      Position p1, p2;
      ArrayList<Position> positions = new ArrayList<Position>();

      // South-North lines
      for (int i = 1; i <= 9; i++) {
        double easting = this.SWEasting + gridStep * i;
        positions.clear();
        p1 = computePosition(this.UTMZone, this.hemisphere, easting, SWNorthing);
        p2 = computePosition(this.UTMZone, this.hemisphere, easting, SWNorthing + this.size);
        if (this.isTruncated) {
          computeTruncatedSegment(p1, p2, this.UTMZoneSector, positions);
        } else {
          positions.add(p1);
          positions.add(p2);
        }
        if (positions.size() > 0) {
          p1 = positions.get(0);
          p2 = positions.get(1);
          Object polyline = createLineRenderable(positions, Polyline.GREAT_CIRCLE);
          Sector lineSector = Sector.boundingSector(p1, p2);
          GridElement ge = new GridElement(lineSector, polyline, GridElement.TYPE_LINE_EASTING);
          ge.setValue(easting);
          this.gridElements.add(ge);
        }
      }
      // West-East lines
      for (int i = 1; i <= 9; i++) {
        double northing = this.SWNorthing + gridStep * i;
        positions.clear();
        p1 = computePosition(this.UTMZone, this.hemisphere, SWEasting, northing);
        p2 = computePosition(this.UTMZone, this.hemisphere, SWEasting + this.size, northing);
        if (this.isTruncated) {
          computeTruncatedSegment(p1, p2, this.UTMZoneSector, positions);
        } else {
          positions.add(p1);
          positions.add(p2);
        }
        if (positions.size() > 0) {
          p1 = positions.get(0);
          p2 = positions.get(1);
          Object polyline = createLineRenderable(positions, Polyline.GREAT_CIRCLE);
          Sector lineSector = Sector.boundingSector(p1, p2);
          GridElement ge = new GridElement(lineSector, polyline, GridElement.TYPE_LINE_NORTHING);
          ge.setValue(northing);
          this.gridElements.add(ge);
        }
      }
    }
Exemple #16
0
    private Info[] buildSurfaceShapes() {
      LatLon position = new LatLon(Angle.fromDegrees(38), Angle.fromDegrees(-105));

      ArrayList<LatLon> surfaceLinePositions = new ArrayList<LatLon>();
      //            surfaceLinePositions.add(LatLon.fromDegrees(37.8484, -119.9754));
      //            surfaceLinePositions.add(LatLon.fromDegrees(38.3540, -119.1526));

      //            surfaceLinePositions.add(new LatLon(Angle.fromDegrees(0),
      // Angle.fromDegrees(-150)));
      //            surfaceLinePositions.add(new LatLon(Angle.fromDegrees(60),
      // Angle.fromDegrees(0)));

      surfaceLinePositions.add(position);
      surfaceLinePositions.add(LatLon.fromDegrees(39, -104));
      surfaceLinePositions.add(LatLon.fromDegrees(39, -105));
      surfaceLinePositions.add(position);

      return new Info[] {
        new Info("Circle", new SurfaceCircle(position, 100e3)),
        new Info("Ellipse", new SurfaceEllipse(position, 100e3, 90e3, Angle.ZERO)),
        new Info("Square", new SurfaceSquare(position, 100e3)),
        new Info("Quad", new SurfaceQuad(position, 100e3, 60e3, Angle.ZERO)),
        new Info("Sector", new SurfaceSector(Sector.fromDegrees(38, 40, -105, -103))),
        new Info("Polygon", new SurfacePolygon(surfaceLinePositions)),
      };
    }
    /**
     * Loads the image at imageuri into the mapMapPanel
     *
     * @param imageuri URI to .jpg file
     * @return If loading was successful
     */
    private boolean loadNewImage(String imageuri) {
      if (mapSurfaceImage != null) {
        mapRenderLayer.removeAllRenderables();
      }

      try {
        mapBufferedImage = ImageIO.read(new URL(imageuri));
      } catch (IOException e) {
        return false;
      }

      double max =
          (mapBufferedImage.getHeight() > mapBufferedImage.getWidth())
              ? mapBufferedImage.getHeight()
              : mapBufferedImage.getWidth();
      mapImageGeoHeight = BASE_MAX_IMAGE_SIZE * mapBufferedImage.getWidth() / max;
      mapImageGeoWidth = BASE_MAX_IMAGE_SIZE * mapBufferedImage.getHeight() / max;

      mapSurfaceImage =
          new SurfaceImage(
              mapBufferedImage, Sector.fromDegrees(0, mapImageGeoWidth, 0, mapImageGeoHeight));
      Polyline boundary = new Polyline(mapSurfaceImage.getCorners(), 0);
      boundary.setFollowTerrain(true);
      boundary.setClosed(true);
      boundary.setPathType(Polyline.RHUMB_LINE);
      boundary.setColor(new Color(0, 255, 0));

      mapRenderLayer.addRenderable(mapSurfaceImage);
      mapRenderLayer.addRenderable(boundary);
      mapMapPanel.wwd.redraw();
      return true;
    }
  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);
  }
  private static MeshCoords transformSector(AffineTransform transform, Sector sector) {
    java.awt.geom.Point2D p = new java.awt.geom.Point2D.Double();
    java.awt.geom.Point2D ll = new java.awt.geom.Point2D.Double();
    java.awt.geom.Point2D ur = new java.awt.geom.Point2D.Double();

    p.setLocation(sector.getMinLongitude().degrees, sector.getMinLatitude().degrees);
    transform.transform(p, ll);

    p.setLocation(sector.getMaxLongitude().degrees, sector.getMaxLatitude().degrees);
    transform.transform(p, ur);

    return new MeshCoords(
        (float) ur.getY(), // Top
        (float) ll.getX(), // Left
        (float) ll.getY(), // Bottom
        (float) ur.getX()); // Right
  }
  protected static boolean isSectorVisible(
      DrawContext dc, Sector sector, double minDistanceSquared, double maxDistanceSquared) {

    View view = dc.getView();
    Position eyePos = view.getEyePosition();
    if (eyePos == null) return false;

    Angle lat = clampAngle(eyePos.getLatitude(), sector.getMinLatitude(), sector.getMaxLatitude());
    Angle lon =
        clampAngle(eyePos.getLongitude(), sector.getMinLongitude(), sector.getMaxLongitude());
    Vec4 p = dc.getGlobe().computePointFromPosition(lat, lon, 0d);
    double distSquared = dc.getView().getEyePoint().distanceToSquared3(p);
    //noinspection RedundantIfStatement
    if (minDistanceSquared > distSquared || maxDistanceSquared < distSquared) return false;

    return true;
  }
 protected void createRectangularArray() {
   this.arraySector = Sector.fromDegrees(20, 30, -110, -100);
   this.arrayWidth = 60;
   this.arrayHeight = 60;
   this.arrayValues =
       ExampleUtil.readCommaDelimitedNumbers(
           "gov/nasa/worldwindx/examples/data/GridValues01_60x60.csv");
 }
Exemple #22
0
  @Override
  protected Sector calculateSector() {
    Sector sector = null;

    for (GMLPoint point : getPoints()) sector = Sector.union(sector, point.getSector());

    return sector;
  }
  protected int determineAdjustmentSide(Movable dragObject, double factor) {
    if (dragObject instanceof SurfaceSector) {
      SurfaceSector quad = (SurfaceSector) dragObject;
      Sector s = quad.getSector(); // TODO: go over all sectors
      Position p = this.getWwd().getCurrentPosition();

      if (p == null) {
        return NONE;
      }

      double dN = abs(s.getMaxLatitude().subtract(p.getLatitude()).degrees);
      double dS = abs(s.getMinLatitude().subtract(p.getLatitude()).degrees);
      double dW = abs(s.getMinLongitude().subtract(p.getLongitude()).degrees);
      double dE = abs(s.getMaxLongitude().subtract(p.getLongitude()).degrees);

      double sLat = factor * s.getDeltaLatDegrees();
      double sLon = factor * s.getDeltaLonDegrees();

      if (dN < sLat && dW < sLon) return NORTHWEST;
      if (dN < sLat && dE < sLon) return NORTHEAST;
      if (dS < sLat && dW < sLon) return SOUTHWEST;
      if (dS < sLat && dE < sLon) return SOUTHEAST;
      if (dN < sLat) return NORTH;
      if (dS < sLat) return SOUTH;
      if (dW < sLon) return WEST;
      if (dE < sLon) return EAST;
    }

    return NONE;
  }
  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;
  }
  private static MeshTile[] createTiles(LevelSet levelSet, int levelNumber, MeshCoords coords) {
    Sector sector = levelSet.getSector();
    Level level = levelSet.getLevel(levelNumber);
    Angle dLat = level.getTileDelta().getLatitude();
    Angle dLon = level.getTileDelta().getLongitude();
    Angle latOrigin = levelSet.getTileOrigin().getLatitude();
    Angle lonOrigin = levelSet.getTileOrigin().getLongitude();

    // Determine the row and column offset from the common World Wind global tiling origin.
    int firstRow = Tile.computeRow(dLat, sector.getMinLatitude(), latOrigin);
    int firstCol = Tile.computeColumn(dLon, sector.getMinLongitude(), lonOrigin);
    int lastRow = Tile.computeRow(dLat, sector.getMaxLatitude(), latOrigin);
    int lastCol = Tile.computeColumn(dLon, sector.getMaxLongitude(), lonOrigin);

    int numLatTiles = lastRow - firstRow + 1;
    int numLonTiles = lastCol - firstCol + 1;

    AffineTransform sectorTransform = createTransform(sector, coords);

    MeshTile[] tiles = new MeshTile[numLatTiles * numLonTiles];
    int index = 0;

    Angle p1 = Tile.computeRowLatitude(firstRow, dLat, latOrigin);

    for (int row = firstRow; row <= lastRow; row++) {
      Angle p2 = p1.add(dLat);

      Angle t1 = Tile.computeColumnLongitude(firstCol, dLon, lonOrigin);

      for (int col = firstCol; col <= lastCol; col++) {
        Angle t2 = t1.add(dLon);

        Sector tileSector = new Sector(p1, p2, t1, t2);
        MeshCoords tileCoords = transformSector(sectorTransform, tileSector);
        tiles[index++] = new MeshTile(tileSector, level, row, col, tileCoords);

        t1 = t2;
      }
      p1 = p2;
    }

    return tiles;
  }
 // manages change of attributes for highlighting, annotation bubble toggle, event firing
 private void internalHighlight(SurfaceShape shape, boolean noDeselect) {
   if (!highlightingEnabled) {
     return;
   }
   String shpId = (String) shape.getValue(AVKey.HOVER_TEXT);
   // if annotation visible and same shape
   if (shape.equals(prevPopupShape) && shape.isHighlighted()) {
     if (!noDeselect) {
       // hide annotation and de-highlight
       popupAnnotation.getAttributes().setVisible(false);
       shape.setHighlighted(false);
       // forget previous highlighted shape and fire deselection event
       prevPopupShape = null;
       firePropertyChange(new PropertyChangeEvent(this, PROPERTY_SELECTION, shpId, null));
     }
   } else {
     if (showAnnotation) {
       // find shape centroid
       final Sector boundingSector =
           Sector.boundingSector(shape.getLocations(wwd.getModel().getGlobe()));
       Position centroid = new Position(boundingSector.getCentroid(), 0d);
       // prepare and show annotation
       popupAnnotation.setText(shpId);
       popupAnnotation.setPosition(centroid);
       popupAnnotation.getAttributes().setVisible(true);
     }
     // highlight shape
     shape.setHighlighted(true);
     if (prevPopupShape != null) {
       // de-highlight previous shape and fire deselection event
       prevPopupShape.setHighlighted(false);
       firePropertyChange(
           new PropertyChangeEvent(
               this, PROPERTY_SELECTION, prevPopupShape.getValue(AVKey.HOVER_TEXT), shpId));
     } else {
       // fire event only
       firePropertyChange(new PropertyChangeEvent(this, PROPERTY_SELECTION, null, shpId));
     }
     // remember shape
     prevPopupShape = shape;
   }
 }
  public static Sector union(Sector sectorA, Sector sectorB) {
    if (sectorA == null || sectorB == null) {
      if (sectorA == sectorB) {
        return sectorA;
      }

      return sectorB == null ? sectorA : sectorB;
    }

    return sectorA.union(sectorB);
  }
  /**
   * Returns the intersection of all sectors in the specified iterable. This returns a non-null
   * sector if the iterable contains at least one non-null entry and all non-null entries intersect.
   * The returned sector represents the geographic region in which all sectors intersect. This
   * returns null if at least one of the sectors does not intersect the others.
   *
   * @param sectors the sectors to intersect.
   * @return the intersection of all sectors in the specified iterable, or null if at least one of
   *     the sectors does not intersect the others.
   * @throws java.lang.IllegalArgumentException if the iterable is null.
   */
  public static Sector intersection(Iterable<? extends Sector> sectors) {
    if (sectors == null) {
      throw new IllegalArgumentException("SectorListIsNull");
    }

    Sector result = null;

    for (Sector s : sectors) {
      if (s == null) {
        continue; // ignore null sectors
      }
      if (result == null) {
        result = s; // start with the first non-null sector
      } else if ((result = result.intersection(s)) == null) {
        break; // at least one of the sectors does not intersect the others
      }
    }

    return result;
  }
 private void recalculateVertices(Globe globe, double verticalExaggeration) {
   synchronized (elevationLock) {
     if (elevations != null) {
       elevations.rewind();
       vertices.rewind();
       Angle minlon = sector.getMinLongitude();
       Angle minlat = sector.getMaxLatitude();
       double lonstep = sector.getDeltaLonDegrees() / (width - 1);
       double latstep = sector.getDeltaLatDegrees() / (height - 1);
       for (int y = 0; y < height; y++) {
         Angle lat = minlat.subtractDegrees(latstep * y);
         for (int x = 0; x < width; x++) {
           Angle lon = minlon.addDegrees(lonstep * x);
           double elev = elevations.get() * scale * verticalExaggeration;
           Vec4 point = globe.computePointFromPosition(lat, lon, elev);
           vertices.put(point.x).put(point.y).put(point.z);
         }
       }
     }
   }
 }
    protected void performIntersectionTests(final Position curPos) throws InterruptedException {
      // Clear the results lists when the user selects a new location.
      this.firstIntersectionPositions.clear();
      this.sightLines.clear();

      // Raise the selected location and the grid points a little above ground just to show we can.
      final double height = 5; // meters

      // Form the grid.
      double gridRadius = GRID_RADIUS.degrees;
      Sector sector =
          Sector.fromDegrees(
              curPos.getLatitude().degrees - gridRadius, curPos.getLatitude().degrees + gridRadius,
              curPos.getLongitude().degrees - gridRadius,
                  curPos.getLongitude().degrees + gridRadius);

      this.grid = buildGrid(sector, height, GRID_DIMENSION, GRID_DIMENSION);
      this.numGridPoints = grid.size();

      // Compute the position of the selected location (incorporate its height).
      this.referencePosition = new Position(curPos.getLatitude(), curPos.getLongitude(), height);
      this.referencePoint =
          terrain.getSurfacePoint(curPos.getLatitude(), curPos.getLongitude(), height);

      //            // Pre-caching is unnecessary and is useful only when it occurs before the
      // intersection
      //            // calculations. It will incur extra overhead otherwise. The normal intersection
      // calculations
      //            // cause the same caching, making subsequent calculations on the same area
      // faster.
      //            this.preCache(grid, this.referencePosition);

      // On the EDT, show the grid.
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              progressBar.setValue(0);
              progressBar.setString(null);
              clearLayers();
              showGrid(grid, referencePosition);
              getWwd().redraw();
            }
          });

      // Perform the intersection calculations.
      this.startTime = System.currentTimeMillis();
      for (Position gridPos : this.grid) // for each grid point.
      {
        //noinspection ConstantConditions
        if (NUM_THREADS > 0) this.threadPool.execute(new Intersector(gridPos));
        else performIntersection(gridPos);
      }
    }