Issue #2015 fix NPP displaying in collaboration shared display sessions

Change-Id: Ie5e40d8ff3e7a222448777b86d188822e3990746

Former-commit-id: d4e2da7f81d5c3ad005f299c936bd2d70f05b17a
This commit is contained in:
Nate Jensen 2014-03-27 18:32:00 -05:00
parent e7882b1409
commit 32ae6bfb63
3 changed files with 207 additions and 11 deletions

View file

@ -62,6 +62,7 @@ import com.vividsolutions.jts.geom.LineSegment;
* algorithm to use great circle intersections for
* more accurate results
* Aug 27, 2013 #2190 mschenke Sped up transform functions
* Mar 27, 2014 #2015 njensen Overrode getParameterValues()
*
* </pre>
*
@ -148,6 +149,24 @@ public class VIIRSMapProjection extends MapProjection {
return Provider.PARAMETERS;
}
@Override
public ParameterValueGroup getParameterValues() {
final ParameterDescriptorGroup descriptor = getParameterDescriptors();
final ParameterValueGroup values = descriptor.createValue();
values.parameter(CENTER_LATITUDES).setValue(centerLats);
values.parameter(CENTER_LONGITUDES).setValue(centerLons);
values.parameter(DIRECTIONS).setValue(directions);
values.parameter(CENTER_LENGTH).setValue(actualHeight);
values.parameter(RESOLUTION).setValue(resolution);
values.parameter(SEMI_MAJOR).setValue(
VIIRSMapProjectionFactory.SEMI_MINOR_MAJOR_VALUE);
values.parameter(SEMI_MINOR).setValue(
VIIRSMapProjectionFactory.SEMI_MINOR_MAJOR_VALUE);
values.parameter(Provider.CENTRAL_MERIDIAN.getName().getCode())
.setValue(Provider.CENTRAL_MERIDIAN.getDefaultValue());
return values;
}
/*
* (non-Javadoc)
*

View file

@ -19,7 +19,6 @@
**/
package com.raytheon.uf.common.dataplugin.npp.viirs.projection;
import org.geotools.referencing.crs.DefaultProjectedCRS;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.FactoryException;
@ -38,6 +37,7 @@ import com.raytheon.uf.common.geospatial.MapUtil;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 16, 2012 mschenke Initial creation
* Mar 27, 2014 2015 njensen Made semi minor/major a constant
*
* </pre>
*
@ -50,6 +50,12 @@ public class VIIRSMapProjectionFactory {
/** Using single factory is faster due to internal caching */
private static DefaultMathTransformFactory dmtFactory = new DefaultMathTransformFactory();
/**
* MapProjection requires semi_major/minor but our projection does not use
* them
*/
protected static final double SEMI_MINOR_MAJOR_VALUE = 1.0;
public static ProjectedCRS construct(VIIRSSpatialCoverage record)
throws FactoryException {
try {
@ -65,10 +71,10 @@ public class VIIRSMapProjectionFactory {
record.getDirections());
group.parameter(VIIRSMapProjection.RESOLUTION).setValue(
record.getDy().doubleValue());
// MapProjection requires semi_major/minor but our projection does
// not use them
group.parameter(VIIRSMapProjection.SEMI_MAJOR).setValue(1.0);
group.parameter(VIIRSMapProjection.SEMI_MINOR).setValue(1.0);
group.parameter(VIIRSMapProjection.SEMI_MAJOR).setValue(
SEMI_MINOR_MAJOR_VALUE);
group.parameter(VIIRSMapProjection.SEMI_MINOR).setValue(
SEMI_MINOR_MAJOR_VALUE);
return MapUtil.constructProjection(
VIIRSMapProjection.PROJECTION_NAME, group);
} catch (Exception e) {

View file

@ -19,12 +19,33 @@
**/
package com.raytheon.uf.common.serialization.adapters;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.Envelope2D;
import org.geotools.parameter.DefaultParameterDescriptor;
import org.geotools.parameter.Parameter;
import org.geotools.parameter.ParameterGroup;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultProjectedCRS;
import org.geotools.referencing.cs.DefaultCartesianCS;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.geotools.referencing.operation.DefiningConversion;
import org.opengis.geometry.Envelope;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.referencing.cs.CartesianCS;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.util.InternationalString;
import com.raytheon.uf.common.serialization.IDeserializationContext;
import com.raytheon.uf.common.serialization.ISerializationContext;
@ -32,14 +53,18 @@ import com.raytheon.uf.common.serialization.ISerializationTypeAdapter;
import com.raytheon.uf.common.serialization.SerializationException;
/**
* TODO Add Description
* Dynamic Serialize type adapter for GridGeometry2D
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 5, 2010 randerso Initial creation
* Jan 5, 2010 randerso Initial creation
* Mar 27, 2014 2015 njensen Added ParameterValueAdapter and
* serialize PROJCS differently to
* work around geotools WKT limitations
*
*
* </pre>
*
@ -50,6 +75,87 @@ import com.raytheon.uf.common.serialization.SerializationException;
public class GridGeometry2DAdapter implements
ISerializationTypeAdapter<GridGeometry2D> {
/**
* Serialization adapter for ParameterValues. Also has to serialize the
* descriptor, default, etc due to geotools API. Intentionally private class
* because it's barely better than a hack to work around geotools
* limitations of recreating objects from a serialized form. See
* http://jira.codehaus.org/browse/GEOT-4752 for more information.
*/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
private static class ParameterValueAdapter implements
ISerializationTypeAdapter<ParameterValue> {
@Override
public void serialize(ISerializationContext serializer,
ParameterValue object) throws SerializationException {
// serialize everything for the descriptor first
ParameterDescriptor<?> desc = object.getDescriptor();
serializer.writeString(desc.getName().getCode());
InternationalString rmk = desc.getRemarks();
if (rmk != null) {
serializer.writeString(rmk.toString());
} else {
serializer.writeString("null");
}
serializer.writeString(desc.getValueClass().getName());
serializer.writeObject(desc.getDefaultValue());
serializer.writeBool(desc.getMinimumOccurs() > 0);
// finally serialize the object itself
serializer.writeObject(object.getValue());
}
@Override
public ParameterValue<?> deserialize(
IDeserializationContext deserializer)
throws SerializationException {
return deserializeInternal(deserializer);
}
/**
* Internal deserialization, method exists entirely to work around Java
* generics issues with DefaultParameterDescriptor.create(...).
*
* @param deserializer
* @return
* @throws SerializationException
*/
private <T> ParameterValue<T> deserializeInternal(
IDeserializationContext deserializer)
throws SerializationException {
String nameCode = deserializer.readString();
CharSequence rmk = deserializer.readString();
if ("null".equals(rmk)) {
rmk = null;
}
String classname = deserializer.readString();
Class<T> valueClass;
try {
valueClass = (Class<T>) Class.forName(classname);
} catch (ClassNotFoundException e) {
throw new SerializationException(
"Unknown parameter value class " + classname);
}
T defaultValue = (T) deserializer.readObject();
boolean required = deserializer.readBool();
Object value = deserializer.readObject();
ParameterDescriptor<T> desc = DefaultParameterDescriptor.create(
nameCode, rmk, valueClass, defaultValue, required);
Parameter param = new Parameter(desc, value);
return param;
}
}
private static final ParameterValueAdapter paramValAdapter = new ParameterValueAdapter();
private static final DefaultMathTransformFactory dmtFactory = new DefaultMathTransformFactory();
private static final String PROJCS = "PROJCS";
@Override
public GridGeometry2D deserialize(IDeserializationContext deserializer)
throws SerializationException {
@ -61,8 +167,47 @@ public class GridGeometry2DAdapter implements
int height = deserializer.readI32();
GridEnvelope2D gridRange = new GridEnvelope2D(x, y, width, height);
CoordinateReferenceSystem crs = CRS.parseWKT(deserializer
.readString());
/*
* Some of our projected CRS instances don't conform to WKT due to
* custom parameters, so we have to handle those differently
*/
String crsType = deserializer.readString();
CoordinateReferenceSystem crs = null;
if (PROJCS.equals(crsType)) {
Map<String, Object> props = null;
String projName = deserializer.readString();
GeographicCRS baseCrs = (GeographicCRS) CRS
.parseWKT(deserializer.readString());
String conversionName = deserializer.readString();
// recreate the ParameterValueGroup
String groupName = deserializer.readString();
int paramValueSize = deserializer.readI32();
GeneralParameterValue[] parameters = new GeneralParameterValue[paramValueSize];
for (int i = 0; i < paramValueSize; i++) {
parameters[i] = paramValAdapter.deserialize(deserializer);
}
props = new HashMap<String, Object>();
props.put("name", groupName);
ParameterGroup group = new ParameterGroup(props, parameters);
// create the conversions with the group
DefiningConversion dc = new DefiningConversion(conversionName,
group);
MathTransform mt = dmtFactory
.createParameterizedTransform(group);
CartesianCS cs = DefaultCartesianCS.PROJECTED;
props = new HashMap<String, Object>();
props.put("name", projName);
crs = new DefaultProjectedCRS(props, dc, baseCrs, mt, cs);
} else {
/*
* only had special handling for ProjectedCRS, just hope it
* correctly parses anything else as WKT
*/
crs = CRS.parseWKT(deserializer.readString());
}
double dx = deserializer.readDouble();
double dy = deserializer.readDouble();
@ -74,7 +219,7 @@ public class GridGeometry2DAdapter implements
return gridGeom;
} catch (Throwable e) {
throw new SerializationException(
"Error deserializing GridGeomtry2D", e);
"Error deserializing GridGeometry2D", e);
}
}
@ -86,7 +231,33 @@ public class GridGeometry2DAdapter implements
serializer.writeI32(gridGeom.getGridRange2D().width);
serializer.writeI32(gridGeom.getGridRange2D().height);
serializer.writeString(gridGeom.getCoordinateReferenceSystem().toWKT());
CoordinateReferenceSystem crs = gridGeom.getCoordinateReferenceSystem();
if (crs instanceof ProjectedCRS) {
serializer.writeString(PROJCS);
ProjectedCRS projCrs = (ProjectedCRS) crs;
String projName = projCrs.getName().toString();
serializer.writeString(projName);
serializer.writeString(projCrs.getBaseCRS().toWKT());
Conversion conversion = projCrs.getConversionFromBase();
serializer.writeString(conversion.getName().toString());
ParameterValueGroup params = conversion.getParameterValues();
serializer.writeString(params.getDescriptor().getName().getCode());
List<GeneralParameterValue> values = params.values();
serializer.writeI32(values.size());
for (GeneralParameterValue v : values) {
paramValAdapter.serialize(serializer, (ParameterValue<?>) v);
}
} else {
/*
* Cross fingers and hope it works ok with WKT. Seems to generally
* always write to WKT ok but then fails to parse it back out on
* some custom CRS instances.
*/
serializer.writeString("WKT");
serializer.writeString(crs.toWKT());
}
serializer.writeDouble(gridGeom.getEnvelope().getMinimum(0));
serializer.writeDouble(gridGeom.getEnvelope().getMinimum(1));
serializer.writeDouble(gridGeom.getEnvelope().getSpan(0));