diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java
index f9a16efd4c..bccd386919 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java
+++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java
@@ -12,14 +12,14 @@ import javax.measure.converter.UnitConverter;
import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration;
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil.Direction;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.warngen.PreferenceUtil;
import com.raytheon.viz.warngen.gis.Area;
import com.raytheon.viz.warngen.gis.ClosestPoint;
-import com.raytheon.viz.warngen.gis.GisUtil;
-import com.raytheon.viz.warngen.gis.GisUtil.Direction;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
@@ -41,7 +41,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
* Apr 24, 2013 1944 jsanchez Updated calculateLocationPortion visibility to public.
* May 2, 2013 1963 jsanchez Referenced calculatePortion from GisUtil if intersection less than DEFAULT_PORTION_TOLERANCE.
* Sep 13, 2013 DR 16601 D. Friedman Fix from jsanchez: Allow cities outside the CWA.
- *
+ * Dec 4, 2013 2604 jsanchez Refactored GisUtil.
*
*
* @author jsanchez
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java
index 90e1542724..63a3acab55 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java
+++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java
@@ -33,6 +33,8 @@ import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration.
import com.raytheon.uf.common.dataplugin.warning.config.GeospatialConfiguration;
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
+import com.raytheon.uf.common.dataplugin.warning.portions.PortionsUtil;
import com.raytheon.uf.common.dataplugin.warning.util.CountyUserData;
import com.raytheon.uf.common.dataplugin.warning.util.FileUtil;
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
@@ -74,6 +76,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometry;
* Apr 29, 2013 1955 jsanchez Ignored comparing the geometry's user data when finding intersected areas.
* May 2, 2013 1963 jsanchez Updated method to determine partOfArea.
* Aug 19, 2013 2177 jsanchez Used portionsUtil to calculate area portion descriptions.
+ * Dec 4, 2013 2604 jsanchez Refactored GisUtil and PortionsUtil.
*
*
* @author chammack
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PortionsUtil.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PortionsUtil.java
deleted file mode 100644
index c7f294da93..0000000000
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/PortionsUtil.java
+++ /dev/null
@@ -1,459 +0,0 @@
-/**
- * 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.viz.warngen.gis;
-
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-
-import com.raytheon.viz.warngen.gis.GisUtil.Direction;
-import com.raytheon.viz.warngen.gui.WarngenLayer;
-import com.vividsolutions.jts.geom.Geometry;
-
-/**
- * Port of A1 code that determines the portions of the county or zone
- * descriptions, such as NORTHWEST.
- *
- *
- *
- * SOFTWARE HISTORY
- *
- * Date Ticket# Engineer Description
- * ------------ ---------- ----------- --------------------------
- * Aug 5, 2013 2177 jsanchez Initial creation
- * Sep 22, 2013 2177 jsanchez Updated logic. Used GisUtil for very small portions.
- *
- *
- *
- * @author jsanchez
- * @version 1.0
- */
-
-public class PortionsUtil {
-
- private GridUtil gridUtil;
-
- public PortionsUtil(WarngenLayer layer) throws Exception {
- gridUtil = new GridUtil(layer, layer.getLocalGridGeometry(),
- layer.getlocalToLatLon());
- }
-
- /**
- * Determines the the appropriate portion description for the warnedArea
- * intersecting the countyOrZone.
- *
- * @param entityID
- * @param countyOrZone
- * @param warnedArea
- * @param useExtreme
- * @return
- * @throws Exception
- */
- public EnumSet getPortions(String entityID,
- Geometry countyOrZone, Geometry warnedArea, boolean useExtreme)
- throws Exception {
- countyOrZone.getUserData();
- EntityData entityData = gridUtil.calculateGrids(countyOrZone,
- warnedArea);
- EnumSet portions = null;
- if (entityData.getMeanMask() == 0 || entityData.getCoverageMask() == 0
- || entityData.getMeanMask() == entityData.getCoverageMask()) {
- // This takes into account the warned areas that are very small
- // the convex hull of the warned area is used for case the
- // warnedArea is a geometry collection.
- portions = GisUtil.calculateLocationPortion(countyOrZone,
- warnedArea.convexHull(), useExtreme);
- } else {
- portions = getAreaDesc(entityData.getMeanMask(),
- entityData.getCoverageMask(), entityData.getOctants(),
- useExtreme);
- }
- return suppressPortions(entityID, portions);
- }
-
- /**
- * Looks up if the designated entity ID has an suppressed directions. For
- * example, a county or zone may not need to include the north and sound
- * direction description if it was included in the area.suppress file.
- *
- * @param entityID
- * @param portions
- * @return
- */
- private EnumSet suppressPortions(String entityID,
- EnumSet portions) {
- Map> suppressedCounties = SuppressMap
- .getInstance().getAreas();
- if (entityID != null && suppressedCounties != null
- && !suppressedCounties.isEmpty()) {
- List suppressedDirections = suppressedCounties
- .get(entityID.toUpperCase());
- if (suppressedDirections != null && !suppressedDirections.isEmpty()) {
- portions.removeAll(suppressedDirections);
- }
- }
-
- return portions;
- }
-
- /**
- * Port from A1 code of GeoEntityLookupTable::getAreaDesc.
- *
- * @param meanMask
- * @param areaMask
- * @param octants
- * @param exYes
- */
- private static EnumSet getAreaDesc(int meanMask, int areaMask,
- int octants, boolean exYes) {
- EnumSet portions = EnumSet.noneOf(Direction.class);
-
- // Test for case where we cannot do portions
- if (meanMask == 0 || areaMask == 0) {
- return portions;
- }
-
- // The next block of code is the original port of A1 code but prevented
- // producing the correct result:
- // Test for case where area is completely within one subsection.
- // if (meanMask == areaMask) {
- // return getPointDesc(meanMask, exYes);
- // }
-
- // Test for central by not being near adjacent borders.
- // Another possible case of a stripe across the middle.
- if (octants == 0
- || ((octants & CoverageConstants.EXTREME_YES) == 0)
- && (meanMask & CoverageConstants.CENTER) == CoverageConstants.CENTER) {
- portions.add(Direction.CENTRAL);
- return portions;
- }
-
- if ((octants & 0xFFFF) == 0xFFFF) {
- return portions;
- }
-
- // Identify quadrants in use, q is typical, qq is diagonal.
- int xoctant = octants >> 8;
- int xxoctant = octants >> 16;
- int nn, ss, ee, ww, ne, nw, se, sw;
- nn = ss = ee = ww = ne = nw = se = sw = 0;
- int omerge = xxoctant | xoctant | octants;
- if ((omerge & (CoverageConstants.NNE | CoverageConstants.ENE)) != 0) {
- ne = 1;
- }
- if ((omerge & (CoverageConstants.SSE | CoverageConstants.ESE)) != 0) {
- se = 1;
- }
- if ((omerge & (CoverageConstants.NNW | CoverageConstants.WNW)) != 0) {
- nw = 1;
- }
- if ((omerge & (CoverageConstants.SSW | CoverageConstants.WSW)) != 0) {
- sw = 1;
- }
- if ((omerge & (CoverageConstants.NNE | CoverageConstants.NNW)) != 0) {
- nn = 1;
- }
- if ((omerge & (CoverageConstants.SSE | CoverageConstants.SSW)) != 0) {
- ss = 1;
- }
- if ((omerge & (CoverageConstants.WNW | CoverageConstants.WSW)) != 0) {
- ww = 1;
- }
- if ((omerge & (CoverageConstants.ENE | CoverageConstants.ESE)) != 0) {
- ee = 1;
- }
- if ((areaMask & CoverageConstants.NORTH_SOUTH) == 0) {
- nn = ss = ne = nw = se = sw = 0;
- }
- if ((areaMask & CoverageConstants.EAST_WEST) == 0) {
- ee = ww = ne = nw = se = sw = 0;
- }
- int q = ne + nw + se + sw;
- int qq = nn + ss + ee + ww;
-
- // Identify extremes in use.
- int nnx, ssx, eex, wwx;
- nnx = ssx = eex = wwx = 0;
- if ((areaMask & CoverageConstants.XNORTH) != 0) {
- nnx = 1;
- }
- if ((areaMask & CoverageConstants.XSOUTH) != 0) {
- ssx = 1;
- }
- if ((areaMask & CoverageConstants.XWEST) != 0) {
- wwx = 1;
- }
- if ((areaMask & CoverageConstants.XEAST) != 0) {
- eex = 1;
- }
- int xxx = nnx + ssx + eex + wwx;
-
- // Modify masks based on whether we can use extreme.
- if ((octants & CoverageConstants.EXTREME_NO) != 0
- && (areaMask & CoverageConstants.EXTREME) != 0) {
- areaMask &= CoverageConstants.NOT_EXTREME;
- meanMask &= CoverageConstants.NOT_EXTREME;
- }
-
- // Possible case of a stripe across the middle
- if (q == 0) {
- ;// Only one direction encoded
- } else if (q == 2 && nw == se || q == 2 && ne == sw || qq == 2
- && nn == ss || qq == 2 && ee == ww) {
- if ((meanMask & CoverageConstants.CENTRAL) == CoverageConstants.CENTRAL
- || nnx == ssx && wwx == eex) {
- portions.add(Direction.CENTRAL);
- return portions;
- }
- return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
- }
-
- // Modify masks based on whether we can use central.
- if (xxx > 2 || nnx != ssx && wwx != eex) {
- areaMask &= CoverageConstants.NOT_CENTRAL;
- meanMask &= CoverageConstants.NOT_CENTRAL;
- }
-
- // All quadrants in use.
- if (q == 4 && qq == 4) {
- return EnumSet.noneOf(Direction.class);
- }
-
- // Only one typical quadrant in use.
- if (q == 1) {
- return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
- }
-
- // Further modify masks based on whether we can use central.
- if (xxx >= 2) {
- areaMask &= CoverageConstants.NOT_CENTRAL;
- meanMask &= CoverageConstants.NOT_CENTRAL;
- }
-
- // No more than two quadrants of any kind in use, or all quadrants.
- if (q < 3 && qq < 3) {
- if (nnx != ssx && wwx != eex
- || (meanMask & CoverageConstants.CENTRAL) != 0) {
- return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
-
- } else {
- return getPointDesc2(areaMask, exYes, nn, ss, ee, ww);
- }
- }
-
- // Three typical quadrants in use.
- if (q == 3 && qq != 3) {
-
- if (ne == 0) {
- // The next line is the original port of A1 code but prevented
- // producing the correct result:
- // if (ne == 0 && (xxoctant & (SSW | WSW)) != 0) {
- portions.add(Direction.SOUTH);
- portions.add(Direction.WEST);
-
- } else if (se == 0) {
- // The next line is the original port of A1 code but prevented
- // producing the correct result:
- // } else if (se == 0 && (xxoctant & (NNW | WNW)) != 0) {
- portions.add(Direction.NORTH);
- portions.add(Direction.WEST);
-
- } else if (nw == 0) {
- // The next line is the original port of A1 code but prevented
- // producing the correct result:
- // } else if (nw == 0 && (xxoctant & (SSE | ESE)) != 0) {
- portions.add(Direction.SOUTH);
- portions.add(Direction.EAST);
-
- } else if (sw == 0) {
- // The next line is the original port of A1 code but prevented
- // producing the correct result:
- // } else if (sw == 0 && (xxoctant & (NNE | ENE)) != 0) {
- portions.add(Direction.NORTH);
- portions.add(Direction.EAST);
- }
- // The next line is the original port of A1 code but prevented
- // producing the correct result:
- // return getPointDesc(meanMask, exYes);
- }
-
- // Three diagonal quadrants in use.
- if (qq == 3 && portions.isEmpty()) {
- if (nn == 0) {
- portions.add(Direction.SOUTH);
- } else if (ss == 0) {
- portions.add(Direction.NORTH);
- } else if (ww == 0) {
- portions.add(Direction.EAST);
- } else if (ee == 0) {
- portions.add(Direction.WEST);
- }
- }
-
- // add extreme for three quadrant case.
- if (!portions.isEmpty()) {
- if (exYes && ((areaMask & CoverageConstants.EXTREME)) != 0) {
- portions.add(Direction.EXTREME);
- }
- return portions;
- }
-
- // All of either type of quadrant in use.
- if (q == 4 || qq == 4) {
- return EnumSet.noneOf(Direction.class);
- }
-
- // Case of a pure simple direction.
- nn = areaMask & CoverageConstants.NORTHERN;
- ss = areaMask & CoverageConstants.SOUTHERN;
- ee = areaMask & CoverageConstants.EASTERN;
- ww = areaMask & CoverageConstants.WESTERN;
- if (ss != 0 && nn != 0 || q == 0) {
- if (ee == 0 && ww != 0) {
- portions.add(Direction.WEST);
- }
- if (ww == 0 && ee != 0) {
- portions.add(Direction.EAST);
- }
- } else if (ee != 0 && ww != 0 || q == 0) {
- if (nn == 0 && ss != 0) {
- portions.add(Direction.SOUTH);
- }
- if (ss == 0 && nn != 0) {
- portions.add(Direction.NORTH);
- }
- }
-
- // add extreme for simple direction case.
- if (!portions.isEmpty()) {
- if (exYes && ((areaMask & CoverageConstants.EXTREME)) != 0) {
- portions.add(Direction.EXTREME);
- }
- return portions;
- }
-
- // Catch with the point descriptor one last time
- return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
- }
-
- /**
- * Port from A1 code of GeoEntityLookupTable::getPointDesc.
- *
- * @param mask
- * @param exYes
- * @return
- */
- private static EnumSet getPointDesc(int mask, boolean exYes) {
- EnumSet portions = EnumSet.noneOf(Direction.class);
-
- int cc = mask & CoverageConstants.CENTRAL;
- if (cc == CoverageConstants.CENTRAL) {
- portions.add(Direction.CENTRAL);
- return portions;
- }
-
- if ((mask & CoverageConstants.NORTH_SOUTH) == 0) {
- ;
- } else if ((mask & CoverageConstants.SOUTHERN) == (mask & CoverageConstants.NORTH_SOUTH)) {
- portions.add(Direction.SOUTH);
- } else if ((mask & CoverageConstants.NORTHERN) == (mask & CoverageConstants.NORTH_SOUTH)) {
- portions.add(Direction.NORTH);
- }
-
- if ((mask & CoverageConstants.EAST_WEST) == 0) {
- ;
- } else if ((mask & CoverageConstants.WESTERN) == (mask & CoverageConstants.EAST_WEST)) {
- portions.add(Direction.WEST);
- } else if ((mask & CoverageConstants.EASTERN) == (mask & CoverageConstants.EAST_WEST)) {
- portions.add(Direction.EAST);
- }
-
- if (portions.isEmpty()) {
- return portions;
- }
-
- if (cc != 0) {
- portions.add(Direction.CENTRAL);
- }
-
- if (exYes && ((int) (mask & CoverageConstants.EXTREME) != 0)) {
- portions.add(Direction.EXTREME);
- }
-
- return portions;
- }
-
- /**
- * This method is not a direct port from A1. The original getPointDesc did
- * not produce the expected results. This method is a modified version of
- * getPointDesct that uses the calculated qq values instead of just the
- * meanMask.
- *
- * @param mask
- * @param exYes
- * @return
- */
- private static EnumSet getPointDesc2(int mask, boolean exYes,
- int nn, int ss, int ee, int ww) {
- EnumSet portions = EnumSet.noneOf(Direction.class);
-
- if (mask == 0) {
- return portions;
- }
-
- int counter = 0;
- if (nn != 0 && ss != 0) {
- ;
- } else if (ss != 0) {
- portions.add(Direction.SOUTH);
- counter++;
- } else if (nn != 0) {
- portions.add(Direction.NORTH);
- counter++;
- }
-
- if (ee != 0 && ww != 0) {
- ;
- } else if (ww != 0) {
- portions.add(Direction.WEST);
- counter++;
- } else if (ee != 0) {
- portions.add(Direction.EAST);
- counter++;
- }
-
- if (portions.isEmpty()) {
- return portions;
- }
-
- int cc = mask & CoverageConstants.CENTRAL;
- boolean useCentral = counter < 2;
- if (useCentral && cc != 0) {
- portions.add(Direction.CENTRAL);
- }
-
- if (exYes && ((int) (mask & CoverageConstants.EXTREME) != 0)) {
- portions.add(Direction.EXTREME);
- }
-
- return portions;
- }
-}
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java
index 741aabf8ba..2abfe36a7d 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java
+++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java
@@ -56,6 +56,7 @@ import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialFactory;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
import com.raytheon.uf.common.dataplugin.warning.util.FileUtil;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
import com.raytheon.uf.common.geospatial.DestinationGeodeticCalculator;
@@ -114,7 +115,7 @@ import com.vividsolutions.jts.geom.Point;
* points that are in the past.
* Jun 24, 2013 DR 16317 D. Friedman Handle "motionless" track.
* Jun 25, 2013 16224 Qinglu Lin Resolved the issue with "Date start" for pathcast in CON.
- *
+ * Dec 4, 2013 2604 jsanchez Refactored GisUtil.
*
*
* @author chammack
@@ -255,7 +256,7 @@ public class Wx {
GeometryFactory gf = new GeometryFactory();
- boolean flag = true;
+ boolean flag = true;
List pointsToBeRemoved = null;
try {
Abbreviation areaTypeAbbrev = null;
@@ -279,8 +280,8 @@ public class Wx {
if (stormTrackState.isNonstationary()) {
List coordinates = new ArrayList();
Date stormTime = new Date();
- Date start = DateUtil.roundDate(new Date(stormTime.getTime() + delta),
- pathcastConfiguration.getInterval());
+ Date start = DateUtil.roundDate(new Date(stormTime.getTime()
+ + delta), pathcastConfiguration.getInterval());
DestinationGeodeticCalculator gc = new DestinationGeodeticCalculator();
while (start.getTime() <= wwaStopTime) {
PathCast cast = new PathCast();
@@ -449,16 +450,20 @@ public class Wx {
points = new ArrayList(0);
}
if (flag) {
- pointsToBeRemoved = findPointsToBeRemoved(centroid, points, stormTrackState.angle);
+ pointsToBeRemoved = findPointsToBeRemoved(centroid, points,
+ stormTrackState.angle);
flag = false;
}
if (pointsToBeRemoved != null) {
- for (int i=0; i points2 = pcPoints.get(pc2);
- ClosestPoint found = find(cp, points2, Integer.MAX_VALUE);
+ ClosestPoint found = find(cp, points2,
+ Integer.MAX_VALUE);
if (found != null) {
// We found a point within maxCount in this
// list.
@@ -958,7 +964,8 @@ public class Wx {
return new Date(this.wwaStartTime);
}
- private List findPointsToBeRemoved(Point centroid, List points, double stormtrackAngle) {
+ private List findPointsToBeRemoved(Point centroid,
+ List points, double stormtrackAngle) {
// convert storm track angle to geometry angle in range of (0,360)
double convertedAngle = 90.0 - stormtrackAngle;
if (convertedAngle < 0.0)
@@ -968,17 +975,19 @@ public class Wx {
List removedPoints = new ArrayList();
while (iter.hasNext()) {
ClosestPoint cp = iter.next();
- double d = Math.abs(convertedAngle - computeAngle(centroid, cp.point));
+ double d = Math.abs(convertedAngle
+ - computeAngle(centroid, cp.point));
if (d > 180.0)
d = 360.0 - d;
if (d > 90.0)
removedPoints.add(cp);
}
- return removedPoints;
+ return removedPoints;
}
private double computeAngle(Point p, Coordinate c) {
- double angle = Math.atan2(c.y - p.getY(), c.x - p.getX()) * 180 / Math.PI;
+ double angle = Math.atan2(c.y - p.getY(), c.x - p.getX()) * 180
+ / Math.PI;
if (angle < 0)
angle += 360;
return angle;
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java
index 13ccbf53d4..78401c876f 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java
+++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java
@@ -67,6 +67,7 @@ import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialFactory;
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialMetadata;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
import com.raytheon.uf.common.dataplugin.warning.util.CountyUserData;
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
import com.raytheon.uf.common.geospatial.DestinationGeodeticCalculator;
@@ -112,7 +113,6 @@ import com.raytheon.viz.awipstools.common.stormtrack.StormTrackUIManager;
import com.raytheon.viz.core.rsc.jts.JTSCompiler;
import com.raytheon.viz.radar.RadarHelper;
import com.raytheon.viz.warngen.WarngenException;
-import com.raytheon.viz.warngen.gis.GisUtil;
import com.raytheon.viz.warngen.gis.PolygonUtil;
import com.raytheon.viz.warngen.util.CurrentWarnings;
import com.raytheon.viz.warngen.util.FipsUtil;
@@ -194,6 +194,7 @@ import com.vividsolutions.jts.io.WKTReader;
* 10/21/2013 DR 16632 D. Friedman Modify areaPercent exception handling. Fix an NPE.
* Use A1 hatching behavior when no county passes the inclusion filter.
* 10/29/2013 DR 16734 D. Friedman If redraw-from-hatched-area fails, don't allow the pollygon the be used.
+ * 12/04/2013 2604 jsanchez Refactored GisUtil.
*
*
* @author mschenke
@@ -530,7 +531,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
break;
}
}
- if (! this.haveInput)
+ if (!this.haveInput)
return null;
hatchedArea = this.hatchedArea;
hatchedWarningArea = this.hatchedWarningArea;
@@ -1614,30 +1615,31 @@ public class WarngenLayer extends AbstractStormTrackResource {
Geometry newHatchedArea = null;
Geometry newUnfilteredArea = null;
boolean useFilteredArea = false;
- boolean useFallback = getConfiguration().getHatchedAreaSource().isInclusionFallback();
+ boolean useFallback = getConfiguration().getHatchedAreaSource()
+ .isInclusionFallback();
/*
* The resultant warning area is constructed in one of two ways:
- *
+ *
* 1. When preservedSelection is null:
- *
+ *
* If at least one county in hatchedArea passes the inclusion filter,
* the result contains only the counties in hatchedArea that pass the
* inclusion filter. Otherwise, all counties in hatchedArea are
* included.
- *
+ *
* This behavior reflects A1 baseline template logic. The fallback can
* be disabled by setting AreaSourceConfiguration.isInclusionFallback to
* false.
- *
+ *
* 2. When preservedSelection is not null:
- *
+ *
* A county is included in the result if and only if it is contained in
* preservedSelection. If the portion of the county in hatchedArea is
* non-empty, it used. Otherwise, the hatched portion from
* preservedSelection is used.
- *
- *
+ *
+ *
* In both cases, when there is an old warning area in effect (i.e., for
* followups), the intersection of hatchedArea and the old warning area
* is used instead of hatchedArea.
@@ -1709,7 +1711,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
} else {
boolean passed = filterArea(f, intersection, true);
useFilteredArea = useFilteredArea || passed;
- include = (passed || filterAreaSecondChance(f, intersection, true))
+ include = (passed || filterAreaSecondChance(f,
+ intersection, true))
&& (oldWarningPolygon == null
|| prepGeom.intersects(oldWarningPolygon) || isOldAreaOutsidePolygon(f));
newUnfilteredArea = union(newUnfilteredArea, intersection);
@@ -1727,8 +1730,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
}
}
- newHatchedArea = useFilteredArea && newHatchedArea != null ? newHatchedArea :
- useFallback ? newUnfilteredArea : null;
+ newHatchedArea = useFilteredArea && newHatchedArea != null ? newHatchedArea
+ : useFallback ? newUnfilteredArea : null;
return newHatchedArea != null ? newHatchedArea : new GeometryFactory()
.createGeometryCollection(new Geometry[0]);
}
@@ -1768,13 +1771,16 @@ public class WarngenLayer extends AbstractStormTrackResource {
if (oldWarningArea != null) {
int areaPercent = -1;
try {
- areaPercent = Double.valueOf(
- ((oldWarningPolygon.intersection(warningPolygon)
- .getArea() / oldWarningArea.getArea()) * 100))
- .intValue();
+ areaPercent = Double
+ .valueOf(
+ ((oldWarningPolygon.intersection(
+ warningPolygon).getArea() / oldWarningArea
+ .getArea()) * 100)).intValue();
} catch (Exception e) {
- statusHandler.handle(Priority.VERBOSE,
- "Error determining amount of overlap with original polygon", e);
+ statusHandler
+ .handle(Priority.VERBOSE,
+ "Error determining amount of overlap with original polygon",
+ e);
areaPercent = 100;
}
if (oldWarningPolygon.intersects(warningPolygon) == false
@@ -2277,7 +2283,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
if (areaHatcher != null) {
Geometry[] areas = areaHatcher.getHatchedAreas();
if (areas == null) {
- // Somehow, the hatcher has not been run. Try it now.
+ // Somehow, the hatcher has not been run. Try it now.
warningAreaChanged();
areas = areaHatcher.getHatchedAreas();
// If still null, give up.
@@ -2298,8 +2304,9 @@ public class WarngenLayer extends AbstractStormTrackResource {
/*
* If redraw failed, do not allow this polygon to be used to
* generate a warning.
- *
- * Note that this duplicates code from updateWarnedAreaState.
+ *
+ * Note that this duplicates code from
+ * updateWarnedAreaState.
*/
state.strings.clear();
state.setWarningArea(null);
@@ -2848,9 +2855,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
if (oldWarningArea != null) {
// for a CON, prevents extra areas to be added
Set fipsIds = getAllFipsInArea(oldWarningArea);
- if (fipsIds.contains(featureFips) == false ||
- ! (oldWarningPolygon.contains(point) == true
- || isOldAreaOutsidePolygon(f))) {
+ if (fipsIds.contains(featureFips) == false
+ || !(oldWarningPolygon.contains(point) == true || isOldAreaOutsidePolygon(f))) {
break;
}
}
@@ -2862,7 +2868,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
for (GeospatialData gd : dataWithFips) {
Geometry g = gd.geometry;
if (oldWarningArea != null) {
- g = GeometryUtil.intersection(oldWarningArea, g);
+ g = GeometryUtil
+ .intersection(oldWarningArea, g);
}
fipsParts.add(g);
}
@@ -2871,12 +2878,11 @@ public class WarngenLayer extends AbstractStormTrackResource {
.toArray(new Geometry[fipsParts.size()]));
if (warningPolygon.contains(point)) {
// If inside warning polygon, intersect
- geom = GeometryUtil.intersection(
- warningPolygon, geom);
+ geom = GeometryUtil.intersection(warningPolygon,
+ geom);
}
newWarningArea = GeometryUtil.union(
- removeCounty(warningArea, featureFips),
- geom);
+ removeCounty(warningArea, featureFips), geom);
}
state.setWarningArea(filterWarningArea(newWarningArea));
setUniqueFip();
@@ -2898,25 +2904,29 @@ public class WarngenLayer extends AbstractStormTrackResource {
return null;
/*
* Note: Currently does not determine if warningArea is valid (i.e., in
- * contained in CWA, old warning area, etc.) or has overlapping geometries.
+ * contained in CWA, old warning area, etc.) or has overlapping
+ * geometries.
*/
Geometry newHatchedArea = null;
Geometry newUnfilteredArea = null;
boolean useFilteredArea = false;
- boolean useFallback = getConfiguration().getHatchedAreaSource().isInclusionFallback();
+ boolean useFallback = getConfiguration().getHatchedAreaSource()
+ .isInclusionFallback();
for (GeospatialData f : geoData.features) {
String gid = GeometryUtil.getPrefix(f.geometry.getUserData());
- Geometry warningAreaForFeature = getWarningAreaForGids(Arrays.asList(gid), warningArea);
+ Geometry warningAreaForFeature = getWarningAreaForGids(
+ Arrays.asList(gid), warningArea);
boolean passed = filterArea(f, warningAreaForFeature, false);
useFilteredArea = useFilteredArea || passed;
- if (passed || filterAreaSecondChance(f, warningAreaForFeature, false))
+ if (passed
+ || filterAreaSecondChance(f, warningAreaForFeature, false))
newHatchedArea = union(newHatchedArea, warningAreaForFeature);
newUnfilteredArea = union(newUnfilteredArea, warningAreaForFeature);
}
- newHatchedArea = useFilteredArea && newHatchedArea != null ? newHatchedArea :
- useFallback ? newUnfilteredArea : null;
+ newHatchedArea = useFilteredArea && newHatchedArea != null ? newHatchedArea
+ : useFallback ? newUnfilteredArea : null;
return newHatchedArea != null ? newHatchedArea : new GeometryFactory()
.createGeometryCollection(new Geometry[0]);
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java
index a951233d94..7c40a71560 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java
+++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java
@@ -66,6 +66,8 @@ import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration;
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration.AreaType;
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
+import com.raytheon.uf.common.dataplugin.warning.portions.PortionsUtil;
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
@@ -96,9 +98,7 @@ import com.raytheon.viz.warngen.WarngenException;
import com.raytheon.viz.warngen.gis.AffectedAreas;
import com.raytheon.viz.warngen.gis.Area;
import com.raytheon.viz.warngen.gis.ClosestPointComparator;
-import com.raytheon.viz.warngen.gis.GisUtil;
import com.raytheon.viz.warngen.gis.PathCast;
-import com.raytheon.viz.warngen.gis.PortionsUtil;
import com.raytheon.viz.warngen.gis.Wx;
import com.raytheon.viz.warngen.gui.BackupData;
import com.raytheon.viz.warngen.gui.FollowupData;
@@ -156,6 +156,7 @@ import com.vividsolutions.jts.io.WKTReader;
* May 30, 2013 DR 16237 D. Friedman Fix watch query.
* Jun 18, 2013 2118 njensen Only calculate pathcast if it's actually used
* Aug 19, 2013 2177 jsanchez Passed PortionsUtil to Area class.
+ * Dec 4, 2013 2604 jsanchez Refactored GisUtil and PortionsUtil.
*
*
* @author njensen
@@ -303,7 +304,9 @@ public class TemplateRunner {
AffectedAreas[] cancelareas = null;
Map intersectAreas = null;
Wx wx = null;
- Area area = new Area(new PortionsUtil(warngenLayer));
+ Area area = new Area(new PortionsUtil(LocalizationManager.getInstance()
+ .getCurrentSite(), warngenLayer.getLocalGridGeometry(),
+ warngenLayer.getlocalToLatLon()));
long wwaMNDTime = 0l;
try {
t0 = System.currentTimeMillis();
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/FollowUpUtil.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/FollowUpUtil.java
index 04b3dca957..572657a8e5 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/FollowUpUtil.java
+++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/FollowUpUtil.java
@@ -10,12 +10,12 @@ import java.util.regex.Pattern;
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil.Direction;
import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.viz.warngen.gis.AffectedAreas;
-import com.raytheon.viz.warngen.gis.GisUtil;
-import com.raytheon.viz.warngen.gis.GisUtil.Direction;
import com.raytheon.viz.warngen.text.ICommonPatterns;
/**
@@ -33,7 +33,7 @@ import com.raytheon.viz.warngen.text.ICommonPatterns;
* Aug 6, 2013 2243 jsanchez Updated the time ranges to be removed from the follow up list correctly.
* Aug 13, 2013 2243 jsanchez Removed calendar object.
* Aug 15, 2013 2243 jsanchez Reset the time ranges to the correct values.
- *
+ * Dec 4, 2013 2604 jsanchez Refactored GisUtil.
*
*
* @author bwoodle
diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/META-INF/MANIFEST.MF
index 7892dfdf1e..771618bf0a 100644
--- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/META-INF/MANIFEST.MF
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/META-INF/MANIFEST.MF
@@ -8,6 +8,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: com.raytheon.uf.common.dataplugin.warning,
com.raytheon.uf.common.dataplugin.warning.config,
com.raytheon.uf.common.dataplugin.warning.gis,
+ com.raytheon.uf.common.dataplugin.warning.portions,
com.raytheon.uf.common.dataplugin.warning.util
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization, com.raytheon.uf.common.serialization.comm
Import-Package: com.raytheon.uf.common.time,
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/CoverageConstants.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/CoverageConstants.java
similarity index 97%
rename from cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/CoverageConstants.java
rename to edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/CoverageConstants.java
index 64789b2751..0f747d7858 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/CoverageConstants.java
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/CoverageConstants.java
@@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.viz.warngen.gis;
+package com.raytheon.uf.common.dataplugin.warning.portions;
/**
* Port of A1 constants applied to a grid to determine county or zone portions.
@@ -30,6 +30,7 @@ package com.raytheon.viz.warngen.gis;
* ------------ ---------- ----------- --------------------------
* Aug 5, 2013 2177 jsanchez Initial creation
* Sep 22, 2013 2177 jsanchez Updated EW_MASK.
+ * Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
*
*
*
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/EntityData.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/EntityData.java
similarity index 92%
rename from cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/EntityData.java
rename to edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/EntityData.java
index 44d2311829..ae8afa1d66 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/EntityData.java
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/EntityData.java
@@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.viz.warngen.gis;
+package com.raytheon.uf.common.dataplugin.warning.portions;
/**
* Simple port of an A1 struct created by GridUtil and used by PortionsUtil.
@@ -29,6 +29,7 @@ package com.raytheon.viz.warngen.gis;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 5, 2013 2177 jsanchez Initial creation
+ * Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
*
*
*
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/GisUtil.java
similarity index 99%
rename from cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java
rename to edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/GisUtil.java
index 5fcb24e5b6..1bba3944ab 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GisUtil.java
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/GisUtil.java
@@ -18,7 +18,7 @@
* further licensing information.
**/
-package com.raytheon.viz.warngen.gis;
+package com.raytheon.uf.common.dataplugin.warning.portions;
import java.awt.geom.Point2D;
import java.util.ArrayList;
@@ -53,6 +53,7 @@ import com.vividsolutions.jts.geom.GeometryFactory;
* 0.10 to 0.0625 for EXTREME_DELTA; Added/modified code.
* May 1, 2013 1963 jsanchez Refactored calculatePortion to match A1. Do not allow 'Central' to be included if East and West is included.
* Jun 3, 2013 2029 jsanchez Updated A1 special case for calculating a central portion. Allowed East Central and West Central.
+ * Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
*
*
* @author chammack
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GridUtil.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/GridUtil.java
similarity index 94%
rename from cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GridUtil.java
rename to edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/GridUtil.java
index 061ac1b73d..a31996bcb5 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/GridUtil.java
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/GridUtil.java
@@ -17,21 +17,20 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.viz.warngen.gis;
+package com.raytheon.uf.common.dataplugin.warning.portions;
import java.util.ArrayList;
import java.util.List;
import org.geotools.coverage.grid.GeneralGridGeometry;
import org.geotools.coverage.grid.GridGeometry2D;
+import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
-import com.raytheon.uf.viz.core.exception.VizException;
-import com.raytheon.viz.warngen.gui.WarngenLayer;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Envelope;
@@ -55,6 +54,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 5, 2013 jsanchez Initial creation
+ * Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
*
*
*
@@ -76,13 +76,10 @@ public class GridUtil {
private byte[] countyOrZoneGrid;
- private WarngenLayer layer;
-
private MathTransform latLonToContour, contourToLatLon;
- public GridUtil(WarngenLayer layer, GeneralGridGeometry localGridGeometry,
+ public GridUtil(GeneralGridGeometry localGridGeometry,
MathTransform localToLatLon) throws Exception {
- this.layer = layer;
GridEnvelope range = localGridGeometry.getGridRange();
this.nx = range.getHigh(0);
@@ -124,7 +121,7 @@ public class GridUtil {
* @return
* @throws VizException
*/
- private byte[] toByteArray(Geometry geometry) throws VizException {
+ private byte[] toByteArray(Geometry geometry) throws Exception {
byte[] bytes = new byte[nx * ny];
float[][] floatData = toFloatData(geometry);
@@ -149,8 +146,8 @@ public class GridUtil {
* @return
* @throws VizException
*/
- private float[][] toFloatData(Geometry geometry) throws VizException {
- Geometry contoured = layer.convertGeom(geometry, latLonToContour);
+ private float[][] toFloatData(Geometry geometry) throws Exception {
+ Geometry contoured = convertGeom(geometry, latLonToContour);
List geomList = new ArrayList(
contoured.getNumGeometries());
GeometryUtil.buildGeometryList(geomList, contoured);
@@ -194,6 +191,27 @@ public class GridUtil {
return contourAreaData;
}
+ static private T convertGeom(T geom, MathTransform transform) {
+ if (geom == null) {
+ return null;
+ }
+ try {
+ if (geom instanceof Coordinate) {
+ return (T) JTS.transform(
+ new GeometryFactory().createPoint((Coordinate) geom),
+ transform).getCoordinate();
+ } else if (geom instanceof Geometry) {
+ return (T) JTS.transform((Geometry) geom, transform);
+ } else {
+ throw new RuntimeException("Invalid type passed in: "
+ + geom.getClass());
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Error transforming object, "
+ + e.getLocalizedMessage(), e);
+ }
+ }
+
/**
* Ported only the logic from A1 code
* GeoEntityLookupTable::finishDefineArea() that calculates the meanMask,
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ImpactedQuadrants.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/ImpactedQuadrants.java
similarity index 99%
rename from cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ImpactedQuadrants.java
rename to edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/ImpactedQuadrants.java
index acb3f6e94e..d9eea261d9 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ImpactedQuadrants.java
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/ImpactedQuadrants.java
@@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.viz.warngen.gis;
+package com.raytheon.uf.common.dataplugin.warning.portions;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
@@ -37,7 +37,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
* ------------ ---------- ----------- --------------------------
* May 2, 2013 1963 jsanchez Initial creation
* Jun 3, 2013 2029 jsanchez Fixed incorrect A1 port. Added additional attributes to calculate portions of areas.
- *
+ * Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
*
*
* @author jsanchez
diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/PortionsUtil.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/PortionsUtil.java
new file mode 100644
index 0000000000..2f97f7c354
--- /dev/null
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/PortionsUtil.java
@@ -0,0 +1,465 @@
+/**
+ * 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.common.dataplugin.warning.portions;
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.coverage.grid.GeneralGridGeometry;
+import org.opengis.referencing.operation.MathTransform;
+
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil.Direction;
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Port of A1 code that determines the portions of the county or zone
+ * descriptions, such as NORTHWEST.
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 5, 2013 2177 jsanchez Initial creation
+ * Sep 22, 2013 2177 jsanchez Updated logic. Used GisUtil for very small portions.
+ * Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
+ *
+ *
+ * @author jsanchez
+ * @version 1.0
+ */
+
+public class PortionsUtil {
+
+ private GridUtil gridUtil;
+
+ private String threeLetterSiteID;
+
+ public PortionsUtil(String threeLetterSiteID,
+ GeneralGridGeometry localGridGeometry, MathTransform localToLatLon)
+ throws Exception {
+ this.threeLetterSiteID = threeLetterSiteID;
+ gridUtil = new GridUtil(localGridGeometry, localToLatLon);
+ }
+
+ /**
+ * Determines the the appropriate portion description for the warnedArea
+ * intersecting the countyOrZone.
+ *
+ * @param entityID
+ * @param countyOrZone
+ * @param warnedArea
+ * @param useExtreme
+ * @return
+ * @throws Exception
+ */
+ public EnumSet getPortions(String entityID,
+ Geometry countyOrZone, Geometry warnedArea, boolean useExtreme)
+ throws Exception {
+ countyOrZone.getUserData();
+ EntityData entityData = gridUtil.calculateGrids(countyOrZone,
+ warnedArea);
+ EnumSet portions = null;
+ if (entityData.getMeanMask() == 0 || entityData.getCoverageMask() == 0
+ || entityData.getMeanMask() == entityData.getCoverageMask()) {
+ // This takes into account the warned areas that are very small
+ // the convex hull of the warned area is used for case the
+ // warnedArea is a geometry collection.
+ portions = GisUtil.calculateLocationPortion(countyOrZone,
+ warnedArea.convexHull(), useExtreme);
+ } else {
+ portions = getAreaDesc(entityData.getMeanMask(),
+ entityData.getCoverageMask(), entityData.getOctants(),
+ useExtreme);
+ }
+ return suppressPortions(entityID, portions);
+ }
+
+ /**
+ * Looks up if the designated entity ID has an suppressed directions. For
+ * example, a county or zone may not need to include the north and sound
+ * direction description if it was included in the area.suppress file.
+ *
+ * @param entityID
+ * @param portions
+ * @return
+ */
+ private EnumSet suppressPortions(String entityID,
+ EnumSet portions) {
+ Map> suppressedCounties = SuppressMap
+ .getInstance().getAreas(threeLetterSiteID);
+ if (entityID != null && suppressedCounties != null
+ && !suppressedCounties.isEmpty()) {
+ List suppressedDirections = suppressedCounties
+ .get(entityID.toUpperCase());
+ if (suppressedDirections != null && !suppressedDirections.isEmpty()) {
+ portions.removeAll(suppressedDirections);
+ }
+ }
+
+ return portions;
+ }
+
+ /**
+ * Port from A1 code of GeoEntityLookupTable::getAreaDesc.
+ *
+ * @param meanMask
+ * @param areaMask
+ * @param octants
+ * @param exYes
+ */
+ private static EnumSet getAreaDesc(int meanMask, int areaMask,
+ int octants, boolean exYes) {
+ EnumSet portions = EnumSet.noneOf(Direction.class);
+
+ // Test for case where we cannot do portions
+ if (meanMask == 0 || areaMask == 0) {
+ return portions;
+ }
+
+ // The next block of code is the original port of A1 code but prevented
+ // producing the correct result:
+ // Test for case where area is completely within one subsection.
+ // if (meanMask == areaMask) {
+ // return getPointDesc(meanMask, exYes);
+ // }
+
+ // Test for central by not being near adjacent borders.
+ // Another possible case of a stripe across the middle.
+ if (octants == 0
+ || ((octants & CoverageConstants.EXTREME_YES) == 0)
+ && (meanMask & CoverageConstants.CENTER) == CoverageConstants.CENTER) {
+ portions.add(Direction.CENTRAL);
+ return portions;
+ }
+
+ if ((octants & 0xFFFF) == 0xFFFF) {
+ return portions;
+ }
+
+ // Identify quadrants in use, q is typical, qq is diagonal.
+ int xoctant = octants >> 8;
+ int xxoctant = octants >> 16;
+ int nn, ss, ee, ww, ne, nw, se, sw;
+ nn = ss = ee = ww = ne = nw = se = sw = 0;
+ int omerge = xxoctant | xoctant | octants;
+ if ((omerge & (CoverageConstants.NNE | CoverageConstants.ENE)) != 0) {
+ ne = 1;
+ }
+ if ((omerge & (CoverageConstants.SSE | CoverageConstants.ESE)) != 0) {
+ se = 1;
+ }
+ if ((omerge & (CoverageConstants.NNW | CoverageConstants.WNW)) != 0) {
+ nw = 1;
+ }
+ if ((omerge & (CoverageConstants.SSW | CoverageConstants.WSW)) != 0) {
+ sw = 1;
+ }
+ if ((omerge & (CoverageConstants.NNE | CoverageConstants.NNW)) != 0) {
+ nn = 1;
+ }
+ if ((omerge & (CoverageConstants.SSE | CoverageConstants.SSW)) != 0) {
+ ss = 1;
+ }
+ if ((omerge & (CoverageConstants.WNW | CoverageConstants.WSW)) != 0) {
+ ww = 1;
+ }
+ if ((omerge & (CoverageConstants.ENE | CoverageConstants.ESE)) != 0) {
+ ee = 1;
+ }
+ if ((areaMask & CoverageConstants.NORTH_SOUTH) == 0) {
+ nn = ss = ne = nw = se = sw = 0;
+ }
+ if ((areaMask & CoverageConstants.EAST_WEST) == 0) {
+ ee = ww = ne = nw = se = sw = 0;
+ }
+ int q = ne + nw + se + sw;
+ int qq = nn + ss + ee + ww;
+
+ // Identify extremes in use.
+ int nnx, ssx, eex, wwx;
+ nnx = ssx = eex = wwx = 0;
+ if ((areaMask & CoverageConstants.XNORTH) != 0) {
+ nnx = 1;
+ }
+ if ((areaMask & CoverageConstants.XSOUTH) != 0) {
+ ssx = 1;
+ }
+ if ((areaMask & CoverageConstants.XWEST) != 0) {
+ wwx = 1;
+ }
+ if ((areaMask & CoverageConstants.XEAST) != 0) {
+ eex = 1;
+ }
+ int xxx = nnx + ssx + eex + wwx;
+
+ // Modify masks based on whether we can use extreme.
+ if ((octants & CoverageConstants.EXTREME_NO) != 0
+ && (areaMask & CoverageConstants.EXTREME) != 0) {
+ areaMask &= CoverageConstants.NOT_EXTREME;
+ meanMask &= CoverageConstants.NOT_EXTREME;
+ }
+
+ // Possible case of a stripe across the middle
+ if (q == 0) {
+ ;// Only one direction encoded
+ } else if (q == 2 && nw == se || q == 2 && ne == sw || qq == 2
+ && nn == ss || qq == 2 && ee == ww) {
+ if ((meanMask & CoverageConstants.CENTRAL) == CoverageConstants.CENTRAL
+ || nnx == ssx && wwx == eex) {
+ portions.add(Direction.CENTRAL);
+ return portions;
+ }
+ return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
+ }
+
+ // Modify masks based on whether we can use central.
+ if (xxx > 2 || nnx != ssx && wwx != eex) {
+ areaMask &= CoverageConstants.NOT_CENTRAL;
+ meanMask &= CoverageConstants.NOT_CENTRAL;
+ }
+
+ // All quadrants in use.
+ if (q == 4 && qq == 4) {
+ return EnumSet.noneOf(Direction.class);
+ }
+
+ // Only one typical quadrant in use.
+ if (q == 1) {
+ return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
+ }
+
+ // Further modify masks based on whether we can use central.
+ if (xxx >= 2) {
+ areaMask &= CoverageConstants.NOT_CENTRAL;
+ meanMask &= CoverageConstants.NOT_CENTRAL;
+ }
+
+ // No more than two quadrants of any kind in use, or all quadrants.
+ if (q < 3 && qq < 3) {
+ if (nnx != ssx && wwx != eex
+ || (meanMask & CoverageConstants.CENTRAL) != 0) {
+ return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
+
+ } else {
+ return getPointDesc2(areaMask, exYes, nn, ss, ee, ww);
+ }
+ }
+
+ // Three typical quadrants in use.
+ if (q == 3 && qq != 3) {
+
+ if (ne == 0) {
+ // The next line is the original port of A1 code but prevented
+ // producing the correct result:
+ // if (ne == 0 && (xxoctant & (SSW | WSW)) != 0) {
+ portions.add(Direction.SOUTH);
+ portions.add(Direction.WEST);
+
+ } else if (se == 0) {
+ // The next line is the original port of A1 code but prevented
+ // producing the correct result:
+ // } else if (se == 0 && (xxoctant & (NNW | WNW)) != 0) {
+ portions.add(Direction.NORTH);
+ portions.add(Direction.WEST);
+
+ } else if (nw == 0) {
+ // The next line is the original port of A1 code but prevented
+ // producing the correct result:
+ // } else if (nw == 0 && (xxoctant & (SSE | ESE)) != 0) {
+ portions.add(Direction.SOUTH);
+ portions.add(Direction.EAST);
+
+ } else if (sw == 0) {
+ // The next line is the original port of A1 code but prevented
+ // producing the correct result:
+ // } else if (sw == 0 && (xxoctant & (NNE | ENE)) != 0) {
+ portions.add(Direction.NORTH);
+ portions.add(Direction.EAST);
+ }
+ // The next line is the original port of A1 code but prevented
+ // producing the correct result:
+ // return getPointDesc(meanMask, exYes);
+ }
+
+ // Three diagonal quadrants in use.
+ if (qq == 3 && portions.isEmpty()) {
+ if (nn == 0) {
+ portions.add(Direction.SOUTH);
+ } else if (ss == 0) {
+ portions.add(Direction.NORTH);
+ } else if (ww == 0) {
+ portions.add(Direction.EAST);
+ } else if (ee == 0) {
+ portions.add(Direction.WEST);
+ }
+ }
+
+ // add extreme for three quadrant case.
+ if (!portions.isEmpty()) {
+ if (exYes && ((areaMask & CoverageConstants.EXTREME)) != 0) {
+ portions.add(Direction.EXTREME);
+ }
+ return portions;
+ }
+
+ // All of either type of quadrant in use.
+ if (q == 4 || qq == 4) {
+ return EnumSet.noneOf(Direction.class);
+ }
+
+ // Case of a pure simple direction.
+ nn = areaMask & CoverageConstants.NORTHERN;
+ ss = areaMask & CoverageConstants.SOUTHERN;
+ ee = areaMask & CoverageConstants.EASTERN;
+ ww = areaMask & CoverageConstants.WESTERN;
+ if (ss != 0 && nn != 0 || q == 0) {
+ if (ee == 0 && ww != 0) {
+ portions.add(Direction.WEST);
+ }
+ if (ww == 0 && ee != 0) {
+ portions.add(Direction.EAST);
+ }
+ } else if (ee != 0 && ww != 0 || q == 0) {
+ if (nn == 0 && ss != 0) {
+ portions.add(Direction.SOUTH);
+ }
+ if (ss == 0 && nn != 0) {
+ portions.add(Direction.NORTH);
+ }
+ }
+
+ // add extreme for simple direction case.
+ if (!portions.isEmpty()) {
+ if (exYes && ((areaMask & CoverageConstants.EXTREME)) != 0) {
+ portions.add(Direction.EXTREME);
+ }
+ return portions;
+ }
+
+ // Catch with the point descriptor one last time
+ return getPointDesc2(meanMask, exYes, nn, ss, ee, ww);
+ }
+
+ /**
+ * Port from A1 code of GeoEntityLookupTable::getPointDesc.
+ *
+ * @param mask
+ * @param exYes
+ * @return
+ */
+ private static EnumSet getPointDesc(int mask, boolean exYes) {
+ EnumSet portions = EnumSet.noneOf(Direction.class);
+
+ int cc = mask & CoverageConstants.CENTRAL;
+ if (cc == CoverageConstants.CENTRAL) {
+ portions.add(Direction.CENTRAL);
+ return portions;
+ }
+
+ if ((mask & CoverageConstants.NORTH_SOUTH) == 0) {
+ ;
+ } else if ((mask & CoverageConstants.SOUTHERN) == (mask & CoverageConstants.NORTH_SOUTH)) {
+ portions.add(Direction.SOUTH);
+ } else if ((mask & CoverageConstants.NORTHERN) == (mask & CoverageConstants.NORTH_SOUTH)) {
+ portions.add(Direction.NORTH);
+ }
+
+ if ((mask & CoverageConstants.EAST_WEST) == 0) {
+ ;
+ } else if ((mask & CoverageConstants.WESTERN) == (mask & CoverageConstants.EAST_WEST)) {
+ portions.add(Direction.WEST);
+ } else if ((mask & CoverageConstants.EASTERN) == (mask & CoverageConstants.EAST_WEST)) {
+ portions.add(Direction.EAST);
+ }
+
+ if (portions.isEmpty()) {
+ return portions;
+ }
+
+ if (cc != 0) {
+ portions.add(Direction.CENTRAL);
+ }
+
+ if (exYes && ((int) (mask & CoverageConstants.EXTREME) != 0)) {
+ portions.add(Direction.EXTREME);
+ }
+
+ return portions;
+ }
+
+ /**
+ * This method is not a direct port from A1. The original getPointDesc did
+ * not produce the expected results. This method is a modified version of
+ * getPointDesct that uses the calculated qq values instead of just the
+ * meanMask.
+ *
+ * @param mask
+ * @param exYes
+ * @return
+ */
+ private static EnumSet getPointDesc2(int mask, boolean exYes,
+ int nn, int ss, int ee, int ww) {
+ EnumSet portions = EnumSet.noneOf(Direction.class);
+
+ if (mask == 0) {
+ return portions;
+ }
+
+ int counter = 0;
+ if (nn != 0 && ss != 0) {
+ ;
+ } else if (ss != 0) {
+ portions.add(Direction.SOUTH);
+ counter++;
+ } else if (nn != 0) {
+ portions.add(Direction.NORTH);
+ counter++;
+ }
+
+ if (ee != 0 && ww != 0) {
+ ;
+ } else if (ww != 0) {
+ portions.add(Direction.WEST);
+ counter++;
+ } else if (ee != 0) {
+ portions.add(Direction.EAST);
+ counter++;
+ }
+
+ if (portions.isEmpty()) {
+ return portions;
+ }
+
+ int cc = mask & CoverageConstants.CENTRAL;
+ boolean useCentral = counter < 2;
+ if (useCentral && cc != 0) {
+ portions.add(Direction.CENTRAL);
+ }
+
+ if (exYes && ((int) (mask & CoverageConstants.EXTREME) != 0)) {
+ portions.add(Direction.EXTREME);
+ }
+
+ return portions;
+ }
+}
diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/SuppressMap.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/SuppressMap.java
similarity index 95%
rename from cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/SuppressMap.java
rename to edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/SuppressMap.java
index 83de8980aa..cb8346fc55 100644
--- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/SuppressMap.java
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/portions/SuppressMap.java
@@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.viz.warngen.gis;
+package com.raytheon.uf.common.dataplugin.warning.portions;
import java.io.BufferedReader;
import java.io.File;
@@ -33,6 +33,7 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil.Direction;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
@@ -41,8 +42,6 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
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.localization.LocalizationManager;
-import com.raytheon.viz.warngen.gis.GisUtil.Direction;
/**
* Creates a map of all the site's area suppress files.
@@ -54,6 +53,7 @@ import com.raytheon.viz.warngen.gis.GisUtil.Direction;
* ------------ ---------- ----------- --------------------------
* Aug 2, 2010 jsanchez Initial creation
* Aug 15,2013 2177 jsanchez Refactored.
+ * Dec 4,2013 2604 jsanchez Moved out of viz.warngen.
*
*
*
@@ -104,9 +104,7 @@ public class SuppressMap {
*
* @return
*/
- public Map> getAreas() {
- String threeLetterSiteID = LocalizationManager.getInstance()
- .getCurrentSite();
+ public Map> getAreas(String threeLetterSiteID) {
Map> areas = suppressMap.get(threeLetterSiteID);
if (areas == null) {