/******************************************************************************* * Copyright 2014 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.target; import gov.nasa.worldwind.awt.AbstractViewInputHandler; import gov.nasa.worldwind.awt.ViewInputAttributes; import gov.nasa.worldwind.awt.ViewInputAttributes.ActionAttributes; import gov.nasa.worldwind.awt.ViewInputAttributes.DeviceAttributes; import gov.nasa.worldwind.geom.Angle; import gov.nasa.worldwind.geom.LatLon; import gov.nasa.worldwind.geom.Position; import gov.nasa.worldwind.geom.Vec4; import gov.nasa.worldwind.view.orbit.OrbitView; import java.awt.Point; import au.gov.ga.earthsci.worldwind.common.view.orbit.BaseOrbitViewInputHandler; /** * Extension of the standard orbit view input handler that adds support for the * {@link TargetOrbitView}, which allows manually changing the center point. * * @author Michael de Hoog (michael.dehoog@ga.gov.au) */ public class TargetOrbitViewInputHandler extends BaseOrbitViewInputHandler { public TargetOrbitViewInputHandler() { super(); ViewInputAttributes.ActionAttributes actionAttrs; actionAttrs = this.getAttributes().getActionMap(ViewInputAttributes.DEVICE_MOUSE).getActionAttributes( ViewInputAttributes.VIEW_MOVE_TO); actionAttrs.setMouseActionListener(new TargetMoveToMouseActionListener()); } protected boolean isTargetMode() { OrbitView view = getView(); return view instanceof ITargetView && ((ITargetView) view).isTargetMode(); } protected boolean isTranslateAbsAllowed() { return !isTargetMode(); } @Override protected void onHorizontalTranslateRel(double forwardInput, double sideInput, double totalForwardInput, double totalSideInput, DeviceAttributes deviceAttributes, ActionAttributes actionAttributes) { if (!isTranslateAbsAllowed()) { //if the view is in target mode, then don't perform the absolute positioning, so //only call the relative positioning function this.stopGoToAnimators(); this.stopUserInputAnimators(VIEW_ANIM_HEADING, VIEW_ANIM_PITCH, VIEW_ANIM_ZOOM); Angle forwardChange = Angle.fromDegrees( forwardInput * getScaleValueHorizTransRel(deviceAttributes, actionAttributes)); Angle sideChange = Angle.fromDegrees( sideInput * getScaleValueHorizTransRel(deviceAttributes, actionAttributes)); onHorizontalTranslateRel(forwardChange, sideChange, actionAttributes); return; } super.onHorizontalTranslateRel(forwardInput, sideInput, totalForwardInput, totalSideInput, deviceAttributes, actionAttributes); } @Override protected void onHorizontalTranslateRel(Angle forwardChange, Angle sideChange, ActionAttributes actionAttribs) { if (isTargetMode()) { OrbitView view = getView(); if (view == null) { return; } if (forwardChange.equals(Angle.ZERO) && sideChange.equals(Angle.ZERO)) { return; } double elevationChangePerDegree = 0; LatLon centerLocation = view.getCenterPosition(); if (centerLocation != null && view.getGlobe() != null) { Angle nearByLatitude = centerLocation.latitude.addDegrees(centerLocation.latitude.degrees > 0 ? -1 : 1); LatLon nearByLocation = new LatLon(nearByLatitude, centerLocation.longitude); Vec4 v1 = view.getGlobe().computePointFromLocation(centerLocation); Vec4 v2 = view.getGlobe().computePointFromLocation(nearByLocation); elevationChangePerDegree = v1.distanceTo3(v2); //for the earth, will be approx 111km } //move the center position, including elevation, according to the current view heading/pitch double sinHeading = view.getHeading().sin(); double cosHeading = view.getHeading().cos(); double sinPitch = view.getPitch().sin(); double cosPitch = view.getPitch().cos(); double latChange = cosPitch * cosHeading * forwardChange.degrees - sinHeading * sideChange.degrees; double lonChange = cosPitch * sinHeading * forwardChange.degrees + cosHeading * sideChange.degrees; double elevChange = sinPitch * forwardChange.degrees * elevationChangePerDegree; Position newPosition = view.getCenterPosition().add(Position.fromDegrees(latChange, lonChange, elevChange)); this.setCenterPosition(view, this.uiAnimControl, newPosition, actionAttribs); return; } super.onHorizontalTranslateRel(forwardChange, sideChange, actionAttribs); } @Override public Point getMousePoint() { return super.getMousePoint(); } public class TargetMoveToMouseActionListener extends MoveToMouseActionListener { @Override public boolean inputActionPerformed(AbstractViewInputHandler inputHandler, java.awt.event.MouseEvent mouseEvent, ViewInputAttributes.ActionAttributes viewAction) { boolean handleThisEvent = false; java.util.List<?> buttonList = viewAction.getMouseActions(); for (Object b : buttonList) { ViewInputAttributes.ActionAttributes.MouseAction buttonAction = (ViewInputAttributes.ActionAttributes.MouseAction) b; if ((mouseEvent.getButton() == buttonAction.mouseButton)) { handleThisEvent = true; } } if (!handleThisEvent) { return false; } if (isTargetMode()) { Position mousePosition = ((ITargetView) getView()).getMousePosition(); if (mousePosition != null) { onMoveTo(mousePosition, getAttributes().getDeviceAttributes(ViewInputAttributes.DEVICE_MOUSE), viewAction); return true; } } return super.inputActionPerformed(inputHandler, mouseEvent, viewAction); } } }