Пример #1
0
  protected void setDepthFunc(DrawContext dc, OrderedIcon uIcon, Vec4 screenPoint) {
    GL gl = dc.getGL();

    if (uIcon.icon.isAlwaysOnTop()) {
      gl.glDepthFunc(GL.GL_ALWAYS);
      return;
    }

    Position eyePos = dc.getView().getEyePosition();
    if (eyePos == null) {
      gl.glDepthFunc(GL.GL_ALWAYS);
      return;
    }

    double altitude = eyePos.getElevation();
    if (altitude < (dc.getGlobe().getMaxElevation() * dc.getVerticalExaggeration())) {
      double depth = screenPoint.z - (8d * 0.00048875809d);
      depth = depth < 0d ? 0d : (depth > 1d ? 1d : depth);
      gl.glDepthFunc(GL.GL_LESS);
      gl.glDepthRange(depth, depth);
    } else if (uIcon.eyeDistance > uIcon.horizonDistance) {
      gl.glDepthFunc(GL.GL_EQUAL);
      gl.glDepthRange(1d, 1d);
    } else {
      gl.glDepthFunc(GL.GL_ALWAYS);
    }
  }
  /**
   * Select the visible grid elements
   *
   * @param dc the current <code>DrawContext</code>.
   */
  protected void selectRenderables(DrawContext dc) {
    if (dc == null) {
      String message = Logging.getMessage("nullValue.DrawContextIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    Sector vs = dc.getVisibleSector();
    OrbitView view = (OrbitView) dc.getView();
    // Compute labels offset from view center
    Position centerPos = view.getCenterPosition();
    Double pixelSizeDegrees =
        Angle.fromRadians(
                view.computePixelSizeAtDistance(view.getZoom())
                    / dc.getGlobe().getEquatorialRadius())
            .degrees;
    Double labelOffsetDegrees = pixelSizeDegrees * view.getViewport().getWidth() / 4;
    Position labelPos =
        Position.fromDegrees(
            centerPos.getLatitude().degrees - labelOffsetDegrees,
            centerPos.getLongitude().degrees - labelOffsetDegrees,
            0);
    Double labelLatDegrees = labelPos.getLatitude().normalizedLatitude().degrees;
    labelLatDegrees = Math.min(Math.max(labelLatDegrees, -76), 78);
    labelPos =
        new Position(
            Angle.fromDegrees(labelLatDegrees), labelPos.getLongitude().normalizedLongitude(), 0);

    if (vs != null) {
      for (GridElement ge : this.gridElements) {
        if (ge.isInView(dc)) {
          if (ge.renderable instanceof GeographicText) {
            GeographicText gt = (GeographicText) ge.renderable;
            if (labelPos.getLatitude().degrees < 72
                || "*32*34*36*".indexOf("*" + gt.getText() + "*") == -1) {
              // Adjust label position according to eye position
              Position pos = gt.getPosition();
              if (ge.type.equals(GridElement.TYPE_LATITUDE_LABEL))
                pos =
                    Position.fromDegrees(
                        pos.getLatitude().degrees,
                        labelPos.getLongitude().degrees,
                        pos.getElevation());
              else if (ge.type.equals(GridElement.TYPE_LONGITUDE_LABEL))
                pos =
                    Position.fromDegrees(
                        labelPos.getLatitude().degrees,
                        pos.getLongitude().degrees,
                        pos.getElevation());

              gt.setPosition(pos);
            }
          }

          this.graticuleSupport.addRenderable(ge.renderable, GRATICULE_UTM);
        }
      }
      // System.out.println("Total elements: " + count + " visible sector: " + vs);
    }
  }
    @SuppressWarnings({"RedundantIfStatement"})
    public boolean isInView(DrawContext dc) {
      if (!viewFrustum.intersects(this.getExtent(dc.getGlobe(), dc.getVerticalExaggeration())))
        return false;

      // Check apparent size
      if (getSizeInPixels(dc) <= MIN_CELL_SIZE_PIXELS) return false;

      return true;
    }
Пример #4
0
  /**
   * Compute the lat/lon position of the view center
   *
   * @param dc the current DrawContext
   * @param view the current View
   * @return the ground position of the view center or null
   */
  protected Position computeGroundPosition(DrawContext dc, View view) {
    if (view == null) return null;

    Position groundPos =
        view.computePositionFromScreenPoint(
            view.getViewport().getWidth() / 2, view.getViewport().getHeight() / 2);
    if (groundPos == null) return null;

    double elevation =
        dc.getGlobe().getElevation(groundPos.getLatitude(), groundPos.getLongitude());
    return new Position(
        groundPos.getLatitude(),
        groundPos.getLongitude(),
        elevation * dc.getVerticalExaggeration());
  }
 public void computeZone(DrawContext dc) {
   try {
     Position centerPos = ((OrbitView) dc.getView()).getCenterPosition();
     if (centerPos != null) {
       if (centerPos.latitude.degrees <= UTM_MAX_LATITUDE
           && centerPos.latitude.degrees >= UTM_MIN_LATITUDE) {
         UTMCoord UTM =
             UTMCoord.fromLatLon(
                 centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe());
         this.zone = UTM.getZone();
       } else this.zone = 0;
     }
   } catch (Exception ex) {
     this.zone = 0;
   }
 }
Пример #6
0
 /**
  * Compute the view range footprint on the globe.
  *
  * @param dc the current <code>DrawContext</code>
  * @param steps the number of steps.
  * @return an array list of <code>LatLon</code> forming a closed shape.
  */
 protected ArrayList<LatLon> computeViewFootPrint(DrawContext dc, int steps) {
   ArrayList<LatLon> positions = new ArrayList<LatLon>();
   Position eyePos = dc.getView().getEyePosition();
   Angle distance =
       Angle.fromRadians(
           Math.asin(
               dc.getView().getFarClipDistance()
                   / (dc.getGlobe().getRadius() + eyePos.getElevation())));
   if (distance.degrees > 10) {
     double headStep = 360d / steps;
     Angle heading = Angle.ZERO;
     for (int i = 0; i <= steps; i++) {
       LatLon p = LatLon.greatCircleEndPosition(eyePos, heading, distance);
       positions.add(p);
       heading = heading.addDegrees(headStep);
     }
     return positions;
   } else return null;
 }
    public void selectRenderables(DrawContext dc) {
      try {
        OrbitView view = (OrbitView) dc.getView();
        // Compute easting and northing label offsets
        Double pixelSize = view.computePixelSizeAtDistance(view.getZoom());
        Double eastingOffset = view.getViewport().width * pixelSize * offsetFactorX / 2;
        Double northingOffset = view.getViewport().height * pixelSize * offsetFactorY / 2;
        // Derive labels center pos from the view center
        Position centerPos = view.getCenterPosition();
        double labelEasting;
        double labelNorthing;
        String labelHemisphere;
        if (this.zone > 0) {
          UTMCoord UTM =
              UTMCoord.fromLatLon(centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe());
          labelEasting = UTM.getEasting() + eastingOffset;
          labelNorthing = UTM.getNorthing() + northingOffset;
          labelHemisphere = UTM.getHemisphere();
          if (labelNorthing < 0) {
            labelNorthing = 10e6 + labelNorthing;
            labelHemisphere = AVKey.SOUTH;
          }
        } else {
          UPSCoord UPS =
              UPSCoord.fromLatLon(centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe());
          labelEasting = UPS.getEasting() + eastingOffset;
          labelNorthing = UPS.getNorthing() + northingOffset;
          labelHemisphere = UPS.getHemisphere();
        }

        Position labelPos;
        for (int i = 0; i < this.extremes.length; i++) {
          UTMExtremes levelExtremes = this.extremes[i];
          double gridStep = Math.pow(10, i);
          double gridStepTimesTen = gridStep * 10;
          String graticuleType = getTypeFor((int) gridStep);
          if (levelExtremes.minX <= levelExtremes.maxX) {
            // Process easting scale labels for this level
            for (double easting = levelExtremes.minX;
                easting <= levelExtremes.maxX;
                easting += gridStep) {
              // Skip multiples of ten grid steps except for last (higher) level
              if (i == this.extremes.length - 1 || easting % gridStepTimesTen != 0) {
                try {
                  labelPos = computePosition(this.zone, labelHemisphere, easting, labelNorthing);
                  if (labelPos == null) continue;
                  Angle lat = labelPos.getLatitude();
                  Angle lon = labelPos.getLongitude();
                  Vec4 surfacePoint = getSurfacePoint(dc, lat, lon);
                  if (viewFrustum.contains(surfacePoint) && isPointInRange(dc, surfacePoint)) {
                    String text = String.valueOf((int) (easting % this.scaleModulo));
                    GeographicText gt = new UserFacingText(text, new Position(lat, lon, 0));
                    gt.setPriority(gridStepTimesTen);
                    addRenderable(gt, graticuleType);
                  }
                } catch (IllegalArgumentException ignore) {
                }
              }
            }
          }
          if (!(levelExtremes.maxYHemisphere.equals(AVKey.SOUTH) && levelExtremes.maxY == 0)) {
            // Process northing scale labels for this level
            String currentHemisphere = levelExtremes.minYHemisphere;
            for (double northing = levelExtremes.minY;
                (northing <= levelExtremes.maxY)
                    || !currentHemisphere.equals(levelExtremes.maxYHemisphere);
                northing += gridStep) {
              // Skip multiples of ten grid steps except for last (higher) level
              if (i == this.extremes.length - 1 || northing % gridStepTimesTen != 0) {
                try {
                  labelPos = computePosition(this.zone, currentHemisphere, labelEasting, northing);
                  if (labelPos == null) continue;
                  Angle lat = labelPos.getLatitude();
                  Angle lon = labelPos.getLongitude();
                  Vec4 surfacePoint = getSurfacePoint(dc, lat, lon);
                  if (viewFrustum.contains(surfacePoint) && isPointInRange(dc, surfacePoint)) {
                    String text = String.valueOf((int) (northing % this.scaleModulo));
                    GeographicText gt = new UserFacingText(text, new Position(lat, lon, 0));
                    gt.setPriority(gridStepTimesTen);
                    addRenderable(gt, graticuleType);
                  }
                } catch (IllegalArgumentException ignore) {
                }

                if (!currentHemisphere.equals(levelExtremes.maxYHemisphere)
                    && northing >= 10e6 - gridStep) {
                  // Switch hemisphere
                  currentHemisphere = levelExtremes.maxYHemisphere;
                  northing = -gridStep;
                }
              }
            }
          } // end northing
        } // for levels
      } catch (IllegalArgumentException ignore) {
      }
    }
Пример #8
0
  protected void drawMany(DrawContext dc, Iterable<? extends WWIcon> icons, Layer layer) {
    if (dc == null) {
      String msg = Logging.getMessage("nullValue.DrawContextIsNull");
      Logging.logger().severe(msg);
      throw new IllegalArgumentException(msg);
    }

    if (dc.getVisibleSector() == null) return;

    SectorGeometryList geos = dc.getSurfaceGeometry();
    //noinspection RedundantIfStatement
    if (geos == null) return;

    if (icons == null) {
      String msg = Logging.getMessage("nullValue.IconIterator");
      Logging.logger().severe(msg);
      throw new IllegalArgumentException(msg);
    }

    Iterator<? extends WWIcon> iterator = icons.iterator();

    if (!iterator.hasNext()) return;

    double horizon = dc.getView().getHorizonDistance();

    while (iterator.hasNext()) {
      WWIcon icon = iterator.next();
      if (!isIconValid(icon, true)) {
        // Record feedback data for this WWIcon if feedback is enabled.
        if (icon != null) this.recordFeedback(dc, icon, null, null);

        continue;
      }

      if (!icon.isVisible()) {
        // Record feedback data for this WWIcon if feedback is enabled.
        this.recordFeedback(dc, icon, null, null);

        continue;
      }

      // Determine Cartesian position from the surface geometry if the icon is near the surface,
      // otherwise draw it from the globe.
      Position pos = icon.getPosition();
      Vec4 iconPoint = null;
      if (pos.getElevation() < dc.getGlobe().getMaxElevation()
          && !this.isAlwaysUseAbsoluteElevation()) {
        iconPoint = dc.getSurfaceGeometry().getSurfacePoint(icon.getPosition());
      }

      if (iconPoint == null) {
        Angle lat = pos.getLatitude();
        Angle lon = pos.getLongitude();
        double elevation = pos.getElevation();
        if (!this.isAlwaysUseAbsoluteElevation()) elevation += dc.getGlobe().getElevation(lat, lon);
        iconPoint = dc.getGlobe().computePointFromPosition(lat, lon, elevation);
      }

      double eyeDistance =
          icon.isAlwaysOnTop() ? 0 : dc.getView().getEyePoint().distanceTo3(iconPoint);

      // X-PATCH Marjan
      // extracted skip conditions into an overrideable method
      if (!meetsRenderCriteria(dc, icon, iconPoint, eyeDistance)) {
        this.recordFeedback(dc, icon, iconPoint, null);
        continue;
      }
      // X-END

      // The icons aren't drawn here, but added to the ordered queue to be drawn back-to-front.
      dc.addOrderedRenderable(new OrderedIcon(icon, iconPoint, layer, eyeDistance, horizon));

      if (icon.isShowToolTip()) this.addToolTip(dc, icon, iconPoint);
    }
  }
Пример #9
0
  // Rendering
  public void draw(DrawContext dc) {
    GL gl = dc.getGL();

    boolean attribsPushed = false;
    boolean modelviewPushed = false;
    boolean projectionPushed = false;

    try {
      gl.glPushAttrib(
          GL.GL_DEPTH_BUFFER_BIT
              | GL.GL_COLOR_BUFFER_BIT
              | GL.GL_ENABLE_BIT
              | GL.GL_TEXTURE_BIT
              | GL.GL_TRANSFORM_BIT
              | GL.GL_VIEWPORT_BIT
              | GL.GL_CURRENT_BIT);
      attribsPushed = true;

      gl.glDisable(GL.GL_TEXTURE_2D); // no textures

      gl.glEnable(GL.GL_BLEND);
      gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
      gl.glDisable(GL.GL_DEPTH_TEST);

      double width = this.size.width;
      double height = this.size.height;

      // Load a parallel projection with xy dimensions (viewportWidth, viewportHeight)
      // into the GL projection matrix.
      java.awt.Rectangle viewport = dc.getView().getViewport();
      gl.glMatrixMode(javax.media.opengl.GL.GL_PROJECTION);
      gl.glPushMatrix();
      projectionPushed = true;
      gl.glLoadIdentity();
      double maxwh = width > height ? width : height;
      gl.glOrtho(0d, viewport.width, 0d, viewport.height, -0.6 * maxwh, 0.6 * maxwh);

      gl.glMatrixMode(GL.GL_MODELVIEW);
      gl.glPushMatrix();
      modelviewPushed = true;
      gl.glLoadIdentity();

      // Scale to a width x height space
      // located at the proper position on screen
      double scale = this.computeScale(viewport);
      Vec4 locationSW = this.computeLocation(viewport, scale);
      gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z());
      gl.glScaled(scale, scale, 1);

      // Compute scale size in real world
      Position referencePosition = dc.getViewportCenterPosition();
      if (referencePosition != null) {
        Vec4 groundTarget = dc.getGlobe().computePointFromPosition(referencePosition);
        Double distance = dc.getView().getEyePoint().distanceTo3(groundTarget);
        this.pixelSize = dc.getView().computePixelSizeAtDistance(distance);
        Double scaleSize = this.pixelSize * width * scale; // meter
        String unitLabel = "m";
        if (this.unit.equals(UNIT_METRIC)) {
          if (scaleSize > 10000) {
            scaleSize /= 1000;
            unitLabel = "Km";
          }
        } else if (this.unit.equals(UNIT_IMPERIAL)) {
          scaleSize *= 3.280839895; // feet
          unitLabel = "ft";
          if (scaleSize > 5280) {
            scaleSize /= 5280;
            unitLabel = "mile(s)";
          }
        }

        // Rounded division size
        int pot = (int) Math.floor(Math.log10(scaleSize));
        if (!Double.isNaN(pot)) {
          int digit = Integer.parseInt(String.format("%.0f", scaleSize).substring(0, 1));
          double divSize = digit * Math.pow(10, pot);
          if (digit >= 5) divSize = 5 * Math.pow(10, pot);
          else if (digit >= 2) divSize = 2 * Math.pow(10, pot);
          double divWidth = width * divSize / scaleSize;

          // Draw scale
          if (!dc.isPickingMode()) {
            // Set color using current layer opacity
            Color backColor = this.getBackgroundColor(this.color);
            float[] colorRGB = backColor.getRGBColorComponents(null);
            gl.glColor4d(
                colorRGB[0],
                colorRGB[1],
                colorRGB[2],
                (double) backColor.getAlpha() / 255d * this.getOpacity());
            gl.glTranslated((width - divWidth) / 2, 0d, 0d);
            this.drawScale(dc, divWidth, height);

            colorRGB = this.color.getRGBColorComponents(null);
            gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity());
            gl.glTranslated(-1d / scale, 1d / scale, 0d);
            this.drawScale(dc, divWidth, height);

            // Draw label
            String label = String.format("%.0f ", divSize) + unitLabel;
            gl.glLoadIdentity();
            gl.glDisable(GL.GL_CULL_FACE);
            drawLabel(
                dc,
                label,
                locationSW.add3(
                    new Vec4(divWidth * scale / 2 + (width - divWidth) / 2, height * scale, 0)));
          } else {
            // Picking
            this.pickSupport.clearPickList();
            this.pickSupport.beginPicking(dc);
            // Draw unique color across the map
            Color color = dc.getUniquePickColor();
            int colorCode = color.getRGB();
            // Add our object(s) to the pickable list
            this.pickSupport.addPickableObject(colorCode, this, referencePosition, false);
            gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());
            gl.glTranslated((width - divWidth) / 2, 0d, 0d);
            this.drawRectangle(dc, divWidth, height);
            // Done picking
            this.pickSupport.endPicking(dc);
            this.pickSupport.resolvePick(dc, dc.getPickPoint(), this);
          }
        }
      }
    } finally {
      if (projectionPushed) {
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPopMatrix();
      }
      if (modelviewPushed) {
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPopMatrix();
      }
      if (attribsPushed) gl.glPopAttrib();
    }
  }