Issue #2028 Fixed date line issue in MakeHazardDialog

Change-Id: I033642a36bc601e74e37e091dc703dcb06e0f287

Former-commit-id: 08e09382db [formerly 6557515f64 [formerly 168dcc10eaf0102cc1e04a74db5ca7e2afa4be4f]]
Former-commit-id: 6557515f64
Former-commit-id: 165bc6c409
This commit is contained in:
Ron Anderson 2013-05-30 11:01:07 -05:00
parent 80896a4e31
commit ff6fe9e225
4 changed files with 189 additions and 34 deletions

View file

@ -112,6 +112,7 @@ import com.raytheon.viz.ui.statusline.StatusStore;
* Feb 28,2012 14436 mli Add RP.S - Rip Current * Feb 28,2012 14436 mli Add RP.S - Rip Current
* Apr 03,2012 436 randerso Reworked dialog to be called by Python MakeHazard procedure * Apr 03,2012 436 randerso Reworked dialog to be called by Python MakeHazard procedure
* Apr 09,2012 436 randerso Merged RNK's MakeHazards_Elevation procedure * Apr 09,2012 436 randerso Merged RNK's MakeHazards_Elevation procedure
* May 30,2012 2028 randerso Cleaned up dialog layout
* *
* </pre> * </pre>
* *
@ -786,7 +787,6 @@ public class MakeHazardDialog extends CaveSWTDialog implements
gd = new GridData(SWT.FILL, SWT.FILL, true, true); gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.minimumHeight = 100; gd.minimumHeight = 100;
gd.minimumWidth = 100; gd.minimumWidth = 100;
gd.heightHint = this.defaultMapWidth;
gd.widthHint = this.defaultMapWidth; gd.widthHint = this.defaultMapWidth;
theMapComposite.setLayoutData(gd); theMapComposite.setLayoutData(gd);
try { try {
@ -1021,7 +1021,8 @@ public class MakeHazardDialog extends CaveSWTDialog implements
hazardGroupList = new org.eclipse.swt.widgets.List(hazardTypeGroup, hazardGroupList = new org.eclipse.swt.widgets.List(hazardTypeGroup,
SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE); SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
gd.heightHint = hazardGroupList.getItemHeight() * 12 gd.heightHint = hazardGroupList.getItemHeight()
* Math.min(12, groups.size())
+ hazardGroupList.getBorderWidth(); + hazardGroupList.getBorderWidth();
hazardGroupList.setLayoutData(gd); hazardGroupList.setLayoutData(gd);
hazardGroupList.addSelectionListener(selAdapt); hazardGroupList.addSelectionListener(selAdapt);

View file

@ -36,7 +36,6 @@ import org.eclipse.swt.widgets.ScrollBar;
import org.geotools.coverage.grid.GeneralGridEnvelope; import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D; import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope; import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.operation.builder.GridToEnvelopeMapper; import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
import org.opengis.coverage.grid.GridEnvelope; import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.metadata.spatial.PixelOrientation; import org.opengis.metadata.spatial.PixelOrientation;
@ -73,7 +72,8 @@ import com.vividsolutions.jts.geom.Envelope;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Aug 23, 2011 randerso Initial creation * Aug 23, 2011 randerso Initial creation
* May 30, 2013 #2028 randerso Fixed date line issue with map display
* *
* </pre> * </pre>
* *
@ -305,25 +305,10 @@ public abstract class AbstractZoneSelector extends PaneManager {
this.mapRscList = mapRscList; this.mapRscList = mapRscList;
try { try {
// display envelope in lat/lon
Envelope env = getBoundingEnvelope(); Envelope env = getBoundingEnvelope();
// get envelope in the projection Coordinate llCrs = new Coordinate(env.getMinX(), env.getMinY());
ReferencedEnvelope llEnv = new ReferencedEnvelope(env, Coordinate urCrs = new Coordinate(env.getMaxX(), env.getMaxY());
MapUtil.LATLON_PROJECTION);
ReferencedEnvelope projEnv = llEnv.transform(gloc.getCrs(), true);
double[] in = new double[] { llEnv.getMinX(), llEnv.getMinY(),
llEnv.getMaxX(), llEnv.getMaxY() };
double[] out = new double[in.length];
MathTransform mt1 = MapUtil.getTransformFromLatLon(gloc.getCrs());
mt1.transform(in, 0, out, 0, 2);
Coordinate llCrs = new Coordinate(projEnv.getMinX(),
projEnv.getMinY());
Coordinate urCrs = new Coordinate(projEnv.getMaxX(),
projEnv.getMaxY());
Coordinate llGrid = MapUtil.nativeToGridCoordinate(llCrs, Coordinate llGrid = MapUtil.nativeToGridCoordinate(llCrs,
PixelOrientation.CENTER, gloc); PixelOrientation.CENTER, gloc);
@ -384,6 +369,8 @@ public abstract class AbstractZoneSelector extends PaneManager {
for (ZoneSelectorResource mapRsc : this.mapRscList) { for (ZoneSelectorResource mapRsc : this.mapRscList) {
env.expandToInclude(mapRsc.getBoundingEnvelope()); env.expandToInclude(mapRsc.getBoundingEnvelope());
} }
double delta = Math.max(env.getWidth(), env.getHeight()) * 0.02;
env.expandBy(delta);
return env; return env;
} }

View file

@ -36,11 +36,19 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Rectangle;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation; import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation;
import com.raytheon.uf.common.dataquery.db.QueryResult; import com.raytheon.uf.common.dataquery.db.QueryResult;
import com.raytheon.uf.common.geospatial.MapUtil; import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.util.WorldWrapCorrector;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
@ -74,6 +82,7 @@ import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.prep.PreparedGeometry; import com.vividsolutions.jts.geom.prep.PreparedGeometry;
@ -91,6 +100,7 @@ import com.vividsolutions.jts.io.WKBReader;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Aug 11, 2011 randerso Initial creation * Aug 11, 2011 randerso Initial creation
* Apr 10, 2013 #1854 randerso Fix for compatibility with PostGIS 2.0 * Apr 10, 2013 #1854 randerso Fix for compatibility with PostGIS 2.0
* May 30, 2013 #2028 randerso Fixed date line issue with map display
* *
* </pre> * </pre>
* *
@ -543,6 +553,8 @@ public class ZoneSelectorResource extends DbMapResource {
private GridLocation gloc; private GridLocation gloc;
private WorldWrapCorrector worldWrapCorrector;
/** /**
* @param data * @param data
* @param loadProperties * @param loadProperties
@ -557,6 +569,14 @@ public class ZoneSelectorResource extends DbMapResource {
this.outlineColor = RGBColors.getRGBColor("white"); this.outlineColor = RGBColors.getRGBColor("white");
this.wfoOutlineColor = RGBColors.getRGBColor("yellow"); this.wfoOutlineColor = RGBColors.getRGBColor("yellow");
this.gloc = gloc; this.gloc = gloc;
GeneralEnvelope env = new GeneralEnvelope(MapUtil.LATLON_PROJECTION);
env.setEnvelope(-180.0, -90.0, 180.0, 90.0);
GridGeometry2D latLonGridGeometry = new GridGeometry2D(
new GeneralGridEnvelope(new int[] { 0, 0 }, new int[] { 360,
180 }, false), env);
this.worldWrapCorrector = new WorldWrapCorrector(latLonGridGeometry);
} }
private ZoneInfo getZoneInfo(String zoneName) { private ZoneInfo getZoneInfo(String zoneName) {
@ -746,7 +766,7 @@ public class ZoneSelectorResource extends DbMapResource {
if (font == null) { if (font == null) {
font = GFEFonts.getFont(aTarget, 2); font = GFEFonts.getFont(aTarget, 2);
} }
double screenToWorldRatio = paintProps.getView().getExtent() double worldToScreenRatio = paintProps.getView().getExtent()
.getWidth() .getWidth()
/ paintProps.getCanvasBounds().width; / paintProps.getCanvasBounds().width;
@ -772,7 +792,7 @@ public class ZoneSelectorResource extends DbMapResource {
+ Math.abs(tuple.y - y); + Math.abs(tuple.y - y);
minDistance = Math.min(distance, minDistance); minDistance = Math.min(distance, minDistance);
} }
if (minDistance > 100 * screenToWorldRatio) { if (minDistance > 100 * worldToScreenRatio) {
String[] text = new String[] { "", "" }; String[] text = new String[] { "", "" };
if (this.labelZones) { if (this.labelZones) {
text[0] = zone; text[0] = zone;
@ -972,7 +992,7 @@ public class ZoneSelectorResource extends DbMapResource {
protected String getGeospatialConstraint(String geometryField, Envelope env) { protected String getGeospatialConstraint(String geometryField, Envelope env) {
StringBuilder constraint = new StringBuilder(); StringBuilder constraint = new StringBuilder();
Geometry g1 = MapUtil.getBoundingGeometry(gloc); Geometry g1 = buildBoundingGeometry(gloc);
if (env != null) { if (env != null) {
g1 = g1.intersection(MapUtil.createGeometry(env)); g1 = g1.intersection(MapUtil.createGeometry(env));
} }
@ -980,19 +1000,24 @@ public class ZoneSelectorResource extends DbMapResource {
constraint.append("ST_Intersects("); constraint.append("ST_Intersects(");
constraint.append(geometryField); constraint.append(geometryField);
constraint.append(", ST_GeomFromText('"); constraint.append(", ST_GeomFromText('");
constraint.append(g1.toString()); constraint.append(g1.toText());
constraint.append("',4326))"); constraint.append("',4326))");
return constraint.toString(); return constraint.toString();
} }
/**
* Get the bounding envelope of all overlapping geometry in CRS coordinates
*
* @return the envelope
*/
public Envelope getBoundingEnvelope() { public Envelope getBoundingEnvelope() {
if (this.boundingEnvelope == null) { if (this.boundingEnvelope == null) {
try { try {
this.boundingEnvelope = new Envelope(); this.boundingEnvelope = new Envelope();
StringBuilder query = new StringBuilder("SELECT "); StringBuilder query = new StringBuilder("SELECT ");
query.append("asBinary(ST_extent("); query.append("asBinary(ST_Envelope(");
query.append(resourceData.getGeomField()); query.append(resourceData.getGeomField());
query.append(")) as extent"); query.append(")) as extent");
@ -1019,11 +1044,20 @@ public class ZoneSelectorResource extends DbMapResource {
query.toString(), "maps", QueryLanguage.SQL); query.toString(), "maps", QueryLanguage.SQL);
WKBReader wkbReader = new WKBReader(); WKBReader wkbReader = new WKBReader();
byte[] b = (byte[]) mappedResult.getRowColumnValue(0, "extent"); for (int i = 0; i < mappedResult.getResultCount(); i++) {
if (b != null) { byte[] b = (byte[]) mappedResult.getRowColumnValue(i,
Geometry g = wkbReader.read(b); "extent");
this.boundingEnvelope.expandToInclude(g if (b != null) {
.getEnvelopeInternal()); Geometry g = wkbReader.read(b);
Envelope env = g.getEnvelopeInternal();
ReferencedEnvelope llEnv = new ReferencedEnvelope(env,
MapUtil.LATLON_PROJECTION);
ReferencedEnvelope projEnv = llEnv.transform(
gloc.getCrs(), true);
this.boundingEnvelope.expandToInclude(projEnv);
}
} }
} catch (VizException e) { } catch (VizException e) {
@ -1048,4 +1082,129 @@ public class ZoneSelectorResource extends DbMapResource {
// d = new double[] { d[d.length - 1] }; // d = new double[] { d[d.length - 1] };
return d; return d;
} }
private Geometry buildBoundingGeometry(GridLocation gloc) {
try {
Coordinate ll = MapUtil.gridCoordinateToNative(
new Coordinate(0, 0), PixelOrientation.LOWER_LEFT, gloc);
Coordinate ur = MapUtil.gridCoordinateToNative(
new Coordinate(gloc.getNx(), gloc.getNy()),
PixelOrientation.LOWER_LEFT, gloc);
MathTransform latLonToCRS = MapUtil.getTransformFromLatLon(gloc
.getCrs());
Coordinate pole = null;
double[] output = new double[2];
try {
latLonToCRS.transform(new double[] { 0, 90 }, 0, output, 0, 1);
Coordinate northPole = new Coordinate(output[0], output[1]);
if (northPole.x >= ll.x && northPole.x <= ur.x
&& northPole.y >= ll.y && northPole.y <= ur.y) {
pole = northPole;
}
} catch (TransformException e) {
// north pole not defined in CRS
}
if (pole == null) {
try {
latLonToCRS.transform(new double[] { 0, -90 }, 0, output,
0, 1);
Coordinate southPole = new Coordinate(output[0], output[1]);
if (southPole.x >= ll.x && southPole.x <= ur.x
&& southPole.y >= ll.y && southPole.y <= ur.y) {
pole = southPole;
}
} catch (TransformException e) {
// south pole not defined in CRS
}
}
// compute delta = min cell dimension in meters
Coordinate cellSize = gloc.gridCellSize();
double delta = Math.min(cellSize.x, cellSize.y) * 1000;
Geometry poly;
if (pole == null) {
poly = polygonFromGloc(gloc, delta, ll, ur);
} else {
// if pole is in the domain split the domain into four quadrants
// with corners at the pole
Coordinate[][] quadrant = new Coordinate[4][2];
quadrant[0][0] = ll;
quadrant[0][1] = pole;
quadrant[1][0] = new Coordinate(ll.x, pole.y);
quadrant[1][1] = new Coordinate(pole.x, ur.y);
quadrant[2][0] = pole;
quadrant[2][1] = ur;
quadrant[3][0] = new Coordinate(pole.x, ll.y);
quadrant[3][1] = new Coordinate(ur.x, pole.y);
List<Polygon> polygons = new ArrayList<Polygon>(4);
for (Coordinate[] q : quadrant) {
if (q[1].x > q[0].x && q[1].y > q[0].y) {
polygons.add(polygonFromGloc(gloc, delta, q[0], q[1]));
}
}
GeometryFactory gf = new GeometryFactory();
poly = gf.createMultiPolygon(polygons
.toArray(new Polygon[polygons.size()]));
}
MathTransform crsToLatLon = MapUtil.getTransformToLatLon(gloc
.getCrs());
poly = JTS.transform(poly, crsToLatLon);
// correct for world wrap
poly = this.worldWrapCorrector.correct(poly);
return poly;
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
"Error computing bounding geometry", e);
}
return null;
}
private Polygon polygonFromGloc(GridLocation gridLoc, double delta,
Coordinate ll, Coordinate ur) {
double width = ur.x - ll.x;
double height = ur.y - ll.y;
int nx = (int) Math.abs(Math.ceil(width / delta));
int ny = (int) Math.abs(Math.ceil(height / delta));
double dx = width / nx;
double dy = height / ny;
Coordinate[] coordinates = new Coordinate[2 * (nx + ny) + 1];
int i = 0;
for (int x = 0; x < nx; x++) {
coordinates[i++] = new Coordinate(x * dx + ll.x, ll.y);
}
for (int y = 0; y < ny; y++) {
coordinates[i++] = new Coordinate(ur.x, y * dy + ll.y);
}
for (int x = nx; x > 0; x--) {
coordinates[i++] = new Coordinate(x * dx + ll.x, ur.y);
}
for (int y = ny; y > 0; y--) {
coordinates[i++] = new Coordinate(ll.x, y * dy + ll.y);
}
coordinates[i++] = coordinates[0];
GeometryFactory gf = new GeometryFactory();
LinearRing shell = gf.createLinearRing(coordinates);
Polygon poly = gf.createPolygon(shell, null);
return poly;
}
} }

View file

@ -48,7 +48,8 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 12, 2011 mschenke Initial creation * Oct 12, 2011 mschenke Initial creation
* May 30, 2013 #2028 randerso Changed to return simple geometry or multi-geometry if possible
* *
* </pre> * </pre>
* *
@ -93,8 +94,15 @@ public class WorldWrapCorrector {
} else { } else {
wrapCorrect(geom, geoms); wrapCorrect(geom, geoms);
} }
return geom.getFactory().createGeometryCollection(
geoms.toArray(new Geometry[geoms.size()])); Geometry retVal;
if (geoms.size() == 1) {
retVal = geoms.get(0);
} else {
retVal = geom.getFactory().buildGeometry(geoms);
}
return retVal;
} }
/** /**