analysispanel.java
来自「world wind java sdk 源码」· Java 代码 · 共 718 行 · 第 1/2 页
JAVA
718 行
private int getCurrentPositionNumber() { return this.trackViewPanel.getCurrentPositionNumber(); } private boolean isLastPosition(int n) { return n >= this.currentTrack.size() - 1; } public Position getCurrentSegmentStartPosition() { int n = this.getCurrentPositionNumber(); return getSegmentStartPosition(n); } public Position getSegmentStartPosition(int startPositionNumber) { if (this.currentTrack == null || this.currentTrack.size() == 0) return null; Position pos; if (isLastPosition(startPositionNumber)) pos = this.currentTrack.get(this.currentTrack.size() - 1); else pos = this.currentTrack.get(startPositionNumber); return new Position(pos.getLatitude(), pos.getLongitude(), pos.getElevation() + this.currentTrack.getOffset()); } public Position getCurrentSegmentEndPosition() { int n = this.getCurrentPositionNumber(); return getSegmentEndPosition(n); } public Position getSegmentEndPosition(int startPositionNumber) { if (this.currentTrack == null || this.currentTrack.size() == 0) return null; Position pos; if (isLastPosition(startPositionNumber + 1)) pos = this.currentTrack.get(this.currentTrack.size() - 1); else pos = this.currentTrack.get(startPositionNumber + 1); return new Position(pos.getLatitude(), pos.getLongitude(), pos.getElevation() + this.currentTrack.getOffset()); } public double getSegmentLength(int startPositionNumber) { Vec4 start = wwd.getModel().getGlobe().computePointFromPosition(getSegmentStartPosition(startPositionNumber)); Vec4 end = wwd.getModel().getGlobe().computePointFromPosition(getSegmentEndPosition(startPositionNumber)); return start.distanceTo3(end); } public Position getPositionAlongSegment() { double t = this.trackViewPanel.getPositionDelta(); return this.getPositionAlongSegment(t); } private Position getPositionAlongSegment(double t) { Position pa = this.getCurrentSegmentStartPosition(); if (pa == null) return null; Position pb = this.getCurrentSegmentEndPosition(); if (pb == null) return pa; return interpolateTrackPosition(t, pa, pb); } public Angle getHeading() { return getHeading(this.getCurrentPositionNumber()); } public Angle getHeading(int cpn) { Position pA; Position pB; if ((cpn < 1) && (this.isLastPosition(cpn))) //handle first position return Angle.ZERO; else if (!this.isLastPosition(cpn)) { pA = this.currentTrack.get(cpn); pB = this.currentTrack.get(cpn + 1); } else { pA = this.currentTrack.get(cpn - 1); pB = this.currentTrack.get(cpn); } return LatLon.greatCircleAzimuth(pA, pB); } // Interpolate heading at track jonctions private Angle getSmoothedHeading(double dt) { int cpn = this.getCurrentPositionNumber(); Angle heading1, heading2; double t1, t; // Current segment heading1 = getHeading(cpn); t1 = this.trackViewPanel.getPositionDelta(); if (t1 <= dt && cpn > 0) { heading2 = getHeading(cpn - 1); t = (1 - t1 / dt) * .5; } else if (t1 >= (1 - dt) && !this.isLastPosition(cpn)) { heading2 = getHeading(cpn + 1); t = (1 - (1 - t1) / dt) * .5; } else return heading1; return Angle.mix(t, heading1, heading2); } @SuppressWarnings({"UnusedDeclaration"}) private Position getGroundPositionAlongSegment() { if (this.wwd == null) return null; Position pos = getPositionAlongSegment(); if (pos == null) return null; double elevation = this.wwd.getModel().getGlobe().getElevation(pos.getLatitude(), pos.getLongitude()); return new Position(pos, elevation); } // TODO: weighted average should be over actual polyline track points private Position getSmoothedGroundPositionAlongSegment() { if (this.currentTrack == null || this.currentTrack.size() == 0) return null; Position start = getCurrentSegmentStartPosition(); Position end = getCurrentSegmentEndPosition(); if (start == null || end == null) return null; Globe globe = this.wwd.getModel().getGlobe(); if (globe == null) return null; int n = this.getCurrentPositionNumber(); double t = this.trackViewPanel.getPositionDelta(); // Limit t to 0 if this is the last position. if (isLastPosition(n)) t = 0; double tstep = 1 / 100.0; int numWeights = 15; // TODO: extract to configurable property double elev = 0; double sumOfWeights = 0; // Compute the moving weighted average of track positions on both sides of the current track position. for (int i = 0; i < numWeights; i++) { double tt; Position pos; // Previous ground positions. tt = t - i * tstep; pos = null; if (tt >= 0) // Position is in the current track segment. pos = interpolateTrackPosition(tt, start, end); else if (tt < 0 && n > 0) // Position is in the previous track segment. pos = interpolateTrackPosition(tt + 1, this.currentTrack.get(n-1), start); if (pos != null) { double e = globe.getElevation(pos.getLatitude(), pos.getLongitude()); elev += (numWeights - i) * e; sumOfWeights += (numWeights - i); } // Next ground positions. // We don't want to count the first position twice. if (i != 0) { tt = t + i * tstep; pos = null; if (tt <= 1) // Position is in the current track segment. pos = interpolateTrackPosition(tt, start, end); else if (tt > 1 && !isLastPosition(n + 1)) // Position is in the next track segment. pos = interpolateTrackPosition(tt - 1, end, this.currentTrack.get(n+2)); if (pos != null) { double e = globe.getElevation(pos.getLatitude(), pos.getLongitude()); elev += (numWeights - i) * e; sumOfWeights += (numWeights - i); } } } elev /= sumOfWeights; Position actualPos = interpolateTrackPosition(t, start, end); return new Position(actualPos, elev); } /** * SAR tracks points are connected with lines of constant heading (rhumb lines). In order to compute * an interpolated position between two track points, we must use rhumb computations, rather * than linearly interpolate the position. * @param t a decimal number between 0 and 1 * @param begin first position * @param end second position * @return Position in between begin and end */ private Position interpolateTrackPosition(double t, Position begin, Position end) { if (begin == null || end == null) return null; // The track is drawn as a rhumb line. // Therefore we must use rhumb computations to interpolate lat/lon. Angle az = LatLon.rhumbAzimuth(begin, end); Angle dist = LatLon.rhumbDistance(begin, end); dist = dist.multiply(t); LatLon ll = LatLon.rhumbEndPosition(begin, az, dist); // Elevation is independent of track line type (i.e. rhumb, great-circle, linear), // so we interpolate elevation normally. double e = (1d - t) * begin.getElevation() + t * end.getElevation(); return new Position(ll, e); }// /**// * Compute crosshair location in viewport for 'follow' - 'fly-it' mode.// * <p>// * It computes the intersection of the air track with the near clipping plane// * and determines the corresponding crosshair position in the viewport.</p>// * <p>// * This assumes the view is headed in the same direction as the air track,// * and the eye is set to look at the aircraft from a distance and angle.</p>// *// * @param view the current <code>View</code>// * @param a view pitch angle relative to the air track (0 degree = horizontal)// * @param distance eye distance from the aircraft// * @return the crosshair center position in the viewport.// */// private Vec4 computeCrosshairPosition(View view, Angle a, double distance)// {// double hfovH = view.getFieldOfView().radians / 2; // half horizontal fov in radians// double hw = view.getViewport().width / 2; // half viewport width// double hh = view.getViewport().height / 2; // half viewport height// double d = hw / Math.tan(hfovH); // distance to viewport plane in pixels// // distance to near plane in meters// double dNearMeter = Math.abs(view.getFrustum().getNear().getDistance());// // crosshair elevation above viewport center in meter// double dyMeter = (dNearMeter - distance) * Math.sin(a.radians);// // corresponding vertical fov half angle// double ay = Math.atan(dyMeter / dNearMeter);// // corresponding viewport crosshair elevation in pixels// double dy = Math.tan(ay) * d;// // final crosshair viewport position// return new Vec4(hw, hh + dy, 0, 0);// } // Mark crosshair as needing update after next render pass private void updateCrosshair() { this.crosshairNeedsUpdate = true; this.wwd.redraw(); } // Update crosshair position to follow the air track private void doUpdateCrosshair() { Vec4 crosshairPos = computeCrosshairPosition(); if (crosshairPos != null) { this.crosshairLayer.setEnabled(true); this.crosshairLayer.setLocationCenter(crosshairPos); } else { this.crosshairLayer.setEnabled(false); } this.crosshairNeedsUpdate = false; } // Compute cartesian intersection between the current air track segment and the near plane. // Follow rhumb line segments. private Vec4 computeCrosshairPosition() { Position posA = getCurrentSegmentStartPosition(); Position posB = getCurrentSegmentEndPosition(); Angle segmentAzimuth = LatLon.rhumbAzimuth(posA, posB); Angle segmentDistance = LatLon.rhumbDistance(posA, posB); int numSubsegments = 10; // TODO: get from track polyline double step = 1d / numSubsegments; // Extend the track segment ends by one subsegment to make sure it will intersect the near plane double deltaElevation = posB.getElevation() - posA.getElevation(); LatLon latLon = LatLon.rhumbEndPosition(posA, segmentAzimuth.addRadians(Math.PI), Angle.fromRadians(segmentDistance.radians / numSubsegments)); posA = new Position(latLon, posA.getElevation() - deltaElevation / numSubsegments); latLon = LatLon.rhumbEndPosition(posB, segmentAzimuth, Angle.fromRadians(segmentDistance.radians / numSubsegments)); posB = new Position(latLon, posB.getElevation() + deltaElevation / numSubsegments); segmentDistance = LatLon.rhumbDistance(posA, posB); // Iterate through segments to find intersection Globe globe = this.wwd.getModel().getGlobe(); Plane near = this.wwd.getView().getFrustumInModelCoordinates().getNear(); Position p1 = null, p2; for (double s = 0; s <= 1; s += step) { if (s == 0) p2 = posA; else if (s >= 1) p2 = posB; else { Angle distance = Angle.fromRadians(s * segmentDistance.radians); latLon = LatLon.rhumbEndPosition(posA, segmentAzimuth, distance); p2 = new Position(latLon, (1 - s) * posA.getElevation() + s * posB.getElevation()); } if (p1 != null) { Vec4 pa = globe.computePointFromPosition(p1); Vec4 pb = globe.computePointFromPosition(p2); if(pa.distanceTo3(pb) > 0) { Vec4 intersection = near.intersect(pa, pb); if (intersection != null) { return this.wwd.getView().project(intersection); } } } p1 = p2; } return null; } private void initComponents() { setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); this.trackViewPanel = new TrackViewPanel(this); this.trackViewPanel.setAlignmentX(Component.LEFT_ALIGNMENT); add(this.trackViewPanel); this.terrainProfilePanel = new TerrainProfilePanel(); this.terrainProfilePanel.setAlignmentX(Component.LEFT_ALIGNMENT); add(this.terrainProfilePanel); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?