Issue #1141 - Merging KML into the Common Baseline
Former-commit-id:7b45633097
[formerly c3f584fdc5f53ecd62afe41c481aaa96cf532009] Former-commit-id:3180ae0c57
This commit is contained in:
parent
35aff16e89
commit
8d444b35d3
56 changed files with 6755 additions and 1 deletions
|
@ -112,6 +112,10 @@
|
|||
<copy todir="${buildDirectory}/plugins">
|
||||
<fileset dir="${buildDirectory}/../../../" includes="edu.*/**"/>
|
||||
</copy>
|
||||
<echo message="de.*/**"/>
|
||||
<copy todir="${buildDirectory}/plugins">
|
||||
<fileset dir="${buildDirectory}/../../../" includes="de.*/**"/>
|
||||
</copy>
|
||||
<antcall target="getBaseComponents" />
|
||||
</target>
|
||||
|
||||
|
|
|
@ -107,6 +107,12 @@
|
|||
<fileset dir="${workspace.dir}"
|
||||
includes="edu.*/**" />
|
||||
</copy>
|
||||
|
||||
<echo message="PLUGINS: de.*/**" />
|
||||
<copy todir="${basedir}/cave/p2/plugins">
|
||||
<fileset dir="${workspace.dir}"
|
||||
includes="de.*/**" />
|
||||
</copy>
|
||||
<!-- END: Copy The Plugins -->
|
||||
|
||||
<!-- Copy The Features -->
|
||||
|
@ -266,7 +272,11 @@
|
|||
<param name="feature"
|
||||
value="com.raytheon.uf.viz.thinclient.feature" />
|
||||
</antcall>
|
||||
|
||||
<antcall target="p2.build.repo">
|
||||
<param name="feature"
|
||||
value="com.raytheon.uf.viz.kml.export.feature" />
|
||||
</antcall>
|
||||
|
||||
<antcall target="cleanup.features" />
|
||||
</target>
|
||||
|
||||
|
|
11
cave/com.raytheon.uf.viz.kml.export.feature/.project
Normal file
11
cave/com.raytheon.uf.viz.kml.export.feature/.project
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.kml.export.feature</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
</natures>
|
||||
</projectDescription>
|
1
cave/com.raytheon.uf.viz.kml.export.feature/build.properties
Executable file
1
cave/com.raytheon.uf.viz.kml.export.feature/build.properties
Executable file
|
@ -0,0 +1 @@
|
|||
bin.includes = feature.xml
|
32
cave/com.raytheon.uf.viz.kml.export.feature/feature.xml
Executable file
32
cave/com.raytheon.uf.viz.kml.export.feature/feature.xml
Executable file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feature
|
||||
id="com.raytheon.uf.viz.kml.export.feature"
|
||||
label="Kml Export Feature"
|
||||
version="1.0.0.qualifier">
|
||||
|
||||
<description url="http://www.example.com/description">
|
||||
[Enter Feature Description here.]
|
||||
</description>
|
||||
|
||||
<copyright url="http://www.example.com/copyright">
|
||||
[Enter Copyright Description here.]
|
||||
</copyright>
|
||||
|
||||
<license url="http://www.example.com/license">
|
||||
[Enter License Description here.]
|
||||
</license>
|
||||
|
||||
<plugin
|
||||
id="de.micromata.opengis.kml"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.viz.kml.export"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
7
cave/com.raytheon.uf.viz.kml.export/.classpath
Normal file
7
cave/com.raytheon.uf.viz.kml.export/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
cave/com.raytheon.uf.viz.kml.export/.project
Normal file
28
cave/com.raytheon.uf.viz.kml.export/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.kml.export</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,8 @@
|
|||
#Wed May 30 15:50:31 CDT 2012
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
27
cave/com.raytheon.uf.viz.kml.export/META-INF/MANIFEST.MF
Normal file
27
cave/com.raytheon.uf.viz.kml.export/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,27 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: KML Export
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.kml.export;singleton:=true
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Activator: com.raytheon.uf.viz.kml.export.Activator
|
||||
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
org.eclipse.core.runtime,
|
||||
com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
|
||||
org.geotools;bundle-version="2.6.4",
|
||||
com.raytheon.uf.viz.core;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.viz.core.rsc;bundle-version="1.0.0",
|
||||
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.colormap;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.time;bundle-version="1.12.1174",
|
||||
com.raytheon.viz.ui;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.viz.core.maps;bundle-version="1.12.1174",
|
||||
de.micromata.opengis.kml;bundle-version="1.0.0",
|
||||
com.raytheon.viz.pointdata;bundle-version="1.12.1174",
|
||||
com.raytheon.viz.radar;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.dataplugin.radar;bundle-version="1.0.0",
|
||||
javax.measure;bundle-version="1.0.0",
|
||||
javax.vecmath;bundle-version="1.3.1"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
5
cave/com.raytheon.uf.viz.kml.export/build.properties
Normal file
5
cave/com.raytheon.uf.viz.kml.export/build.properties
Normal file
|
@ -0,0 +1,5 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
plugin.xml
|
62
cave/com.raytheon.uf.viz.kml.export/plugin.xml
Normal file
62
cave/com.raytheon.uf.viz.kml.export/plugin.xml
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.4"?>
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="menu:export">
|
||||
<command
|
||||
commandId="com.raytheon.uf.viz.kml.export.exportKML"
|
||||
label="KML"
|
||||
style="push">
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
<command
|
||||
id="com.raytheon.uf.viz.kml.export.exportKML"
|
||||
name="Export KML">
|
||||
</command>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="com.raytheon.uf.viz.kml.export.KmlExportHandler"
|
||||
commandId="com.raytheon.uf.viz.kml.export.exportKML">
|
||||
</handler>
|
||||
</extension>
|
||||
<extension
|
||||
point="com.raytheon.uf.viz.core.graphicsExtension">
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.point.KmlPointImageExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.KmlSingleColorImageExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.KmlColormappedImageExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.KmlRasterImageExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.KmlMapMeshExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.radar.KmlRadialMeshExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.KmlMosaicImageExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.KmlMosaicMaxValImageExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.KmlMosaicOrderedImageExtension">
|
||||
</graphicsExtension>
|
||||
<graphicsExtension
|
||||
class="com.raytheon.uf.viz.kml.export.graphics.ext.KmlCanvasRenderingExtension">
|
||||
</graphicsExtension>
|
||||
</extension>
|
||||
</plugin>
|
|
@ -0,0 +1,50 @@
|
|||
package com.raytheon.uf.viz.kml.export;
|
||||
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class Activator extends AbstractUIPlugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "com.raytheon.uf.viz.kml.export"; //$NON-NLS-1$
|
||||
|
||||
// The shared instance
|
||||
private static Activator plugin;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
public Activator() {
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
plugin = null;
|
||||
super.stop(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static Activator getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,606 @@
|
|||
/**
|
||||
* 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.kml.export;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.layout.RowData;
|
||||
import org.eclipse.swt.layout.RowLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.FileDialog;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Layout;
|
||||
import org.eclipse.swt.widgets.MessageBox;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
import org.eclipse.swt.widgets.Tree;
|
||||
import org.eclipse.swt.widgets.TreeItem;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||
import com.raytheon.uf.viz.kml.export.KmlExportOptions.KmlExportTimeMode;
|
||||
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||
|
||||
/**
|
||||
* Allow user to select options for export and starts the KmlExportJob.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 5, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlExportDialog extends CaveSWTDialog {
|
||||
|
||||
private final KmlExportOptions options;
|
||||
|
||||
private Text locationText;
|
||||
|
||||
private Tree productTree;
|
||||
|
||||
private Button exportHiddenButton;
|
||||
|
||||
private Button exportMapsButton;
|
||||
|
||||
private Button shadeEarthButton;
|
||||
|
||||
private Button setTimesButton;
|
||||
|
||||
private Button timeSpanButton;
|
||||
|
||||
private Button timeStampButton;
|
||||
|
||||
private Button fillPlotsButton;
|
||||
|
||||
private Button selectedFramesButton;
|
||||
|
||||
private Button currentFramesButton;
|
||||
|
||||
private Button allFramesButton;
|
||||
|
||||
private Text framesFromText;
|
||||
|
||||
private Text framesToText;
|
||||
|
||||
public KmlExportDialog(Shell shell, KmlExportOptions options) {
|
||||
super(shell, SWT.RESIZE | SWT.DIALOG_TRIM);
|
||||
this.setText("Export KML");
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeComponents(Shell shell) {
|
||||
|
||||
Composite leftComposite = new Composite(shell, SWT.NONE);
|
||||
leftComposite.setLayoutData(new GridData(SWT.NONE, SWT.FILL, false,
|
||||
true));
|
||||
RowLayout layout = new RowLayout(SWT.VERTICAL);
|
||||
layout.fill = true;
|
||||
leftComposite.setLayout(layout);
|
||||
|
||||
Group locationGroup = new Group(leftComposite, SWT.NONE);
|
||||
initializeLocationGroup(locationGroup);
|
||||
|
||||
Group framesGroup = new Group(leftComposite, SWT.NONE);
|
||||
initializeFramesGroup(framesGroup);
|
||||
|
||||
Group optionsGroup = new Group(leftComposite, SWT.NONE);
|
||||
initializeOptionsGroup(optionsGroup);
|
||||
|
||||
// Group timeOptionsGroup = new Group(leftComposite, SWT.NONE);
|
||||
// initializeTimeOptionsGroup(timeOptionsGroup);
|
||||
|
||||
Group productsGroup = new Group(shell, SWT.NONE);
|
||||
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
gridData.widthHint = 250;
|
||||
productsGroup.setLayoutData(gridData);
|
||||
initializeProductsGroup(productsGroup);
|
||||
|
||||
Composite buttonComposite = new Composite(shell, SWT.NONE);
|
||||
gridData = new GridData(SWT.FILL, SWT.NONE, true, false, 2, 1);
|
||||
gridData.horizontalAlignment = SWT.CENTER;
|
||||
buttonComposite.setLayoutData(gridData);
|
||||
initializeButtons(buttonComposite);
|
||||
|
||||
populateProductTree();
|
||||
if (productTree.getItemCount() == 0) {
|
||||
// for the intial load change this option so there is something to
|
||||
// export.
|
||||
exportMapsButton.setSelection(true);
|
||||
populateProductTree();
|
||||
}
|
||||
|
||||
shell.pack();
|
||||
shell.setMinimumSize(shell.getSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Layout constructShellLayout() {
|
||||
GridLayout mainLayout = new GridLayout(2, false);
|
||||
mainLayout.marginHeight = 3;
|
||||
mainLayout.marginWidth = 3;
|
||||
return mainLayout;
|
||||
}
|
||||
|
||||
protected void initializeLocationGroup(Group group) {
|
||||
group.setLayout(new GridLayout(2, false));
|
||||
group.setText("Export Location");
|
||||
locationText = new Text(group, SWT.BORDER);
|
||||
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
gridData.widthHint = 250;
|
||||
locationText.setLayoutData(gridData);
|
||||
locationText.setText(options.getKmzFileLocation().getAbsolutePath());
|
||||
Button button = new Button(group, SWT.PUSH);
|
||||
button.setText("Browse ...");
|
||||
button.addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
selectDestinationFile();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void initializeFramesGroup(Group group) {
|
||||
group.setLayout(new GridLayout(5, false));
|
||||
group.setText("Export Location");
|
||||
|
||||
allFramesButton = new Button(group, SWT.RADIO);
|
||||
allFramesButton.setText("All Frames");
|
||||
GridData gridData = new GridData();
|
||||
gridData.horizontalSpan = 5;
|
||||
allFramesButton.setLayoutData(gridData);
|
||||
allFramesButton.setSelection(true);
|
||||
|
||||
currentFramesButton = new Button(group, SWT.RADIO);
|
||||
currentFramesButton.setText("Current Frame");
|
||||
gridData = new GridData();
|
||||
gridData.horizontalSpan = 5;
|
||||
currentFramesButton.setLayoutData(gridData);
|
||||
|
||||
selectedFramesButton = new Button(group, SWT.RADIO);
|
||||
selectedFramesButton.setText("Frames");
|
||||
|
||||
new Label(group, SWT.NONE).setText("from:");
|
||||
framesFromText = new Text(group, SWT.BORDER);
|
||||
gridData = new GridData();
|
||||
gridData.widthHint = 24;
|
||||
framesFromText.setLayoutData(gridData);
|
||||
framesFromText.setEnabled(false);
|
||||
framesFromText.setText("1");
|
||||
new Label(group, SWT.NONE).setText("to:");
|
||||
framesToText = new Text(group, SWT.BORDER);
|
||||
gridData = new GridData();
|
||||
gridData.widthHint = 24;
|
||||
framesToText.setLayoutData(gridData);
|
||||
framesToText.setEnabled(false);
|
||||
int numFrames = 1;
|
||||
for (KmlPane pane : options.getPanes()) {
|
||||
int frames = pane.getDisplay().getDescriptor().getFramesInfo()
|
||||
.getFrameCount();
|
||||
numFrames = Math.max(frames, numFrames);
|
||||
}
|
||||
framesToText.setText(Integer.toString(numFrames));
|
||||
selectedFramesButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
framesToText.setEnabled(selectedFramesButton.getSelection());
|
||||
framesFromText.setEnabled(selectedFramesButton.getSelection());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected void initializeOptionsGroup(Group group) {
|
||||
group.setText("Other Options");
|
||||
group.setLayout(new RowLayout(SWT.VERTICAL));
|
||||
exportHiddenButton = new Button(group, SWT.CHECK);
|
||||
exportHiddenButton.setText("Export Hidden");
|
||||
exportHiddenButton.setSelection(true);
|
||||
exportHiddenButton
|
||||
.setToolTipText("Include hidden products in the selection of products to export.");
|
||||
exportHiddenButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
populateProductTree();
|
||||
}
|
||||
});
|
||||
exportMapsButton = new Button(group, SWT.CHECK);
|
||||
exportMapsButton.setText("Export Maps");
|
||||
exportMapsButton.setSelection(false);
|
||||
exportMapsButton
|
||||
.setToolTipText("Include maps in the selection of products to export.");
|
||||
exportMapsButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
populateProductTree();
|
||||
}
|
||||
});
|
||||
shadeEarthButton = new Button(group, SWT.CHECK);
|
||||
shadeEarthButton.setText("Shade Earth");
|
||||
shadeEarthButton.setSelection(options.isShadeEarth());
|
||||
shadeEarthButton
|
||||
.setToolTipText("Hides the Google Earth surface imagery.");
|
||||
fillPlotsButton = new Button(group, SWT.CHECK);
|
||||
fillPlotsButton.setText("Show Background Tiles");
|
||||
fillPlotsButton.setSelection(options.isFillPlotBackground());
|
||||
fillPlotsButton
|
||||
.setToolTipText("Displays an opaque background tile behind point observations");
|
||||
}
|
||||
|
||||
protected void initializeTimeOptionsGroup(Group group) {
|
||||
group.setText("Time Options");
|
||||
group.setLayout(new RowLayout(SWT.VERTICAL));
|
||||
setTimesButton = new Button(group, SWT.CHECK);
|
||||
setTimesButton.setText("Set KML Time");
|
||||
setTimesButton
|
||||
.setSelection(options.getTimeMode() != KmlExportTimeMode.NONE);
|
||||
setTimesButton
|
||||
.setToolTipText("Causes Google Earth to display a time slider.");
|
||||
Composite timeComposite = new Composite(group, SWT.NONE);
|
||||
RowLayout layout = new RowLayout(SWT.VERTICAL);
|
||||
layout.marginLeft = 20;
|
||||
timeComposite.setLayout(layout);
|
||||
timeSpanButton = new Button(timeComposite, SWT.RADIO);
|
||||
timeSpanButton.setText("Time Span");
|
||||
timeSpanButton
|
||||
.setSelection(options.getTimeMode() != KmlExportTimeMode.TIME_STAMP);
|
||||
timeSpanButton.setEnabled(setTimesButton.getSelection());
|
||||
timeSpanButton
|
||||
.setToolTipText("Allow products to be visible over a time range.");
|
||||
timeStampButton = new Button(timeComposite, SWT.RADIO);
|
||||
timeStampButton.setText("Time Stamp");
|
||||
timeStampButton
|
||||
.setSelection(options.getTimeMode() == KmlExportTimeMode.TIME_STAMP);
|
||||
timeStampButton.setEnabled(setTimesButton.getSelection());
|
||||
timeStampButton
|
||||
.setToolTipText("Makes each product visible only at its exact valid time.");
|
||||
setTimesButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
timeSpanButton.setEnabled(setTimesButton.getSelection());
|
||||
timeStampButton.setEnabled(setTimesButton.getSelection());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected void initializeProductsGroup(Group group) {
|
||||
group.setText("Products");
|
||||
group.setLayout(new FillLayout());
|
||||
productTree = new Tree(group, SWT.CHECK);
|
||||
productTree.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if (e.detail == SWT.CHECK) {
|
||||
treeItemChecked((TreeItem) e.item);
|
||||
}
|
||||
super.widgetSelected(e);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected void initializeButtons(Composite comp) {
|
||||
comp.setLayout(new RowLayout(SWT.HORIZONTAL));
|
||||
Button okButton = new Button(comp, SWT.PUSH);
|
||||
okButton.setText("OK");
|
||||
okButton.setLayoutData(new RowData(100, SWT.DEFAULT));
|
||||
okButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
okPressed();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Button cancelButton = new Button(comp, SWT.PUSH);
|
||||
cancelButton.setText("Cancel");
|
||||
cancelButton.setLayoutData(new RowData(100, SWT.DEFAULT));
|
||||
cancelButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
close();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected void populateProductTree() {
|
||||
boolean exportMaps = exportMapsButton.getSelection();
|
||||
boolean exportHidden = exportHiddenButton.getSelection();
|
||||
if (options.isSinglePane()) {
|
||||
List<ResourcePair> rscList = options.getSinglPane().getResources(
|
||||
exportMaps, exportHidden);
|
||||
populateProductSubTree(rscList, null);
|
||||
} else {
|
||||
int index = 0;
|
||||
for (KmlPane pane : options.getPanes()) {
|
||||
List<ResourcePair> rscList = pane.getResources(exportMaps,
|
||||
exportHidden);
|
||||
TreeItem item = null;
|
||||
if (index < productTree.getItemCount()) {
|
||||
item = productTree.getItem(index);
|
||||
}
|
||||
if (!rscList.isEmpty()) {
|
||||
if (item == null || item.getData() != pane) {
|
||||
item = new TreeItem(productTree, SWT.NONE, index);
|
||||
item.setText("Pane " + (index + 1));
|
||||
item.setData(pane);
|
||||
populateProductSubTree(rscList, item);
|
||||
item.setExpanded(true);
|
||||
} else {
|
||||
populateProductSubTree(rscList, item);
|
||||
}
|
||||
index += 1;
|
||||
} else {
|
||||
if (item != null && item.getData() == pane) {
|
||||
item.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void populateProductSubTree(List<ResourcePair> rscList,
|
||||
final TreeItem parent) {
|
||||
TreeItem[] items = parent != null ? parent.getItems() : productTree
|
||||
.getItems();
|
||||
int itemIndex = 0;
|
||||
int rscIndex = 0;
|
||||
while (itemIndex < items.length || rscIndex < rscList.size()) {
|
||||
TreeItem item = null;
|
||||
if (itemIndex < items.length) {
|
||||
item = items[itemIndex];
|
||||
}
|
||||
ResourcePair pair = null;
|
||||
if (rscIndex < rscList.size()) {
|
||||
pair = rscList.get(rscIndex);
|
||||
}
|
||||
if (item != null && item.getData() == pair) {
|
||||
itemIndex += 1;
|
||||
rscIndex += 1;
|
||||
} else if (item != null && !rscList.contains(item.getData())) {
|
||||
item.dispose();
|
||||
itemIndex += 1;
|
||||
} else {
|
||||
if (parent != null) {
|
||||
item = new TreeItem(parent, SWT.NONE, rscIndex);
|
||||
} else {
|
||||
item = new TreeItem(productTree, SWT.NONE, rscIndex);
|
||||
}
|
||||
String name = pair.getResource().getName();
|
||||
if (name == null) {
|
||||
name = pair.getResource().getClass().getSimpleName();
|
||||
}
|
||||
item.setText(name);
|
||||
item.setData(pair);
|
||||
item.setChecked(true);
|
||||
treeItemChecked(item);
|
||||
rscIndex += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void treeItemChecked(TreeItem item) {
|
||||
for (TreeItem ti : item.getItems()) {
|
||||
ti.setChecked(item.getChecked());
|
||||
}
|
||||
TreeItem parent = item.getParentItem();
|
||||
while (parent != null) {
|
||||
parent.setChecked(true);
|
||||
for (TreeItem ti : parent.getItems()) {
|
||||
if (!ti.getChecked()) {
|
||||
parent.setChecked(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
parent = parent.getParentItem();
|
||||
}
|
||||
}
|
||||
|
||||
protected void selectDestinationFile() {
|
||||
FileDialog fileDialog = new FileDialog(this.shell, SWT.SAVE);
|
||||
File file = new File(locationText.getText());
|
||||
fileDialog.setFileName(file.getName());
|
||||
if (file.getParentFile() != null && file.getParentFile().isDirectory()) {
|
||||
fileDialog.setFilterPath(file.getParent());
|
||||
}
|
||||
fileDialog.setFilterExtensions(new String[] { ".kmz" });
|
||||
fileDialog.open();
|
||||
|
||||
String filterPath = fileDialog.getFilterPath();
|
||||
String selectedFile = fileDialog.getFileName();
|
||||
/*
|
||||
* Ensure that the user has entered a name for the file.
|
||||
*/
|
||||
if (selectedFile.equalsIgnoreCase("")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!filterPath.endsWith("/")) {
|
||||
filterPath += "/";
|
||||
}
|
||||
String destinationFile = filterPath + selectedFile;
|
||||
this.locationText.setText(destinationFile);
|
||||
this.locationText.setToolTipText(destinationFile);
|
||||
}
|
||||
|
||||
protected void okPressed() {
|
||||
if (allFramesButton.getSelection()) {
|
||||
options.setFirstFrameIndex(Integer.MIN_VALUE);
|
||||
options.setLastFrameIndex(Integer.MAX_VALUE);
|
||||
} else if (currentFramesButton.getSelection()) {
|
||||
for (KmlPane pane : options.getPanes()) {
|
||||
int frame = pane.getDisplay().getDescriptor().getFramesInfo()
|
||||
.getFrameIndex();
|
||||
frame = Math.max(0, frame);
|
||||
options.setFirstFrameIndex(frame);
|
||||
options.setLastFrameIndex(frame + 1);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
int from = Integer.parseInt(framesFromText.getText()) - 1;
|
||||
options.setFirstFrameIndex(from);
|
||||
} catch (NumberFormatException e) {
|
||||
MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR
|
||||
| SWT.OK);
|
||||
mb.setText("Invalid Number");
|
||||
mb.setMessage(framesFromText.getText()
|
||||
+ " is not a valid number, please enter a valid number for the starting frame.");
|
||||
mb.open();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int to = Integer.parseInt(framesToText.getText());
|
||||
options.setLastFrameIndex(to);
|
||||
} catch (NumberFormatException e) {
|
||||
MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR
|
||||
| SWT.OK);
|
||||
mb.setText("Invalid Number");
|
||||
mb.setMessage(framesFromText.getText()
|
||||
+ " is not a valid number, please enter a valid number for the ending frame.");
|
||||
mb.open();
|
||||
return;
|
||||
}
|
||||
}
|
||||
options.setKmzFileLocation(new File(locationText.getText()));
|
||||
options.setShadeEarth(shadeEarthButton.getSelection());
|
||||
// if (!setTimesButton.getSelection()) {
|
||||
// options.setTimeMode(KmlExportTimeMode.NONE);
|
||||
// } else if (timeSpanButton.getSelection()) {
|
||||
// options.setTimeMode(KmlExportTimeMode.TIME_SPAN);
|
||||
// } else if (timeStampButton.getSelection()) {
|
||||
// options.setTimeMode(KmlExportTimeMode.TIME_STAMP);
|
||||
//
|
||||
// }
|
||||
options.setFillPlotBackground(fillPlotsButton.getSelection());
|
||||
if (options.isSinglePane()) {
|
||||
List<ResourcePair> resourcesToExport = new ArrayList<ResourcePair>();
|
||||
for (TreeItem ti : productTree.getItems()) {
|
||||
if (ti.getChecked()) {
|
||||
resourcesToExport.add((ResourcePair) ti.getData());
|
||||
}
|
||||
}
|
||||
options.getSinglPane().setResourcesToExport(resourcesToExport);
|
||||
} else {
|
||||
for (TreeItem paneitem : productTree.getItems()) {
|
||||
KmlPane pane = (KmlPane) paneitem.getData();
|
||||
List<ResourcePair> resourcesToExport = new ArrayList<ResourcePair>();
|
||||
for (TreeItem ti : paneitem.getItems()) {
|
||||
if (ti.getChecked()) {
|
||||
resourcesToExport.add((ResourcePair) ti.getData());
|
||||
}
|
||||
}
|
||||
pane.setResourcesToExport(resourcesToExport);
|
||||
}
|
||||
}
|
||||
if (!validate()) {
|
||||
// clear the current selection
|
||||
for (KmlPane pane : options.getPanes()) {
|
||||
pane.setResourcesToExport(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
new KmlExportJob(options).schedule();
|
||||
close();
|
||||
}
|
||||
|
||||
protected boolean validate() {
|
||||
boolean products = false;
|
||||
for (KmlPane pane : options.getPanes()) {
|
||||
if (pane.getResourcesToExport() != null
|
||||
&& !pane.getResourcesToExport().isEmpty()) {
|
||||
products = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!products) {
|
||||
MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
|
||||
mb.setText("No Products");
|
||||
mb.setMessage("No products are selected.");
|
||||
mb.open();
|
||||
return false;
|
||||
}
|
||||
if (options.getFirstFrameIndex() > options.getLastFrameIndex()
|
||||
|| options.getLastFrameIndex() < 0) {
|
||||
MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
|
||||
mb.setText("Invalid Range");
|
||||
mb.setMessage("The frame range you entered is invalid, please enter a valid range");
|
||||
mb.open();
|
||||
return false;
|
||||
}
|
||||
File file = options.getKmzFileLocation();
|
||||
if (!file.getParentFile().exists()) {
|
||||
MessageBox mb = new MessageBox(getShell(), SWT.ICON_QUESTION
|
||||
| SWT.YES | SWT.NO);
|
||||
mb.setText("Create Directory");
|
||||
mb.setMessage("The directory " + file.getParent()
|
||||
+ " does not exist, would you like to create it.");
|
||||
int result = mb.open();
|
||||
if (result == SWT.YES) {
|
||||
if (!file.getParentFile().mkdirs()) {
|
||||
mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
|
||||
mb.setText("Error Creating Directory");
|
||||
mb.setMessage("An unspecified error has occured creating the directory, please select a new file location.");
|
||||
mb.open();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (file.exists()) {
|
||||
MessageBox mb = new MessageBox(getShell(), SWT.ICON_WARNING
|
||||
| SWT.YES | SWT.NO);
|
||||
mb.setText("Overwrite file");
|
||||
mb.setMessage("The specified file already exist. Would you like to overwrite it?");
|
||||
int result = mb.open();
|
||||
if (result == SWT.NO) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* 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.kml.export;
|
||||
|
||||
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 org.eclipse.ui.handlers.HandlerUtil;
|
||||
|
||||
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.maps.display.MapRenderableDisplay;
|
||||
import com.raytheon.uf.viz.kml.export.KmlExportOptions.KmlExportTimeMode;
|
||||
import com.raytheon.viz.ui.EditorUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* Handler for events from the KML Export menu item.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlExportHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public Object execute(ExecutionEvent event) throws ExecutionException {
|
||||
new KmlExportDialog(HandlerUtil.getActiveShell(event),
|
||||
getDefaultOptions()).open();
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static KmlExportOptions getDefaultOptions() {
|
||||
KmlExportOptions options = new KmlExportOptions();
|
||||
options.setFirstFrameIndex(Integer.MIN_VALUE);
|
||||
options.setLastFrameIndex(Integer.MAX_VALUE);
|
||||
options.setPreserveVisibility(true);
|
||||
options.setShadeEarth(false);
|
||||
options.setTimeMode(KmlExportTimeMode.TIME_SPAN);
|
||||
options.setKmzFileLocation(new File(System.getProperty("user.home"),
|
||||
"caveExport.kmz"));
|
||||
options.setPlotIconScale(3.5);
|
||||
options.setFillPlotBackground(false);
|
||||
options.setPaintSleepMillis(10);
|
||||
options.setMaxRefreshSeconds(60);
|
||||
IDisplayPaneContainer container = EditorUtil.getActiveVizContainer();
|
||||
List<KmlPane> panes = new ArrayList<KmlPane>();
|
||||
for (IDisplayPane pane : container.getDisplayPanes()) {
|
||||
AbstractRenderableDisplay display = (AbstractRenderableDisplay) pane
|
||||
.getRenderableDisplay();
|
||||
panes.add(new KmlPane(display, pane.getBounds()));
|
||||
}
|
||||
options.setPanes(panes);
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(Object evaluationContext) {
|
||||
IDisplayPaneContainer container = EditorUtil.getActiveVizContainer();
|
||||
if (container == null) {
|
||||
super.setBaseEnabled(false);
|
||||
return;
|
||||
}
|
||||
IDisplayPane pane = container.getActiveDisplayPane();
|
||||
if (pane == null) {
|
||||
super.setBaseEnabled(false);
|
||||
return;
|
||||
}
|
||||
super.setBaseEnabled(pane.getRenderableDisplay() instanceof MapRenderableDisplay);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,676 @@
|
|||
/**
|
||||
* 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.kml.export;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.SubMonitor;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.geotools.geometry.DirectPosition2D;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.datum.PixelInCell;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.colormap.Color;
|
||||
import com.raytheon.uf.common.colormap.IColorMap;
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
import com.raytheon.uf.common.geospatial.TransformFactory;
|
||||
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.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay;
|
||||
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.drawables.ColorMapParameters.LabelEntry;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintStatus;
|
||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.jobs.JobPool;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.uf.viz.core.rsc.IResourceGroup;
|
||||
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.BlendableCapability;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.BlendedCapability;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsFactoryAdapter;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlRootOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.AbstractObject;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Document;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Feature;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Folder;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LinearRing;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LookAt;
|
||||
import de.micromata.opengis.kml.v_2_2_0.MultiGeometry;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
import de.micromata.opengis.kml.v_2_2_0.PolyStyle;
|
||||
import de.micromata.opengis.kml.v_2_2_0.ScreenOverlay;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Style;
|
||||
import de.micromata.opengis.kml.v_2_2_0.TimePrimitive;
|
||||
import de.micromata.opengis.kml.v_2_2_0.TimeSpan;
|
||||
import de.micromata.opengis.kml.v_2_2_0.TimeStamp;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Units;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Vec2;
|
||||
|
||||
/**
|
||||
* The main Job for exporting KML in a background thread
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 6, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlExportJob extends Job {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlExportJob.class);
|
||||
|
||||
private static final SimpleDateFormat KML_TIME_FORMAT = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||
|
||||
private final KmlExportOptions options;
|
||||
|
||||
private final JobPool backgroundPool = new JobPool("Exporting KML", 4,
|
||||
true, Job.INTERACTIVE);
|
||||
|
||||
public KmlExportJob(KmlExportOptions options) {
|
||||
super("Generating Kml");
|
||||
setUser(true);
|
||||
this.options = options;
|
||||
KML_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
SubMonitor smonitor = SubMonitor
|
||||
.convert(monitor, "Generating KML", 800);
|
||||
|
||||
try {
|
||||
copyPanes(smonitor.newChild(20, SubMonitor.SUPPRESS_NONE));
|
||||
|
||||
initPanes(smonitor.newChild(80, SubMonitor.SUPPRESS_NONE));
|
||||
|
||||
KmlRootOutputManager out = new KmlRootOutputManager(
|
||||
options.getKmzFileLocation());
|
||||
|
||||
exportPanes(smonitor.newChild(500, SubMonitor.SUPPRESS_NONE), out);
|
||||
joinBackground(smonitor.newChild(150, SubMonitor.SUPPRESS_NONE));
|
||||
// Do not dispose until all background processes are done
|
||||
for (KmlPane pane : options.getPanes()) {
|
||||
pane.getDisplay().dispose();
|
||||
}
|
||||
recursiveInvisibility(out.getContainer(), true);
|
||||
out.close();
|
||||
smonitor.worked(50);
|
||||
} catch (IOException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, "Error writing KML", e);
|
||||
}
|
||||
smonitor.done();
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy each pane and remove any panes that aren't being exported.
|
||||
*
|
||||
* @param monitor
|
||||
*/
|
||||
private void copyPanes(IProgressMonitor monitor) {
|
||||
// Keep this code as fast as possible, if the user runs kml export in
|
||||
// the background and modifies the main display it will affect kml if
|
||||
// copy is not done.
|
||||
List<KmlPane> panes = options.getPanes();
|
||||
monitor.beginTask("Copying Displays", panes.size());
|
||||
Iterator<KmlPane> paneIt = panes.iterator();
|
||||
while (paneIt.hasNext()) {
|
||||
KmlPane pane = paneIt.next();
|
||||
List<ResourcePair> exports = pane.getResourcesToExport();
|
||||
if (exports == null || exports.isEmpty()) {
|
||||
paneIt.remove();
|
||||
} else {
|
||||
try {
|
||||
AbstractRenderableDisplay display = pane.getDisplay();
|
||||
// copy the current time before clone
|
||||
FramesInfo fi = display.getDescriptor().getFramesInfo();
|
||||
if (fi.getFrameTimes() != null) {
|
||||
int index = fi.getFrameIndex();
|
||||
if (index > options.getFirstFrameIndex()
|
||||
&& index < options.getLastFrameIndex()) {
|
||||
pane.setDisplayedTime(fi.getFrameTimes()[fi
|
||||
.getFrameIndex()]);
|
||||
}
|
||||
}
|
||||
display = display.cloneDisplay();
|
||||
pane.setDisplay(display);
|
||||
KmlGraphicsFactoryAdapter graphicsAdapter = new KmlGraphicsFactoryAdapter(
|
||||
display.getView().getExtent(), pane.getBounds());
|
||||
display.setGraphicsAdapter(graphicsAdapter);
|
||||
KmlGraphicsTarget target = graphicsAdapter.constructTarget(
|
||||
null, 0.0f, 0.0f);
|
||||
target.setBackgroundColor(display.getBackgroundColor());
|
||||
display.setup(target);
|
||||
pane.setTarget(target);
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
paneIt.remove();
|
||||
}
|
||||
}
|
||||
monitor.worked(1);
|
||||
}
|
||||
monitor.done();
|
||||
}
|
||||
|
||||
private void initPanes(IProgressMonitor monitor) {
|
||||
List<KmlPane> panes = options.getPanes();
|
||||
monitor.beginTask("Initializing Displays", panes.size());
|
||||
Iterator<KmlPane> paneIt = panes.iterator();
|
||||
while (paneIt.hasNext()) {
|
||||
KmlPane pane = paneIt.next();
|
||||
try {
|
||||
AbstractRenderableDisplay display = pane.getDisplay();
|
||||
|
||||
IDescriptor descriptor = display.getDescriptor();
|
||||
descriptor.setRenderableDisplay(display);
|
||||
descriptor.getResourceList().instantiateResources(descriptor,
|
||||
true);
|
||||
for (ResourcePair rp : descriptor.getResourceList()) {
|
||||
rp.getResource().init(pane.getTarget());
|
||||
monitor.worked(1);
|
||||
}
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
paneIt.remove();
|
||||
}
|
||||
monitor.worked(1);
|
||||
}
|
||||
monitor.done();
|
||||
}
|
||||
|
||||
private void exportPanes(IProgressMonitor monitor, KmlOutputManager out)
|
||||
throws IOException {
|
||||
List<KmlPane> panes = options.getPanes();
|
||||
SubMonitor smonitor = SubMonitor.convert(monitor, "Exporting Displays",
|
||||
panes.size() * 100);
|
||||
int paneNumber = 1;
|
||||
for (KmlPane pane : options.getPanes()) {
|
||||
KmlOutputManager displayOut = out;
|
||||
if (!options.isSinglePane()) {
|
||||
displayOut = out.createFolder("Pane " + (paneNumber++));
|
||||
}
|
||||
AbstractRenderableDisplay display = pane.getDisplay();
|
||||
setView(pane, displayOut);
|
||||
if (options.isShadeEarth()) {
|
||||
shadeEarth(displayOut, display.getBackgroundColor());
|
||||
}
|
||||
IDescriptor descriptor = display.getDescriptor();
|
||||
List<ResourcePair> exports = new ArrayList<ResourcePair>();
|
||||
for (ResourcePair rp : descriptor.getResourceList()) {
|
||||
if (pane.getResourcesToExport().contains(rp)) {
|
||||
exports.add(rp);
|
||||
} else {
|
||||
rp.getProperties().setVisible(false);
|
||||
}
|
||||
}
|
||||
exportResources(smonitor.newChild(100, SubMonitor.SUPPRESS_NONE),
|
||||
displayOut, exports, pane);
|
||||
if (smonitor.isCanceled()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
smonitor.done();
|
||||
}
|
||||
|
||||
private void exportResources(IProgressMonitor monitor,
|
||||
KmlOutputManager out, List<ResourcePair> exports, KmlPane pane)
|
||||
throws IOException {
|
||||
SubMonitor smonitor = SubMonitor.convert(monitor, "Exporting Products",
|
||||
exports.size() * 100);
|
||||
KmlGraphicsTarget target = pane.getTarget();
|
||||
AbstractRenderableDisplay display = pane.getDisplay();
|
||||
IDescriptor descriptor = display.getDescriptor();
|
||||
List<Boolean> visibility = new ArrayList<Boolean>();
|
||||
for (ResourcePair rp : exports) {
|
||||
visibility.add(rp.getProperties().isVisible());
|
||||
rp.getProperties().setVisible(false);
|
||||
}
|
||||
for (int c = 0; c < exports.size(); c++) {
|
||||
ResourcePair rp = exports.get(c);
|
||||
AbstractVizResource<?, ?> rsc = rp.getResource();
|
||||
rp.getProperties().setVisible(true);
|
||||
String name = rp.getResource().getName();
|
||||
if (name == null) {
|
||||
name = rp.getResource().getClass().getSimpleName();
|
||||
}
|
||||
KmlOutputManager resourceOut = out.createFolder(name.trim());
|
||||
SubMonitor rscmonitor = smonitor.newChild(100,
|
||||
SubMonitor.SUPPRESS_NONE);
|
||||
if (rsc.hasCapability(BlendableCapability.class)) {
|
||||
ResourceList list = rsc
|
||||
.getCapability(BlendableCapability.class)
|
||||
.getResourceList();
|
||||
exportResources(rscmonitor, resourceOut, list, pane);
|
||||
} else {
|
||||
int startIndex = options.getFirstFrameIndex();
|
||||
startIndex = Math.max(startIndex, 0);
|
||||
int lastIndex = options.getLastFrameIndex();
|
||||
lastIndex = Math.min(lastIndex, descriptor.getNumberOfFrames());
|
||||
rscmonitor.beginTask("Saving " + rsc.getName(), lastIndex
|
||||
- startIndex);
|
||||
addColorMap(resourceOut, display.getBackgroundColor(), rsc);
|
||||
DataTime[] times = descriptor.getFramesInfo().getTimeMap()
|
||||
.get(rsc);
|
||||
if ((times == null || times.length == 0)
|
||||
&& rsc instanceof IResourceGroup) {
|
||||
ResourceList list = ((IResourceGroup) rsc)
|
||||
.getResourceList();
|
||||
for (ResourcePair pair : list) {
|
||||
times = descriptor.getFramesInfo().getTimeMap()
|
||||
.get(pair.getResource());
|
||||
if (times != null && times.length > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<DataTime> pastFrames = new ArrayList<DataTime>();
|
||||
for (int i = startIndex; i < lastIndex; i += 1) {
|
||||
descriptor.setFramesInfo(new FramesInfo(i));
|
||||
KmlOutputManager timeOut = resourceOut;
|
||||
if (rsc.isTimeAgnostic()
|
||||
&& (times == null || times.length == 0)) {
|
||||
i = lastIndex - 1;
|
||||
} else {
|
||||
if (i < 0 || times == null || i >= times.length) {
|
||||
rscmonitor.worked(1);
|
||||
continue;
|
||||
}
|
||||
DataTime time = times[i];
|
||||
if (time == null || pastFrames.contains(time)) {
|
||||
rscmonitor.worked(1);
|
||||
continue;
|
||||
}
|
||||
timeOut = resourceOut.createFolder(time
|
||||
.getLegendString());
|
||||
timeOut.getContainer().setTimePrimitive(
|
||||
getTimePrimitive(times, i));
|
||||
pastFrames.add(time);
|
||||
}
|
||||
PaintProperties paintProps = new PaintProperties(1.0f,
|
||||
(float) display.getZoom(), display.getView(),
|
||||
pane.getBounds(), false, descriptor.getFramesInfo());
|
||||
paintResource(rscmonitor, timeOut, display, target, rsc,
|
||||
paintProps);
|
||||
rscmonitor.worked(1);
|
||||
if (rscmonitor.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
rp.getProperties().setVisible(false);
|
||||
if (options.isPreserveVisibility() && !visibility.get(c)) {
|
||||
resourceOut.getContainer().setVisibility(false);
|
||||
}
|
||||
rscmonitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
private void setView(KmlPane pane, KmlOutputManager out) {
|
||||
IExtent extent = pane.getDisplay().getView().getExtent();
|
||||
try {
|
||||
DirectPosition2D center = new DirectPosition2D(
|
||||
extent.getCenter()[0], extent.getCenter()[1]);
|
||||
DirectPosition2D corner = new DirectPosition2D(extent.getMaxX(),
|
||||
extent.getMinX());
|
||||
MathTransform gridToLatLon = TransformFactory.gridToLatLon(pane
|
||||
.getDisplay().getDescriptor().getGridGeometry(),
|
||||
PixelInCell.CELL_CENTER);
|
||||
gridToLatLon.transform(center, center);
|
||||
gridToLatLon.transform(corner, corner);
|
||||
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
gc.setStartingGeographicPoint(MapUtil.correctLon(center.x),
|
||||
center.y);
|
||||
gc.setDestinationGeographicPoint(MapUtil.correctLon(corner.x),
|
||||
corner.y);
|
||||
LookAt lookAt = out.getContainer().createAndSetLookAt();
|
||||
lookAt.setLongitude(center.x);
|
||||
lookAt.setLatitude(center.y);
|
||||
lookAt.setRange(gc.getOrthodromicDistance());
|
||||
if (pane.getDisplayedTime() != null) {
|
||||
DataTime time = pane.getDisplayedTime();
|
||||
TimeStamp ts = new TimeStamp();
|
||||
ts.setWhen(KML_TIME_FORMAT.format(new Date(time.getMatchValid())));
|
||||
// At the time of this writing the current api doesn't allow
|
||||
// setting time primitive for AbstractView
|
||||
lookAt.setAbstractViewObjectExtension(Arrays
|
||||
.asList((AbstractObject) ts));
|
||||
}
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of times for a resource and the index of the current time,
|
||||
* generate a KML TimePrimitive for a resource. When the time mode is SPAN
|
||||
* the times in the array are used to calculate a span such that the spans
|
||||
* for every time create a continuos time line.
|
||||
*
|
||||
* @param times
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private TimePrimitive getTimePrimitive(DataTime[] times, int index) {
|
||||
long validTime = times[index].getMatchValid();
|
||||
switch (options.getTimeMode()) {
|
||||
case TIME_STAMP: {
|
||||
TimeStamp ts = new TimeStamp();
|
||||
ts.setWhen(KML_TIME_FORMAT.format(new Date(validTime)));
|
||||
return ts;
|
||||
}
|
||||
case TIME_SPAN: {
|
||||
long prevValid = 0;
|
||||
long nextValid = 0;
|
||||
for (DataTime t : times) {
|
||||
if (t == null) {
|
||||
continue;
|
||||
}
|
||||
long valid = t.getMatchValid();
|
||||
if (valid < validTime) {
|
||||
if (prevValid == 0 || prevValid < valid) {
|
||||
prevValid = valid;
|
||||
}
|
||||
} else if (valid > validTime) {
|
||||
if (nextValid == 0 || nextValid > valid) {
|
||||
nextValid = valid;
|
||||
}
|
||||
}
|
||||
}
|
||||
long prevDist = 0;
|
||||
long nextDist = 0;
|
||||
if (prevValid != 0) {
|
||||
nextDist = prevDist = (validTime - prevValid) / 2;
|
||||
}
|
||||
if (nextValid != 0) {
|
||||
nextDist = (nextValid - validTime) / 2;
|
||||
if (prevDist == 0) {
|
||||
prevDist = nextDist;
|
||||
}
|
||||
}
|
||||
TimeSpan span = new TimeSpan();
|
||||
span.setBegin(KML_TIME_FORMAT
|
||||
.format(new Date(validTime - prevDist)));
|
||||
span.setEnd(KML_TIME_FORMAT.format(new Date(validTime + nextDist)));
|
||||
return span;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* KML reference documentation from google clearly states that a feature is
|
||||
* visible only if all of it's ancestors are also visible. Google
|
||||
* Earth(tested on version 6.2) ignores this and displays everything as
|
||||
* visible unless that item is specifically set to invisible even when
|
||||
* ancestors are invisible. This function makes google earth work properly
|
||||
* by finding invisible features and making all their children invisible.
|
||||
*
|
||||
* @param feature
|
||||
* @param parentVisibility
|
||||
*/
|
||||
private void recursiveInvisibility(Feature feature, boolean parentVisibility) {
|
||||
if (!parentVisibility) {
|
||||
feature.setVisibility(false);
|
||||
}
|
||||
List<Feature> features = null;
|
||||
if (feature instanceof Folder) {
|
||||
features = ((Folder) feature).getFeature();
|
||||
} else if (feature instanceof Document) {
|
||||
features = ((Document) feature).getFeature();
|
||||
}
|
||||
if (features == null) {
|
||||
return;
|
||||
}
|
||||
for (Feature f : features) {
|
||||
if (f == null) {
|
||||
continue;
|
||||
}
|
||||
recursiveInvisibility(f,
|
||||
!Boolean.FALSE.equals(feature.isVisibility()));
|
||||
}
|
||||
}
|
||||
|
||||
private void paintResource(IProgressMonitor monitor, KmlOutputManager out,
|
||||
AbstractRenderableDisplay display, KmlGraphicsTarget target,
|
||||
AbstractVizResource<?, ?> resource, PaintProperties paintProps) {
|
||||
target.setNeedsRefresh(true);
|
||||
long startTime = System.currentTimeMillis();
|
||||
while (target.isNeedsRefresh()
|
||||
|| resource.getPaintStatus() != PaintStatus.PAINTED) {
|
||||
if (target.isNeedsRefresh()) {
|
||||
target.beginFrame(paintProps.getView(), false);
|
||||
try {
|
||||
display.paint(target, paintProps);
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
return;
|
||||
}
|
||||
target.endFrame();
|
||||
}
|
||||
if (System.currentTimeMillis() - startTime > options
|
||||
.getMaxRefreshSeconds() * 1000) {
|
||||
statusHandler.handle(Priority.PROBLEM, resource.getName()
|
||||
+ " took more than " + options.getMaxRefreshSeconds()
|
||||
+ " seconds to paint, KML may be incomplete.");
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(options.getPaintSleepMillis());
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
if (monitor.isCanceled()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<KmlFeatureGenerator> generators = new ArrayList<KmlFeatureGenerator>(
|
||||
target.getGenerators());
|
||||
for (KmlFeatureGenerator generator : generators) {
|
||||
generator
|
||||
.setGridGeometry(display.getDescriptor().getGridGeometry());
|
||||
generator.setBackgroundColor(display.getBackgroundColor());
|
||||
generator.setOptions(options);
|
||||
}
|
||||
backgroundPool.schedule(new GenerateRunnable(generators, out));
|
||||
}
|
||||
|
||||
private void addColorMap(KmlOutputManager out, RGB backcolor,
|
||||
AbstractVizResource<?, ?> rsc) throws IOException {
|
||||
ColorMapParameters parameters = null;
|
||||
if (rsc.hasCapability(ColorMapCapability.class)) {
|
||||
ColorMapCapability cap = rsc
|
||||
.getCapability(ColorMapCapability.class);
|
||||
parameters = cap.getColorMapParameters();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
double xAnchor = 0;
|
||||
if (rsc.hasCapability(BlendedCapability.class)) {
|
||||
BlendedCapability cap = rsc.getCapability(BlendedCapability.class);
|
||||
xAnchor = Math.min(1, cap.getResourceIndex());
|
||||
}
|
||||
IColorMap colorMap = parameters.getColorMap();
|
||||
BufferedImage bi = new BufferedImage(colorMap.getSize() * 2, 25,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
Graphics graphics = bi.getGraphics();
|
||||
graphics.setColor(new java.awt.Color(backcolor.red, backcolor.green,
|
||||
backcolor.blue));
|
||||
graphics.fillRect(0, 0, bi.getWidth(), 25);
|
||||
int x = 0;
|
||||
for (Color color : colorMap.getColors()) {
|
||||
graphics.setColor(new java.awt.Color(color.getRed(), color
|
||||
.getGreen(), color.getBlue(), color.getAlpha()));
|
||||
graphics.drawLine(x, 0, x, 25);
|
||||
x += 1;
|
||||
graphics.drawLine(x, 0, x, 25);
|
||||
x += 1;
|
||||
}
|
||||
for (LabelEntry label : parameters.getLabels()) {
|
||||
if (label.getText().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Rectangle2D bounds = graphics.getFontMetrics().getStringBounds(
|
||||
label.getText(), graphics);
|
||||
int centerX = (int) (bi.getWidth() * label.getLocation());
|
||||
int leftX = (int) (centerX - bounds.getWidth() / 2);
|
||||
if (leftX < 0) {
|
||||
leftX = 0;
|
||||
} else if (leftX + bounds.getWidth() > bi.getWidth()) {
|
||||
leftX = (int) (bi.getWidth() - bounds.getWidth());
|
||||
}
|
||||
graphics.setColor(java.awt.Color.BLACK);
|
||||
graphics.fillRect(leftX - 1, 2, (int) bounds.getWidth() + 2,
|
||||
(int) bounds.getHeight() + 2);
|
||||
graphics.setColor(java.awt.Color.WHITE);
|
||||
graphics.drawString(label.getText(), leftX,
|
||||
(int) bounds.getHeight() + 1);
|
||||
}
|
||||
graphics.dispose();
|
||||
ScreenOverlay overlay = new ScreenOverlay();
|
||||
overlay.setName("ColorMap");
|
||||
Vec2 overlayxy = overlay.createAndSetOverlayXY();
|
||||
overlayxy.withX(xAnchor).withXunits(Units.FRACTION);
|
||||
overlayxy.withY(1).withYunits(Units.FRACTION);
|
||||
Vec2 screenxy = overlay.createAndSetScreenXY();
|
||||
screenxy.withX(xAnchor).withXunits(Units.FRACTION);
|
||||
screenxy.withY(1).withYunits(Units.FRACTION);
|
||||
overlay.createAndSetIcon().setHref(
|
||||
out.addImage(bi, "colormap" + xAnchor + ".png"));
|
||||
out.addFeature(overlay);
|
||||
}
|
||||
|
||||
private void shadeEarth(KmlOutputManager out, RGB color) {
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName("Background Color");
|
||||
Style style = new Style();
|
||||
style.createAndSetIconStyle().setScale(0.0);
|
||||
PolyStyle polyStyle = style.createAndSetPolyStyle();
|
||||
polyStyle.setFill(true);
|
||||
polyStyle.setOutline(false);
|
||||
polyStyle.setColor(KmlFeatureGenerator.toColorStr(1.0, color));
|
||||
placemark.setStyleUrl(out.getStyleUrl(style));
|
||||
// Google earth seems to do a weird things with one big polygon when you
|
||||
// zoom way out, specifically there is lots of flickering and it misses
|
||||
// big pieces towards the back of the sphere, lots of smaller polygons
|
||||
// helps avoid the missing hunks but I still see a lot of flickering.
|
||||
MultiGeometry multi = placemark.createAndSetMultiGeometry();
|
||||
for (int i = -180; i < 180; i += 10) {
|
||||
for (int j = -90; j < 90; j += 10) {
|
||||
LinearRing ring = multi.createAndAddPolygon()
|
||||
.createAndSetOuterBoundaryIs().createAndSetLinearRing();
|
||||
ring.addToCoordinates(i, j);
|
||||
ring.addToCoordinates(i, j + 10);
|
||||
ring.addToCoordinates(i + 10, j + 10);
|
||||
ring.addToCoordinates(i + 10, j);
|
||||
ring.addToCoordinates(i, j);
|
||||
}
|
||||
|
||||
}
|
||||
out.addFeature(placemark);
|
||||
}
|
||||
|
||||
private void joinBackground(IProgressMonitor monitor) {
|
||||
// some tasks(like radar mosaic) can take a very long time to finish the
|
||||
// background task, so this waits for those to finish and makes an
|
||||
// attempt to let the user know how it is going.
|
||||
int remaining = backgroundPool.getWorkRemaining();
|
||||
monitor.beginTask("Finalizing KML", remaining);
|
||||
while (remaining > 0) {
|
||||
try {
|
||||
Thread.sleep(300);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
int r = backgroundPool.getWorkRemaining();
|
||||
monitor.worked(remaining - r);
|
||||
remaining = r;
|
||||
if (monitor.isCanceled()) {
|
||||
monitor.subTask("Canceling");
|
||||
backgroundPool.cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
backgroundPool.join();
|
||||
}
|
||||
|
||||
private static class GenerateRunnable implements Runnable {
|
||||
|
||||
private final List<KmlFeatureGenerator> generators;
|
||||
|
||||
private final KmlOutputManager outputManager;
|
||||
|
||||
public GenerateRunnable(List<KmlFeatureGenerator> generators,
|
||||
KmlOutputManager outputManager) {
|
||||
this.generators = generators;
|
||||
this.outputManager = outputManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (KmlFeatureGenerator generator : generators) {
|
||||
generator.addFeature(outputManager);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* 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.kml.export;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Contains any options which can be configured for KML export.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 4, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlExportOptions {
|
||||
|
||||
public enum KmlExportTimeMode {
|
||||
NONE, TIME_STAMP, TIME_SPAN;
|
||||
}
|
||||
|
||||
private File kmzFileLocation;
|
||||
|
||||
private int firstFrameIndex;
|
||||
|
||||
private int lastFrameIndex;
|
||||
|
||||
private boolean shadeEarth;
|
||||
|
||||
// Google Earth requires a fairly large plot scale to make plots look nice
|
||||
// but World Wind prefers a smaller scale.
|
||||
private double plotIconScale;
|
||||
|
||||
private boolean fillPlotBackground;
|
||||
|
||||
private boolean preserveVisibility;
|
||||
|
||||
private KmlExportTimeMode timeMode;
|
||||
|
||||
private List<KmlPane> panes;
|
||||
|
||||
private int paintSleepMillis;
|
||||
|
||||
private int maxRefreshSeconds;
|
||||
|
||||
public File getKmzFileLocation() {
|
||||
return kmzFileLocation;
|
||||
}
|
||||
|
||||
public void setKmzFileLocation(File kmzFileLocation) {
|
||||
this.kmzFileLocation = kmzFileLocation;
|
||||
}
|
||||
|
||||
public int getFirstFrameIndex() {
|
||||
return firstFrameIndex;
|
||||
}
|
||||
|
||||
public void setFirstFrameIndex(int firstFrameIndex) {
|
||||
this.firstFrameIndex = firstFrameIndex;
|
||||
}
|
||||
|
||||
public int getLastFrameIndex() {
|
||||
return lastFrameIndex;
|
||||
}
|
||||
|
||||
public void setLastFrameIndex(int lastFrameIndex) {
|
||||
this.lastFrameIndex = lastFrameIndex;
|
||||
}
|
||||
|
||||
public boolean isShadeEarth() {
|
||||
return shadeEarth;
|
||||
}
|
||||
|
||||
public void setShadeEarth(boolean shadeEarth) {
|
||||
this.shadeEarth = shadeEarth;
|
||||
}
|
||||
|
||||
public boolean isFillPlotBackground() {
|
||||
return fillPlotBackground;
|
||||
}
|
||||
|
||||
public void setFillPlotBackground(boolean fillPlotBackground) {
|
||||
this.fillPlotBackground = fillPlotBackground;
|
||||
}
|
||||
|
||||
public boolean isPreserveVisibility() {
|
||||
return preserveVisibility;
|
||||
}
|
||||
|
||||
public void setPreserveVisibility(boolean preserveVisibility) {
|
||||
this.preserveVisibility = preserveVisibility;
|
||||
}
|
||||
|
||||
public KmlExportTimeMode getTimeMode() {
|
||||
return timeMode;
|
||||
}
|
||||
|
||||
public void setTimeMode(KmlExportTimeMode timeMode) {
|
||||
this.timeMode = timeMode;
|
||||
}
|
||||
|
||||
public List<KmlPane> getPanes() {
|
||||
return panes;
|
||||
}
|
||||
|
||||
public void setPanes(List<KmlPane> panes) {
|
||||
this.panes = panes;
|
||||
}
|
||||
|
||||
public boolean isSinglePane() {
|
||||
return panes != null && panes.size() == 1;
|
||||
}
|
||||
|
||||
public KmlPane getSinglPane() {
|
||||
if (isSinglePane()) {
|
||||
return panes.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getPaintSleepMillis() {
|
||||
return paintSleepMillis;
|
||||
}
|
||||
|
||||
public void setPaintSleepMillis(int paintSleepMillis) {
|
||||
this.paintSleepMillis = paintSleepMillis;
|
||||
}
|
||||
|
||||
public int getMaxRefreshSeconds() {
|
||||
return maxRefreshSeconds;
|
||||
}
|
||||
|
||||
public void setMaxRefreshSeconds(int maxRefreshSeconds) {
|
||||
this.maxRefreshSeconds = maxRefreshSeconds;
|
||||
}
|
||||
|
||||
public double getPlotIconScale() {
|
||||
return plotIconScale;
|
||||
}
|
||||
|
||||
public void setPlotIconScale(double plotIconScale) {
|
||||
this.plotIconScale = plotIconScale;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* 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.kml.export;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.datum.PixelInCell;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.TransformFactory;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Coordinate;
|
||||
|
||||
/**
|
||||
* Anything that can be drawn on the screen can also be used to create a KML
|
||||
* feature, this class provides some basic utility functions as well as an
|
||||
* interface for classes that generate KML.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 14, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class KmlFeatureGenerator {
|
||||
|
||||
protected GridGeometry2D gridGeometry;
|
||||
|
||||
protected MathTransform gridToLatLon;
|
||||
|
||||
protected RGB backgroundColor;
|
||||
|
||||
protected KmlExportOptions options;
|
||||
|
||||
public void setGridGeometry(GeneralGridGeometry gridGeometry) {
|
||||
this.gridGeometry = GridGeometry2D.wrap(gridGeometry);
|
||||
}
|
||||
|
||||
public void setBackgroundColor(RGB backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
public void setOptions(KmlExportOptions options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public Coordinate transformToLatLon(double gridX, double gridY)
|
||||
throws TransformException, FactoryException {
|
||||
return transformToLatLon(new double[] { gridX, gridY });
|
||||
}
|
||||
|
||||
public Coordinate transformToLatLon(double[] gridPixel)
|
||||
throws TransformException, FactoryException {
|
||||
if (gridToLatLon == null) {
|
||||
gridToLatLon = TransformFactory.gridToLatLon(gridGeometry,
|
||||
PixelInCell.CELL_CENTER);
|
||||
}
|
||||
double[] out = new double[2];
|
||||
gridToLatLon.transform(gridPixel, 0, out, 0, 1);
|
||||
return new Coordinate(out[0], out[1]);
|
||||
}
|
||||
|
||||
public List<Coordinate> transformToLatLon(List<double[]> gridPixels)
|
||||
throws TransformException, FactoryException {
|
||||
List<Coordinate> result = new ArrayList<Coordinate>();
|
||||
for (double[] gridPixel : gridPixels) {
|
||||
result.add(transformToLatLon(gridPixel));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public abstract void addFeature(KmlOutputManager outputManager);
|
||||
|
||||
public static String toColorStr(double alpha, RGB rgb) {
|
||||
return String.format("%02x%02x%02x%02x", (int) (alpha * 255), rgb.blue,
|
||||
rgb.green, rgb.red);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* 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.kml.export;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay;
|
||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
|
||||
/**
|
||||
* VizDisplayPane but for KML!
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 5, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlPane {
|
||||
|
||||
private List<ResourcePair> resourcesToExport;
|
||||
|
||||
private AbstractRenderableDisplay display;
|
||||
|
||||
private Rectangle bounds;
|
||||
|
||||
private KmlGraphicsTarget target;
|
||||
|
||||
private DataTime displayedTime;
|
||||
|
||||
public KmlPane(AbstractRenderableDisplay display, Rectangle bounds) {
|
||||
this.display = display;
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public List<ResourcePair> getResources(boolean includeMaps,
|
||||
boolean includeHidden) {
|
||||
List<ResourcePair> rscList = new ArrayList<ResourcePair>();
|
||||
for (ResourcePair rp : display.getDescriptor().getResourceList()) {
|
||||
if (!rp.getResourceData().equals(rp.getResourceData())) {
|
||||
// A special check for those special resources which will never
|
||||
// work with KML because they don't properly implement equals.
|
||||
// ... like GFE
|
||||
continue;
|
||||
} else if (rp.getProperties().isSystemResource()) {
|
||||
continue;
|
||||
} else if (!includeMaps && rp.getProperties().isMapLayer()) {
|
||||
continue;
|
||||
} else if (!includeHidden && !rp.getProperties().isVisible()) {
|
||||
continue;
|
||||
}
|
||||
rscList.add(rp);
|
||||
}
|
||||
return rscList;
|
||||
}
|
||||
|
||||
public void setDisplay(AbstractRenderableDisplay display) {
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
public void setTarget(KmlGraphicsTarget target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public List<ResourcePair> getResourcesToExport() {
|
||||
return resourcesToExport;
|
||||
}
|
||||
|
||||
public void setResourcesToExport(List<ResourcePair> resourcesToExport) {
|
||||
this.resourcesToExport = resourcesToExport;
|
||||
}
|
||||
|
||||
public AbstractRenderableDisplay getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
public KmlGraphicsTarget getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public DataTime getDisplayedTime() {
|
||||
return displayedTime;
|
||||
}
|
||||
|
||||
public void setDisplayedTime(DataTime displayedTime) {
|
||||
this.displayedTime = displayedTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
/**
|
||||
* 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.kml.export.graphics;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.IFont;
|
||||
|
||||
/**
|
||||
*
|
||||
* KML has really bad font support so only support the minimum operations
|
||||
* required to avoid errors.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlFont implements IFont {
|
||||
|
||||
private Font font;
|
||||
|
||||
private float magnification;
|
||||
|
||||
private boolean scaleFont;
|
||||
|
||||
private boolean smoothing;
|
||||
|
||||
public KmlFont(Font font) {
|
||||
this.font = font;
|
||||
this.magnification = 1.0f;
|
||||
}
|
||||
|
||||
public KmlFont() {
|
||||
this(new Font(java.awt.Font.MONOSPACED, Font.BOLD, 14));
|
||||
}
|
||||
|
||||
public KmlFont(String fontName) {
|
||||
this(new Font(fontName, Font.PLAIN, 10));
|
||||
|
||||
}
|
||||
|
||||
public KmlFont(String fontName, float fontSize) {
|
||||
this(new Font(fontName, Font.PLAIN, (int) fontSize));
|
||||
}
|
||||
|
||||
public KmlFont(String fontName, float fontSize, Style[] styles) {
|
||||
this(new Font(fontName, toAwtStyle(styles), (int) fontSize));
|
||||
}
|
||||
|
||||
public KmlFont(File fontFile, float fontSize, Style[] styles)
|
||||
throws FontFormatException, IOException {
|
||||
this(Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(fontSize)
|
||||
.deriveFont(toAwtStyle(styles)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFontName() {
|
||||
return this.font.getFontName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFontSize() {
|
||||
return this.font.getSize2D();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Style[] getStyle() {
|
||||
return toVizStyles(font.getStyle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFont deriveWithSize(float size) {
|
||||
return new KmlFont(font.deriveFont(size));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMagnification(float magnification) {
|
||||
setMagnification(magnification, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMagnification(float magnification, boolean scaleFont) {
|
||||
if (scaleFont) {
|
||||
this.font = font.deriveFont(font.getSize2D() * magnification);
|
||||
} else {
|
||||
this.magnification = magnification;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMagnification() {
|
||||
return magnification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmoothing(boolean smooth) {
|
||||
this.smoothing = smooth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSmoothing() {
|
||||
return smoothing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScaleFont() {
|
||||
return scaleFont;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleFont(boolean scaleFont) {
|
||||
this.scaleFont = scaleFont;
|
||||
}
|
||||
|
||||
public Font getFont() {
|
||||
return font;
|
||||
}
|
||||
|
||||
public void setFont(Font font) {
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
private static int toAwtStyle(Style[] styles) {
|
||||
int styleInt = Font.PLAIN;
|
||||
if (styles == null || styles.length == 0) {
|
||||
return styleInt;
|
||||
}
|
||||
for (Style style : styles) {
|
||||
if (style == Style.BOLD) {
|
||||
styleInt |= Font.BOLD;
|
||||
} else if (style == Style.ITALIC) {
|
||||
styleInt |= Font.ITALIC;
|
||||
}
|
||||
}
|
||||
return styleInt;
|
||||
}
|
||||
|
||||
private static Style[] toVizStyles(int style) {
|
||||
List<Style> styles = new ArrayList<Style>();
|
||||
if ((style & Font.BOLD) != 0) {
|
||||
styles.add(Style.BOLD);
|
||||
}
|
||||
if ((style & Font.ITALIC) != 0) {
|
||||
styles.add(Style.ITALIC);
|
||||
}
|
||||
return styles.toArray(new Style[0]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* 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.kml.export.graphics;
|
||||
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.widgets.Canvas;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.opengis.coverage.grid.GridEnvelope;
|
||||
|
||||
import com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.PixelExtent;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
/**
|
||||
*
|
||||
* Not very interesting, just constructs KML things
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlGraphicsFactoryAdapter extends AbstractGraphicsFactoryAdapter {
|
||||
|
||||
// The view needs to know the extent and canvas bounds from the source pane.
|
||||
private final IExtent extent;
|
||||
|
||||
private final Rectangle canvasBounds;
|
||||
|
||||
public KmlGraphicsFactoryAdapter(IExtent extent, Rectangle canvasBounds) {
|
||||
this.extent = extent;
|
||||
this.canvasBounds = canvasBounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlView constructView() {
|
||||
return new KmlView(extent, canvasBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlGraphicsTarget constructTarget(Canvas canvas, float width,
|
||||
float height) throws VizException {
|
||||
return new KmlGraphicsTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IExtent constructExtent(Coordinate[] coords) throws VizException {
|
||||
return new PixelExtent(coords);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IExtent constructExtent(double aMinX, double aMaxX, double aMinY,
|
||||
double aMaxY) throws VizException {
|
||||
return new PixelExtent(aMinX, aMaxX, aMinY, aMaxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IExtent constructExtent(Rectangle rect) throws VizException {
|
||||
return new PixelExtent(rect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IExtent constructExtent(GridEnvelope range) throws VizException {
|
||||
return new PixelExtent(range);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Canvas constrcutCanvas(Composite canvasComp) throws VizException {
|
||||
// Its possible we should just return null and not worry so much
|
||||
throw new UnsupportedOperationException(
|
||||
"KmlGraphicsFactoryAdapter does not support creating a canvas");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,333 @@
|
|||
/**
|
||||
* 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.kml.export.graphics;
|
||||
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jface.resource.FontRegistry;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
|
||||
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.AbstractGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.DrawableCircle;
|
||||
import com.raytheon.uf.viz.core.DrawableColorMap;
|
||||
import com.raytheon.uf.viz.core.DrawableLine;
|
||||
import com.raytheon.uf.viz.core.DrawableString;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.IView;
|
||||
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont;
|
||||
import com.raytheon.uf.viz.core.drawables.IFont.Style;
|
||||
import com.raytheon.uf.viz.core.drawables.IImage;
|
||||
import com.raytheon.uf.viz.core.drawables.IShadedShape;
|
||||
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.basicgen.KmlCirclesGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.basicgen.KmlLinesGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.basicgen.KmlPointsGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.basicgen.KmlRectGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.basicgen.KmlStringsGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.ext.KmlRasterImage;
|
||||
|
||||
/**
|
||||
*
|
||||
* Takes graphics operations and produces a list of KmlFeatureGenerators that
|
||||
* can be used to make KML.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlGraphicsTarget extends AbstractGraphicsTarget {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlGraphicsTarget.class);
|
||||
|
||||
private final KmlFont defaultFont = new KmlFont();
|
||||
|
||||
private List<KmlFeatureGenerator> generators = new ArrayList<KmlFeatureGenerator>(
|
||||
256);
|
||||
|
||||
protected IView view;
|
||||
|
||||
public KmlGraphicsTarget() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setView(IView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlFont initializeFont(String fontId) {
|
||||
FontRegistry registry = PlatformUI.getWorkbench().getThemeManager()
|
||||
.getCurrentTheme().getFontRegistry();
|
||||
if (registry.hasValueFor(fontId)) {
|
||||
FontData[] data = registry.getFontData(fontId);
|
||||
FontData fd = data[0];
|
||||
if (fd == null) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"No font data found for id: " + fontId);
|
||||
}
|
||||
float size = fd.height;
|
||||
String name = fd.getName();
|
||||
List<IFont.Style> styles = new ArrayList<IFont.Style>();
|
||||
|
||||
int style = fd.getStyle();
|
||||
if ((style & SWT.BOLD) != 0) {
|
||||
styles.add(IFont.Style.BOLD);
|
||||
}
|
||||
if ((style & SWT.ITALIC) != 0) {
|
||||
styles.add(IFont.Style.ITALIC);
|
||||
}
|
||||
|
||||
return new KmlFont(name, size,
|
||||
styles.toArray(new IFont.Style[styles.size()]));
|
||||
} else {
|
||||
return getDefaultFont();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlFont initializeFont(String fontName, float size, Style[] styles) {
|
||||
return new KmlFont(fontName, size, styles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlFont initializeFont(File fontFile, float size, Style[] styles) {
|
||||
try {
|
||||
return new KmlFont(fontFile, size, styles);
|
||||
} catch (FontFormatException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
} catch (IOException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return new KmlFont((String) null, size, styles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawWireframeShape(IWireframeShape shape, RGB color,
|
||||
float lineWidth, LineStyle lineStyle, IFont font, float alpha)
|
||||
throws VizException {
|
||||
addGenerator(new KmlWireframeShape.Generator((KmlWireframeShape) shape,
|
||||
alpha, color, lineWidth));
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlWireframeShape createWireframeShape(boolean mutable,
|
||||
GeneralGridGeometry geom, float simplificationLevel) {
|
||||
return new KmlWireframeShape(geom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlWireframeShape createWireframeShape(boolean mutableFlag,
|
||||
GeneralGridGeometry geom) {
|
||||
return new KmlWireframeShape(geom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlWireframeShape createWireframeShape(boolean mutable,
|
||||
GeneralGridGeometry geom, float simplificationLevel,
|
||||
boolean spatialChopFlag, IExtent extent) {
|
||||
return new KmlWireframeShape(geom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlFont getDefaultFont() {
|
||||
return defaultFont;
|
||||
}
|
||||
|
||||
public RGB getBackgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getStringsBounds(DrawableString parameters, String string) {
|
||||
KmlFont kmlFont = (KmlFont) parameters.font;
|
||||
if (kmlFont == null) {
|
||||
kmlFont = getDefaultFont();
|
||||
}
|
||||
FontRenderContext frc = new FontRenderContext(null, false, false);
|
||||
Rectangle2D rect = kmlFont.getFont().getStringBounds(string, frc);
|
||||
double width = rect.getWidth() * kmlFont.getMagnification();
|
||||
double height = rect.getHeight() * kmlFont.getMagnification();
|
||||
return new Rectangle2D.Double(0, 0, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawStrings(Collection<DrawableString> parameters)
|
||||
throws VizException {
|
||||
addGenerator(new KmlStringsGenerator(parameters));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPoints(Collection<double[]> locations, RGB color,
|
||||
PointStyle pointStyle, float magnification) throws VizException {
|
||||
addGenerator(new KmlPointsGenerator(locations, color, pointStyle,
|
||||
magnification));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLine(DrawableLine... lines) throws VizException {
|
||||
addGenerator(new KmlLinesGenerator(lines));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawCircle(DrawableCircle... circles) throws VizException {
|
||||
addGenerator(new KmlCirclesGenerator(circles));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImage initializeRaster(IRenderedImageCallback imageCallback) {
|
||||
return new KmlRasterImage(imageCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IShadedShape createShadedShape(boolean mutable,
|
||||
GeneralGridGeometry targetGeometry, boolean tesselate) {
|
||||
return new KmlShadedShape(targetGeometry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawShadedShapes(float alpha, float brightness,
|
||||
IShadedShape... shapes) throws VizException {
|
||||
for (IShadedShape shape : shapes) {
|
||||
addGenerator(new KmlShadedShape.Generator(alpha,
|
||||
(KmlShadedShape) shape));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(IExtent pe, RGB color, float lineWidth, double alpha)
|
||||
throws VizException {
|
||||
addGenerator(new KmlRectGenerator(pe, color, alpha, lineWidth, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawShadedRect(IExtent pe, RGB color, double alpha,
|
||||
byte[] pattern) throws VizException {
|
||||
addGenerator(new KmlRectGenerator(pe, color, alpha, 1.0f, true));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// this function intentionally left blank
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(IView view, boolean isClearBackground) {
|
||||
setNeedsRefresh(false);
|
||||
generators.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endFrame() {
|
||||
// this function intentionally left blank
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize() {
|
||||
// no need
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage screenshot() {
|
||||
// No one should be doing this.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupClippingPlane(IExtent extent) {
|
||||
// for now always ignore cliiping panes
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearClippingPlane() {
|
||||
// for now always ignore cliiping panes
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawColorRamp(DrawableColorMap colorMap) throws VizException {
|
||||
// currently this is handled outside the target, it might move here some
|
||||
// day but screen overlay rendering through the target is a bit
|
||||
// difficult for labels and things.
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by graphics extensions to add generators to the current frame.
|
||||
*
|
||||
* @param generator
|
||||
*/
|
||||
public void addGenerator(KmlFeatureGenerator generator) {
|
||||
generators.add(generator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the generators used during the last frame paint.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<KmlFeatureGenerator> getGenerators() {
|
||||
return generators;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawWireframeShape(IWireframeShape shape, RGB color,
|
||||
float lineWidth, LineStyle lineStyle, float alpha)
|
||||
throws VizException {
|
||||
drawWireframeShape(shape, color, lineWidth, lineStyle,
|
||||
getDefaultFont(), alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IView getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/**
|
||||
* 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.kml.export.graphics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.datum.PixelInCell;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.TransformFactory;
|
||||
import com.raytheon.uf.viz.core.drawables.IShadedShape;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.LineString;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Folder;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Geometry;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LinearRing;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Polygon;
|
||||
|
||||
/**
|
||||
* Implementation of shaded shape that can create a generator for making KML
|
||||
* filled polygons. KML has no concept of a fill pattern so it is completly
|
||||
* ignored and all polygons are filled with color.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 11, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlShadedShape implements IShadedShape {
|
||||
|
||||
private Map<RGB, List<Polygon>> polygons = new HashMap<RGB, List<Polygon>>();
|
||||
|
||||
private final GeneralGridGeometry gridGeometry;
|
||||
|
||||
public KmlShadedShape(GeneralGridGeometry gridGeometry) {
|
||||
this.gridGeometry = gridGeometry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compile() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDrawable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
polygons.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
polygons.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPolygon(LineString[] lineString, RGB color) {
|
||||
Polygon p = new Polygon();
|
||||
LinearRing outer = p.createAndSetOuterBoundaryIs()
|
||||
.createAndSetLinearRing();
|
||||
for (Coordinate c : lineString[0].getCoordinates()) {
|
||||
outer.addToCoordinates(c.x, c.y);
|
||||
}
|
||||
for (int i = 1; i < lineString.length; i += 1) {
|
||||
LinearRing inner = p.createAndAddInnerBoundaryIs()
|
||||
.createAndSetLinearRing();
|
||||
for (Coordinate c : lineString[i].getCoordinates()) {
|
||||
inner.addToCoordinates(c.x, c.y);
|
||||
}
|
||||
}
|
||||
List<Polygon> polygons = this.polygons.get(color);
|
||||
if (polygons == null) {
|
||||
polygons = new ArrayList<Polygon>();
|
||||
this.polygons.put(color, polygons);
|
||||
}
|
||||
polygons.add(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPolygonPixelSpace(LineString[] contours, RGB color) {
|
||||
try {
|
||||
MathTransform transform = TransformFactory.gridToLatLon(
|
||||
gridGeometry, PixelInCell.CELL_CENTER);
|
||||
double[] loc = new double[2];
|
||||
LineString[] newContours = new LineString[contours.length];
|
||||
for (int i = 0; i < contours.length; i += 1) {
|
||||
List<Coordinate> newCoordinates = new ArrayList<Coordinate>();
|
||||
for (Coordinate c : contours[i].getCoordinates()) {
|
||||
loc = new double[] { c.x, c.y };
|
||||
transform.transform(loc, 0, loc, 0, 1);
|
||||
newCoordinates.add(new Coordinate(loc[0], loc[1]));
|
||||
}
|
||||
newContours[i] = contours[i].getFactory().createLineString(
|
||||
newCoordinates.toArray(new Coordinate[0]));
|
||||
}
|
||||
addPolygon(newContours, color);
|
||||
} catch (TransformException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (FactoryException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFillPattern(byte[] pattern) {
|
||||
|
||||
}
|
||||
|
||||
public static class Generator extends KmlFeatureGenerator {
|
||||
|
||||
private final double alpha;
|
||||
|
||||
private final Map<RGB, List<Polygon>> polygons;
|
||||
|
||||
public Generator(double alpha, KmlShadedShape shape) {
|
||||
this.alpha = alpha;
|
||||
this.polygons = new HashMap<RGB, List<Polygon>>(shape.polygons);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
if (polygons.size() == 1) {
|
||||
Entry<RGB, List<Polygon>> entry = polygons.entrySet()
|
||||
.iterator().next();
|
||||
outputManager.addFeature(getPlacemark(outputManager,
|
||||
entry.getKey(), entry.getValue()));
|
||||
} else if (!polygons.isEmpty()) {
|
||||
Folder folder = new Folder();
|
||||
folder.setName("Shaded Shapes");
|
||||
for (Entry<RGB, List<Polygon>> entry : polygons.entrySet()) {
|
||||
folder.addToFeature(getPlacemark(outputManager,
|
||||
entry.getKey(), entry.getValue()));
|
||||
}
|
||||
outputManager.addFeature(folder);
|
||||
}
|
||||
}
|
||||
|
||||
private Placemark getPlacemark(KmlOutputManager out, RGB color,
|
||||
List<Polygon> polygons) {
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName("Shaded Shape");
|
||||
|
||||
de.micromata.opengis.kml.v_2_2_0.Style kmlStyle = new de.micromata.opengis.kml.v_2_2_0.Style();
|
||||
|
||||
kmlStyle.createAndSetPolyStyle().withFill(true)
|
||||
.withColor(toColorStr(alpha, color));
|
||||
kmlStyle.createAndSetLineStyle()
|
||||
.withColor(toColorStr(alpha, color));
|
||||
placemark.setStyleUrl(out.getStyleUrl(kmlStyle));
|
||||
if (polygons.size() == 1) {
|
||||
placemark.setGeometry(polygons.get(0));
|
||||
} else {
|
||||
placemark.createAndSetMultiGeometry().setGeometry(
|
||||
new ArrayList<Geometry>(polygons));
|
||||
}
|
||||
return placemark;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* 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.kml.export.graphics;
|
||||
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
|
||||
import com.raytheon.uf.viz.core.AbstractView;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* Minimalistic implementation of a view for KML. Can not be shifted or
|
||||
* modified, so KML does not supprt Pan/Zoom.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlView extends AbstractView {
|
||||
|
||||
private final Rectangle canvasBounds;
|
||||
|
||||
public KmlView(IExtent extent, Rectangle canvasBounds) {
|
||||
super(extent);
|
||||
this.canvasBounds = canvasBounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupView(IGraphicsTarget target) {
|
||||
if (target instanceof KmlGraphicsTarget) {
|
||||
((KmlGraphicsTarget) target).setView(this);
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"KmlView was expecting a KmlGraphicsTarget but recieved "
|
||||
+ target.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double recalcZoomLevel(int[] dimensions) {
|
||||
throw new UnsupportedOperationException("KmlView is read only!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoom(double zoomLevel) {
|
||||
throw new UnsupportedOperationException("KmlView is read only!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scaleAndBias(double factor, double screenX, double screenY,
|
||||
IGraphicsTarget target) {
|
||||
throw new UnsupportedOperationException("KmlView is read only!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtent(IExtent pe) {
|
||||
throw new UnsupportedOperationException("KmlView is read only!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shiftExtent(double[] startScreen, double[] endScreen,
|
||||
IGraphicsTarget target) {
|
||||
throw new UnsupportedOperationException("KmlView is read only!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scaleToClientArea(Rectangle clientArea, int[] dimensions) {
|
||||
throw new UnsupportedOperationException("KmlView is read only!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlView clone() {
|
||||
return new KmlView(extent.clone(), canvasBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getCanvasBounds(IGraphicsTarget target) {
|
||||
return canvasBounds;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,284 @@
|
|||
/**
|
||||
* 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.kml.export.graphics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.datum.PixelInCell;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.TransformFactory;
|
||||
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Feature;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Folder;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Geometry;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LabelStyle;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LineString;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LineStyle;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Point;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Style;
|
||||
|
||||
/**
|
||||
*
|
||||
* Converts a wireframe shape into KML LineStrings and Labels.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlWireframeShape implements IWireframeShape {
|
||||
|
||||
private List<Geometry> segments = new ArrayList<Geometry>();
|
||||
|
||||
private Map<String, List<Geometry>> labels = new HashMap<String, List<Geometry>>();
|
||||
|
||||
private final GeneralGridGeometry gridGeometry;
|
||||
|
||||
public KmlWireframeShape(GeneralGridGeometry gridGeometry) {
|
||||
this.gridGeometry = gridGeometry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compile() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDrawable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
segments.clear();
|
||||
labels.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
segments.clear();
|
||||
labels.clear();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLineSegment(Coordinate[] latLong) {
|
||||
LineString line = new LineString();
|
||||
for (Coordinate c : latLong) {
|
||||
line.addToCoordinates(round(c.x), round(c.y));
|
||||
}
|
||||
segments.add(line);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLineSegment(double[][] screenCoordinates) {
|
||||
try {
|
||||
MathTransform transform = TransformFactory.gridToLatLon(
|
||||
gridGeometry, PixelInCell.CELL_CENTER);
|
||||
LineString line = new LineString();
|
||||
double[] out = new double[2];
|
||||
for (int i = 0; i < screenCoordinates.length; i += 1) {
|
||||
transform.transform(screenCoordinates[i], 0, out, 0, 1);
|
||||
line.addToCoordinates(round(out[0]), round(out[1]));
|
||||
}
|
||||
segments.add(line);
|
||||
} catch (TransformException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (FactoryException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* round a latitude or longitude, rounding can cut the size of the generated
|
||||
* kml and only moves the actual line by less than a meter.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private double round(double value) {
|
||||
return ((long) (value * 100000)) / 100000.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLabel(String label, double[] screenCoordinate) {
|
||||
try {
|
||||
MathTransform transform = TransformFactory.gridToLatLon(
|
||||
gridGeometry, PixelInCell.CELL_CENTER);
|
||||
double[] out = new double[2];
|
||||
transform.transform(screenCoordinate, 0, out, 0, 1);
|
||||
Point point = new Point();
|
||||
point.addToCoordinates(round(out[0]), round(out[1]));
|
||||
List<Geometry> points = labels.get(label);
|
||||
if (points == null) {
|
||||
points = new ArrayList<Geometry>();
|
||||
labels.put(label, points);
|
||||
}
|
||||
points.add(point);
|
||||
} catch (TransformException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (FactoryException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearLabels() {
|
||||
labels.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allocate(int points) {
|
||||
}
|
||||
|
||||
public static class Generator extends KmlFeatureGenerator {
|
||||
|
||||
private final List<Geometry> segments;
|
||||
|
||||
private final Map<String, List<Geometry>> labels;
|
||||
|
||||
private final float alpha;
|
||||
|
||||
private final RGB color;
|
||||
|
||||
private final float lineWidth;
|
||||
|
||||
public Generator(KmlWireframeShape shape, float alpha, RGB color,
|
||||
float lineWidth) {
|
||||
this.segments = new ArrayList<Geometry>(shape.segments);
|
||||
this.labels = new HashMap<String, List<Geometry>>(shape.labels);
|
||||
this.alpha = alpha;
|
||||
this.color = color;
|
||||
this.lineWidth = lineWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
if (segments.isEmpty() && labels.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String styleUrl = outputManager.getStyleUrl(getStyle());
|
||||
Feature lineFeature = getLineFeature(styleUrl);
|
||||
Feature labelFeature = getLabelFeature(styleUrl);
|
||||
if (lineFeature == null) {
|
||||
outputManager.addFeature(labelFeature);
|
||||
} else if (labelFeature == null) {
|
||||
outputManager.addFeature(lineFeature);
|
||||
} else {
|
||||
Folder folder = new Folder();
|
||||
folder.setName("LinesAndLabels");
|
||||
folder.addToFeature(lineFeature);
|
||||
folder.addToFeature(labelFeature);
|
||||
outputManager.addFeature(folder);
|
||||
}
|
||||
}
|
||||
|
||||
private Style getStyle() {
|
||||
Style style = new de.micromata.opengis.kml.v_2_2_0.Style();
|
||||
LineStyle lineStyle = style.createAndSetLineStyle();
|
||||
LabelStyle labelStyle = style.createAndSetLabelStyle();
|
||||
style.createAndSetIconStyle().setScale(0);
|
||||
String colorStr = toColorStr(alpha, color);
|
||||
lineStyle.setColor(colorStr);
|
||||
lineStyle.setWidth(lineWidth);
|
||||
labelStyle.setColor(colorStr);
|
||||
labelStyle.setScale(1.0);
|
||||
return style;
|
||||
}
|
||||
|
||||
private Feature getLineFeature(String styleUrl) {
|
||||
if (segments.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName("Lines");
|
||||
placemark.setStyleUrl(styleUrl);
|
||||
if (segments.size() == 1) {
|
||||
placemark.setGeometry(segments.get(0));
|
||||
} else {
|
||||
placemark.createAndSetMultiGeometry().setGeometry(
|
||||
new ArrayList<Geometry>(segments));
|
||||
}
|
||||
return placemark;
|
||||
}
|
||||
|
||||
private Feature getLabelFeature(String styleUrl) {
|
||||
if (labels.size() == 1) {
|
||||
for (Entry<String, List<Geometry>> entry : labels.entrySet()) {
|
||||
return createLabelPlacemark(entry.getKey(),
|
||||
entry.getValue(), styleUrl);
|
||||
}
|
||||
} else if (!labels.isEmpty()) {
|
||||
Folder folder = new Folder();
|
||||
folder.setName("Labels");
|
||||
for (Entry<String, List<Geometry>> entry : labels.entrySet()) {
|
||||
Placemark placemark = createLabelPlacemark(entry.getKey(),
|
||||
entry.getValue(), styleUrl);
|
||||
folder.addToFeature(placemark);
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Placemark createLabelPlacemark(String label,
|
||||
List<Geometry> points, String styleUrl) {
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName(label);
|
||||
placemark.setStyleUrl(styleUrl);
|
||||
if (points.size() == 1) {
|
||||
placemark.setGeometry(points.get(0));
|
||||
} else {
|
||||
placemark.createAndSetMultiGeometry().setGeometry(points);
|
||||
}
|
||||
return placemark;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.basicgen;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
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.DrawableCircle;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
|
||||
/**
|
||||
* Generates KML polygons for DrawableCircles.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 14, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlCirclesGenerator extends KmlFeatureGenerator {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlLinesGenerator.class);
|
||||
|
||||
private final DrawableCircle[] circles;
|
||||
|
||||
public KmlCirclesGenerator(DrawableCircle[] circles) {
|
||||
this.circles = circles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
if (circles.length > 1) {
|
||||
outputManager = outputManager.createFolder("Circles");
|
||||
}
|
||||
for (DrawableCircle circle : circles) {
|
||||
String colorStr = toColorStr(circle.basics.alpha,
|
||||
circle.basics.color);
|
||||
de.micromata.opengis.kml.v_2_2_0.Style kmlStyle = new de.micromata.opengis.kml.v_2_2_0.Style();
|
||||
kmlStyle.createAndSetLabelStyle().setScale(0);
|
||||
kmlStyle.createAndSetIconStyle().setScale(0);
|
||||
if (circle.filled) {
|
||||
kmlStyle.createAndSetPolyStyle().withFill(true)
|
||||
.withColor(colorStr);
|
||||
} else {
|
||||
kmlStyle.createAndSetLineStyle().withWidth(circle.lineWidth)
|
||||
.withColor(colorStr);
|
||||
}
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName("Circle");
|
||||
placemark.setStyleUrl(outputManager.getStyleUrl(kmlStyle));
|
||||
List<double[]> pts = new ArrayList<double[]>();
|
||||
double step = 360.0 / (circle.numberOfPoints);
|
||||
double radius = circle.radius == null ? circle.screenRadius
|
||||
: circle.radius;
|
||||
try {
|
||||
for (double i = 0; i <= circle.numberOfPoints; i++) {
|
||||
double[] pt = new double[2];
|
||||
pt[0] = circle.basics.x + radius
|
||||
* Math.cos(Math.toRadians(i * step));
|
||||
pt[1] = circle.basics.y + radius
|
||||
* Math.sin(Math.toRadians(i * step));
|
||||
pts.add(pt);
|
||||
}
|
||||
if (circle.filled) {
|
||||
placemark.createAndSetPolygon()
|
||||
.createAndSetOuterBoundaryIs()
|
||||
.createAndSetLinearRing()
|
||||
.withCoordinates(transformToLatLon(pts));
|
||||
|
||||
} else {
|
||||
placemark.createAndSetLineString().withCoordinates(
|
||||
transformToLatLon(pts));
|
||||
}
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
}
|
||||
outputManager.addFeature(placemark);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.basicgen;
|
||||
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
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.DrawableLine;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
|
||||
/**
|
||||
* Generates KML line strings for DrawableLine.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 14, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlLinesGenerator extends KmlFeatureGenerator {
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlLinesGenerator.class);
|
||||
|
||||
private final DrawableLine[] lines;
|
||||
|
||||
public KmlLinesGenerator(DrawableLine[] lines) {
|
||||
super();
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
if (lines.length > 1) {
|
||||
outputManager = outputManager.createFolder("Lines");
|
||||
}
|
||||
for (DrawableLine line : lines) {
|
||||
de.micromata.opengis.kml.v_2_2_0.Style kmlStyle = new de.micromata.opengis.kml.v_2_2_0.Style();
|
||||
kmlStyle.createAndSetLabelStyle().setScale(0);
|
||||
kmlStyle.createAndSetIconStyle().setScale(0);
|
||||
kmlStyle.createAndSetLineStyle()
|
||||
.withWidth(line.width)
|
||||
.withColor(toColorStr(line.basics.alpha, line.basics.color));
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName("Line");
|
||||
placemark.setStyleUrl(outputManager.getStyleUrl(kmlStyle));
|
||||
try {
|
||||
placemark.createAndSetLineString().withCoordinates(
|
||||
transformToLatLon(line.points));
|
||||
outputManager.addFeature(placemark);
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.basicgen;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
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.IGraphicsTarget.PointStyle;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Coordinate;
|
||||
import de.micromata.opengis.kml.v_2_2_0.IconStyle;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LabelStyle;
|
||||
import de.micromata.opengis.kml.v_2_2_0.MultiGeometry;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Point;
|
||||
|
||||
/**
|
||||
* Generates KML point icons.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 14, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlPointsGenerator extends KmlFeatureGenerator {
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlStringsGenerator.class);
|
||||
|
||||
private final Collection<double[]> locations;
|
||||
|
||||
private final RGB color;
|
||||
|
||||
private final PointStyle pointStyle;
|
||||
|
||||
private final float magnification;
|
||||
|
||||
public KmlPointsGenerator(Collection<double[]> locations, RGB color,
|
||||
PointStyle pointStyle, float magnification) {
|
||||
super();
|
||||
this.locations = locations;
|
||||
this.color = color;
|
||||
this.pointStyle = pointStyle;
|
||||
this.magnification = magnification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
BufferedImage image = new BufferedImage(15, 15,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics graphics = image.getGraphics();
|
||||
if (graphics instanceof Graphics2D) {
|
||||
((Graphics2D) graphics).setStroke(new BasicStroke(3.0f));
|
||||
}
|
||||
graphics.setColor(new java.awt.Color(0, 0, 0, 0));
|
||||
graphics.fillRect(0, 0, 24, 24);
|
||||
graphics.setColor(new java.awt.Color(color.red, color.green, color.blue));
|
||||
switch (pointStyle) {
|
||||
case NONE:
|
||||
graphics.dispose();
|
||||
return;
|
||||
case SQUARE:
|
||||
graphics.fillRect(1, 1, 13, 13);
|
||||
break;
|
||||
case CIRCLE:
|
||||
graphics.drawOval(1, 1, 13, 13);
|
||||
break;
|
||||
case CROSS:
|
||||
graphics.drawLine(7, 0, 7, 14);
|
||||
graphics.drawLine(0, 7, 14, 7);
|
||||
break;
|
||||
case DASH:
|
||||
graphics.drawLine(0, 7, 14, 7);
|
||||
break;
|
||||
case POINT:
|
||||
graphics.fillOval(5, 5, 5, 5);
|
||||
break;
|
||||
case BOX:
|
||||
graphics.drawRect(1, 1, 13, 13);
|
||||
break;
|
||||
case STAR:
|
||||
graphics.drawLine(7, 0, 7, 14);
|
||||
case X:
|
||||
graphics.drawLine(0, 0, 14, 14);
|
||||
graphics.drawLine(0, 14, 14, 0);
|
||||
break;
|
||||
case DISC:
|
||||
default:
|
||||
graphics.fillOval(1, 1, 13, 13);
|
||||
break;
|
||||
}
|
||||
|
||||
graphics.dispose();
|
||||
de.micromata.opengis.kml.v_2_2_0.Style kmlStyle = new de.micromata.opengis.kml.v_2_2_0.Style();
|
||||
LabelStyle kmlLabelStyle = kmlStyle.createAndSetLabelStyle();
|
||||
IconStyle kmlIconStyle = kmlStyle.createAndSetIconStyle();
|
||||
kmlIconStyle.createAndSetIcon().setHref(outputManager.addImage(image));
|
||||
kmlLabelStyle.setScale(0);
|
||||
kmlIconStyle.setScale(magnification * 0.5);
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName(pointStyle.toString());
|
||||
placemark.setStyleUrl(outputManager.getStyleUrl(kmlStyle));
|
||||
try {
|
||||
if (locations.size() == 1) {
|
||||
Point p = placemark.createAndSetPoint();
|
||||
Coordinate loc = transformToLatLon(locations.iterator().next());
|
||||
p.addToCoordinates(loc.getLongitude(), loc.getLatitude());
|
||||
|
||||
} else {
|
||||
MultiGeometry multi = placemark.createAndSetMultiGeometry();
|
||||
for (double[] location : locations) {
|
||||
Point p = multi.createAndAddPoint();
|
||||
Coordinate loc = transformToLatLon(location);
|
||||
p.addToCoordinates(loc.getLongitude(), loc.getLatitude());
|
||||
}
|
||||
}
|
||||
outputManager.addFeature(placemark);
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.basicgen;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
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.IExtent;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Coordinate;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LinearRing;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Style;
|
||||
|
||||
/**
|
||||
* Generates kml Polygon for both filled and not filled rectangles.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 14, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlRectGenerator extends KmlFeatureGenerator {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlRectGenerator.class);
|
||||
|
||||
private final IExtent pe;
|
||||
|
||||
private final RGB color;
|
||||
|
||||
private final double alpha;
|
||||
|
||||
private final float lineWidth;
|
||||
|
||||
private final boolean filled;
|
||||
|
||||
public KmlRectGenerator(IExtent pe, RGB color, double alpha,
|
||||
float lineWidth, boolean filled) {
|
||||
this.pe = pe;
|
||||
this.color = color;
|
||||
this.alpha = alpha;
|
||||
this.lineWidth = lineWidth;
|
||||
this.filled = filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName("Rectangle");
|
||||
Style style = new de.micromata.opengis.kml.v_2_2_0.Style();
|
||||
style.createAndSetLabelStyle().setScale(0);
|
||||
style.createAndSetIconStyle().setScale(0);
|
||||
style.createAndSetLineStyle().withWidth(lineWidth)
|
||||
.withColor(toColorStr(alpha, color));
|
||||
style.createAndSetPolyStyle().withFill(filled)
|
||||
.withColor(toColorStr(alpha, color));
|
||||
|
||||
try {
|
||||
LinearRing ring = placemark.createAndSetPolygon()
|
||||
.createAndSetOuterBoundaryIs().createAndSetLinearRing();
|
||||
Coordinate corner = transformToLatLon(pe.getMinX(), pe.getMinY());
|
||||
ring.addToCoordinates(corner.getLongitude(), corner.getLatitude());
|
||||
corner = transformToLatLon(pe.getMaxX(), pe.getMinY());
|
||||
ring.addToCoordinates(corner.getLongitude(), corner.getLatitude());
|
||||
corner = transformToLatLon(pe.getMaxX(), pe.getMaxY());
|
||||
ring.addToCoordinates(corner.getLongitude(), corner.getLatitude());
|
||||
corner = transformToLatLon(pe.getMinX(), pe.getMaxY());
|
||||
ring.addToCoordinates(corner.getLongitude(), corner.getLatitude());
|
||||
corner = transformToLatLon(pe.getMinX(), pe.getMinY());
|
||||
ring.addToCoordinates(corner.getLongitude(), corner.getLatitude());
|
||||
|
||||
placemark.setStyleUrl(outputManager.getStyleUrl(style));
|
||||
outputManager.addFeature(placemark);
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.basicgen;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
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.DrawableString;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Coordinate;
|
||||
import de.micromata.opengis.kml.v_2_2_0.IconStyle;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LabelStyle;
|
||||
import de.micromata.opengis.kml.v_2_2_0.MultiGeometry;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Point;
|
||||
|
||||
/**
|
||||
* Generates KML Placemark Labels for DrawableStrings.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 14, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlStringsGenerator extends KmlFeatureGenerator {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlStringsGenerator.class);
|
||||
|
||||
private final Collection<DrawableString> parameters;
|
||||
|
||||
public KmlStringsGenerator(Collection<DrawableString> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
Collection<DrawableString> parameters = mergeDuplicatePoints();
|
||||
if (parameters.size() > 1) {
|
||||
outputManager = outputManager.createFolder("Labels");
|
||||
}
|
||||
Map<String, Placemark> redundantPlacemarks = new HashMap<String, Placemark>();
|
||||
for (DrawableString dstring : parameters) {
|
||||
RGB color = dstring.getColors()[0];
|
||||
for (RGB dcolor : dstring.getColors()) {
|
||||
if (!dcolor.equals(color)) {
|
||||
statusHandler.handle(Priority.INFO,
|
||||
"Multicolor labels will be one color in kml");
|
||||
}
|
||||
break;
|
||||
}
|
||||
String colorStr = toColorStr(dstring.basics.alpha, color);
|
||||
StringBuilder text = new StringBuilder(dstring.getText()[0]);
|
||||
for (int i = 1; i < dstring.getText().length; i++) {
|
||||
text.append(" ");
|
||||
text.append(dstring.getText()[i]);
|
||||
}
|
||||
Placemark placemark = redundantPlacemarks.get(text.toString()
|
||||
+ colorStr + dstring.magnification);
|
||||
if (placemark == null) {
|
||||
// google earth handles multiple points in a single placemark
|
||||
// faster than multiple placemarks with a single point, so
|
||||
// combine wherever possible
|
||||
de.micromata.opengis.kml.v_2_2_0.Style kmlStyle = new de.micromata.opengis.kml.v_2_2_0.Style();
|
||||
LabelStyle kmlLabelStyle = kmlStyle.createAndSetLabelStyle();
|
||||
IconStyle kmlIconStyle = kmlStyle.createAndSetIconStyle();
|
||||
kmlLabelStyle.setColor(colorStr);
|
||||
double magnifiaction = dstring.magnification;
|
||||
if (dstring.font != null) {
|
||||
magnifiaction *= dstring.font.getMagnification();
|
||||
}
|
||||
kmlLabelStyle.setScale(magnifiaction);
|
||||
kmlIconStyle.setScale(0);
|
||||
placemark = new Placemark();
|
||||
placemark.setName(text.toString());
|
||||
placemark.setStyleUrl(outputManager.getStyleUrl(kmlStyle));
|
||||
outputManager.addFeature(placemark);
|
||||
redundantPlacemarks.put(text.toString() + colorStr
|
||||
+ dstring.magnification, placemark);
|
||||
}
|
||||
Point point = null;
|
||||
if (placemark.getGeometry() == null) {
|
||||
point = placemark.createAndSetPoint();
|
||||
} else if (placemark.getGeometry() instanceof Point) {
|
||||
point = (Point) placemark.getGeometry();
|
||||
MultiGeometry multi = placemark.createAndSetMultiGeometry();
|
||||
multi.addToGeometry(point);
|
||||
point = multi.createAndAddPoint();
|
||||
} else {
|
||||
MultiGeometry multi = (MultiGeometry) placemark.getGeometry();
|
||||
point = multi.createAndAddPoint();
|
||||
}
|
||||
try {
|
||||
Coordinate loc = transformToLatLon(dstring.basics.x,
|
||||
dstring.basics.y);
|
||||
point.addToCoordinates(loc.getLongitude(), loc.getLatitude());
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Collection<DrawableString> mergeDuplicatePoints() {
|
||||
Map<Coordinate, DrawableString> pointMap = new HashMap<Coordinate, DrawableString>();
|
||||
for (DrawableString dstring : parameters) {
|
||||
Coordinate c = new Coordinate(dstring.basics.x, dstring.basics.y);
|
||||
if (pointMap.containsKey(c)) {
|
||||
DrawableString inMap = pointMap.get(c);
|
||||
DrawableString dstring2 = inMap;
|
||||
// try determine which of the two dtrings would be considered
|
||||
// "first"
|
||||
if (dstring2.verticallAlignment != dstring.verticallAlignment) {
|
||||
if (dstring2.verticallAlignment == VerticalAlignment.BOTTOM
|
||||
|| dstring.verticallAlignment == VerticalAlignment.TOP) {
|
||||
DrawableString tmp = dstring2;
|
||||
dstring2 = dstring;
|
||||
dstring = tmp;
|
||||
}
|
||||
} else if (dstring2.horizontalAlignment != dstring.horizontalAlignment) {
|
||||
if (dstring2.horizontalAlignment == HorizontalAlignment.RIGHT
|
||||
|| dstring.horizontalAlignment == HorizontalAlignment.LEFT) {
|
||||
DrawableString tmp = dstring2;
|
||||
dstring2 = dstring;
|
||||
dstring = tmp;
|
||||
}
|
||||
}
|
||||
String[] text1 = dstring.getText();
|
||||
String[] text2 = dstring2.getText();
|
||||
RGB[] colors1 = dstring.getColors();
|
||||
RGB[] colors2 = dstring2.getColors();
|
||||
String[] text = Arrays.copyOf(text1, text1.length
|
||||
+ text2.length);
|
||||
System.arraycopy(text2, 0, text, text1.length, text2.length);
|
||||
RGB[] colors = Arrays.copyOf(colors1, colors1.length
|
||||
+ colors2.length);
|
||||
System.arraycopy(colors2, 0, colors, colors1.length,
|
||||
colors2.length);
|
||||
inMap.setText(text, colors);
|
||||
} else {
|
||||
pointMap.put(c, dstring);
|
||||
}
|
||||
}
|
||||
return pointMap.values();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,412 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
|
||||
import com.raytheon.uf.viz.core.DrawableColorMap;
|
||||
import com.raytheon.uf.viz.core.DrawableLine;
|
||||
import com.raytheon.uf.viz.core.DrawableString;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.ICanvasRenderingExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlFont;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.ScreenOverlay;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Units;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Vec2;
|
||||
|
||||
/**
|
||||
* Converts canvas rendering into KML screen overlays.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 26, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlCanvasRenderingExtension extends
|
||||
GraphicsExtension<KmlGraphicsTarget> implements
|
||||
ICanvasRenderingExtension {
|
||||
|
||||
@Override
|
||||
public void drawStrings(PaintProperties paintProps,
|
||||
DrawableString... parameters) throws VizException {
|
||||
getGenerator(paintProps).addStrings(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLines(PaintProperties paintProps,
|
||||
DrawableLine... parameters) throws VizException {
|
||||
getGenerator(paintProps).addLines(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawColorRamp(PaintProperties paintProps,
|
||||
DrawableColorMap colorMap) throws VizException {
|
||||
getGenerator(paintProps).addColorMaps(colorMap);
|
||||
}
|
||||
|
||||
protected Generator getGenerator(PaintProperties paintProps) {
|
||||
for (KmlFeatureGenerator generator : target.getGenerators()) {
|
||||
if (generator instanceof Generator) {
|
||||
return (Generator) generator;
|
||||
}
|
||||
}
|
||||
Generator generator = new Generator(paintProps.getCanvasBounds());
|
||||
target.addGenerator(generator);
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompatibilityValue(KmlGraphicsTarget target) {
|
||||
return Compatibilty.TARGET_COMPATIBLE;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Renders all canvas drawables to one or more screen overlays. The number
|
||||
* of screen overlays is determined by overlapping the rendering area all
|
||||
* objects and drawing any overlapping objects to a single overlay. This
|
||||
* provides a good compromise between a single overlay which does not work
|
||||
* well on different sized clients and one screen overlay per object, which
|
||||
* causes problems when nearby objects do not line up(such as radar tables).
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 26, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
private static class Generator extends KmlFeatureGenerator {
|
||||
|
||||
private final Rectangle canvasBounds;
|
||||
|
||||
private final List<Object> objects = new ArrayList<Object>();
|
||||
|
||||
public Generator(Rectangle canvasBounds) {
|
||||
this.canvasBounds = canvasBounds;
|
||||
}
|
||||
|
||||
public void addStrings(DrawableString... strings) {
|
||||
this.objects.addAll(Arrays.asList(strings));
|
||||
}
|
||||
|
||||
public void addLines(DrawableLine... lines) {
|
||||
this.objects.addAll(Arrays.asList(lines));
|
||||
}
|
||||
|
||||
public void addColorMaps(DrawableColorMap... colorMaps) {
|
||||
this.objects.addAll(Arrays.asList(colorMaps));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
Map<Object, Rectangle2D> boundsMap = new IdentityHashMap<Object, Rectangle2D>();
|
||||
List<Rectangle2D> combinedBounds = new ArrayList<Rectangle2D>();
|
||||
for (Object object : objects) {
|
||||
Rectangle2D bounds = getBounds(object);
|
||||
boundsMap.put(object, bounds);
|
||||
addBounds(combinedBounds, bounds);
|
||||
}
|
||||
for (Rectangle2D bounds : combinedBounds) {
|
||||
BufferedImage bi = new BufferedImage((int) Math.ceil(bounds
|
||||
.getWidth()), (int) Math.ceil(bounds.getHeight()),
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics graphics = bi.getGraphics();
|
||||
for (Object object : objects) {
|
||||
if (bounds.contains(boundsMap.get(object))) {
|
||||
draw(graphics, bounds, object);
|
||||
}
|
||||
}
|
||||
graphics.dispose();
|
||||
graphics.finalize();
|
||||
bi.flush();
|
||||
ScreenOverlay overlay = new ScreenOverlay();
|
||||
overlay.setName("ScreenOverlay");
|
||||
Vec2 overlayxy = overlay.createAndSetOverlayXY();
|
||||
overlayxy.withXunits(Units.FRACTION).withYunits(Units.FRACTION);
|
||||
Vec2 screenxy = overlay.createAndSetScreenXY();
|
||||
screenxy.withXunits(Units.FRACTION).withYunits(Units.FRACTION);
|
||||
|
||||
// This is fairly complex placement code but it produces rather
|
||||
// nice results on any size of display. Basically if something
|
||||
// is flush against either the left or right of the screen it
|
||||
// ends up anchored on that side, if some is smack in the center
|
||||
// than the anchor point is in the middle of both the overlay
|
||||
// and the display. Now if an object is offcenter to the left or
|
||||
// right than the anchor point moves in the correct direction in
|
||||
// proportion to how far off center it is, its hard to explain
|
||||
// without a picture but at the end of the day it produces a
|
||||
// nice result.
|
||||
double leftFrac = bounds.getMinX() / canvasBounds.width;
|
||||
double rightFrac = 1.0 - bounds.getMaxX() / canvasBounds.width;
|
||||
if (leftFrac < rightFrac) {
|
||||
overlayxy.setX(leftFrac / rightFrac / 2);
|
||||
} else {
|
||||
overlayxy.setX(1.0 - rightFrac / leftFrac / 2);
|
||||
}
|
||||
double x = (bounds.getX() + bounds.getWidth()
|
||||
* overlayxy.getX())
|
||||
/ canvasBounds.width;
|
||||
screenxy.setX(x);
|
||||
|
||||
double topFrac = bounds.getMinY() / canvasBounds.height;
|
||||
double botFrac = 1.0 - bounds.getMaxY() / canvasBounds.height;
|
||||
if (topFrac < botFrac) {
|
||||
overlayxy.setY(1.0 - topFrac / botFrac / 2);
|
||||
} else {
|
||||
overlayxy.setY(botFrac / topFrac / 2);
|
||||
}
|
||||
// all this 1.0 - stuff is because the math is mostly assuming 0
|
||||
// is up and 1.0 is down but kml expects the opposite.
|
||||
double y = 1.0
|
||||
- (bounds.getY() + bounds.getHeight()
|
||||
* (1.0 - overlayxy.getY()))
|
||||
/ canvasBounds.height;
|
||||
screenxy.setY(y);
|
||||
|
||||
overlay.createAndSetIcon().setHref(
|
||||
outputManager.addImage(bi, "ScreenOverlay.png"));
|
||||
outputManager.addFeature(overlay);
|
||||
}
|
||||
}
|
||||
|
||||
private void addBounds(List<Rectangle2D> allBounds, Rectangle2D bounds) {
|
||||
Iterator<Rectangle2D> it = allBounds.iterator();
|
||||
while (it.hasNext()) {
|
||||
Rectangle2D b = it.next();
|
||||
if (b.intersects(bounds)) {
|
||||
if (!b.contains(bounds)) {
|
||||
// need to recheck the larger rectangle of b for any new
|
||||
// intersections.
|
||||
it.remove();
|
||||
b.add(bounds);
|
||||
addBounds(allBounds, b);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
allBounds.add(bounds);
|
||||
}
|
||||
|
||||
protected void draw(Graphics graphics, Rectangle2D imageBounds,
|
||||
Object object) {
|
||||
if (object instanceof DrawableString) {
|
||||
drawStrings(graphics, imageBounds, (DrawableString) object);
|
||||
} else if (object instanceof DrawableLine) {
|
||||
drawLines(graphics, imageBounds, (DrawableLine) object);
|
||||
} else if (object instanceof DrawableColorMap) {
|
||||
drawColorMap(graphics, imageBounds, (DrawableColorMap) object);
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawStrings(Graphics graphics, Rectangle2D imageBounds,
|
||||
DrawableString string) {
|
||||
KmlFont kmlFont = (KmlFont) string.font;
|
||||
if (kmlFont == null) {
|
||||
kmlFont = new KmlFont();
|
||||
}
|
||||
graphics.setFont(kmlFont.getFont());
|
||||
double x = (string.basics.x - imageBounds.getX());
|
||||
double y = (string.basics.y - imageBounds.getY());
|
||||
String[] text = string.getText();
|
||||
RGB[] colors = string.getColors();
|
||||
for (int i = 0; i < text.length; i += 1) {
|
||||
Rectangle2D bounds = graphics.getFontMetrics().getStringBounds(
|
||||
text[i], graphics);
|
||||
double realX = x;
|
||||
double realY = y;
|
||||
if (HorizontalAlignment.RIGHT == string.horizontalAlignment) {
|
||||
realX -= bounds.getWidth();
|
||||
} else if (HorizontalAlignment.CENTER == string.horizontalAlignment) {
|
||||
realX -= bounds.getWidth() / 2;
|
||||
}
|
||||
if (VerticalAlignment.TOP == string.verticallAlignment) {
|
||||
realY -= bounds.getY();
|
||||
} else if (VerticalAlignment.MIDDLE == string.verticallAlignment) {
|
||||
realY -= bounds.getY() / 2;
|
||||
}
|
||||
if (string.textStyle == TextStyle.BLANKED) {
|
||||
setColor(graphics, backgroundColor);
|
||||
graphics.fillRect((int) realX,
|
||||
(int) (realY + bounds.getY()),
|
||||
(int) bounds.getWidth(),
|
||||
(int) bounds.getHeight() + 1);
|
||||
}
|
||||
setColor(graphics, colors[i]);
|
||||
graphics.drawString(text[i], (int) realX, (int) realY);
|
||||
y += bounds.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawLines(Graphics graphics, Rectangle2D imageBounds,
|
||||
DrawableLine line) {
|
||||
setColor(graphics, line.basics.color);
|
||||
double[] pt1 = line.points.get(0);
|
||||
pt1[0] -= imageBounds.getX();
|
||||
pt1[1] -= imageBounds.getY();
|
||||
for (int i = 1; i < line.points.size(); i++) {
|
||||
double[] pt2 = line.points.get(i);
|
||||
pt2[0] -= imageBounds.getX();
|
||||
pt2[1] -= imageBounds.getY();
|
||||
graphics.drawLine((int) pt1[0], (int) pt1[1], (int) pt2[0],
|
||||
(int) pt2[1]);
|
||||
pt1 = pt2;
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawColorMap(Graphics graphics, Rectangle2D imageBounds,
|
||||
DrawableColorMap colorMap) {
|
||||
double xStart = colorMap.extent.getMinX() - imageBounds.getX();
|
||||
double yStart = colorMap.extent.getMinY() - imageBounds.getY();
|
||||
|
||||
setColor(graphics, backgroundColor);
|
||||
graphics.fillRect((int) xStart, (int) yStart,
|
||||
(int) colorMap.extent.getWidth(),
|
||||
(int) colorMap.extent.getHeight());
|
||||
double x1 = xStart;
|
||||
double xd = colorMap.extent.getWidth()
|
||||
/ colorMap.getColorMapParams().getColorMap().getSize();
|
||||
for (com.raytheon.uf.common.colormap.Color color : colorMap
|
||||
.getColorMapParams().getColorMap().getColors()) {
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(),
|
||||
color.getBlue(), color.getAlpha()));
|
||||
graphics.fillRect((int) x1, (int) yStart, (int) Math.ceil(xd),
|
||||
(int) colorMap.extent.getHeight());
|
||||
x1 += xd;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setColor(Graphics graphics, RGB color) {
|
||||
graphics.setColor(new Color(color.red, color.green, color.blue));
|
||||
}
|
||||
|
||||
protected Rectangle2D getBounds(Object object) {
|
||||
if (object instanceof DrawableString) {
|
||||
return getStringBounds((DrawableString) object);
|
||||
} else if (object instanceof DrawableLine) {
|
||||
return getLineBounds((DrawableLine) object);
|
||||
} else if (object instanceof DrawableColorMap) {
|
||||
return getColorMapBounds((DrawableColorMap) object);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Rectangle2D getLineBounds(DrawableLine line) {
|
||||
Rectangle2D bounds = null;
|
||||
for (double[] point : line.points) {
|
||||
if (bounds == null) {
|
||||
bounds = new Rectangle2D.Double(point[0], point[1], 0, 0);
|
||||
} else {
|
||||
bounds.add(point[0], point[1]);
|
||||
}
|
||||
}
|
||||
// add a buffer region to ensure we have room for wide lines on
|
||||
// the edge.
|
||||
bounds.add(bounds.getMinX() - line.width, bounds.getMinY()
|
||||
- line.width);
|
||||
bounds.add(bounds.getMaxX() + line.width, bounds.getMaxY()
|
||||
+ line.width);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
protected Rectangle2D getStringBounds(DrawableString string) {
|
||||
KmlFont kmlFont = (KmlFont) string.font;
|
||||
if (kmlFont == null) {
|
||||
kmlFont = new KmlFont();
|
||||
}
|
||||
FontRenderContext frc = new FontRenderContext(null, false, false);
|
||||
Rectangle2D bounds = null;
|
||||
String[] text = string.getText();
|
||||
double x = string.basics.x;
|
||||
double y = string.basics.y;
|
||||
for (int i = 0; i < text.length; i += 1) {
|
||||
Rectangle2D b = kmlFont.getFont().getStringBounds(text[i], frc);
|
||||
b.setFrame(x, y, b.getWidth(), b.getHeight());
|
||||
y += b.getHeight();
|
||||
if (bounds == null) {
|
||||
bounds = b;
|
||||
} else {
|
||||
bounds.add(b);
|
||||
}
|
||||
}
|
||||
if (HorizontalAlignment.RIGHT == string.horizontalAlignment) {
|
||||
bounds.setFrame(bounds.getMinX() - bounds.getWidth(),
|
||||
bounds.getMinY(), bounds.getWidth(), bounds.getHeight());
|
||||
} else if (HorizontalAlignment.CENTER == string.horizontalAlignment) {
|
||||
bounds.setFrame(bounds.getMinX() - bounds.getWidth() / 2,
|
||||
bounds.getMinY(), bounds.getWidth(), bounds.getHeight());
|
||||
}
|
||||
if (VerticalAlignment.BOTTOM == string.verticallAlignment) {
|
||||
bounds.setFrame(bounds.getMinX(),
|
||||
bounds.getMinY() - bounds.getHeight(),
|
||||
bounds.getWidth(), bounds.getHeight());
|
||||
} else if (VerticalAlignment.MIDDLE == string.verticallAlignment) {
|
||||
bounds.setFrame(bounds.getMinX(),
|
||||
bounds.getMinY() - bounds.getHeight() / 2,
|
||||
bounds.getWidth(), bounds.getHeight());
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
protected Rectangle2D getColorMapBounds(DrawableColorMap colorMap) {
|
||||
return new Rectangle2D.Double(colorMap.extent.getMinX(),
|
||||
colorMap.extent.getMinY(), colorMap.extent.getWidth(),
|
||||
colorMap.extent.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.ByteBufferWrapper;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.IntBufferWrapper;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.ShortBufferWrapper;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.UnsignedByteBufferWrapper;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.UnsignedShortBufferWrapper;
|
||||
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
|
||||
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback.ColorMapData;
|
||||
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements the interface and converts all data callbacks into raw float
|
||||
* arrays.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlColormappedImage extends KmlImage implements IColormappedImage {
|
||||
|
||||
private final IColorMapDataRetrievalCallback dataCallback;
|
||||
|
||||
private ColorMapParameters colorMapParameters;
|
||||
|
||||
public KmlColormappedImage(IColorMapDataRetrievalCallback dataCallback,
|
||||
ColorMapParameters colorMapParameters) {
|
||||
this.dataCallback = dataCallback;
|
||||
this.colorMapParameters = colorMapParameters;
|
||||
}
|
||||
|
||||
public DataSource getData(GridGeometry2D geometry) throws VizException {
|
||||
ColorMapData data = dataCallback.getColorMapData();
|
||||
switch (data.getDataType()) {
|
||||
case FLOAT:
|
||||
return new FloatBufferWrapper(((FloatBuffer) data.getBuffer()),
|
||||
geometry);
|
||||
case BYTE: {
|
||||
return new UnsignedByteBufferWrapper(
|
||||
((ByteBuffer) data.getBuffer()), geometry);
|
||||
}
|
||||
case SIGNED_BYTE: {
|
||||
return new ByteBufferWrapper(((ByteBuffer) data.getBuffer()),
|
||||
geometry);
|
||||
}
|
||||
case INT: {
|
||||
return new IntBufferWrapper(((IntBuffer) data.getBuffer()),
|
||||
geometry);
|
||||
}
|
||||
case SHORT: {
|
||||
return new ShortBufferWrapper(((ShortBuffer) data.getBuffer()),
|
||||
geometry);
|
||||
}
|
||||
case UNSIGNED_SHORT: {
|
||||
return new UnsignedShortBufferWrapper(
|
||||
((ShortBuffer) data.getBuffer()), geometry);
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException(
|
||||
"Kml Export does not supprt image type: " + data.getDataType());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IImagingExtension> getExtensionClass() {
|
||||
return KmlColormappedImageExtension.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorMapParameters getColorMapParameters() {
|
||||
return colorMapParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorMapParameters(ColorMapParameters params) {
|
||||
this.colorMapParameters = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue(int x, int y) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.geotools.coverage.grid.GridEnvelope2D;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.geotools.coverage.grid.InvalidGridGeometryException;
|
||||
import org.geotools.geometry.Envelope2D;
|
||||
import org.opengis.coverage.grid.GridEnvelope;
|
||||
import org.opengis.geometry.Envelope;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
|
||||
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.DrawableImage;
|
||||
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
|
||||
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* Responsible for creating KML Ground Overlays from colormapped images.
|
||||
* Converts all raw data to floats, reproject to LatLon using an Interpolation
|
||||
* and use the Colormapper to generate a RenderedImage.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlColormappedImageExtension extends
|
||||
GraphicsExtension<KmlGraphicsTarget> implements
|
||||
IColormappedImageExtension {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlColormappedImageExtension.class);
|
||||
|
||||
@Override
|
||||
public boolean drawRasters(PaintProperties paintProps,
|
||||
DrawableImage... images) throws VizException {
|
||||
target.addGenerator(new Generator(paintProps.getAlpha(), images));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IColormappedImage initializeRaster(
|
||||
IColorMapDataRetrievalCallback dataCallback,
|
||||
ColorMapParameters colorMapParameters) {
|
||||
return new KmlColormappedImage(dataCallback, colorMapParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompatibilityValue(KmlGraphicsTarget target) {
|
||||
return Compatibilty.TARGET_COMPATIBLE;
|
||||
}
|
||||
|
||||
private static class Generator extends KmlGroundOverlayGenerator {
|
||||
|
||||
private final DrawableImage[] images;
|
||||
|
||||
public Generator(float alpha, DrawableImage[] images) {
|
||||
super(alpha);
|
||||
this.images = images;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
drawRasters(outputManager, Arrays.asList(images));
|
||||
}
|
||||
|
||||
private void drawRasters(KmlOutputManager out,
|
||||
List<DrawableImage> images) {
|
||||
Map<GridGeometry2D, DataSource> matches = new HashMap<GridGeometry2D, DataSource>();
|
||||
List<DrawableImage> others = new ArrayList<DrawableImage>();
|
||||
ColorMapParameters params = null;
|
||||
boolean interpolated = false;
|
||||
// find candidates for merging tiles, matches must have the same
|
||||
// color map parameters and interpolations state.
|
||||
for (DrawableImage image : images) {
|
||||
KmlColormappedImage kmlImage = (KmlColormappedImage) image
|
||||
.getImage();
|
||||
KmlMesh mesh = (KmlMesh) image.getCoverage().getMesh();
|
||||
try {
|
||||
if (params == null) {
|
||||
params = kmlImage.getColorMapParameters();
|
||||
interpolated = kmlImage.isInterpolated();
|
||||
matches.put(mesh.getImageGeometry(),
|
||||
kmlImage.getData(mesh.getImageGeometry()));
|
||||
} else if (!params.equals(kmlImage.getColorMapParameters())) {
|
||||
others.add(image);
|
||||
} else if (interpolated != kmlImage.isInterpolated()) {
|
||||
others.add(image);
|
||||
} else {
|
||||
matches.put(mesh.getImageGeometry(),
|
||||
kmlImage.getData(mesh.getImageGeometry()));
|
||||
}
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
if (!others.isEmpty()) {
|
||||
drawRasters(out, others);
|
||||
}
|
||||
try {
|
||||
drawRastersInternal(out, matches, params, interpolated);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* images must all have the same colormap parameters and interpolation
|
||||
*
|
||||
* @param paintProps
|
||||
* @param images
|
||||
* @return
|
||||
* @throws TransformException
|
||||
* @throws FactoryException
|
||||
* @throws VizException
|
||||
*/
|
||||
private void drawRastersInternal(KmlOutputManager out,
|
||||
Map<GridGeometry2D, DataSource> map,
|
||||
ColorMapParameters parameters, boolean interpolated)
|
||||
throws FactoryException, TransformException {
|
||||
// attempt to merge
|
||||
map = mergeTiles(map);
|
||||
// and then draw any that were merged.
|
||||
for (Entry<GridGeometry2D, DataSource> entry : map.entrySet()) {
|
||||
reprojectAndMakeOverlay(out, entry.getKey(), entry.getValue(),
|
||||
parameters, interpolated);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* make the kml overlay object.
|
||||
*
|
||||
* @param paintProps
|
||||
* @param geometry
|
||||
* @param images
|
||||
* @throws TransformException
|
||||
* @throws FactoryException
|
||||
* @throws VizException
|
||||
*/
|
||||
private void reprojectAndMakeOverlay(KmlOutputManager out,
|
||||
GridGeometry2D geometry, DataSource data,
|
||||
ColorMapParameters parameters, boolean interpolated)
|
||||
throws FactoryException, TransformException {
|
||||
Envelope env = new Envelope2D(MapUtil.LATLON_PROJECTION, -180, -90,
|
||||
360, 180);
|
||||
GridGeometry2D projectedGeometry;
|
||||
projectedGeometry = GridGeometry2D.wrap(MapUtil.reprojectGeometry(
|
||||
geometry, env));
|
||||
float[] fdata = reproject(geometry, projectedGeometry, data,
|
||||
interpolated);
|
||||
makeOverlay(out, projectedGeometry, fdata, parameters);
|
||||
}
|
||||
|
||||
private Map<GridGeometry2D, DataSource> mergeTiles(
|
||||
Map<GridGeometry2D, DataSource> map) {
|
||||
Map<GridGeometry2D, DataSource> newmap = new HashMap<GridGeometry2D, DataSource>();
|
||||
while (!map.isEmpty()) {
|
||||
// each iteration removes a single entry and also any entries
|
||||
// that are representable in the same grid space.
|
||||
Iterator<Entry<GridGeometry2D, DataSource>> it = map.entrySet()
|
||||
.iterator();
|
||||
Entry<GridGeometry2D, DataSource> entry = it.next();
|
||||
it.remove();
|
||||
GridGeometry2D geom = entry.getKey();
|
||||
CoordinateReferenceSystem crs = geom
|
||||
.getCoordinateReferenceSystem();
|
||||
Envelope2D env = geom.getEnvelope2D();
|
||||
// bigenv will be an envelope big enopugh to hold all compatible
|
||||
// grids.
|
||||
Envelope2D bigenv = null;
|
||||
Map<Envelope2D, DataSource> envmap = new HashMap<Envelope2D, DataSource>();
|
||||
envmap.put(env, entry.getValue());
|
||||
float dx = (float) (env.width / geom.getGridRange2D().width);
|
||||
float dy = (float) (env.height / geom.getGridRange2D().height);
|
||||
// loop through remaining entries to find any matches, a match
|
||||
// will have the same crs, grid spacing and the distance between
|
||||
// the envelopes will be a multiple of the grid spacing.
|
||||
while (it.hasNext()) {
|
||||
entry = it.next();
|
||||
GridGeometry2D geom2 = entry.getKey();
|
||||
CoordinateReferenceSystem crs2 = geom2
|
||||
.getCoordinateReferenceSystem();
|
||||
Envelope2D env2 = geom2.getEnvelope2D();
|
||||
float dx2 = (float) (env2.width / geom2.getGridRange2D().width);
|
||||
float dy2 = (float) (env2.height / geom2.getGridRange2D().height);
|
||||
// numeric comparisons are done using floats because float
|
||||
// precision is considered "close enough" and double
|
||||
// precision results in very small inconsitencies.
|
||||
if (!crs.equals(crs2) || dx != dx2 || dy != dy2) {
|
||||
continue;
|
||||
}
|
||||
// Make sure that the two grids line up, the distance
|
||||
// between the envelopes should be an even multiple of dx
|
||||
// and dy otherwise the grids are slightly offset from
|
||||
// eachother and incompatible.
|
||||
float xoffset = (float) ((env.x - env2.x) / dx);
|
||||
float yoffset = (float) ((env.y - env2.y) / dy);
|
||||
if (xoffset != (int) xoffset || yoffset != (int) yoffset) {
|
||||
continue;
|
||||
}
|
||||
// at this point the two grids are compatible so we add them
|
||||
// to the bigenv.
|
||||
if (bigenv == null) {
|
||||
bigenv = new Envelope2D(env);
|
||||
}
|
||||
it.remove();
|
||||
envmap.put(env2, entry.getValue());
|
||||
bigenv.add(env2);
|
||||
}
|
||||
if (bigenv != null) {
|
||||
// determine GridEnvelope mapping needed to put all the
|
||||
// matching grids into the same space.
|
||||
try {
|
||||
GridEnvelope2D range = geom.worldToGrid(bigenv);
|
||||
range.x = 0;
|
||||
range.y = 0;
|
||||
GridGeometry2D newGeom = new GridGeometry2D(
|
||||
(GridEnvelope) range, bigenv);
|
||||
Map<GridEnvelope2D, DataSource> rangemap = new HashMap<GridEnvelope2D, DataSource>();
|
||||
for (Entry<Envelope2D, DataSource> envent : envmap
|
||||
.entrySet()) {
|
||||
rangemap.put(newGeom.worldToGrid(envent.getKey()),
|
||||
envent.getValue());
|
||||
}
|
||||
newmap.put(newGeom, new MergedDataSource(rangemap));
|
||||
} catch (InvalidGridGeometryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
} else {
|
||||
// if there are no compatible grids than this grid must be
|
||||
// handled all alone.
|
||||
newmap.put(geom, envmap.get(env));
|
||||
}
|
||||
}
|
||||
return newmap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Wraps multiple data sources that each cover a tile into a single data
|
||||
* source so it can all be reprojected in a single pass.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 25, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
private static class MergedDataSource implements DataSource {
|
||||
|
||||
private final Map<GridEnvelope2D, DataSource> sources;
|
||||
|
||||
public MergedDataSource(Map<GridEnvelope2D, DataSource> sources) {
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDataValue(int x, int y) {
|
||||
for (Entry<GridEnvelope2D, DataSource> entry : sources.entrySet()) {
|
||||
GridEnvelope2D env = entry.getKey();
|
||||
if (env.contains(x, y)) {
|
||||
x -= env.x;
|
||||
y -= env.y;
|
||||
return entry.getValue().getDataValue(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.collections.keyvalue.MultiKey;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.geotools.coverage.grid.GridEnvelope2D;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.geotools.geometry.Envelope2D;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.Interpolation;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.NearestNeighborInterpolation;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
|
||||
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback.ColorMapData;
|
||||
import com.raytheon.uf.viz.core.data.prep.Colormapper;
|
||||
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.GroundOverlay;
|
||||
import de.micromata.opengis.kml.v_2_2_0.LatLonBox;
|
||||
|
||||
/**
|
||||
* Base class for any feature generator that is creating a ground overlay,
|
||||
* provides the reproject logic as well as logic for actually making the
|
||||
* overlay.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 14, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class KmlGroundOverlayGenerator extends KmlFeatureGenerator {
|
||||
|
||||
private static Map<MultiKey, Reference<GridReprojection>> reprojCache = new HashMap<MultiKey, Reference<GridReprojection>>();
|
||||
|
||||
protected final double alpha;
|
||||
|
||||
public KmlGroundOverlayGenerator(double alpha) {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
protected void makeOverlay(KmlOutputManager out, GridGeometry2D geometry,
|
||||
float[] fdata, ColorMapParameters parameters) {
|
||||
GridEnvelope2D range = geometry.getGridRange2D();
|
||||
int[] dimensions = { range.width, range.height };
|
||||
ColorMapData data = new ColorMapData(FloatBuffer.wrap(fdata),
|
||||
dimensions);
|
||||
RenderedImage image = Colormapper.colorMap(data, parameters);
|
||||
makeOverlay(out, image, geometry.getEnvelope2D());
|
||||
}
|
||||
|
||||
protected void makeOverlay(KmlOutputManager out, RenderedImage image,
|
||||
Envelope2D envelope) {
|
||||
GroundOverlay overlay = new GroundOverlay();
|
||||
overlay.setColor(toColorStr(alpha, new RGB(255, 255, 255)));
|
||||
overlay.setName("Image");
|
||||
overlay.createAndSetIcon().setHref(out.addImage(image));
|
||||
LatLonBox box = overlay.createAndSetLatLonBox();
|
||||
box.setNorth(envelope.getMaxY());
|
||||
box.setEast(envelope.getMaxX());
|
||||
box.setSouth(envelope.getMinY());
|
||||
box.setWest(envelope.getMinX());
|
||||
out.addFeature(overlay);
|
||||
}
|
||||
|
||||
protected float[] reproject(GridGeometry2D src, GridGeometry2D dest,
|
||||
DataSource data, Boolean interpolated) throws FactoryException,
|
||||
TransformException {
|
||||
GridReprojection reproj = getReprojection(src, dest);
|
||||
Interpolation interp = null;
|
||||
if (interpolated) {
|
||||
interp = new BilinearInterpolation();
|
||||
} else {
|
||||
interp = new NearestNeighborInterpolation();
|
||||
}
|
||||
FloatArrayWrapper dst = new FloatArrayWrapper(dest);
|
||||
return reproj.reprojectedGrid(interp, data, dst).getArray();
|
||||
}
|
||||
|
||||
protected GridReprojection getReprojection(GridGeometry2D src,
|
||||
GridGeometry2D dest) throws FactoryException, TransformException {
|
||||
MultiKey key = new MultiKey(src, dest);
|
||||
GridReprojection reproj = null;
|
||||
boolean needsCompute = false;
|
||||
synchronized (reprojCache) {
|
||||
Reference<GridReprojection> reprojRef = reprojCache.get(key);
|
||||
if (reprojRef != null) {
|
||||
reproj = reprojRef.get();
|
||||
}
|
||||
if (reproj == null) {
|
||||
reproj = new GridReprojection(src, dest);
|
||||
needsCompute = true;
|
||||
reprojCache.put(key,
|
||||
new SoftReference<GridReprojection>(reproj));
|
||||
}
|
||||
}
|
||||
synchronized (reproj) {
|
||||
if (needsCompute) {
|
||||
reproj.computeTransformTable();
|
||||
}
|
||||
}
|
||||
return reproj;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.IImage;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
* Base image class for KML that does almost nothing and ignores any of the
|
||||
* methods that aren't important to KML.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class KmlImage implements IImage {
|
||||
|
||||
private boolean interpolated;
|
||||
|
||||
@Override
|
||||
public void stage() throws VizException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
return Status.LOADED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInterpolated(boolean isInterpolated) {
|
||||
this.interpolated = isInterpolated;
|
||||
}
|
||||
|
||||
public boolean isInterpolated() {
|
||||
return interpolated;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IImage#dispose()
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBrightness(float brightness) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContrast(float contrast) {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.geotools.coverage.grid.GridEnvelope2D;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.geotools.geometry.Envelope2D;
|
||||
import org.opengis.coverage.grid.GridEnvelope;
|
||||
|
||||
import com.raytheon.uf.viz.core.IMesh;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.map.IMapMeshExtension;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates meshes.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlMapMeshExtension extends GraphicsExtension<KmlGraphicsTarget>
|
||||
implements IMapMeshExtension {
|
||||
|
||||
@Override
|
||||
public IMesh constructMesh(GridGeometry2D imageGeometry,
|
||||
GeneralGridGeometry targetGeometry) throws VizException {
|
||||
GridEnvelope2D range = imageGeometry.getGridRange2D();
|
||||
Envelope2D envelope = imageGeometry.getEnvelope2D();
|
||||
range.x = 0;
|
||||
range.y = 0;
|
||||
imageGeometry = new GridGeometry2D((GridEnvelope) range, envelope);
|
||||
return new KmlMesh(imageGeometry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMesh constructMesh(GridGeometry2D imageGeometry,
|
||||
IDescriptor targetDescriptor) throws VizException {
|
||||
return constructMesh(imageGeometry, targetDescriptor.getGridGeometry());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompatibilityValue(KmlGraphicsTarget target) {
|
||||
return Compatibilty.TARGET_COMPATIBLE;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.geotools.geometry.jts.ReferencedEnvelope;
|
||||
import org.opengis.geometry.Envelope;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.IMesh;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Basically just a container for a grid geometry.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlMesh implements IMesh {
|
||||
|
||||
private final GridGeometry2D imageGeometry;
|
||||
|
||||
private Envelope latLonEnvelope;
|
||||
|
||||
public KmlMesh(GridGeometry2D imageGeometry) {
|
||||
this.imageGeometry = imageGeometry;
|
||||
}
|
||||
|
||||
public GridGeometry2D getImageGeometry() {
|
||||
return imageGeometry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(IExtent extent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlMesh reproject(GeneralGridGeometry targetGeometry)
|
||||
throws VizException {
|
||||
return clone(targetGeometry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlMesh clone(GeneralGridGeometry targetGeometry)
|
||||
throws VizException {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Envelope getLatLonEnvelope() throws TransformException {
|
||||
if (latLonEnvelope == null) {
|
||||
ReferencedEnvelope env = new ReferencedEnvelope(
|
||||
imageGeometry.getEnvelope());
|
||||
try {
|
||||
latLonEnvelope = env.transform(MapUtil.LATLON_PROJECTION, true,
|
||||
500);
|
||||
} catch (FactoryException e) {
|
||||
throw new TransformException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
return latLonEnvelope;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.raytheon.uf.viz.core.DrawableImage;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension.IMosaicImage;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Keeps track of the images that are to be mosaiced so that the extension can
|
||||
* handle rendering them.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 20, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
class KmlMosaicImage implements IMosaicImage {
|
||||
|
||||
private ColorMapParameters colorMapParameters;
|
||||
|
||||
private int[] bounds;
|
||||
|
||||
private IExtent imageExtent;
|
||||
|
||||
private DrawableImage[] imagesToMosaic;
|
||||
|
||||
private Comparator<Double> mosaicComparator;
|
||||
|
||||
public KmlMosaicImage(int[] imageBounds, IExtent imageExtent,
|
||||
ColorMapParameters params, Comparator<Double> mosaicComparator) {
|
||||
this.colorMapParameters = params;
|
||||
this.bounds = imageBounds;
|
||||
this.imageExtent = imageExtent;
|
||||
this.mosaicComparator = mosaicComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorMapParameters getColorMapParameters() {
|
||||
return colorMapParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorMapParameters(ColorMapParameters params) {
|
||||
this.colorMapParameters = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue(int x, int y) {
|
||||
// TODO do I need this?
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stage() throws VizException {
|
||||
// TODO do I need this?
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
// TODO do I need this?
|
||||
return Status.LOADED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInterpolated(boolean isInterpolated) {
|
||||
// TODO do I need this?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
// TODO do I need this?
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return bounds[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return bounds[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBrightness(float brightness) {
|
||||
// TODO do I need this?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContrast(float contrast) {
|
||||
// TODO do I need this?
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IMosaicImageExtension> getExtensionClass() {
|
||||
return IMosaicImageExtension.class;
|
||||
}
|
||||
|
||||
public Comparator<Double> getMosaicComparator() {
|
||||
return mosaicComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImagesToMosaic(DrawableImage... images) {
|
||||
this.imagesToMosaic = images;
|
||||
}
|
||||
|
||||
public DrawableImage[] getImagesToMosaic() {
|
||||
return this.imagesToMosaic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageExtent(IExtent imageExtent) {
|
||||
this.imageExtent = imageExtent;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.geotools.coverage.grid.GridEnvelope2D;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.geotools.geometry.Envelope2D;
|
||||
import org.geotools.geometry.jts.ReferencedEnvelope;
|
||||
import org.opengis.coverage.grid.GridEnvelope;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.interpolation.Interpolation;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.NearestNeighborInterpolation;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.AbstractDataWrapper;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.ByteBufferWrapper;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.DataDestination;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
|
||||
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.DrawableImage;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
/**
|
||||
* Generates a KMLGroundOverlay for mosaic by reprojecting all the images to a
|
||||
* common Lat/Lon space and performing a MaxVal algorithm.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 8, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlMosaicImageExtension extends
|
||||
GraphicsExtension<KmlGraphicsTarget> implements IMosaicImageExtension {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlMosaicImageExtension.class);
|
||||
|
||||
@Override
|
||||
public boolean drawRasters(PaintProperties paintProps,
|
||||
DrawableImage... images) throws VizException {
|
||||
for (DrawableImage image : images) {
|
||||
target.addGenerator(new Generator(paintProps.getAlpha(),
|
||||
(KmlMosaicImage) image.getImage()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMosaicImage initializeRaster(int[] imageBounds,
|
||||
IExtent imageExtent, ColorMapParameters params) throws VizException {
|
||||
return new KmlMosaicImage(imageBounds, imageExtent, params,
|
||||
getMosaicComparator());
|
||||
}
|
||||
|
||||
/**
|
||||
* The mosaic comparator is used to implement different mosaicing
|
||||
* algorithms. The first Double will be the current value, and the second
|
||||
* double will be the dataValue, the dataValue will only be used if it is
|
||||
* greater than the existing value.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected Comparator<Double> getMosaicComparator() {
|
||||
return new Comparator<Double>() {
|
||||
@Override
|
||||
public int compare(Double o1, Double o2) {
|
||||
// always use data value.
|
||||
return -1;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompatibilityValue(KmlGraphicsTarget target) {
|
||||
return Compatibilty.TARGET_COMPATIBLE;
|
||||
}
|
||||
|
||||
private static class Generator extends KmlGroundOverlayGenerator {
|
||||
|
||||
private final Comparator<Double> mosaicComparator;
|
||||
|
||||
private final ColorMapParameters parameters;
|
||||
|
||||
private final DrawableImage[] images;
|
||||
|
||||
public Generator(float alpha, KmlMosaicImage image) {
|
||||
super(alpha);
|
||||
this.images = image.getImagesToMosaic();
|
||||
this.parameters = image.getColorMapParameters();
|
||||
this.mosaicComparator = image.getMosaicComparator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
if (images.length == 0) {
|
||||
return;
|
||||
}
|
||||
long startTime = System.currentTimeMillis();
|
||||
// make a big envelope in lat lon space that is large enough to hold
|
||||
// all radar sites.
|
||||
ReferencedEnvelope bigenv = null;
|
||||
for (DrawableImage image : images) {
|
||||
KmlMesh mesh = (KmlMesh) image.getCoverage().getMesh();
|
||||
try {
|
||||
ReferencedEnvelope env = new ReferencedEnvelope(
|
||||
mesh.getLatLonEnvelope());
|
||||
if (bigenv == null) {
|
||||
bigenv = env;
|
||||
} else {
|
||||
bigenv.expandToInclude(env);
|
||||
}
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
// create a range that preserves aspect ratio with the larger
|
||||
// dimension as 1024 pixels, 1024 is a randomly chosen number.
|
||||
GridEnvelope2D range = new GridEnvelope2D(0, 0, 1024, 1024);
|
||||
if (bigenv.getWidth() > bigenv.getHeight()) {
|
||||
range.height = (int) (range.width * bigenv.getHeight() / bigenv
|
||||
.getWidth());
|
||||
} else {
|
||||
range.width = (int) (range.height * bigenv.getWidth() / bigenv
|
||||
.getHeight());
|
||||
}
|
||||
GridGeometry2D geom = new GridGeometry2D(range, bigenv);
|
||||
// fullDest is the end location of reprojected data values
|
||||
FloatArrayWrapper fullDest = new FloatArrayWrapper(geom);
|
||||
Arrays.fill(fullDest.getArray(), Float.NaN);
|
||||
Interpolation interp = new NearestNeighborInterpolation();
|
||||
for (DrawableImage image : images) {
|
||||
KmlMesh mesh = (KmlMesh) image.getCoverage().getMesh();
|
||||
KmlColormappedImage kmlImage = (KmlColormappedImage) image
|
||||
.getImage();
|
||||
try {
|
||||
// Reproject a subgrid rather than the full grid because it
|
||||
// is faster. The MosaicDataDestination maps the subgrid to
|
||||
// the larger grid.
|
||||
GridEnvelope2D gridenv = geom.worldToGrid(new Envelope2D(
|
||||
mesh.getLatLonEnvelope()));
|
||||
DataDestination dest = new MosaicDataDestination(
|
||||
mosaicComparator, fullDest, gridenv.clone());
|
||||
Envelope2D env = geom.gridToWorld(gridenv);
|
||||
gridenv.x = 0;
|
||||
gridenv.y = 0;
|
||||
GridGeometry2D newGeom = new GridGeometry2D(
|
||||
(GridEnvelope) gridenv, env);
|
||||
GridGeometry2D oldGeom = mesh.getImageGeometry();
|
||||
DataSource source = kmlImage.getData(oldGeom);
|
||||
getReprojection(oldGeom, newGeom).reprojectedGrid(interp,
|
||||
source, dest);
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
makeOverlay(outputManager, geom, fullDest.getArray(), parameters);
|
||||
System.out.println(System.currentTimeMillis() - startTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Provides a mapping into a subgrid of a larger destination and performs
|
||||
* maxVal mosaic algorithm when multiple radars map t a single grid cell.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 25, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
private static class MosaicDataDestination implements DataDestination {
|
||||
|
||||
private final Comparator<Double> mosaicComparator;
|
||||
|
||||
private final AbstractDataWrapper fullDest;
|
||||
|
||||
private final GridEnvelope2D envelope;
|
||||
|
||||
public MosaicDataDestination(Comparator<Double> mosaicComparator,
|
||||
AbstractDataWrapper fullDest, GridEnvelope2D envelope) {
|
||||
this.mosaicComparator = mosaicComparator;
|
||||
this.fullDest = fullDest;
|
||||
this.envelope = envelope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDataValue(double dataValue, int x, int y) {
|
||||
x = x + envelope.x;
|
||||
y = y + envelope.y;
|
||||
// shift the data and apply maxVal algorithm
|
||||
double oldValue = fullDest.getDataValue(x, y);
|
||||
if (mosaicComparator.compare(oldValue, dataValue) < 0) {
|
||||
fullDest.setDataValue(dataValue, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IMosaicMaxValImageExtension;
|
||||
|
||||
/**
|
||||
* Extends mosaic extesnion to perform maxVal mosaicing.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 10, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlMosaicMaxValImageExtension extends KmlMosaicImageExtension
|
||||
implements IMosaicMaxValImageExtension {
|
||||
|
||||
@Override
|
||||
protected Comparator<Double> getMosaicComparator() {
|
||||
return new Comparator<Double>() {
|
||||
@Override
|
||||
public int compare(Double o1, Double o2) {
|
||||
if (Double.isNaN(o2)) {
|
||||
return 1;
|
||||
} else if (Double.isNaN(o1)) {
|
||||
return -1;
|
||||
} else {
|
||||
return Double.compare(o1, o2);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IMosaicOrderedImageExtension;
|
||||
|
||||
/**
|
||||
* Extends mosaic extesnion to perform ordered mosaicing.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 10, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlMosaicOrderedImageExtension extends KmlMosaicImageExtension
|
||||
implements IMosaicOrderedImageExtension {
|
||||
|
||||
@Override
|
||||
protected Comparator<Double> getMosaicComparator() {
|
||||
return new Comparator<Double>() {
|
||||
@Override
|
||||
public int compare(Double o1, Double o2) {
|
||||
if (o2 != 0 && !Double.isNaN(o2)) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
|
||||
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
* Basically a wrapper around a RenderedImageCallback but also has logic for
|
||||
* filling in transparent parts of plots.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 11, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlRasterImage extends KmlImage {
|
||||
|
||||
protected final IRenderedImageCallback callback;
|
||||
|
||||
/**
|
||||
* @param imageCallback
|
||||
*/
|
||||
public KmlRasterImage(IRenderedImageCallback imageCallback) {
|
||||
this.callback = imageCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IImagingExtension> getExtensionClass() {
|
||||
return KmlRasterImageExtension.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the image for a ground overlay
|
||||
*
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public RenderedImage getImage() throws VizException {
|
||||
return callback.getImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the image for a plot
|
||||
*
|
||||
* @param target
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public RenderedImage getImage(RGB backcolor) throws VizException {
|
||||
RenderedImage ri = getImage();
|
||||
|
||||
BufferedImage bi = cloneRenderedImage(ri);
|
||||
applyFill(bi, backcolor);
|
||||
return bi;
|
||||
}
|
||||
|
||||
protected BufferedImage cloneRenderedImage(RenderedImage ri)
|
||||
throws VizException {
|
||||
BufferedImage bi = new BufferedImage(ri.getWidth(), ri.getHeight(),
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
if (ri instanceof Image) {
|
||||
bi.getGraphics().drawImage((Image) ri, 0, 0, null);
|
||||
} else {
|
||||
throw new VizException("Cannot handle image of type "
|
||||
+ ri.getClass().getSimpleName());
|
||||
}
|
||||
return bi;
|
||||
}
|
||||
|
||||
protected void applyFill(BufferedImage bi, RGB backcolor) {
|
||||
int backint = (0xFF << 24) | (backcolor.red << 16)
|
||||
| (backcolor.green << 8) | backcolor.blue;
|
||||
for (int i = 0; i < bi.getWidth(); i++) {
|
||||
for (int j = 0; j < bi.getHeight(); j++) {
|
||||
int argb = bi.getRGB(i, j);
|
||||
int alphaint = ((argb >> 24) & 0xFF);
|
||||
if (alphaint == 0) {
|
||||
argb = backint;
|
||||
} else if (alphaint != 255) {
|
||||
// blend the colors.
|
||||
double alpha = alphaint / 255.0;
|
||||
int red = (argb >> 16) & 0xFF;
|
||||
int green = (argb >> 8) & 0xFF;
|
||||
int blue = (argb >> 0) & 0xFF;
|
||||
red = (int) (red * alpha + backcolor.red * (1.0 - alpha));
|
||||
green = (int) (green * alpha + backcolor.green
|
||||
* (1.0 - alpha));
|
||||
blue = (int) (blue * alpha + backcolor.blue * (1.0 - alpha));
|
||||
argb = (0xFF << 24) | (red << 16) | (green << 8) | blue;
|
||||
}
|
||||
bi.setRGB(i, j, argb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import org.geotools.coverage.grid.GridCoverage2D;
|
||||
import org.geotools.coverage.grid.GridCoverageFactory;
|
||||
import org.geotools.coverage.processing.Operations;
|
||||
import org.geotools.geometry.DirectPosition2D;
|
||||
import org.geotools.geometry.Envelope2D;
|
||||
import org.geotools.geometry.jts.ReferencedEnvelope;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
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.DrawableImage;
|
||||
import com.raytheon.uf.viz.core.PixelCoverage;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
|
||||
/**
|
||||
* Extension for creating KML Ground Overlay from raster images.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 11, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlRasterImageExtension extends
|
||||
GraphicsExtension<KmlGraphicsTarget> implements IImagingExtension {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlRasterImageExtension.class);
|
||||
|
||||
@Override
|
||||
public boolean drawRasters(PaintProperties paintProps,
|
||||
DrawableImage... images) throws VizException {
|
||||
target.addGenerator(new Generator(paintProps.getAlpha(), images));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompatibilityValue(KmlGraphicsTarget target) {
|
||||
return Compatibilty.TARGET_COMPATIBLE;
|
||||
}
|
||||
|
||||
private static class Generator extends KmlGroundOverlayGenerator {
|
||||
|
||||
private final DrawableImage[] images;
|
||||
|
||||
public Generator(float alpha, DrawableImage[] images) {
|
||||
super(alpha);
|
||||
this.images = images;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
GridCoverageFactory coverageFactory = new GridCoverageFactory();
|
||||
for (DrawableImage image : images) {
|
||||
KmlRasterImage kmlImage = (KmlRasterImage) image.getImage();
|
||||
PixelCoverage coverage = image.getCoverage();
|
||||
MathTransform transform = gridGeometry.getGridToCRS();
|
||||
DirectPosition2D min = new DirectPosition2D(coverage.getMinX(),
|
||||
coverage.getMinY());
|
||||
DirectPosition2D max = new DirectPosition2D(coverage.getMaxX(),
|
||||
coverage.getMaxY());
|
||||
try {
|
||||
transform.transform(min, min);
|
||||
transform.transform(max, max);
|
||||
ReferencedEnvelope env = new ReferencedEnvelope(
|
||||
new Envelope2D(min, max),
|
||||
gridGeometry.getCoordinateReferenceSystem());
|
||||
GridCoverage2D source = coverageFactory.create("Test",
|
||||
kmlImage.getImage(), env);
|
||||
GridCoverage2D result = (GridCoverage2D) new Operations(
|
||||
null).resample(source, MapUtil.LATLON_PROJECTION);
|
||||
makeOverlay(outputManager, result.getRenderedImage(),
|
||||
result.getEnvelope2D());
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
|
||||
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.ISingleColorImageExtension.ISingleColorImage;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Adds logic to change colors to KmlRasterIamge.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlSingleColorImage extends KmlRasterImage implements
|
||||
ISingleColorImage {
|
||||
|
||||
private RGB color;
|
||||
|
||||
public KmlSingleColorImage(IRenderedImageCallback callback, RGB color) {
|
||||
super(callback);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IImagingExtension> getExtensionClass() {
|
||||
return KmlSingleColorImageExtension.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(RGB color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderedImage getImage() throws VizException {
|
||||
RenderedImage ri = callback.getImage();
|
||||
BufferedImage bi = cloneRenderedImage(ri);
|
||||
makeSingleColor(bi);
|
||||
return bi;
|
||||
}
|
||||
|
||||
protected void makeSingleColor(BufferedImage bi) {
|
||||
int colorint = (0xFF << 24) | (color.red << 16) | (color.green << 8)
|
||||
| color.blue;
|
||||
for (int i = 0; i < bi.getWidth(); i++) {
|
||||
for (int j = 0; j < bi.getHeight(); j++) {
|
||||
int argb = bi.getRGB(i, j);
|
||||
// preserve alpha but color becomes color.
|
||||
argb = (0xFF000000 & argb) | (0x00FFFFFF & colorint);
|
||||
bi.setRGB(i, j, argb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
|
||||
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.ISingleColorImageExtension;
|
||||
|
||||
/**
|
||||
* Extesnion for creating single color images.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 14, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlSingleColorImageExtension extends KmlRasterImageExtension
|
||||
implements ISingleColorImageExtension {
|
||||
|
||||
@Override
|
||||
public ISingleColorImage constructImage(IRenderedImageCallback callback,
|
||||
RGB color) {
|
||||
return new KmlSingleColorImage(callback, color);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext.point;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.opengis.referencing.FactoryException;
|
||||
import org.opengis.referencing.operation.TransformException;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
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.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.ext.KmlRasterImage;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.ext.KmlRasterImageExtension;
|
||||
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
|
||||
import com.raytheon.viz.pointdata.drawables.IPointImageExtension;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Coordinate;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Icon;
|
||||
import de.micromata.opengis.kml.v_2_2_0.IconStyle;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Placemark;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Point;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Style;
|
||||
|
||||
/**
|
||||
*
|
||||
* Renders images at points as placemark icons in KML
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class KmlPointImageExtension extends GraphicsExtension<KmlGraphicsTarget>
|
||||
implements IPointImageExtension {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(KmlRasterImageExtension.class);
|
||||
|
||||
@Override
|
||||
public void drawPointImages(PaintProperties paintProps,
|
||||
PointImage... images) throws VizException {
|
||||
drawPointImages(paintProps, Arrays.asList(images));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPointImages(PaintProperties paintProps,
|
||||
Collection<PointImage> images) throws VizException {
|
||||
target.addGenerator(new Generator(images));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompatibilityValue(KmlGraphicsTarget target) {
|
||||
return Compatibilty.TARGET_COMPATIBLE;
|
||||
}
|
||||
|
||||
private static class Generator extends KmlFeatureGenerator {
|
||||
|
||||
private final Collection<PointImage> images;
|
||||
|
||||
public Generator(Collection<PointImage> images) {
|
||||
this.images = images;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(KmlOutputManager outputManager) {
|
||||
if (images.size() > 1) {
|
||||
outputManager = outputManager.createFolder("Points");
|
||||
}
|
||||
for (PointImage image : images) {
|
||||
try {
|
||||
Placemark placemark = new Placemark();
|
||||
placemark.setName(image.getSiteId());
|
||||
Coordinate loc = transformToLatLon(image.getX(),
|
||||
image.getY());
|
||||
Point point = placemark.createAndSetPoint();
|
||||
point.addToCoordinates(loc.getLongitude(),
|
||||
loc.getLatitude());
|
||||
Style style = new Style();
|
||||
style.createAndSetLabelStyle().setScale(0);
|
||||
|
||||
IconStyle iconStyle = style.createAndSetIconStyle();
|
||||
iconStyle.setScale(options.getPlotIconScale());
|
||||
double heading = 180 + MapUtil.rotation(
|
||||
new com.vividsolutions.jts.geom.Coordinate(loc
|
||||
.getLongitude(), loc.getLatitude()),
|
||||
gridGeometry);
|
||||
iconStyle.setHeading(heading);
|
||||
Icon icon = iconStyle.createAndSetIcon();
|
||||
|
||||
RenderedImage rImage = null;
|
||||
if (options.isFillPlotBackground()) {
|
||||
rImage = ((KmlRasterImage) image.getImage())
|
||||
.getImage(backgroundColor);
|
||||
} else {
|
||||
rImage = ((KmlRasterImage) image.getImage()).getImage();
|
||||
}
|
||||
String siteId = image.getSiteId();
|
||||
if (siteId == null) {
|
||||
icon.setHref(outputManager.addImage(rImage));
|
||||
} else {
|
||||
siteId = siteId.replaceAll("\\?", "QuestionMark");
|
||||
icon.setHref(outputManager.addImage(rImage,
|
||||
"pointIcons/" + siteId + ".png"));
|
||||
}
|
||||
placemark.setStyleUrl(outputManager.getStyleUrl(style));
|
||||
outputManager.addFeature(placemark);
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
} catch (TransformException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
} catch (FactoryException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* 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.kml.export.graphics.ext.radar;
|
||||
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.opengis.referencing.FactoryException;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.radar.RadarRecord;
|
||||
import com.raytheon.uf.common.dataplugin.radar.projection.RadarProjectionFactory;
|
||||
import com.raytheon.uf.viz.core.IMesh;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
|
||||
import com.raytheon.uf.viz.kml.export.graphics.ext.KmlMesh;
|
||||
import com.raytheon.viz.radar.rsc.image.IRadialMeshExtension;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
/**
|
||||
* Creates a KMLMesh by constructing a RadialBinCRS based CrigGeometry object.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 6, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlRadialMeshExtension extends
|
||||
GraphicsExtension<KmlGraphicsTarget> implements IRadialMeshExtension {
|
||||
|
||||
@Override
|
||||
public int getCompatibilityValue(KmlGraphicsTarget target) {
|
||||
return Compatibilty.TARGET_COMPATIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMesh constructMesh(RadarRecord record,
|
||||
GeneralGridGeometry targetGeometry) throws VizException {
|
||||
GridGeometry2D imageGeometry;
|
||||
try {
|
||||
imageGeometry = RadarProjectionFactory
|
||||
.constructGridGeometry(new Coordinate(
|
||||
record.getLongitude(), record.getLatitude()),
|
||||
record.getAngleData(), record.getGateResolution(),
|
||||
record.getTrueElevationAngle(),
|
||||
record.getNumBins(), true);
|
||||
} catch (FactoryException e) {
|
||||
throw new VizException(e);
|
||||
}
|
||||
return new KmlMesh(imageGeometry);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* 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.kml.export.io;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Container;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Feature;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Folder;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Style;
|
||||
|
||||
/**
|
||||
* The Folder output does not actually contain a KMZ stream but allows the
|
||||
* parent to handle all file io.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlFolderOutputManager implements KmlOutputManager {
|
||||
|
||||
protected final KmlOutputManager parent;
|
||||
|
||||
protected final Folder folder;
|
||||
|
||||
private int imageCounter = 1;
|
||||
|
||||
public KmlFolderOutputManager(KmlOutputManager parent, Folder folder) {
|
||||
this.parent = parent;
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlOutputManager createFolder(String name) {
|
||||
return new KmlFolderOutputManager(this, folder.createAndAddFolder()
|
||||
.withName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addImage(RenderedImage image) {
|
||||
return addImage(image, "image" + (imageCounter++) + ".png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addImage(RenderedImage image, String name) {
|
||||
return parent.addImage(image, folder.getName() + "/" + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolvePath(String name) {
|
||||
return parent.resolvePath(folder.getName() + "/" + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStyleUrl(Style style) {
|
||||
return parent.getStyleUrl(style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(Feature feature) {
|
||||
folder.addToFeature(feature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Container getContainer() {
|
||||
return folder;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* 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.kml.export.io;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Container;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Feature;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Style;
|
||||
|
||||
/**
|
||||
* Wrapper around a KMZ file as well as a container java object, each folder an
|
||||
* outputManager creates will be a folder in the KML view as well as a folder in
|
||||
* the kmz file for any image resources that are stored.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public interface KmlOutputManager {
|
||||
|
||||
public KmlOutputManager createFolder(String name);
|
||||
|
||||
public String addImage(RenderedImage image);
|
||||
|
||||
public String addImage(RenderedImage image, String name);
|
||||
|
||||
public String resolvePath(String name);
|
||||
|
||||
public String getStyleUrl(Style style);
|
||||
|
||||
public void addFeature(Feature feature);
|
||||
|
||||
public Container getContainer();
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
* 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.kml.export.io;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.xml.bind.JAXB;
|
||||
|
||||
import de.micromata.opengis.kml.v_2_2_0.Container;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Document;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Feature;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Kml;
|
||||
import de.micromata.opengis.kml.v_2_2_0.Style;
|
||||
|
||||
/**
|
||||
* The root output manager holds a the base output stream as well as the root
|
||||
* KML Document.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class KmlRootOutputManager implements KmlOutputManager {
|
||||
|
||||
private Set<String> names = new HashSet<String>();
|
||||
|
||||
private final Kml kml;
|
||||
|
||||
private final Document document;
|
||||
|
||||
private IOException exception;
|
||||
|
||||
private int imageCounter = 1;
|
||||
|
||||
private int styleCounter = 1;
|
||||
|
||||
private Map<Style, String> styleMap = new HashMap<Style, String>();
|
||||
|
||||
private final ZipOutputStream zos;
|
||||
|
||||
public KmlRootOutputManager(File kmzFile) throws FileNotFoundException {
|
||||
this.zos = new ZipOutputStream(new FileOutputStream(kmzFile));
|
||||
this.kml = new Kml();
|
||||
this.document = this.kml.createAndSetDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KmlOutputManager createFolder(String name) {
|
||||
return new KmlFolderOutputManager(this, document.createAndAddFolder()
|
||||
.withName(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addImage(RenderedImage image) {
|
||||
return addImage(image, "image" + (imageCounter++) + ".png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addImage(RenderedImage image, String name) {
|
||||
if (names.contains(name)) {
|
||||
String newName = name;
|
||||
for (int i = 1; names.contains(newName); i++) {
|
||||
newName = name.replace(".png", "-" + i + ".png");
|
||||
}
|
||||
name = newName;
|
||||
}
|
||||
names.add(name);
|
||||
synchronized (zos) {
|
||||
try {
|
||||
zos.putNextEntry(new ZipEntry(name));
|
||||
ImageIO.write(image, "png", zos);
|
||||
zos.closeEntry();
|
||||
} catch (IOException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolvePath(String name) {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String getStyleUrl(Style style) {
|
||||
Style key = style.clone().withId(null);
|
||||
String id = styleMap.get(key);
|
||||
if (id == null) {
|
||||
id = style.getId();
|
||||
if (id == null) {
|
||||
id = "style" + this.styleCounter++;
|
||||
}
|
||||
styleMap.put(key, id);
|
||||
style.setId(id);
|
||||
document.addToStyleSelector(style);
|
||||
}
|
||||
return "#" + id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFeature(Feature feature) {
|
||||
document.addToFeature(feature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Container getContainer() {
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the kmz stream and serializes the kml document.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
zos.putNextEntry(new ZipEntry("doc.kml"));
|
||||
JAXB.marshal(kml, zos);
|
||||
zos.closeEntry();
|
||||
zos.close();
|
||||
}
|
||||
|
||||
}
|
7
cots/de.micromata.opengis.kml/.classpath
Normal file
7
cots/de.micromata.opengis.kml/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry exported="true" kind="lib" path="JavaAPIforKml.jar" sourcepath="JavaAPIforKml-sources.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
cots/de.micromata.opengis.kml/.project
Normal file
28
cots/de.micromata.opengis.kml/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>de.micromata.opengis.kml</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,8 @@
|
|||
#Wed May 30 18:56:22 CDT 2012
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
BIN
cots/de.micromata.opengis.kml/JavaAPIforKml-sources.jar
Normal file
BIN
cots/de.micromata.opengis.kml/JavaAPIforKml-sources.jar
Normal file
Binary file not shown.
BIN
cots/de.micromata.opengis.kml/JavaAPIforKml.jar
Normal file
BIN
cots/de.micromata.opengis.kml/JavaAPIforKml.jar
Normal file
Binary file not shown.
13
cots/de.micromata.opengis.kml/META-INF/MANIFEST.MF
Normal file
13
cots/de.micromata.opengis.kml/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,13 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Kml
|
||||
Bundle-SymbolicName: de.micromata.opengis.kml
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ClassPath: JavaAPIforKml.jar,
|
||||
.
|
||||
Export-Package: de.micromata.opengis.kml.v_2_2_0,
|
||||
de.micromata.opengis.kml.v_2_2_0.annotations,
|
||||
de.micromata.opengis.kml.v_2_2_0.atom,
|
||||
de.micromata.opengis.kml.v_2_2_0.gx,
|
||||
de.micromata.opengis.kml.v_2_2_0.xal
|
3
cots/de.micromata.opengis.kml/build.properties
Normal file
3
cots/de.micromata.opengis.kml/build.properties
Normal file
|
@ -0,0 +1,3 @@
|
|||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
JavaAPIforKml.jar
|
Loading…
Add table
Reference in a new issue