Issue #2604 Refactored portions util out of viz.warngen.
Change-Id: I58fad25e0a53d34b3369d6b6463f29e753cb6d10 Former-commit-id:966f814d2d
[formerly9878c3a797
] [formerly125e747fc9
] [formerly966f814d2d
[formerly9878c3a797
] [formerly125e747fc9
] [formerly2ecfe79516
[formerly125e747fc9
[formerly ae9f22dbfce191c79e170b242bfc0c905b61e9bf]]]] Former-commit-id:2ecfe79516
Former-commit-id:bef733bb8f
[formerly45903c0e7d
] [formerly 77df683bd7320416ea169ad18d4f073fee509742 [formerly5796d108c3
]] Former-commit-id: 1f72fc394c40567d447019e17db68c0f5a4b80af [formerlya2e5cdeae5
] Former-commit-id:cb03686dc8
This commit is contained in:
parent
aea85a4fb8
commit
fa754ed7f8
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.PathcastConfiguration;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
|
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.dataquery.requests.RequestConstraint;
|
||||||
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
|
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
import com.raytheon.viz.warngen.PreferenceUtil;
|
import com.raytheon.viz.warngen.PreferenceUtil;
|
||||||
import com.raytheon.viz.warngen.gis.Area;
|
import com.raytheon.viz.warngen.gis.Area;
|
||||||
import com.raytheon.viz.warngen.gis.ClosestPoint;
|
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.Coordinate;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
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.
|
* 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.
|
* 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.
|
* Sep 13, 2013 DR 16601 D. Friedman Fix from jsanchez: Allow cities outside the CWA.
|
||||||
*
|
* Dec 4, 2013 2604 jsanchez Refactored GisUtil.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @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.GeospatialConfiguration;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
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.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.CountyUserData;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.util.FileUtil;
|
import com.raytheon.uf.common.dataplugin.warning.util.FileUtil;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
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.
|
* 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.
|
* May 2, 2013 1963 jsanchez Updated method to determine partOfArea.
|
||||||
* Aug 19, 2013 2177 jsanchez Used portionsUtil to calculate area portion descriptions.
|
* Aug 19, 2013 2177 jsanchez Used portionsUtil to calculate area portion descriptions.
|
||||||
|
* Dec 4, 2013 2604 jsanchez Refactored GisUtil and PortionsUtil.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @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.config.WarngenConfiguration;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
|
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.GeospatialFactory;
|
||||||
|
import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.util.FileUtil;
|
import com.raytheon.uf.common.dataplugin.warning.util.FileUtil;
|
||||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||||
import com.raytheon.uf.common.geospatial.DestinationGeodeticCalculator;
|
import com.raytheon.uf.common.geospatial.DestinationGeodeticCalculator;
|
||||||
|
@ -114,7 +115,7 @@ import com.vividsolutions.jts.geom.Point;
|
||||||
* points that are in the past.
|
* points that are in the past.
|
||||||
* Jun 24, 2013 DR 16317 D. Friedman Handle "motionless" track.
|
* 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.
|
* Jun 25, 2013 16224 Qinglu Lin Resolved the issue with "Date start" for pathcast in CON.
|
||||||
*
|
* Dec 4, 2013 2604 jsanchez Refactored GisUtil.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -279,8 +280,8 @@ public class Wx {
|
||||||
if (stormTrackState.isNonstationary()) {
|
if (stormTrackState.isNonstationary()) {
|
||||||
List<Coordinate> coordinates = new ArrayList<Coordinate>();
|
List<Coordinate> coordinates = new ArrayList<Coordinate>();
|
||||||
Date stormTime = new Date();
|
Date stormTime = new Date();
|
||||||
Date start = DateUtil.roundDate(new Date(stormTime.getTime() + delta),
|
Date start = DateUtil.roundDate(new Date(stormTime.getTime()
|
||||||
pathcastConfiguration.getInterval());
|
+ delta), pathcastConfiguration.getInterval());
|
||||||
DestinationGeodeticCalculator gc = new DestinationGeodeticCalculator();
|
DestinationGeodeticCalculator gc = new DestinationGeodeticCalculator();
|
||||||
while (start.getTime() <= wwaStopTime) {
|
while (start.getTime() <= wwaStopTime) {
|
||||||
PathCast cast = new PathCast();
|
PathCast cast = new PathCast();
|
||||||
|
@ -449,16 +450,20 @@ public class Wx {
|
||||||
points = new ArrayList<ClosestPoint>(0);
|
points = new ArrayList<ClosestPoint>(0);
|
||||||
}
|
}
|
||||||
if (flag) {
|
if (flag) {
|
||||||
pointsToBeRemoved = findPointsToBeRemoved(centroid, points, stormTrackState.angle);
|
pointsToBeRemoved = findPointsToBeRemoved(centroid, points,
|
||||||
|
stormTrackState.angle);
|
||||||
flag = false;
|
flag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pointsToBeRemoved != null) {
|
if (pointsToBeRemoved != null) {
|
||||||
for (int i=0; i<pointsToBeRemoved.size(); i++) {
|
for (int i = 0; i < pointsToBeRemoved.size(); i++) {
|
||||||
for (int j=0; j<points.size(); j++) {
|
for (int j = 0; j < points.size(); j++) {
|
||||||
// double comparison below can be replaced by gid comparison when bug in getGid() is fixed.
|
// double comparison below can be replaced by gid
|
||||||
if (pointsToBeRemoved.get(i).getPoint().x == points.get(j).getPoint().x &&
|
// comparison when bug in getGid() is fixed.
|
||||||
pointsToBeRemoved.get(i).getPoint().y == points.get(j).getPoint().y) {
|
if (pointsToBeRemoved.get(i).getPoint().x == points
|
||||||
|
.get(j).getPoint().x
|
||||||
|
&& pointsToBeRemoved.get(i).getPoint().y == points
|
||||||
|
.get(j).getPoint().y) {
|
||||||
points.remove(j);
|
points.remove(j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -482,7 +487,8 @@ public class Wx {
|
||||||
for (PathCast pc2 : tmp) {
|
for (PathCast pc2 : tmp) {
|
||||||
if (pc2 != pc) {
|
if (pc2 != pc) {
|
||||||
List<ClosestPoint> points2 = pcPoints.get(pc2);
|
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) {
|
if (found != null) {
|
||||||
// We found a point within maxCount in this
|
// We found a point within maxCount in this
|
||||||
// list.
|
// list.
|
||||||
|
@ -958,7 +964,8 @@ public class Wx {
|
||||||
return new Date(this.wwaStartTime);
|
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)
|
// convert storm track angle to geometry angle in range of (0,360)
|
||||||
double convertedAngle = 90.0 - stormtrackAngle;
|
double convertedAngle = 90.0 - stormtrackAngle;
|
||||||
if (convertedAngle < 0.0)
|
if (convertedAngle < 0.0)
|
||||||
|
@ -968,7 +975,8 @@ public class Wx {
|
||||||
List<ClosestPoint> removedPoints = new ArrayList<ClosestPoint>();
|
List<ClosestPoint> removedPoints = new ArrayList<ClosestPoint>();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
ClosestPoint cp = iter.next();
|
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)
|
if (d > 180.0)
|
||||||
d = 360.0 - d;
|
d = 360.0 - d;
|
||||||
if (d > 90.0)
|
if (d > 90.0)
|
||||||
|
@ -978,7 +986,8 @@ public class Wx {
|
||||||
}
|
}
|
||||||
|
|
||||||
private double computeAngle(Point p, Coordinate c) {
|
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)
|
if (angle < 0)
|
||||||
angle += 360;
|
angle += 360;
|
||||||
return angle;
|
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.GeospatialData;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialFactory;
|
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.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.CountyUserData;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
||||||
import com.raytheon.uf.common.geospatial.DestinationGeodeticCalculator;
|
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.core.rsc.jts.JTSCompiler;
|
||||||
import com.raytheon.viz.radar.RadarHelper;
|
import com.raytheon.viz.radar.RadarHelper;
|
||||||
import com.raytheon.viz.warngen.WarngenException;
|
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.gis.PolygonUtil;
|
||||||
import com.raytheon.viz.warngen.util.CurrentWarnings;
|
import com.raytheon.viz.warngen.util.CurrentWarnings;
|
||||||
import com.raytheon.viz.warngen.util.FipsUtil;
|
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.
|
* 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.
|
* 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.
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author mschenke
|
* @author mschenke
|
||||||
|
@ -530,7 +531,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! this.haveInput)
|
if (!this.haveInput)
|
||||||
return null;
|
return null;
|
||||||
hatchedArea = this.hatchedArea;
|
hatchedArea = this.hatchedArea;
|
||||||
hatchedWarningArea = this.hatchedWarningArea;
|
hatchedWarningArea = this.hatchedWarningArea;
|
||||||
|
@ -1614,7 +1615,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
Geometry newHatchedArea = null;
|
Geometry newHatchedArea = null;
|
||||||
Geometry newUnfilteredArea = null;
|
Geometry newUnfilteredArea = null;
|
||||||
boolean useFilteredArea = false;
|
boolean useFilteredArea = false;
|
||||||
boolean useFallback = getConfiguration().getHatchedAreaSource().isInclusionFallback();
|
boolean useFallback = getConfiguration().getHatchedAreaSource()
|
||||||
|
.isInclusionFallback();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The resultant warning area is constructed in one of two ways:
|
* The resultant warning area is constructed in one of two ways:
|
||||||
|
@ -1709,7 +1711,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
} else {
|
} else {
|
||||||
boolean passed = filterArea(f, intersection, true);
|
boolean passed = filterArea(f, intersection, true);
|
||||||
useFilteredArea = useFilteredArea || passed;
|
useFilteredArea = useFilteredArea || passed;
|
||||||
include = (passed || filterAreaSecondChance(f, intersection, true))
|
include = (passed || filterAreaSecondChance(f,
|
||||||
|
intersection, true))
|
||||||
&& (oldWarningPolygon == null
|
&& (oldWarningPolygon == null
|
||||||
|| prepGeom.intersects(oldWarningPolygon) || isOldAreaOutsidePolygon(f));
|
|| prepGeom.intersects(oldWarningPolygon) || isOldAreaOutsidePolygon(f));
|
||||||
newUnfilteredArea = union(newUnfilteredArea, intersection);
|
newUnfilteredArea = union(newUnfilteredArea, intersection);
|
||||||
|
@ -1727,8 +1730,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newHatchedArea = useFilteredArea && newHatchedArea != null ? newHatchedArea :
|
newHatchedArea = useFilteredArea && newHatchedArea != null ? newHatchedArea
|
||||||
useFallback ? newUnfilteredArea : null;
|
: useFallback ? newUnfilteredArea : null;
|
||||||
return newHatchedArea != null ? newHatchedArea : new GeometryFactory()
|
return newHatchedArea != null ? newHatchedArea : new GeometryFactory()
|
||||||
.createGeometryCollection(new Geometry[0]);
|
.createGeometryCollection(new Geometry[0]);
|
||||||
}
|
}
|
||||||
|
@ -1768,13 +1771,16 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
if (oldWarningArea != null) {
|
if (oldWarningArea != null) {
|
||||||
int areaPercent = -1;
|
int areaPercent = -1;
|
||||||
try {
|
try {
|
||||||
areaPercent = Double.valueOf(
|
areaPercent = Double
|
||||||
((oldWarningPolygon.intersection(warningPolygon)
|
.valueOf(
|
||||||
.getArea() / oldWarningArea.getArea()) * 100))
|
((oldWarningPolygon.intersection(
|
||||||
.intValue();
|
warningPolygon).getArea() / oldWarningArea
|
||||||
|
.getArea()) * 100)).intValue();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
statusHandler.handle(Priority.VERBOSE,
|
statusHandler
|
||||||
"Error determining amount of overlap with original polygon", e);
|
.handle(Priority.VERBOSE,
|
||||||
|
"Error determining amount of overlap with original polygon",
|
||||||
|
e);
|
||||||
areaPercent = 100;
|
areaPercent = 100;
|
||||||
}
|
}
|
||||||
if (oldWarningPolygon.intersects(warningPolygon) == false
|
if (oldWarningPolygon.intersects(warningPolygon) == false
|
||||||
|
@ -2299,7 +2305,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
* If redraw failed, do not allow this polygon to be used to
|
* If redraw failed, do not allow this polygon to be used to
|
||||||
* generate a warning.
|
* generate a warning.
|
||||||
*
|
*
|
||||||
* Note that this duplicates code from updateWarnedAreaState.
|
* Note that this duplicates code from
|
||||||
|
* updateWarnedAreaState.
|
||||||
*/
|
*/
|
||||||
state.strings.clear();
|
state.strings.clear();
|
||||||
state.setWarningArea(null);
|
state.setWarningArea(null);
|
||||||
|
@ -2848,9 +2855,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
if (oldWarningArea != null) {
|
if (oldWarningArea != null) {
|
||||||
// for a CON, prevents extra areas to be added
|
// for a CON, prevents extra areas to be added
|
||||||
Set<String> fipsIds = getAllFipsInArea(oldWarningArea);
|
Set<String> fipsIds = getAllFipsInArea(oldWarningArea);
|
||||||
if (fipsIds.contains(featureFips) == false ||
|
if (fipsIds.contains(featureFips) == false
|
||||||
! (oldWarningPolygon.contains(point) == true
|
|| !(oldWarningPolygon.contains(point) == true || isOldAreaOutsidePolygon(f))) {
|
||||||
|| isOldAreaOutsidePolygon(f))) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2862,7 +2868,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
for (GeospatialData gd : dataWithFips) {
|
for (GeospatialData gd : dataWithFips) {
|
||||||
Geometry g = gd.geometry;
|
Geometry g = gd.geometry;
|
||||||
if (oldWarningArea != null) {
|
if (oldWarningArea != null) {
|
||||||
g = GeometryUtil.intersection(oldWarningArea, g);
|
g = GeometryUtil
|
||||||
|
.intersection(oldWarningArea, g);
|
||||||
}
|
}
|
||||||
fipsParts.add(g);
|
fipsParts.add(g);
|
||||||
}
|
}
|
||||||
|
@ -2871,12 +2878,11 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
.toArray(new Geometry[fipsParts.size()]));
|
.toArray(new Geometry[fipsParts.size()]));
|
||||||
if (warningPolygon.contains(point)) {
|
if (warningPolygon.contains(point)) {
|
||||||
// If inside warning polygon, intersect
|
// If inside warning polygon, intersect
|
||||||
geom = GeometryUtil.intersection(
|
geom = GeometryUtil.intersection(warningPolygon,
|
||||||
warningPolygon, geom);
|
geom);
|
||||||
}
|
}
|
||||||
newWarningArea = GeometryUtil.union(
|
newWarningArea = GeometryUtil.union(
|
||||||
removeCounty(warningArea, featureFips),
|
removeCounty(warningArea, featureFips), geom);
|
||||||
geom);
|
|
||||||
}
|
}
|
||||||
state.setWarningArea(filterWarningArea(newWarningArea));
|
state.setWarningArea(filterWarningArea(newWarningArea));
|
||||||
setUniqueFip();
|
setUniqueFip();
|
||||||
|
@ -2898,25 +2904,29 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
return null;
|
return null;
|
||||||
/*
|
/*
|
||||||
* Note: Currently does not determine if warningArea is valid (i.e., in
|
* 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 newHatchedArea = null;
|
||||||
Geometry newUnfilteredArea = null;
|
Geometry newUnfilteredArea = null;
|
||||||
boolean useFilteredArea = false;
|
boolean useFilteredArea = false;
|
||||||
boolean useFallback = getConfiguration().getHatchedAreaSource().isInclusionFallback();
|
boolean useFallback = getConfiguration().getHatchedAreaSource()
|
||||||
|
.isInclusionFallback();
|
||||||
|
|
||||||
for (GeospatialData f : geoData.features) {
|
for (GeospatialData f : geoData.features) {
|
||||||
String gid = GeometryUtil.getPrefix(f.geometry.getUserData());
|
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);
|
boolean passed = filterArea(f, warningAreaForFeature, false);
|
||||||
useFilteredArea = useFilteredArea || passed;
|
useFilteredArea = useFilteredArea || passed;
|
||||||
if (passed || filterAreaSecondChance(f, warningAreaForFeature, false))
|
if (passed
|
||||||
|
|| filterAreaSecondChance(f, warningAreaForFeature, false))
|
||||||
newHatchedArea = union(newHatchedArea, warningAreaForFeature);
|
newHatchedArea = union(newHatchedArea, warningAreaForFeature);
|
||||||
newUnfilteredArea = union(newUnfilteredArea, warningAreaForFeature);
|
newUnfilteredArea = union(newUnfilteredArea, warningAreaForFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
newHatchedArea = useFilteredArea && newHatchedArea != null ? newHatchedArea :
|
newHatchedArea = useFilteredArea && newHatchedArea != null ? newHatchedArea
|
||||||
useFallback ? newUnfilteredArea : null;
|
: useFallback ? newUnfilteredArea : null;
|
||||||
|
|
||||||
return newHatchedArea != null ? newHatchedArea : new GeometryFactory()
|
return newHatchedArea != null ? newHatchedArea : new GeometryFactory()
|
||||||
.createGeometryCollection(new Geometry[0]);
|
.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.AreaSourceConfiguration.AreaType;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
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.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.dataplugin.warning.util.GeometryUtil;
|
||||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
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.AffectedAreas;
|
||||||
import com.raytheon.viz.warngen.gis.Area;
|
import com.raytheon.viz.warngen.gis.Area;
|
||||||
import com.raytheon.viz.warngen.gis.ClosestPointComparator;
|
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.PathCast;
|
||||||
import com.raytheon.viz.warngen.gis.PortionsUtil;
|
|
||||||
import com.raytheon.viz.warngen.gis.Wx;
|
import com.raytheon.viz.warngen.gis.Wx;
|
||||||
import com.raytheon.viz.warngen.gui.BackupData;
|
import com.raytheon.viz.warngen.gui.BackupData;
|
||||||
import com.raytheon.viz.warngen.gui.FollowupData;
|
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.
|
* May 30, 2013 DR 16237 D. Friedman Fix watch query.
|
||||||
* Jun 18, 2013 2118 njensen Only calculate pathcast if it's actually used
|
* Jun 18, 2013 2118 njensen Only calculate pathcast if it's actually used
|
||||||
* Aug 19, 2013 2177 jsanchez Passed PortionsUtil to Area class.
|
* Aug 19, 2013 2177 jsanchez Passed PortionsUtil to Area class.
|
||||||
|
* Dec 4, 2013 2604 jsanchez Refactored GisUtil and PortionsUtil.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author njensen
|
* @author njensen
|
||||||
|
@ -303,7 +304,9 @@ public class TemplateRunner {
|
||||||
AffectedAreas[] cancelareas = null;
|
AffectedAreas[] cancelareas = null;
|
||||||
Map<String, Object> intersectAreas = null;
|
Map<String, Object> intersectAreas = null;
|
||||||
Wx wx = 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;
|
long wwaMNDTime = 0l;
|
||||||
try {
|
try {
|
||||||
t0 = System.currentTimeMillis();
|
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.AbstractWarningRecord;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
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.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.SimulatedTime;
|
||||||
import com.raytheon.uf.common.time.TimeRange;
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
import com.raytheon.viz.warngen.gis.AffectedAreas;
|
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;
|
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 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 13, 2013 2243 jsanchez Removed calendar object.
|
||||||
* Aug 15, 2013 2243 jsanchez Reset the time ranges to the correct values.
|
* Aug 15, 2013 2243 jsanchez Reset the time ranges to the correct values.
|
||||||
*
|
* Dec 4, 2013 2604 jsanchez Refactored GisUtil.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bwoodle
|
* @author bwoodle
|
||||||
|
|
|
@ -8,6 +8,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Export-Package: com.raytheon.uf.common.dataplugin.warning,
|
Export-Package: com.raytheon.uf.common.dataplugin.warning,
|
||||||
com.raytheon.uf.common.dataplugin.warning.config,
|
com.raytheon.uf.common.dataplugin.warning.config,
|
||||||
com.raytheon.uf.common.dataplugin.warning.gis,
|
com.raytheon.uf.common.dataplugin.warning.gis,
|
||||||
|
com.raytheon.uf.common.dataplugin.warning.portions,
|
||||||
com.raytheon.uf.common.dataplugin.warning.util
|
com.raytheon.uf.common.dataplugin.warning.util
|
||||||
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization, com.raytheon.uf.common.serialization.comm
|
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization, com.raytheon.uf.common.serialization.comm
|
||||||
Import-Package: com.raytheon.uf.common.time,
|
Import-Package: com.raytheon.uf.common.time,
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* 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.
|
* 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
|
* Aug 5, 2013 2177 jsanchez Initial creation
|
||||||
* Sep 22, 2013 2177 jsanchez Updated EW_MASK.
|
* Sep 22, 2013 2177 jsanchez Updated EW_MASK.
|
||||||
|
* Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
|
@ -17,7 +17,7 @@
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* 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.
|
* 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
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 5, 2013 2177 jsanchez Initial creation
|
* Aug 5, 2013 2177 jsanchez Initial creation
|
||||||
|
* Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
|
@ -18,7 +18,7 @@
|
||||||
* further licensing information.
|
* further licensing information.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
package com.raytheon.viz.warngen.gis;
|
package com.raytheon.uf.common.dataplugin.warning.portions;
|
||||||
|
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.util.ArrayList;
|
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.
|
* 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.
|
* 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.
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
|
@ -17,21 +17,20 @@
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* further licensing information.
|
||||||
**/
|
**/
|
||||||
package com.raytheon.viz.warngen.gis;
|
package com.raytheon.uf.common.dataplugin.warning.portions;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||||
import org.geotools.coverage.grid.GridGeometry2D;
|
import org.geotools.coverage.grid.GridGeometry2D;
|
||||||
|
import org.geotools.geometry.jts.JTS;
|
||||||
import org.geotools.referencing.operation.DefaultMathTransformFactory;
|
import org.geotools.referencing.operation.DefaultMathTransformFactory;
|
||||||
import org.opengis.coverage.grid.GridEnvelope;
|
import org.opengis.coverage.grid.GridEnvelope;
|
||||||
import org.opengis.metadata.spatial.PixelOrientation;
|
import org.opengis.metadata.spatial.PixelOrientation;
|
||||||
import org.opengis.referencing.operation.MathTransform;
|
import org.opengis.referencing.operation.MathTransform;
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
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.Coordinate;
|
||||||
import com.vividsolutions.jts.geom.CoordinateSequence;
|
import com.vividsolutions.jts.geom.CoordinateSequence;
|
||||||
import com.vividsolutions.jts.geom.Envelope;
|
import com.vividsolutions.jts.geom.Envelope;
|
||||||
|
@ -55,6 +54,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 5, 2013 jsanchez Initial creation
|
* Aug 5, 2013 jsanchez Initial creation
|
||||||
|
* Dec 4, 2013 2604 jsanchez Moved out of viz.warngen.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -76,13 +76,10 @@ public class GridUtil {
|
||||||
|
|
||||||
private byte[] countyOrZoneGrid;
|
private byte[] countyOrZoneGrid;
|
||||||
|
|
||||||
private WarngenLayer layer;
|
|
||||||
|
|
||||||
private MathTransform latLonToContour, contourToLatLon;
|
private MathTransform latLonToContour, contourToLatLon;
|
||||||
|
|
||||||
public GridUtil(WarngenLayer layer, GeneralGridGeometry localGridGeometry,
|
public GridUtil(GeneralGridGeometry localGridGeometry,
|
||||||
MathTransform localToLatLon) throws Exception {
|
MathTransform localToLatLon) throws Exception {
|
||||||
this.layer = layer;
|
|
||||||
|
|
||||||
GridEnvelope range = localGridGeometry.getGridRange();
|
GridEnvelope range = localGridGeometry.getGridRange();
|
||||||
this.nx = range.getHigh(0);
|
this.nx = range.getHigh(0);
|
||||||
|
@ -124,7 +121,7 @@ public class GridUtil {
|
||||||
* @return
|
* @return
|
||||||
* @throws VizException
|
* @throws VizException
|
||||||
*/
|
*/
|
||||||
private byte[] toByteArray(Geometry geometry) throws VizException {
|
private byte[] toByteArray(Geometry geometry) throws Exception {
|
||||||
byte[] bytes = new byte[nx * ny];
|
byte[] bytes = new byte[nx * ny];
|
||||||
float[][] floatData = toFloatData(geometry);
|
float[][] floatData = toFloatData(geometry);
|
||||||
|
|
||||||
|
@ -149,8 +146,8 @@ public class GridUtil {
|
||||||
* @return
|
* @return
|
||||||
* @throws VizException
|
* @throws VizException
|
||||||
*/
|
*/
|
||||||
private float[][] toFloatData(Geometry geometry) throws VizException {
|
private float[][] toFloatData(Geometry geometry) throws Exception {
|
||||||
Geometry contoured = layer.convertGeom(geometry, latLonToContour);
|
Geometry contoured = convertGeom(geometry, latLonToContour);
|
||||||
List<Geometry> geomList = new ArrayList<Geometry>(
|
List<Geometry> geomList = new ArrayList<Geometry>(
|
||||||
contoured.getNumGeometries());
|
contoured.getNumGeometries());
|
||||||
GeometryUtil.buildGeometryList(geomList, contoured);
|
GeometryUtil.buildGeometryList(geomList, contoured);
|
||||||
|
@ -194,6 +191,27 @@ public class GridUtil {
|
||||||
return contourAreaData;
|
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
|
* Ported only the logic from A1 code
|
||||||
* GeoEntityLookupTable::finishDefineArea() that calculates the meanMask,
|
* GeoEntityLookupTable::finishDefineArea() that calculates the meanMask,
|
|
@ -17,7 +17,7 @@
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* 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.Coordinate;
|
||||||
import com.vividsolutions.jts.geom.Envelope;
|
import com.vividsolutions.jts.geom.Envelope;
|
||||||
|
@ -37,7 +37,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* May 2, 2013 1963 jsanchez Initial creation
|
* May 2, 2013 1963 jsanchez Initial creation
|
||||||
* Jun 3, 2013 2029 jsanchez Fixed incorrect A1 port. Added additional attributes to calculate portions of areas.
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @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
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* further licensing information.
|
||||||
**/
|
**/
|
||||||
package com.raytheon.viz.warngen.gis;
|
package com.raytheon.uf.common.dataplugin.warning.portions;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -33,6 +33,7 @@ import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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.IPathManager;
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
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.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
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.
|
* 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 2, 2010 jsanchez Initial creation
|
||||||
* Aug 15,2013 2177 jsanchez Refactored.
|
* Aug 15,2013 2177 jsanchez Refactored.
|
||||||
|
* Dec 4,2013 2604 jsanchez Moved out of viz.warngen.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -104,9 +104,7 @@ public class SuppressMap {
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Map<String, List<Direction>> getAreas() {
|
public Map<String, List<Direction>> getAreas(String threeLetterSiteID) {
|
||||||
String threeLetterSiteID = LocalizationManager.getInstance()
|
|
||||||
.getCurrentSite();
|
|
||||||
Map<String, List<Direction>> areas = suppressMap.get(threeLetterSiteID);
|
Map<String, List<Direction>> areas = suppressMap.get(threeLetterSiteID);
|
||||||
|
|
||||||
if (areas == null) {
|
if (areas == null) {
|
Loading…
Add table
Reference in a new issue