Issue #2015 fix NPP displaying in collaboration shared display sessions

Change-Id: Ie5e40d8ff3e7a222448777b86d188822e3990746

Former-commit-id: 1e0026e60f [formerly 32ae6bfb63 [formerly d4e2da7f81d5c3ad005f299c936bd2d70f05b17a]]
Former-commit-id: 32ae6bfb63
Former-commit-id: bd3e4659fb
This commit is contained in:
Nate Jensen 2014-03-27 18:32:00 -05:00
parent 95710fff2a
commit befeb24d13
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 * algorithm to use great circle intersections for
* more accurate results * more accurate results
* Aug 27, 2013 #2190 mschenke Sped up transform functions * Aug 27, 2013 #2190 mschenke Sped up transform functions
* Mar 27, 2014 #2015 njensen Overrode getParameterValues()
* *
* </pre> * </pre>
* *
@ -148,6 +149,24 @@ public class VIIRSMapProjection extends MapProjection {
return Provider.PARAMETERS; 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) * (non-Javadoc)
* *

View file

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

View file

@ -19,12 +19,33 @@
**/ **/
package com.raytheon.uf.common.serialization.adapters; 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.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D; import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.Envelope2D; 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;
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.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.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.IDeserializationContext;
import com.raytheon.uf.common.serialization.ISerializationContext; 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; import com.raytheon.uf.common.serialization.SerializationException;
/** /**
* TODO Add Description * Dynamic Serialize type adapter for GridGeometry2D
* *
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * 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> * </pre>
* *
@ -50,6 +75,87 @@ import com.raytheon.uf.common.serialization.SerializationException;
public class GridGeometry2DAdapter implements public class GridGeometry2DAdapter implements
ISerializationTypeAdapter<GridGeometry2D> { 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 @Override
public GridGeometry2D deserialize(IDeserializationContext deserializer) public GridGeometry2D deserialize(IDeserializationContext deserializer)
throws SerializationException { throws SerializationException {
@ -61,8 +167,47 @@ public class GridGeometry2DAdapter implements
int height = deserializer.readI32(); int height = deserializer.readI32();
GridEnvelope2D gridRange = new GridEnvelope2D(x, y, width, height); 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 dx = deserializer.readDouble();
double dy = deserializer.readDouble(); double dy = deserializer.readDouble();
@ -74,7 +219,7 @@ public class GridGeometry2DAdapter implements
return gridGeom; return gridGeom;
} catch (Throwable e) { } catch (Throwable e) {
throw new SerializationException( 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().width);
serializer.writeI32(gridGeom.getGridRange2D().height); 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(0));
serializer.writeDouble(gridGeom.getEnvelope().getMinimum(1)); serializer.writeDouble(gridGeom.getEnvelope().getMinimum(1));
serializer.writeDouble(gridGeom.getEnvelope().getSpan(0)); serializer.writeDouble(gridGeom.getEnvelope().getSpan(0));