diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/actions/NewMapEditor.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/actions/NewMapEditor.java index 22cae0fb97..a46672f80b 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/actions/NewMapEditor.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/actions/NewMapEditor.java @@ -20,8 +20,6 @@ package com.raytheon.uf.viz.core.maps.actions; * further licensing information. **/ -import java.io.File; - import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -29,9 +27,9 @@ import org.eclipse.core.commands.ExecutionException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.viz.core.maps.scales.MapScales; -import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; import com.raytheon.uf.viz.core.maps.scales.MapScales.PartId; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale; import com.raytheon.uf.viz.core.procedures.Bundle; import com.raytheon.viz.ui.UiUtil; import com.raytheon.viz.ui.editor.AbstractEditor; @@ -45,6 +43,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * ------------ ---------- ----------- -------------------------- * Apr 11, 2007 chammack Initial Creation. * Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d + * Oct 10, 2013 2104 mschenke Switched to use MapScalesManager * * * @@ -66,9 +65,9 @@ public class NewMapEditor extends AbstractHandler { @Override public AbstractEditor execute(ExecutionEvent arg0) throws ExecutionException { - MapScale editorScale = null; + ManagedMapScale editorScale = null; String editorId = null; - for (MapScale scale : MapScales.getInstance().getScales()) { + for (ManagedMapScale scale : MapScalesManager.getInstance().getScales()) { for (PartId partId : scale.getPartIds()) { if (partId.isView() == false) { editorScale = scale; @@ -77,16 +76,19 @@ public class NewMapEditor extends AbstractHandler { } } - File bundle = null; - try { - bundle = editorScale.getFile(); - Bundle b = Bundle.unmarshalBundle(bundle); - return UiUtil.createEditor(editorId, b.getDisplays()); - } catch (Exception e) { + if (editorScale != null) { + try { + Bundle b = editorScale.getScaleBundle(); + return UiUtil.createEditor(editorId, b.getDisplays()); + } catch (Exception e) { + statusHandler.handle(Priority.SIGNIFICANT, + "Unable to load bundle for scale, " + editorScale + + " to screen", e); + } + } else { statusHandler.handle(Priority.SIGNIFICANT, - "Unable to load bundle, " + bundle + " to screen", e); + "Unable to find an editor based map scale"); } - return null; } } diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/dialogs/CreateProjectionDialog.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/dialogs/CreateProjectionDialog.java index 92c73e39db..3f63af5fd4 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/dialogs/CreateProjectionDialog.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/dialogs/CreateProjectionDialog.java @@ -63,22 +63,25 @@ import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.map.IMapDescriptor; import com.raytheon.uf.viz.core.map.MapDescriptor; import com.raytheon.uf.viz.core.maps.actions.NewMapEditor; +import com.raytheon.uf.viz.core.maps.scales.IMapScaleDisplay; import com.raytheon.viz.ui.EditorUtil; import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; import com.vividsolutions.jts.geom.Coordinate; /** - * TODO Add Description + * Dialog that creates a custom geotools projection * *
  * SOFTWARE HISTORY
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Jan. 29, 2013  15567     snaples     Remove Orthographic projection from list temporarily
+ * Jan 16, 2008 783        randerso    Initial Creation
+ * Jan 29, 2013 15567      snaples     Remove Orthographic projection from list temporarily
  * 
  * 
* @@ -96,6 +99,8 @@ public class CreateProjectionDialog extends CaveJFACEDialog { private Combo projList; + private Text projNameText; + private class ParamUI { public Label label; @@ -227,6 +232,12 @@ public class CreateProjectionDialog extends CaveJFACEDialog { }); projList.setText(projections[0]); + new Label(projComp, SWT.NONE).setText("Name:"); + projNameText = new Text(projComp, SWT.BORDER); + projNameText + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + setProjectionNameText(projList.getText()); + paramGroup = new Group(dlgComp, SWT.BORDER); paramGroup.setText("Parameters"); layout = new GridLayout(2, false); @@ -404,6 +415,8 @@ public class CreateProjectionDialog extends CaveJFACEDialog { text.setText("" + param.getValue()); } + setProjectionNameText(projList.getText()); + validateParameters(); } catch (NoSuchIdentifierException e) { @@ -415,6 +428,10 @@ public class CreateProjectionDialog extends CaveJFACEDialog { getShell().pack(true); } + private void setProjectionNameText(String projection) { + projNameText.setText(projection.replace("_", " ")); + } + private void validateParameters() { crs = null; Button okButton = getButton(IDialogConstants.OK_ID); @@ -619,10 +636,17 @@ public class CreateProjectionDialog extends CaveJFACEDialog { } } for (IDisplayPane pane : container.getDisplayPanes()) { - IMapDescriptor oldDescriptor = (IMapDescriptor) pane - .getRenderableDisplay().getDescriptor(); + IRenderableDisplay display = pane.getRenderableDisplay(); + IMapDescriptor oldDescriptor = (IMapDescriptor) display + .getDescriptor(); try { + // Reproject by setting new grid geometry oldDescriptor.setGridGeometry(newMapGeom); + // Give projection custom name if IMapScaleDisplay + if (display instanceof IMapScaleDisplay) { + ((IMapScaleDisplay) display).setScaleName(projNameText + .getText().trim()); + } } catch (VizException e) { statusHandler.handle(Priority.PROBLEM, "Error setting GridGeometry: ", e); diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/IMapScaleDisplay.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/IMapScaleDisplay.java index f56a798e11..793503a9d3 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/IMapScaleDisplay.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/IMapScaleDisplay.java @@ -19,8 +19,6 @@ **/ package com.raytheon.uf.viz.core.maps.scales; -import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; - /** * Interface for display containing a scale * @@ -31,6 +29,8 @@ import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Mar 21, 2013 mschenke Initial creation + * Oct 10, 2013 2104 mschenke Added ability to change name of scale + * without affecting the projection * * * @@ -41,15 +41,23 @@ import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; public interface IMapScaleDisplay { /** - * Returns the name of the scale to be used in - * {@link MapScales#getScaleByName(String)} + * Returns the name of the scale for the display */ public String getScaleName(); /** - * Changes the scale of the display + * Sets the name of the current scale. This should be nothing other than a + * rename operation + * + * @param scaleName + */ + public void setScaleName(String scaleName); + + /** + * Changes the scale of the display to the one passed in. This should cause + * the display to internally change * * @param scale */ - public void changeScale(MapScale scale); + public void changeScale(String scaleName); } diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScaleHandler.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScaleHandler.java index 5cda3a06b8..5fd6d8ad07 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScaleHandler.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScaleHandler.java @@ -65,16 +65,15 @@ public class MapScaleHandler extends AbstractHandler { */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { - MapScale scale = MapScales.getInstance().getScaleByName( - event.getParameter(SCALE_NAME_ID)); - if (scale != null) { + String scaleName = event.getParameter(SCALE_NAME_ID); + if (scaleName != null) { IEditorPart part = HandlerUtil.getActiveEditor(event); if (part instanceof IDisplayPaneContainer) { IDisplayPaneContainer container = (IDisplayPaneContainer) part; for (IDisplayPane pane : container.getDisplayPanes()) { IRenderableDisplay display = pane.getRenderableDisplay(); if (display instanceof IMapScaleDisplay) { - ((IMapScaleDisplay) display).changeScale(scale); + ((IMapScaleDisplay) display).changeScale(scaleName); } } container.refresh(); diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalePopulator.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalePopulator.java index 4ed91e1a81..82603a779e 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalePopulator.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalePopulator.java @@ -30,7 +30,7 @@ import org.eclipse.ui.menus.CommandContributionItem; import org.eclipse.ui.menus.CommandContributionItemParameter; import com.raytheon.uf.viz.core.IDisplayPaneContainer; -import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale; import com.raytheon.viz.ui.EditorUtil; /** @@ -43,7 +43,7 @@ import com.raytheon.viz.ui.EditorUtil; * ------------ ---------- ----------- -------------------------- * Oct 7, 2010 mschenke Initial creation * Mar 21, 2013 1638 mschenke Made map scales not tied to d2d - * + * Oct 10, 2013 2104 mschenke Switched to use MapScalesManager * * * @@ -66,7 +66,8 @@ public class MapScalePopulator extends CompoundContributionItem { if ((cont != null && (cont.getActiveDisplayPane() .getRenderableDisplay() instanceof IMapScaleDisplay)) || EditorUtil.getActiveEditor() == null) { - for (MapScale scale : MapScales.getInstance().getScales()) { + for (ManagedMapScale scale : MapScalesManager.getInstance() + .getScales()) { Map parms = new HashMap(); parms.put(MapScaleHandler.SCALE_NAME_ID, scale.getDisplayName()); CommandContributionItem item = new CommandContributionItem( diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScaleRenderableDisplay.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScaleRenderableDisplay.java index 7092f1069b..c7339cbe96 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScaleRenderableDisplay.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScaleRenderableDisplay.java @@ -26,6 +26,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; +import com.raytheon.uf.common.serialization.SerializationException; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.VizConstants; import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; @@ -35,9 +36,9 @@ import com.raytheon.uf.viz.core.globals.VizGlobalsManager; import com.raytheon.uf.viz.core.map.IMapDescriptor; import com.raytheon.uf.viz.core.maps.display.PlainMapRenderableDisplay; import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale; import com.raytheon.uf.viz.core.procedures.Bundle; import com.raytheon.uf.viz.core.rsc.ResourceList; -import com.raytheon.viz.ui.actions.LoadSerializedXml; /** * MapRenderableDisplay associated with a {@link MapScale} @@ -48,7 +49,8 @@ import com.raytheon.viz.ui.actions.LoadSerializedXml; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Mar 22, 2013 mschenke Initial creation + * Mar 22, 2013 mschenke Initial creation + * Oct 10, 2013 2104 mschenke Switched to use MapScalesManager * * * @@ -60,9 +62,8 @@ import com.raytheon.viz.ui.actions.LoadSerializedXml; public class MapScaleRenderableDisplay extends PlainMapRenderableDisplay implements IMapScaleDisplay { - @XmlAttribute - protected String scale = (String) VizGlobalsManager.getCurrentInstance() - .getPropery(VizConstants.SCALE_ID); + protected String scaleName = (String) VizGlobalsManager + .getCurrentInstance().getPropery(VizConstants.SCALE_ID); public MapScaleRenderableDisplay() { super(); @@ -78,38 +79,46 @@ public class MapScaleRenderableDisplay extends PlainMapRenderableDisplay * @see com.raytheon.uf.viz.core.maps.scales.IMapScaleDisplay#getScaleName() */ @Override + @XmlAttribute(name = "scale") public String getScaleName() { - return scale; + return scaleName; + } + + @Override + public void setScaleName(String scaleName) { + this.scaleName = scaleName; } /* * (non-Javadoc) * * @see - * com.raytheon.uf.viz.core.maps.scales.IMapScaleDisplay#changeScale(com - * .raytheon.uf.viz.core.maps.scales.MapScales.MapScale) + * com.raytheon.uf.viz.core.maps.scales.IMapScaleDisplay#changeScale(java + * .lang.String) */ @Override - public void changeScale(MapScale scale) { - MapScale currentScale = MapScales.getInstance().getScaleByName( - getScaleName()); - Bundle bundle = (Bundle) LoadSerializedXml.deserialize(currentScale - .getFile()); - for (AbstractRenderableDisplay display : bundle.getDisplays()) { - descriptor.getResourceList().removeAll( - display.getDescriptor().getResourceList()); + public void changeScale(String scaleName) { + ManagedMapScale currentScale = MapScalesManager.getInstance() + .getScaleByName(getScaleName()); + if (currentScale != null) { + try { + Bundle bundle = currentScale.getScaleBundle(); + for (AbstractRenderableDisplay display : bundle.getDisplays()) { + descriptor.getResourceList().removeAll( + display.getDescriptor().getResourceList()); + } + } catch (SerializationException e) { + statusHandler.handle(Priority.PROBLEM, + "Error getting scale bundle for " + getScaleName(), e); + } } - loadScale(scale); + loadScale(MapScalesManager.getInstance().getScaleByName(scaleName)); } @Override public void clear() { - MapScale scale = MapScales.getInstance().getScaleByName(getScaleName()); - if (scale == null) { - scale = MapScales.getInstance().getScaleByName( - (String) VizGlobalsManager.getCurrentInstance().getPropery( - VizConstants.SCALE_ID)); - } + ManagedMapScale scale = MapScalesManager.getInstance().getScaleByName( + getScaleName()); if (scale != null) { ResourceList list = descriptor.getResourceList(); for (ResourcePair rp : list) { @@ -119,27 +128,47 @@ public class MapScaleRenderableDisplay extends PlainMapRenderableDisplay } } loadScale(scale); + } else { + // Map scale could not be found, default to remove all + // non-map/system layers and reset display + ResourceList list = descriptor.getResourceList(); + for (ResourcePair rp : list) { + if (rp.getProperties().isMapLayer() == false + && rp.getProperties().isSystemResource() == false) { + list.remove(rp); + } + } + + scaleToClientArea(getBounds()); } } - protected void loadScale(MapScale scale) { - Bundle bundle = (Bundle) LoadSerializedXml.deserialize(scale.getFile()); - for (AbstractRenderableDisplay ard : bundle.getDisplays()) { + protected void loadScale(ManagedMapScale scale) { + if (scale != null) { try { - descriptor.setGridGeometry(ard.getDescriptor() - .getGridGeometry()); - descriptor.getResourceList().addAll( - ard.getDescriptor().getResourceList()); - ard.getDescriptor().getResourceList().clear(); - break; - } catch (VizException e) { + Bundle bundle = scale.getScaleBundle(); + for (AbstractRenderableDisplay ard : bundle.getDisplays()) { + try { + descriptor.setGridGeometry(ard.getDescriptor() + .getGridGeometry()); + descriptor.getResourceList().addAll( + ard.getDescriptor().getResourceList()); + ard.getDescriptor().getResourceList().clear(); + break; + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + descriptor.getResourceList().instantiateResources(descriptor, + true); + scaleToClientArea(getBounds()); + } catch (SerializationException e) { statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); } + setScaleName(scale.getDisplayName()); } - descriptor.getResourceList().instantiateResources(descriptor, true); - this.scale = scale.getDisplayName(); - scaleToClientArea(getBounds()); } @Override diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScales.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScales.java index 81407d179b..08a550c9b8 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScales.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScales.java @@ -19,44 +19,23 @@ **/ package com.raytheon.uf.viz.core.maps.scales; -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.JAXB; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -import org.eclipse.ui.IWorkbenchWindow; - -import com.raytheon.uf.common.localization.FileUpdatedMessage; -import com.raytheon.uf.common.localization.ILocalizationFileObserver; -import com.raytheon.uf.common.localization.LocalizationFile; -import com.raytheon.uf.common.localization.PathManagerFactory; -import com.raytheon.uf.common.serialization.ISerializableObject; -import com.raytheon.uf.common.serialization.SerializationException; -import com.raytheon.uf.common.serialization.SerializationUtil; -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.procedures.Bundle; -import com.raytheon.uf.viz.core.procedures.Procedure; -import com.raytheon.viz.ui.actions.LoadSerializedXml; - /** - * Serializable object representation of map scales + * Serializable object representation of a group of {@link MapScale}s * *
  * 
  * SOFTWARE HISTORY
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Oct 7, 2010             mschenke    Initial creation
+ * Oct  7, 2010            mschenke    Initial creation
  * Mar 21, 2013       1638 mschenke    Made map scales not tied to d2d
+ * Oct  8, 2013       2104 mschenke    Moved logic into manager class
  * 
  * 
* @@ -65,9 +44,7 @@ import com.raytheon.viz.ui.actions.LoadSerializedXml; */ @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class MapScales implements ISerializableObject { - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(MapScales.class); +public class MapScales { @XmlAccessorType(XmlAccessType.NONE) public static class PartId { @@ -95,6 +72,7 @@ public class MapScales implements ISerializableObject { } + /** Serializable object representation of a single map scale */ @XmlAccessorType(XmlAccessType.NONE) public static class MapScale { @@ -134,98 +112,10 @@ public class MapScales implements ISerializableObject { public void setPartIds(PartId[] partIds) { this.partIds = partIds; } - - public File getFile() { - return PathManagerFactory.getPathManager().getStaticFile( - SCALES_DIR + fileName); - } - } - private static final String SCALES_DIR = "bundles" + File.separator - + "scales" + File.separator; - - public static final String FILE_NAME = SCALES_DIR + "scalesInfo.xml"; - - private static ILocalizationFileObserver listener = new ILocalizationFileObserver() { - @Override - public void fileUpdated(FileUpdatedMessage message) { - MapScales.fileUpdated(); - } - }; - - private static LocalizationFile locFile = null; - - private static MapScales instance; - private MapScale[] scales; - public static synchronized MapScales getInstance() { - if (instance == null) { - loadInstance(); - } - return instance; - } - - public static void loadScales(IWorkbenchWindow window, MapScale... scales) - throws VizException { - if (scales == null || scales.length == 0) { - scales = getInstance().getScales(); - } - Procedure procedure = new Procedure(); - List bundles = new ArrayList(); - for (MapScale scale : scales) { - String editorId = null; - for (PartId partId : scale.getPartIds()) { - if (partId.isView() == false) { - editorId = partId.getId(); - break; - } - } - if (editorId != null) { - File file = scale.getFile(); - try { - Bundle b = SerializationUtil.jaxbUnmarshalFromXmlFile( - Bundle.class, file); - b.setEditor(editorId); - bundles.add(b); - } catch (SerializationException e) { - statusHandler.handle( - Priority.PROBLEM, - "Error deserializing bundle: " - + file.getAbsolutePath(), e); - } - } - } - procedure.setBundles(bundles.toArray(new Bundle[bundles.size()])); - LoadSerializedXml.loadProcedureToScreen(procedure, window); - } - - private static synchronized void fileUpdated() { - instance = null; - } - - private static void loadInstance() { - if (locFile != null) { - locFile.removeFileUpdatedObserver(listener); - } - locFile = PathManagerFactory.getPathManager() - .getStaticLocalizationFile(FILE_NAME); - locFile.addFileUpdatedObserver(listener); - File file = locFile.getFile(); - if (file == null) { - statusHandler.handle(Priority.PROBLEM, - "Could not find any version of scale file: " + FILE_NAME); - } else { - try { - instance = JAXB.unmarshal(file, MapScales.class); - } catch (RuntimeException e) { - statusHandler.handle(Priority.PROBLEM, - "Could not parse scale file: " + FILE_NAME, e); - } - } - } - public MapScales() { scales = new MapScale[0]; } @@ -236,15 +126,7 @@ public class MapScales implements ISerializableObject { } public void setScales(MapScale[] scales) { - this.scales = scales; + this.scales = scales != null ? scales : new MapScale[0]; } - public MapScale getScaleByName(String name) { - for (MapScale scale : scales) { - if (scale.displayName.equals(name)) { - return scale; - } - } - return null; - } } diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalesManager.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalesManager.java new file mode 100644 index 0000000000..3b6a6d948e --- /dev/null +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalesManager.java @@ -0,0 +1,409 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.core.maps.scales; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.xml.bind.JAXBException; + +import org.eclipse.ui.IWorkbenchWindow; + +import com.raytheon.uf.common.localization.AutoUpdatingLocalizationFile; +import com.raytheon.uf.common.localization.AutoUpdatingLocalizationFile.AutoUpdatingFileChangedListener; +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.serialization.JAXBManager; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.serialization.SerializationUtil; +import com.raytheon.uf.common.serialization.SingleTypeJAXBManager; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; +import com.raytheon.uf.viz.core.maps.scales.MapScales.PartId; +import com.raytheon.uf.viz.core.procedures.Bundle; +import com.raytheon.uf.viz.core.procedures.Procedure; +import com.raytheon.viz.ui.actions.LoadSerializedXml; + +/** + * Manager for {@link MapScales}. May be constructed from any file or the + * default instance can be used via {@link #getInstance()} + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 8, 2013            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class MapScalesManager { + + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(MapScalesManager.class); + + private static final String DEFAULT_SCALES_DIR = "bundles" + + IPathManager.SEPARATOR + "scales"; + + private static final String DEFAULT_SCALES_FILE = "scalesInfo.xml"; + + /** + * Manager class for a single {@link MapScale}. Is able to create a Bundle + * for the scale. May provide functions for modifying/saving scales + */ + public static final class ManagedMapScale { + + private final AutoUpdatingFileChangedListener listener = new AutoUpdatingFileChangedListener() { + @Override + public void fileChanged(AutoUpdatingLocalizationFile file) { + loadBundleXml(); + } + }; + + private final String displayName; + + private final PartId[] partIds; + + private final AutoUpdatingLocalizationFile scaleFile; + + private String bundleXml; + + private boolean isCustom; + + private ManagedMapScale(String baseDir, MapScale scale) + throws SerializationException { + this.isCustom = false; + this.scaleFile = new AutoUpdatingLocalizationFile( + PathManagerFactory.getPathManager() + .getStaticLocalizationFile( + baseDir + IPathManager.SEPARATOR + + scale.getFileName())); + this.scaleFile.addListener(listener); + this.partIds = scale.getPartIds(); + this.displayName = scale.getDisplayName(); + loadBundleXml(); + } + + private ManagedMapScale(String displayName, Bundle scaleBundle) + throws SerializationException { + this.isCustom = true; + this.displayName = displayName; + this.partIds = new PartId[0]; + this.scaleFile = null; + try { + this.bundleXml = SerializationUtil.getJaxbManager() + .marshalToXml(scaleBundle); + } catch (JAXBException e) { + throw new SerializationException( + "Error serializing bundle for scale, " + displayName); + } + } + + private void loadBundleXml() { + try { + this.bundleXml = new String(scaleFile.getFile().read()); + } catch (LocalizationException e) { + // Ignore, error will be reported in getScaleBundle + } + } + + /** + * Gets the + * + * @return + * @throws SerializationException + */ + public Bundle getScaleBundle() throws SerializationException { + if (bundleXml != null) { + long t0 = System.currentTimeMillis(); + try { + return (Bundle) SerializationUtil.getJaxbManager() + .unmarshalFromXml(bundleXml); + } catch (JAXBException e) { + throw new SerializationException(e); + } finally { + System.out.println("Time to create Bundle: " + + (System.currentTimeMillis() - t0) + "ms"); + } + } else { + throw new SerializationException( + "Scale Bundle XML could not be read"); + } + } + + public String getDisplayName() { + return displayName; + } + + public PartId[] getPartIds() { + return partIds; + } + + public boolean isCustomScale() { + return isCustom; + } + + @Override + public String toString() { + return "MapScale [displayName=" + displayName + ", fileName=" + + scaleFile.getFilePath() + "]"; + } + + } + + private static SingleTypeJAXBManager jaxbManager; + + private static MapScalesManager DEFAULT_MANAGER; + + private final AutoUpdatingFileChangedListener listener = new AutoUpdatingFileChangedListener() { + @Override + public void fileChanged(AutoUpdatingLocalizationFile file) { + try { + loadMapScales(); + } catch (SerializationException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + }; + + private final AutoUpdatingLocalizationFile scalesFile; + + private final String scaleBundleDir; + + // TODO: Possibly have a Map to handle duplicates + private Collection storedScales = new ArrayList(); + + // TODO: Need to figure out best way to create custom scales (depends on + // maps loaded so it can't be at the projection dialog level) + private Collection customScales = new ArrayList(); + + /** + * Construct a MapScalesManager for the given scales file. File must be + * deserializable into a {@link MapScales} object. IPathManager will be used + * to lookup file + * + * @param scalesDir + * directory which scalesFile and bundles references in + * scalesFile are relative to + * @param scalesFile + * XML file that deserializes into {@link MapScales} object + * @throws SerializationException + */ + public MapScalesManager(String scalesDir, String scalesFile) + throws SerializationException { + this(scalesDir, PathManagerFactory.getPathManager() + .getStaticLocalizationFile( + scalesDir + IPathManager.SEPARATOR + scalesFile)); + } + + /** + * Construct a MapScalesManager for the given scales file. File must be + * deserializable into a {@link MapScales} object + * + * @param bundleDir + * directory bundle files are relative to + * @param scalesFile + * @throws SerializationException + */ + public MapScalesManager(String bundleDir, LocalizationFile scalesFile) + throws SerializationException { + this.scaleBundleDir = bundleDir; + this.scalesFile = new AutoUpdatingLocalizationFile(scalesFile); + this.scalesFile.addListener(listener); + loadMapScales(); + } + + private synchronized void loadMapScales() throws SerializationException { + List storedScales = new ArrayList(); + MapScales scales = this.scalesFile.loadObject(getJAXBManager(), + MapScales.class); + for (MapScale scale : scales.getScales()) { + storedScales.add(new ManagedMapScale(scaleBundleDir, scale)); + } + this.storedScales = storedScales; + } + + /** + * Loads the {@link ManagedMapScale}s referenced to an editor part id onto + * the window + * + * @param window + * @param scales + * @throws VizException + */ + public void loadEditorScales(IWorkbenchWindow window, + ManagedMapScale... scales) throws VizException { + if (scales == null || scales.length == 0) { + scales = getScales(); + } + Procedure procedure = new Procedure(); + List bundles = new ArrayList(); + for (ManagedMapScale scale : scales) { + String editorId = null; + for (PartId partId : scale.getPartIds()) { + if (partId.isView() == false) { + editorId = partId.getId(); + break; + } + } + if (editorId != null) { + try { + Bundle b = scale.getScaleBundle(); + b.setEditor(editorId); + bundles.add(b); + } catch (SerializationException e) { + statusHandler.handle(Priority.PROBLEM, + "Error getting bundle for scale: " + scale, e); + } + } + } + procedure.setBundles(bundles.toArray(new Bundle[bundles.size()])); + LoadSerializedXml.loadProcedureToScreen(procedure, window); + } + + /** + * Gets all {@link ManagedMapScale} + * + * @return + */ + public ManagedMapScale[] getScales() { + Collection stored = storedScales; + Collection custom = customScales; + ManagedMapScale[] scales = new ManagedMapScale[stored.size() + + custom.size()]; + int i = 0; + for (ManagedMapScale scale : stored) { + scales[i++] = scale; + } + for (ManagedMapScale scale : custom) { + scales[i++] = scale; + } + return scales; + } + + /** + * Gets a {@link ManagedMapScale} by scale name + * + * @param name + * @return + */ + public ManagedMapScale getScaleByName(String name) { + // Search for scales by name, search custom first. + for (ManagedMapScale scale : customScales) { + if (scale.getDisplayName().equals(name)) { + return scale; + } + } + for (ManagedMapScale scale : storedScales) { + if (scale.getDisplayName().equals(name)) { + return scale; + } + } + // Scale not found + return null; + } + + /** + * Gets the {@link ManagedMapScale}s defined for the partId + * + * @param partId + * @return + */ + public ManagedMapScale[] getScalesForPart(String partId) { + List scalesForPart = new ArrayList(); + for (ManagedMapScale scale : storedScales) { + for (PartId part : scale.getPartIds()) { + if (partId.equals(part.getId())) { + scalesForPart.add(scale); + break; + } + } + } + return scalesForPart.toArray(new ManagedMapScale[0]); + } + + /** + * Adds a custom scale to be managed. Scale is only active while program is + * running. + * + * TODO: Need to figure out where map resources come from for this to work + * properly... When using CreateProjectionDialog we just have a + * GeneralGridGeometry + * + * @param scaleName + * @param display + */ + public void addCustomScale(String scaleName, + MapScaleRenderableDisplay display) { + Bundle bundle = new Bundle(); + bundle.setDisplays(new AbstractRenderableDisplay[] { display }); + bundle.setName(scaleName); + + try { + customScales.add(new ManagedMapScale(scaleName, bundle)); + } catch (SerializationException e) { + statusHandler.handle( + Priority.PROBLEM, + "Error adding custom scale (" + scaleName + "): " + + e.getLocalizedMessage(), e); + } + } + + public static synchronized MapScalesManager getInstance() { + if (DEFAULT_MANAGER == null) { + try { + DEFAULT_MANAGER = new MapScalesManager(DEFAULT_SCALES_DIR, + DEFAULT_SCALES_FILE); + } catch (SerializationException e) { + throw new IllegalStateException( + "Unable to construct the MapScalesManager using the default file: " + + DEFAULT_SCALES_FILE); + } + } + return DEFAULT_MANAGER; + } + + private static synchronized JAXBManager getJAXBManager() + throws SerializationException { + if (jaxbManager == null) { + try { + jaxbManager = new SingleTypeJAXBManager( + MapScales.class); + } catch (JAXBException e) { + throw new SerializationException( + "Error constructing JAXBManager for MapScales", e); + } + } + return jaxbManager; + } +} diff --git a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/map/D2DMapRenderableDisplay.java b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/map/D2DMapRenderableDisplay.java index 5fd4a7f437..c0222742f8 100644 --- a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/map/D2DMapRenderableDisplay.java +++ b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/map/D2DMapRenderableDisplay.java @@ -177,7 +177,7 @@ public class D2DMapRenderableDisplay extends MapScaleRenderableDisplay */ @Override public String getScale() { - return this.scale; + return getScaleName(); } /* @@ -189,7 +189,7 @@ public class D2DMapRenderableDisplay extends MapScaleRenderableDisplay */ @Override public void setScale(String scale) { - this.scale = scale; + setScaleName(scale); } /* @@ -204,7 +204,7 @@ public class D2DMapRenderableDisplay extends MapScaleRenderableDisplay public void paint(IGraphicsTarget target, PaintProperties paintProps) throws VizException { D2DProperties props = new D2DProperties(); - props.setScale(scale); + props.setScale(getScale()); PaintProperties myProps = new PaintProperties(paintProps); myProps.setPerspectiveProps(props); diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/DisplayPropertiesDialog.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/DisplayPropertiesDialog.java index 3740039046..a328c9c0f0 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/DisplayPropertiesDialog.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/DisplayPropertiesDialog.java @@ -49,8 +49,8 @@ import com.raytheon.uf.viz.core.drawables.IDescriptor; import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.globals.IGlobalChangedListener; import com.raytheon.uf.viz.core.globals.VizGlobalsManager; -import com.raytheon.uf.viz.core.maps.scales.MapScales; -import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.IResourceGroup; import com.raytheon.uf.viz.core.rsc.ResourceList; @@ -75,9 +75,10 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 8, 2009 bgonzale Initial creation + * Apr 8, 2009 bgonzale Initial creation * Oct 16, 2012 1229 rferrel Made dialog non-blocking. * Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d + * Oct 10, 2013 2104 mschenke Switched to use MapScalesManager * * * @@ -254,16 +255,16 @@ public class DisplayPropertiesDialog extends CaveSWTDialog { } }; int maxSize = 0; - MapScale[] mScales = MapScales.getInstance().getScales(); - String[] scales = new String[mScales.length]; - for (int i = 0; i < scales.length; ++i) { - scales[i] = mScales[i].getDisplayName(); - if (scales[i].length() > maxSize) { - maxSize = scales[i].length(); + List scales = new ArrayList(); + for (ManagedMapScale scale : MapScalesManager.getInstance().getScales()) { + String displayName = scale.getDisplayName(); + scales.add(displayName); + if (displayName.length() > maxSize) { + maxSize = displayName.length(); } } - scale = createComboBox(parent, "Scale:", scales, + scale = createComboBox(parent, "Scale:", scales.toArray(new String[0]), String.valueOf(getCurrentValue(VizConstants.SCALE_ID)), listener); } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/SideView.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/SideView.java index a5341204fb..980f4b02e8 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/SideView.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/SideView.java @@ -20,7 +20,6 @@ package com.raytheon.uf.viz.d2d.ui.map; -import java.io.File; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -37,7 +36,6 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; import com.raytheon.uf.common.serialization.SerializationException; -import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -53,9 +51,8 @@ import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.globals.VizGlobalsManager; -import com.raytheon.uf.viz.core.maps.scales.MapScales; -import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; -import com.raytheon.uf.viz.core.maps.scales.MapScales.PartId; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale; import com.raytheon.uf.viz.core.procedures.Bundle; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.IInputHandler; @@ -98,7 +95,8 @@ import com.vividsolutions.jts.geom.Coordinate; * swapped to side panel * Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d * Aug 9, 2013 DR 16427 D. Friedman Swap additional input handlers. - * + * Oct 10, 2013 #2104 mschenke Switched to use MapScalesManager + * * * * @author chammack @@ -143,29 +141,17 @@ public class SideView extends ViewPart implements IMultiPaneEditor, String myId = site.getId() + UiUtil.SECONDARY_ID_SEPARATOR + site.getSecondaryId(); - for (MapScale scale : MapScales.getInstance().getScales()) { - boolean myScale = false; - for (PartId partId : scale.getPartIds()) { - if (partId.isView() && myId.equals(partId.getId())) { - myScale = true; - break; - } - } - if (myScale) { - File file = scale.getFile(); - try { - Bundle b = (Bundle) SerializationUtil - .jaxbUnmarshalFromXmlFile(file); - b.setView(myId); - bundleToLoad = b; - } catch (SerializationException e) { - statusHandler.handle( - Priority.PROBLEM, - "Error deserializing bundle: " - + file.getAbsolutePath(), e); - } - break; + for (ManagedMapScale scale : MapScalesManager.getInstance() + .getScalesForPart(myId)) { + try { + Bundle b = scale.getScaleBundle(); + b.setView(myId); + bundleToLoad = b; + } catch (SerializationException e) { + statusHandler.handle(Priority.PROBLEM, + "Error deserializing bundle for scale: " + scale, e); } + break; } } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/actions/ScaleHandler.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/actions/ScaleHandler.java index c74403a186..ee8c3a8ea5 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/actions/ScaleHandler.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/map/actions/ScaleHandler.java @@ -20,31 +20,19 @@ package com.raytheon.uf.viz.d2d.ui.map.actions; -import java.io.File; -import java.util.ArrayList; -import java.util.List; - import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; -import com.raytheon.uf.common.serialization.SerializationException; -import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.IDisplayPaneContainer; -import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; -import com.raytheon.uf.viz.core.drawables.ResourcePair; -import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; import com.raytheon.uf.viz.core.globals.VizGlobalsManager; -import com.raytheon.uf.viz.core.map.IMapDescriptor; import com.raytheon.uf.viz.core.maps.actions.NewMapEditor; -import com.raytheon.uf.viz.core.maps.scales.MapScales; -import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; -import com.raytheon.uf.viz.core.procedures.Bundle; -import com.raytheon.uf.viz.d2d.core.map.D2DMapRenderableDisplay; +import com.raytheon.uf.viz.core.maps.scales.IMapScaleDisplay; import com.raytheon.viz.ui.EditorUtil; /** @@ -57,6 +45,7 @@ import com.raytheon.viz.ui.EditorUtil; * Jul 24, 2007 randerso Initial Creation. * Oct 21, 2008 #1450 randerso Fixed to support multipane editors * Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d + * Oct 9, 2013 2104 mschenke Switched to use logic in the IMapScaleDisplay * * * @@ -107,92 +96,14 @@ public class ScaleHandler extends AbstractHandler { statusHandler.handle(Priority.PROBLEM, "Could not set scale on null editor"); } - MapScale mapScale = MapScales.getInstance().getScaleByName(scale); - if (mapScale == null) { - statusHandler.handle(Priority.PROBLEM, - "Could not find scale with name: " + scale); - } else { - File scaleBundle = mapScale.getFile(); - if (scaleBundle == null || scaleBundle.exists() == false - || scaleBundle.isFile() == false) { - statusHandler.handle(Priority.PROBLEM, - "Could not find scale file: " + mapScale.getFileName()); - } else { - try { - Object obj = SerializationUtil - .jaxbUnmarshalFromXmlFile(scaleBundle); - if (obj instanceof Bundle == false) { - throw new SerializationException( - "Deserialized object is not of type " - + Bundle.class); - } - Bundle b = (Bundle) obj; - AbstractRenderableDisplay[] displays = b.getDisplays(); - if (displays.length != 1) { - throw new VizException( - "Scale bundle must have exactly 1 renderable display, " - + scaleBundle.getAbsolutePath() - + " had " + displays.length); - } - if (displays[0] instanceof D2DMapRenderableDisplay == false) { - throw new VizException("Bundle, " - + scaleBundle.getAbsolutePath() - + ", is not a valid D2D map scale bundle"); - } - - D2DMapRenderableDisplay rd = (D2DMapRenderableDisplay) displays[0]; - - for (IDisplayPane pane : editor.getDisplayPanes()) { - D2DMapRenderableDisplay existingDisplay = (D2DMapRenderableDisplay) pane - .getRenderableDisplay(); - IMapDescriptor existingMD = existingDisplay - .getDescriptor(); - - // set the projection - existingMD.setGridGeometry(rd.getDescriptor() - .getGridGeometry()); - pane.setZoomLevel(1.0f); - pane.scaleToClientArea(); - - // set the scale name - existingDisplay.setScale(mapScale.getDisplayName()); - - // remove the existing map resources - List remove = new ArrayList(); - for (ResourcePair rp : existingMD.getResourceList()) { - // if resource is not a map layer add it to the new - // md - if (rp.getProperties().isMapLayer()) { - remove.add(rp); - } - } - existingMD.getResourceList().removeAll(remove); - - // add the new map resources - for (ResourcePair rp : rd.getDescriptor() - .getResourceList()) { - if (rp.getProperties().isMapLayer()) { - if (rp.getResource() == null) { - rp.instantiateResource(existingMD); - } - existingMD.getResourceList().add(rp); - } - } - } - - VizGlobalsManager.getCurrentInstance().updateUI(editor); - } catch (SerializationException e) { - statusHandler.handle( - Priority.PROBLEM, - "Error deserializing file: " - + scaleBundle.getAbsolutePath(), e); - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, - "Error loading scale bundle", e); - } + for (IDisplayPane pane : editor.getDisplayPanes()) { + IRenderableDisplay display = pane.getRenderableDisplay(); + if (display instanceof IMapScaleDisplay) { + ((IMapScaleDisplay) display).changeScale(scale); } } - } + VizGlobalsManager.getCurrentInstance().updateUI(editor); + } } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/perspectives/D2D5Pane.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/perspectives/D2D5Pane.java index ab513bb020..ec089f16a9 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/perspectives/D2D5Pane.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/perspectives/D2D5Pane.java @@ -30,9 +30,9 @@ import org.eclipse.ui.IFolderLayout; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; -import com.raytheon.uf.viz.core.maps.scales.MapScales; -import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; import com.raytheon.uf.viz.core.maps.scales.MapScales.PartId; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale; import com.raytheon.uf.viz.d2d.ui.actions.ChangeD2DLayoutAction; import com.raytheon.uf.viz.d2d.ui.map.SideView; import com.raytheon.viz.ui.UiUtil; @@ -50,6 +50,7 @@ import com.raytheon.viz.ui.UiUtil; * ------------ ---------- ----------- -------------------------- * 7/1/06 chammack Initial Creation. * Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d + * Oct 10, 2013 2104 mschenke Switched to use MapScalesManager * * * @@ -83,7 +84,7 @@ public class D2D5Pane implements IPerspectiveFactory { List baseViewsToAdd = new ArrayList(); Set addedViews = new HashSet(); - for (MapScale scale : MapScales.getInstance().getScales()) { + for (ManagedMapScale scale : MapScalesManager.getInstance().getScales()) { for (PartId part : scale.getPartIds()) { if (part.getId().startsWith(BASE_VIEW_ID_PREFIX) && baseViewsToAdd.contains(part.getId()) == false) { @@ -122,7 +123,7 @@ public class D2D5Pane implements IPerspectiveFactory { addedViews.addAll(baseViewsToAdd); List extraViews = new ArrayList(); - for (MapScale scale : MapScales.getInstance().getScales()) { + for (ManagedMapScale scale : MapScalesManager.getInstance().getScales()) { for (PartId part : scale.getPartIds()) { if (part.isView() && addedViews.contains(part.getId()) == false) { extraViews.add(part.getId()); diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/perspectives/D2DPerspectiveManager.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/perspectives/D2DPerspectiveManager.java index ddbf1b3280..0e5dd64980 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/perspectives/D2DPerspectiveManager.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/perspectives/D2DPerspectiveManager.java @@ -40,7 +40,7 @@ import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.map.MapDescriptor; import com.raytheon.uf.viz.core.maps.actions.NewMapEditor; -import com.raytheon.uf.viz.core.maps.scales.MapScales; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.ResourceList; import com.raytheon.uf.viz.core.rsc.capabilities.BlendableCapability; @@ -87,6 +87,7 @@ import com.raytheon.viz.ui.statusline.FrameCountDisplay; * ------------ ---------- ----------- -------------------------- * 04/27/2010 mschenke Initial Creation. * Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d + * Oct 10, 2013 2104 mschenke Switched to use MapScalesManager * * * @author mschenke @@ -114,7 +115,7 @@ public class D2DPerspectiveManager extends AbstractCAVEPerspectiveManager { public void open() { contextActivator = new D2DContextActivator(page); try { - MapScales.loadScales(perspectiveWindow); + MapScalesManager.getInstance().loadEditorScales(perspectiveWindow); } catch (VizException e) { statusHandler.handle(Priority.PROBLEM, "Error loading bundles to screen", e); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/AreaComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/AreaComp.java index 66152eac1f..3a1b2d8422 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/AreaComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/AreaComp.java @@ -19,7 +19,6 @@ **/ package com.raytheon.uf.viz.datadelivery.common.ui; -import java.io.File; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; @@ -49,14 +48,13 @@ import com.raytheon.uf.common.datadelivery.registry.EnvelopeUtils; import com.raytheon.uf.common.geospatial.MapUtil; import com.raytheon.uf.common.localization.LocalizationFile; import com.raytheon.uf.common.serialization.SerializationException; -import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; import com.raytheon.uf.viz.core.map.IMapDescriptor; -import com.raytheon.uf.viz.core.maps.scales.MapScales; -import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager; +import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale; import com.raytheon.uf.viz.core.procedures.Bundle; import com.raytheon.uf.viz.datadelivery.common.xml.AreaXML; import com.raytheon.uf.viz.datadelivery.subscription.subset.IDataSize; @@ -93,6 +91,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Jun 14, 2013 2064 mpduff Reset controls on load. * Jun 21, 2013 2132 mpduff Swap target and source envelopes. * Jul 12, 2013 2141 mpduff Valid envelope test happens as needed instead of when changes are made. + * Oct 10, 2013 2104 mschenke Switched to use MapScalesManager * * * @@ -266,8 +265,7 @@ public class AreaComp extends Composite implements ISubset { * Setup the data. */ private void setupData() { - MapScales mapScales = MapScales.getInstance(); - MapScale[] scales = mapScales.getScales(); + ManagedMapScale[] scales = MapScalesManager.getInstance().getScales(); predefinedRegions = new String[scales.length]; for (int i = 0; i < predefinedRegions.length; i++) { predefinedRegions[i] = scales[i].getDisplayName(); @@ -661,13 +659,12 @@ public class AreaComp extends Composite implements ISubset { String name = regionCombo.getItem(regionCombo.getSelectionIndex()); if (!isUserDefinedRegion()) { - MapScale mapScale = MapScales.getInstance().getScaleByName(name); + ManagedMapScale mapScale = MapScalesManager.getInstance() + .getScaleByName(name); if (mapScale != null) { - File scaleBundle = mapScale.getFile(); try { - Bundle b = SerializationUtil.jaxbUnmarshalFromXmlFile( - Bundle.class, scaleBundle); + Bundle b = mapScale.getScaleBundle(); AbstractRenderableDisplay[] displays = b.getDisplays(); IMapDescriptor descriptor = (IMapDescriptor) displays[0] diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java index 091c824fa0..44005615b2 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java @@ -86,7 +86,6 @@ import org.eclipse.ui.part.ViewPart; import com.raytheon.uf.common.localization.FileUpdatedMessage; import com.raytheon.uf.common.localization.FileUpdatedMessage.FileChangeType; -import com.raytheon.uf.common.localization.ILocalizationFileObserver; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; @@ -134,6 +133,8 @@ import com.raytheon.uf.viz.localization.service.ILocalizationService; * objects even if they weren't expanded * May 1, 2013 1967 njensen Fix for pydev 2.7 * Sep 17, 2013 2285 mschenke Made openFile refresh items if file not found + * Oct 9, 2013 2104 mschenke Fixed file delete/add refresh issue and file change message + * found when testing scalesInfo.xml file * * * @@ -142,8 +143,7 @@ import com.raytheon.uf.viz.localization.service.ILocalizationService; */ public class FileTreeView extends ViewPart implements IPartListener2, - ILocalizationFileObserver, ILocalizationService, - IResourceChangeListener { + ILocalizationService, IResourceChangeListener { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(FileTreeView.class); @@ -201,6 +201,58 @@ public class FileTreeView extends ViewPart implements IPartListener2, } + private class FileUpdateRefresher implements Runnable { + + private final LocalizationFile file; + + private final FileChangeType type; + + public FileUpdateRefresher(LocalizationFile file, FileChangeType type) { + this.file = file; + this.type = type; + } + + @Override + public void run() { + // Find and refresh file in tree + for (TreeItem appItem : getTree().getItems()) { + for (TreeItem rootItem : appItem.getItems()) { + TreeItem found = find(rootItem, file.getContext(), + file.getName(), false); + if (found != null) { + // File found. If updated, set the time stamp to that of + // the file to avoid modification change discrepancies + if (type == FileChangeType.UPDATED) { + if (found.getData() instanceof LocalizationFileGroupData) { + for (LocalizationFileEntryData data : ((LocalizationFileGroupData) found + .getData()).getChildrenData()) { + if (data.getFile().equals(file)) { + try { + data.getResource() + .setLocalTimeStamp( + file.getTimeStamp() + .getTime()); + } catch (CoreException e) { + statusHandler + .handle(Priority.INFO, + "Could not update workspace file timestamp: " + + e.getLocalizedMessage(), + e); + } + } + } + } + } else { + // ADD/DELETE, refresh the file + refresh(found); + } + } + } + } + } + + } + /** Flag for linking view to active editor */ private boolean linkWithEditor = true; @@ -1388,23 +1440,25 @@ public class FileTreeView extends ViewPart implements IPartListener2, private TreeItem find(TreeItem item, LocalizationContext ctx, String path, boolean populateToFind) { FileTreeEntryData data = (FileTreeEntryData) item.getData(); - String itemPath = data.getPath(); - if (path.startsWith(itemPath)) { - if (path.equals(itemPath) - || (data.hasRequestedChildren() == false && !populateToFind)) { - return item; - } else { - if (data.hasRequestedChildren() == false) { - populateNode(item); - } - for (TreeItem child : item.getItems()) { - TreeItem rval = find(child, ctx, path, populateToFind); - if (rval != null) { - return rval; + if (data.getPathData().getType() == ctx.getLocalizationType()) { + String itemPath = data.getPath(); + if (path.startsWith(itemPath)) { + if (path.equals(itemPath) + || (data.hasRequestedChildren() == false && !populateToFind)) { + return item; + } else { + if (data.hasRequestedChildren() == false) { + populateNode(item); + } + for (TreeItem child : item.getItems()) { + TreeItem rval = find(child, ctx, path, populateToFind); + if (rval != null) { + return rval; + } } } + return item; } - return item; } return null; } @@ -1506,34 +1560,19 @@ public class FileTreeView extends ViewPart implements IPartListener2, String filePath = message.getFileName(); IPathManager pathManager = PathManagerFactory.getPathManager(); - final FileChangeType type = message.getChangeType(); - final LocalizationFile file = pathManager.getLocalizationFile(context, + FileChangeType type = message.getChangeType(); + LocalizationFile file = pathManager.getLocalizationFile(context, filePath); - if ((file.exists() == false && (type == FileChangeType.ADDED || type == FileChangeType.UPDATED)) - || (file.exists() && type == FileChangeType.DELETED)) { - System.out.println("Got weird state in update for " + file - + ": exists=" + file.exists() + ", changeType=" - + message.getChangeType()); - } - if (file != null) { - VizApp.runAsync(new Runnable() { - @Override - public void run() { - // Only get closest parent if file added - TreeItem toRefresh = find(file, false, - type == FileChangeType.ADDED); - if (toRefresh != null) { - if (type == FileChangeType.DELETED) { - // If deleted, we found the actual item that was - // deleted, we should refresh it's parent - toRefresh = toRefresh.getParentItem(); - } - refresh(toRefresh); - } - } - }); + if ((file.exists() == false && (type == FileChangeType.ADDED || type == FileChangeType.UPDATED)) + || (file.exists() && type == FileChangeType.DELETED)) { + System.out.println("Got weird state in update for " + file + + ": exists=" + file.exists() + ", changeType=" + + message.getChangeType()); + } + + VizApp.runAsync(new FileUpdateRefresher(file, type)); } } diff --git a/cave/com.raytheon.viz.satellite/src/com/raytheon/viz/satellite/rsc/SatBestResResourceData.java b/cave/com.raytheon.viz.satellite/src/com/raytheon/viz/satellite/rsc/SatBestResResourceData.java index def4e8f333..67ff743ea4 100644 --- a/cave/com.raytheon.viz.satellite/src/com/raytheon/viz/satellite/rsc/SatBestResResourceData.java +++ b/cave/com.raytheon.viz.satellite/src/com/raytheon/viz/satellite/rsc/SatBestResResourceData.java @@ -19,9 +19,7 @@ **/ package com.raytheon.viz.satellite.rsc; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; @@ -29,17 +27,15 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; -import org.geotools.referencing.CRS; -import org.geotools.referencing.operation.transform.ConcatenatedTransform; -import org.opengis.referencing.operation.MathTransform; +import org.geotools.coverage.grid.GeneralGridGeometry; +import org.geotools.coverage.grid.GridGeometry2D; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataquery.requests.DbQueryRequest; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; -import com.raytheon.uf.common.geospatial.BoundaryTool; -import com.raytheon.uf.common.geospatial.ISpatialObject; -import com.raytheon.uf.common.geospatial.MapUtil; +import com.raytheon.uf.common.geospatial.IGridGeometryProvider; +import com.raytheon.uf.common.geospatial.util.EnvelopeIntersection; import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.viz.core.drawables.IDescriptor; import com.raytheon.uf.viz.core.drawables.ResourcePair; @@ -55,6 +51,7 @@ import com.raytheon.uf.viz.core.rsc.ProgressiveDisclosureProperties; import com.raytheon.uf.viz.core.rsc.ResourceList; import com.raytheon.viz.satellite.SatelliteDataCubeAdapter; import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Polygon; @@ -70,6 +67,7 @@ import com.vividsolutions.jts.geom.Polygon; * Jul 30, 2010 mschenke Initial creation * Oct 31, 2012 DR 15287 D. Friedman Fix overlap calculation * Nov 06, 2012 DR 15157 D. Friedman Allow configured inclusion percentage + * Oct 10, 2013 2104 mschenke Fixed broken percentage calculation * * * @@ -121,10 +119,10 @@ public class SatBestResResourceData extends AbstractRequestableResourceData { public ResourcePair getResourceToDraw(IDescriptor descriptor) throws VizException { - double minX = descriptor.getGridGeometry().getGridRange().getLow(0); - double minY = descriptor.getGridGeometry().getGridRange().getLow(1); - double maxX = descriptor.getGridGeometry().getGridRange().getHigh(0); - double maxY = descriptor.getGridGeometry().getGridRange().getHigh(1); + double minX = descriptor.getGridGeometry().getEnvelope().getMinimum(0); + double minY = descriptor.getGridGeometry().getEnvelope().getMinimum(1); + double maxX = descriptor.getGridGeometry().getEnvelope().getMaximum(0); + double maxY = descriptor.getGridGeometry().getEnvelope().getMaximum(1); GeometryFactory gf = new GeometryFactory(); Coordinate first = new Coordinate(minX, minY); Polygon extent = gf.createPolygon( @@ -148,21 +146,19 @@ public class SatBestResResourceData extends AbstractRequestableResourceData { int displayWidth = ((IMapDescriptor) descriptor).getMapWidth(); - int i = 0; for (ResourcePair rp : resourceList) { props = rp.getProperties().getPdProps(); if (props != null && props.isDisclosed(displayWidth)) { disclosedResource = rp; break; } - ++i; } } Map percentOfIntersection = new HashMap(); if (disclosedResource != null) { - final double inclusionPercentageToUse = inclusionFactor != null ? - inclusionFactor : DESIRED_PERCENTAGE; + final double inclusionPercentageToUse = inclusionFactor != null ? inclusionFactor + : DESIRED_PERCENTAGE; // check inclusion percentage of the disclosed resource Double inclusion = getInclusionPercentage(descriptor, disclosedResource, extent); @@ -302,55 +298,47 @@ public class SatBestResResourceData extends AbstractRequestableResourceData { private double getInclusionPercentage(IDescriptor descriptor, ResourcePair rp, Polygon extent) throws VizException { Double totalPercentage = Double.NaN; - MathTransform crsToScreen = null; + GeneralGridGeometry targetGeometry = descriptor.getGridGeometry(); try { - crsToScreen = descriptor.getGridGeometry().getGridToCRS().inverse(); - } catch (Exception e1) { - throw new VizException(e1); - } - if (crsToScreen != null) { - try { - AbstractRequestableResourceData aard = (AbstractRequestableResourceData) rp - .getResourceData(); - DbQueryRequest request = new DbQueryRequest(); - Map copy = new HashMap( - aard.getMetadataMap()); - copy.remove(SatelliteDataCubeAdapter.DERIVED); - request.setConstraints(copy); - request.addRequestField("coverage"); - request.setDistinct(true); - DbQueryResponse response = (DbQueryResponse) ThriftClient - .sendRequest(request); - List prevs = new ArrayList(); - for (Map result : response.getResults()) { - ISpatialObject so = (ISpatialObject) result.get("coverage"); - MathTransform gridToScreen = ConcatenatedTransform.create( - MapUtil.getGridGeometry(so).getGridToCRS(), - ConcatenatedTransform.create(CRS.findMathTransform( - so.getCrs(), descriptor.getCRS()), - crsToScreen)); - Polygon polygon = BoundaryTool.calculateBoundaryGeometry( - gridToScreen, 0, 0, so.getNx(), so.getNy(), false, - Math.max(1, so.getNx() / 100), - Math.max(1, so.getNy() / 100)); - Double percentage = polygon.intersection(extent).getArea() - / extent.getArea(); - if (prevs.size() == 0) { - totalPercentage = percentage; - } else { - totalPercentage += percentage; + AbstractRequestableResourceData aard = (AbstractRequestableResourceData) rp + .getResourceData(); + DbQueryRequest request = new DbQueryRequest(); + Map copy = new HashMap( + aard.getMetadataMap()); + copy.remove(SatelliteDataCubeAdapter.DERIVED); + request.setConstraints(copy); + request.addRequestField("coverage"); + request.setDistinct(true); + DbQueryResponse response = (DbQueryResponse) ThriftClient + .sendRequest(request); + Geometry area = null; + for (Map result : response.getResults()) { + IGridGeometryProvider provider = (IGridGeometryProvider) result + .get("coverage"); + GridGeometry2D gridGeometry = provider.getGridGeometry(); - for (Polygon last : prevs) { - // Don't want to double include percentage areas - totalPercentage -= last.intersection(polygon).intersection(extent) - .getArea() / extent.getArea(); - } - } - prevs.add(polygon); + double envWidth = gridGeometry.getEnvelope().getSpan(0); + double envHeight = gridGeometry.getEnvelope().getSpan(1); + double threshold = targetGeometry.getEnvelope().getSpan(0) + / targetGeometry.getGridRange().getSpan(0); + + Geometry intersection = EnvelopeIntersection + .createEnvelopeIntersection(gridGeometry.getEnvelope(), + targetGeometry.getEnvelope(), threshold, + (int) (envWidth / 100.0), + (int) (envHeight / 100.0)); + if (area == null) { + area = intersection; + } else { + area = area.union(intersection); } - } catch (Exception e) { - e.printStackTrace(); } + if (area != null) { + totalPercentage = area.intersection(extent).getArea() + / extent.getArea(); + } + } catch (Exception e) { + e.printStackTrace(); } return totalPercentage; } diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/ScaleButtonHandler.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/ScaleButtonHandler.java index 2d86b43371..9e17ebbea2 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/ScaleButtonHandler.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/actions/ScaleButtonHandler.java @@ -22,6 +22,8 @@ */ package com.raytheon.viz.ui.actions; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.commands.IElementUpdater; import org.eclipse.ui.menus.UIElement; @@ -37,6 +39,7 @@ import com.raytheon.uf.viz.core.globals.IGlobalChangedListener; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jul 23, 2007 randerso Initial Creation. + * Oct 10, 2013 2104 mschenke Will truncate text if too long * * @author randerso * @@ -44,6 +47,8 @@ import com.raytheon.uf.viz.core.globals.IGlobalChangedListener; public class ScaleButtonHandler extends AbstractGlobalsButtonHandler implements IElementUpdater, IGlobalChangedListener { + private static final int TEXT_LIMIT = 100; + public ScaleButtonHandler() { super(VizConstants.SCALE_ID); } @@ -52,7 +57,25 @@ public class ScaleButtonHandler extends AbstractGlobalsButtonHandler implements protected void updateGlobalValue(IWorkbenchWindow changedWindow, UIElement element, Object value) { String scale = (String) value; + String tooltip = scale; + + GC gc = new GC(Display.getCurrent()); + if (gc.textExtent(scale).x > TEXT_LIMIT) { + String suffix = "..."; + String text = scale.substring(0, suffix.length()) + suffix; + for (int i = suffix.length() + 1; i < scale.length(); ++i) { + String test = scale.substring(0, i) + suffix; + if (gc.textExtent(test).x < TEXT_LIMIT) { + text = test; + } else { + break; + } + } + scale = text; + } + gc.dispose(); element.setText(scale); + element.setTooltip("Scale: " + tooltip); } } diff --git a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/util/EnvelopeIntersection.java b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/util/EnvelopeIntersection.java index 2a32ccf26f..268f65b553 100644 --- a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/util/EnvelopeIntersection.java +++ b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/util/EnvelopeIntersection.java @@ -55,6 +55,8 @@ import com.vividsolutions.jts.geom.Polygon; * Sep 13, 2013 2309 bsteffen Corrected Lines that are extrapolated to * intersect the border will use projection * factor from all 4 corners instead of 3. + * Oct 8, 2013 2104 mschenke Added case for where actual border is + * inside out by checking interior point * * * @@ -69,7 +71,8 @@ public class EnvelopeIntersection { /** * Computes an intersection {@link Geometry} between sourceEnvelope and * targetEnvelope in targetEnvelope's CRS space. The resulting - * {@link Geometry} may contain multiple Geometries within it + * {@link Geometry} may contain multiple Geometries within it. But all + * geometries will be {@link Polygon}s * * @param sourceEnvelope * @param targetEnvelope @@ -88,10 +91,25 @@ public class EnvelopeIntersection { MathTransform sourceCRSToTargetCRS = CRS.findMathTransform( sourceREnvelope.getCoordinateReferenceSystem(), targetREnvelope.getCoordinateReferenceSystem()); + MathTransform targetCRSToSourceCRS = sourceCRSToTargetCRS.inverse(); MathTransform targetCRSToLatLon = MapUtil .getTransformToLatLon(targetREnvelope .getCoordinateReferenceSystem()); + // Create Polygon representing target envelope + Coordinate ul = new Coordinate(targetREnvelope.getMinimum(0), + targetREnvelope.getMinimum(1)); + Coordinate ur = new Coordinate(targetREnvelope.getMaximum(0), + targetREnvelope.getMinimum(1)); + Coordinate lr = new Coordinate(targetREnvelope.getMaximum(0), + targetREnvelope.getMaximum(1)); + Coordinate ll = new Coordinate(targetREnvelope.getMinimum(0), + targetREnvelope.getMaximum(1)); + + Polygon targetBorder = gf.createPolygon( + gf.createLinearRing(new Coordinate[] { ul, ur, lr, ll, ul }), + null); + double midY = sourceREnvelope.getMinimum(1) + (sourceREnvelope.getSpan(1) / 2.0); double[] UL = new double[] { sourceREnvelope.getMinimum(0), @@ -198,22 +216,9 @@ public class EnvelopeIntersection { // This may happen if more than one valid line string found or // correcting the single line string produced invalid geometries and // therefore the border is empty - MathTransform targetCRSToSourceCRS = sourceCRSToTargetCRS.inverse(); + // Here we check for a simple case where entire target CRS is within // source CRS making border equivalent to target CRS border - Coordinate ul = new Coordinate(targetREnvelope.getMinimum(0), - targetREnvelope.getMinimum(1)); - Coordinate ur = new Coordinate(targetREnvelope.getMaximum(0), - targetREnvelope.getMinimum(1)); - Coordinate lr = new Coordinate(targetREnvelope.getMaximum(0), - targetREnvelope.getMaximum(1)); - Coordinate ll = new Coordinate(targetREnvelope.getMinimum(0), - targetREnvelope.getMaximum(1)); - - Polygon targetBorder = gf.createPolygon(gf - .createLinearRing(new Coordinate[] { ul, ur, lr, ll, ul }), - null); - // Convert corner points of target envelope into source envelope // space boolean bad = false; @@ -482,7 +487,7 @@ public class EnvelopeIntersection { } } - if ((border == null || border.isEmpty() || border.isValid() == false)) { + if (border == null || border.isEmpty() || border.isValid() == false) { if (correctedPolygon != null) { // buffering will make an invalid polygon valid. This is known // to be the correct action for rounded grids such as lat/lon @@ -503,9 +508,23 @@ public class EnvelopeIntersection { border = gf.createGeometryCollection(envelopes .toArray(new Geometry[0])); } + } else if (border instanceof Polygon) { + // Simple polygonal border, ensure it accurately represents our + // source envelope by checking interior point + Coordinate interior = JTS.transform(border.getInteriorPoint(), + targetCRSToSourceCRS).getCoordinate(); + if (sourceEnvelope.getMinimum(0) > interior.x + || sourceEnvelope.getMaximum(0) < interior.x + || sourceEnvelope.getMinimum(1) > interior.y + || sourceEnvelope.getMaximum(1) < interior.y) { + // Interior point does not fall inside the source envelope, use + // the difference of the border + border = targetBorder.difference(border); + } } - return border; + // Convert border to polygonal based geometry (Polygon or MultiPolygon) + return toPolygonal(border); } private static void extractLineStrings(List lines, Geometry geom) { @@ -610,4 +629,30 @@ public class EnvelopeIntersection { } return new ReferencedEnvelope(envelope); } + + private static Geometry toPolygonal(Geometry geometry) { + if (geometry instanceof Polygon == false) { + List polygons = new ArrayList( + geometry.getNumGeometries()); + buildPolygonList(polygons, geometry); + if (polygons.size() == 1) { + geometry = polygons.get(0); + } else { + geometry = gf.createMultiPolygon(polygons + .toArray(new Polygon[0])); + } + } + return geometry; + } + + private static void buildPolygonList(List polygons, + Geometry geometry) { + if (geometry instanceof Polygon) { + polygons.add((Polygon) geometry); + } else { + for (int n = 0; n < geometry.getNumGeometries(); ++n) { + buildPolygonList(polygons, geometry.getGeometryN(n)); + } + } + } }