Issue #2604 Refactored portions util out of viz.warngen.
Change-Id: I58fad25e0a53d34b3369d6b6463f29e753cb6d10 Former-commit-id:125e747fc9
[formerly ae9f22dbfce191c79e170b242bfc0c905b61e9bf] Former-commit-id:2ecfe79516
This commit is contained in:
parent
8194559a6e
commit
5796d108c3
15 changed files with 591 additions and 540 deletions
|
@ -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.
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
|
|
|
@ -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.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @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<Direction> getPortions(String entityID,
|
||||
Geometry countyOrZone, Geometry warnedArea, boolean useExtreme)
|
||||
throws Exception {
|
||||
countyOrZone.getUserData();
|
||||
EntityData entityData = gridUtil.calculateGrids(countyOrZone,
|
||||
warnedArea);
|
||||
EnumSet<Direction> 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<Direction> suppressPortions(String entityID,
|
||||
EnumSet<Direction> portions) {
|
||||
Map<String, List<Direction>> suppressedCounties = SuppressMap
|
||||
.getInstance().getAreas();
|
||||
if (entityID != null && suppressedCounties != null
|
||||
&& !suppressedCounties.isEmpty()) {
|
||||
List<Direction> 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<Direction> getAreaDesc(int meanMask, int areaMask,
|
||||
int octants, boolean exYes) {
|
||||
EnumSet<Direction> 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<Direction> getPointDesc(int mask, boolean exYes) {
|
||||
EnumSet<Direction> 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<Direction> getPointDesc2(int mask, boolean exYes,
|
||||
int nn, int ss, int ee, int ww) {
|
||||
EnumSet<Direction> 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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -255,7 +256,7 @@ public class Wx {
|
|||
|
||||
GeometryFactory gf = new GeometryFactory();
|
||||
|
||||
boolean flag = true;
|
||||
boolean flag = true;
|
||||
List<ClosestPoint> pointsToBeRemoved = null;
|
||||
try {
|
||||
Abbreviation areaTypeAbbrev = null;
|
||||
|
@ -279,8 +280,8 @@ public class Wx {
|
|||
if (stormTrackState.isNonstationary()) {
|
||||
List<Coordinate> coordinates = new ArrayList<Coordinate>();
|
||||
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<ClosestPoint>(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<pointsToBeRemoved.size(); i++) {
|
||||
for (int j=0; j<points.size(); j++) {
|
||||
// double comparison below can be replaced by gid comparison when bug in getGid() is fixed.
|
||||
if (pointsToBeRemoved.get(i).getPoint().x == points.get(j).getPoint().x &&
|
||||
pointsToBeRemoved.get(i).getPoint().y == points.get(j).getPoint().y) {
|
||||
for (int i = 0; i < pointsToBeRemoved.size(); i++) {
|
||||
for (int j = 0; j < points.size(); j++) {
|
||||
// double comparison below can be replaced by gid
|
||||
// comparison when bug in getGid() is fixed.
|
||||
if (pointsToBeRemoved.get(i).getPoint().x == points
|
||||
.get(j).getPoint().x
|
||||
&& pointsToBeRemoved.get(i).getPoint().y == points
|
||||
.get(j).getPoint().y) {
|
||||
points.remove(j);
|
||||
break;
|
||||
}
|
||||
|
@ -482,7 +487,8 @@ public class Wx {
|
|||
for (PathCast pc2 : tmp) {
|
||||
if (pc2 != pc) {
|
||||
List<ClosestPoint> 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<ClosestPoint> findPointsToBeRemoved(Point centroid, List<ClosestPoint> points, double stormtrackAngle) {
|
||||
private List<ClosestPoint> findPointsToBeRemoved(Point centroid,
|
||||
List<ClosestPoint> 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<ClosestPoint> removedPoints = new ArrayList<ClosestPoint>();
|
||||
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;
|
||||
|
|
|
@ -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.
|
||||
* </pre>
|
||||
*
|
||||
* @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<String> 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]);
|
||||
|
|
|
@ -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.
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
|
@ -303,7 +304,9 @@ public class TemplateRunner {
|
|||
AffectedAreas[] cancelareas = null;
|
||||
Map<String, Object> 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();
|
||||
|
|
|
@ -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.
|
||||
* </pre>
|
||||
*
|
||||
* @author bwoodle
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* </pre>
|
||||
*
|
|
@ -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.
|
||||
*
|
||||
* </pre>
|
||||
*
|
|
@ -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.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
|
@ -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.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -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<Geometry> geomList = new ArrayList<Geometry>(
|
||||
contoured.getNumGeometries());
|
||||
GeometryUtil.buildGeometryList(geomList, contoured);
|
||||
|
@ -194,6 +191,27 @@ public class GridUtil {
|
|||
return contourAreaData;
|
||||
}
|
||||
|
||||
static private <T> 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,
|
|
@ -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.
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
|
@ -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.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* 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.
|
||||
* </pre>
|
||||
*
|
||||
* @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<Direction> getPortions(String entityID,
|
||||
Geometry countyOrZone, Geometry warnedArea, boolean useExtreme)
|
||||
throws Exception {
|
||||
countyOrZone.getUserData();
|
||||
EntityData entityData = gridUtil.calculateGrids(countyOrZone,
|
||||
warnedArea);
|
||||
EnumSet<Direction> 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<Direction> suppressPortions(String entityID,
|
||||
EnumSet<Direction> portions) {
|
||||
Map<String, List<Direction>> suppressedCounties = SuppressMap
|
||||
.getInstance().getAreas(threeLetterSiteID);
|
||||
if (entityID != null && suppressedCounties != null
|
||||
&& !suppressedCounties.isEmpty()) {
|
||||
List<Direction> 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<Direction> getAreaDesc(int meanMask, int areaMask,
|
||||
int octants, boolean exYes) {
|
||||
EnumSet<Direction> 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<Direction> getPointDesc(int mask, boolean exYes) {
|
||||
EnumSet<Direction> 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<Direction> getPointDesc2(int mask, boolean exYes,
|
||||
int nn, int ss, int ee, int ww) {
|
||||
EnumSet<Direction> 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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -104,9 +104,7 @@ public class SuppressMap {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, List<Direction>> getAreas() {
|
||||
String threeLetterSiteID = LocalizationManager.getInstance()
|
||||
.getCurrentSite();
|
||||
public Map<String, List<Direction>> getAreas(String threeLetterSiteID) {
|
||||
Map<String, List<Direction>> areas = suppressMap.get(threeLetterSiteID);
|
||||
|
||||
if (areas == null) {
|
Loading…
Add table
Reference in a new issue