/******************************************************************************* * Copyright 2012 Geoscience Australia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package au.gov.ga.earthsci.worldwind.common.view.orbit; import gov.nasa.worldwind.WorldWind; import gov.nasa.worldwind.geom.Angle; import gov.nasa.worldwind.geom.LatLon; import gov.nasa.worldwind.geom.Position; import gov.nasa.worldwind.view.orbit.OrbitView; import java.awt.Rectangle; import au.gov.ga.earthsci.worldwind.common.util.Util; /** * Helper class to create an {@link OrbitView} animator that flies to a given * sector. * * @author Michael de Hoog (michael.dehoog@ga.gov.au) */ public class FlyToSectorAnimator { /** * Create a {@link FlyToOrbitViewAnimator} that flies to a given position, * ensuring that a delta lat/lon area is visible. * * @param orbitView * Orbit view to create the animator for * @param beginCenterPos * Begin position * @param endCenterPos * End position * @param beginHeading * Initial heading * @param beginPitch * Initial pitch * @param beginZoom * Initial zoom * @param endVisibleDelta * End lat/lon delta. The end zoom is calculated to ensure that * this lat/lon delta is visible. * @param timeToMove * Time in milliseconds for the animation * @return Animator to fly to the given position and zoom */ public static FlyToOrbitViewAnimator createFlyToSectorAnimator(OrbitView orbitView, Position beginCenterPos, Position endCenterPos, Angle beginHeading, Angle beginPitch, double beginZoom, LatLon endVisibleDelta, long timeToMove) { double endZoom = calculateEndZoom(orbitView, endVisibleDelta); return FlyToOrbitViewAnimator.createFlyToOrbitViewAnimator(orbitView, beginCenterPos, endCenterPos, beginHeading, Angle.ZERO, beginPitch, Angle.ZERO, beginZoom, endZoom, timeToMove, WorldWind.ABSOLUTE); } public static FlyToOrbitViewAnimator createScaledFlyToSectorAnimator(OrbitView orbitView, Position beginCenterPos, Position endCenterPos, Angle beginHeading, Angle beginPitch, double beginZoom, LatLon endVisibleDelta, double timeScale) { double endZoom = calculateEndZoom(orbitView, endVisibleDelta); long timeToMove = (Util.getScaledLengthMillis(timeScale, beginCenterPos, endCenterPos) + Util.getScaledLengthMillis( timeScale, beginZoom, endZoom)) / 2; return FlyToOrbitViewAnimator.createFlyToOrbitViewAnimator(orbitView, beginCenterPos, endCenterPos, beginHeading, Angle.ZERO, beginPitch, Angle.ZERO, beginZoom, endZoom, timeToMove, WorldWind.ABSOLUTE); } public static double calculateEndZoom(OrbitView orbitView, LatLon endVisibleDelta) { Rectangle viewport = orbitView.getViewport(); Angle fieldOfView = orbitView.getFieldOfView(); double deltaLonDegrees = Math.min(endVisibleDelta.getLongitude().degrees, 90); double deltaLatDegrees = Math.min(endVisibleDelta.getLatitude().degrees, 90); double degreesPerPixelWidth = deltaLonDegrees / viewport.getWidth(); double degreesPerPixelHeight = deltaLatDegrees / viewport.getHeight(); double degreesPerPixel = Math.max(degreesPerPixelWidth, degreesPerPixelHeight); double metersPerPixel = 111111.11 * degreesPerPixel; //very! approximate degrees to meters conversion metersPerPixel *= 1.1; //zoom out just a little more, to add a slight border double viewportWidth = viewport.getWidth(); double pixelSizeScale = 2 * fieldOfView.tanHalfAngle() / (viewportWidth <= 0 ? 1d : viewportWidth); return metersPerPixel / pixelSizeScale; } }