Issue #1006 Implemented urban areas. Cherry picked from development on SS builds
Conflicts: edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/config/WarngenConfiguration.java Change-Id: Ife20e07ccffeb6e6f5cc4aabdc6c57c9ed6e9ff8 Former-commit-id:20c65a4677
[formerly1b45f1b6d9
] [formerly20c65a4677
[formerly1b45f1b6d9
] [formerlyf646b185da
[formerly a7f030f7ee05c60820c1ef82a5093b404e5e97a0]]] Former-commit-id:f646b185da
Former-commit-id:da1f3fe29b
[formerlya09fa0b649
] Former-commit-id:acf62bb8d9
This commit is contained in:
parent
54e452911f
commit
e1a3c762b7
14 changed files with 800 additions and 429 deletions
46
cave/build/static/common/cave/etc/bundles/maps/Locations.xml
Normal file
46
cave/build/static/common/cave/etc/bundles/maps/Locations.xml
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<bundle>
|
||||
<displayList>
|
||||
<displays xsi:type="mapRenderableDisplay" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<descriptor xsi:type="mapDescriptor">
|
||||
<resource>
|
||||
<loadProperties>
|
||||
<capabilities>
|
||||
<capability xsi:type="outlineCapability" lineStyle="SOLID" outlineOn="true" outlineWidth="1" />
|
||||
<capability xsi:type="colorableCapability" colorAsString="#9b9b9b" />
|
||||
<capability xsi:type="labelableCapability" labelField="name" />
|
||||
</capabilities>
|
||||
<resourceType>PLAN_VIEW</resourceType>
|
||||
</loadProperties>
|
||||
<properties isSystemResource="false" isBlinking="false" isMapLayer="true" isHoverOn="false" isVisible="true">
|
||||
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0"/>
|
||||
</properties>
|
||||
<resourceData xsi:type="dbMapResourceData">
|
||||
<table>mapdata.location</table>
|
||||
<constraint>cwa = '${site}'</constraint>
|
||||
<mapName>Locations</mapName>
|
||||
</resourceData>
|
||||
</resource>
|
||||
</descriptor>
|
||||
</displays>
|
||||
</displayList>
|
||||
</bundle>
|
|
@ -0,0 +1,163 @@
|
|||
package com.raytheon.viz.warngen.config;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.geospatial.ISpatialQuery.SearchMode;
|
||||
import com.raytheon.uf.common.geospatial.SpatialException;
|
||||
import com.raytheon.uf.common.geospatial.SpatialQueryFactory;
|
||||
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory;
|
||||
import com.raytheon.viz.warngen.gis.ClosestPoint;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
||||
abstract public class AbstractDbSourceDataAdaptor {
|
||||
|
||||
protected Set<String> sortFields = new HashSet<String>(
|
||||
Arrays.asList(new String[] { "distance", "area", "parentArea" }));
|
||||
|
||||
protected PointSourceConfiguration pointConfig;
|
||||
|
||||
protected Geometry searchArea;
|
||||
|
||||
protected String localizedSite;
|
||||
|
||||
abstract protected Set<String> createSpatialQueryField();
|
||||
|
||||
abstract protected ClosestPoint createClosestPoint(Set<String> ptFields,
|
||||
SpatialQueryResult ptRslt);
|
||||
|
||||
abstract protected Map<String, RequestConstraint> processFilterSubstitution();
|
||||
|
||||
public Collection<ClosestPoint> getData(WarngenConfiguration config,
|
||||
PointSourceConfiguration pointConfig, Geometry searchArea,
|
||||
String localizedSite) throws VizException {
|
||||
this.pointConfig = pointConfig;
|
||||
this.searchArea = searchArea;
|
||||
this.localizedSite = localizedSite;
|
||||
|
||||
Map<String, RequestConstraint> filter = processFilterSubstitution();
|
||||
Set<String> ptFields = createSpatialQueryField();
|
||||
List<ClosestPoint> points = null;
|
||||
|
||||
try {
|
||||
long t0 = System.currentTimeMillis();
|
||||
SpatialQueryResult[] ptFeatures = null;
|
||||
Double decimationTolerance = pointConfig
|
||||
.getGeometryDecimationTolerance();
|
||||
String field = "the_geom";
|
||||
|
||||
if (decimationTolerance != null && decimationTolerance > 0) {
|
||||
// find available tolerances
|
||||
List<Double> results = DbMapQueryFactory
|
||||
.getMapQuery(
|
||||
"mapdata."
|
||||
+ pointConfig.getPointSource()
|
||||
.toLowerCase(), field)
|
||||
.getLevels();
|
||||
Collections.sort(results, Collections.reverseOrder());
|
||||
|
||||
boolean found = false;
|
||||
for (Double val : results) {
|
||||
if (val <= decimationTolerance) {
|
||||
decimationTolerance = val;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
decimationTolerance = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (decimationTolerance != null) {
|
||||
DecimalFormat df = new DecimalFormat("0.######");
|
||||
String suffix = "_"
|
||||
+ StringUtils.replaceChars(
|
||||
df.format(decimationTolerance), '.', '_');
|
||||
ptFeatures = SpatialQueryFactory.create().query(
|
||||
pointConfig.getPointSource(), field + suffix,
|
||||
ptFields.toArray(new String[ptFields.size()]),
|
||||
searchArea, filter, SearchMode.INTERSECTS);
|
||||
} else {
|
||||
ptFeatures = SpatialQueryFactory.create().query(
|
||||
pointConfig.getPointSource(),
|
||||
ptFields.toArray(new String[ptFields.size()]),
|
||||
searchArea, filter, SearchMode.INTERSECTS);
|
||||
}
|
||||
|
||||
if (ptFeatures != null) {
|
||||
points = new ArrayList<ClosestPoint>(ptFeatures.length);
|
||||
} else {
|
||||
points = new ArrayList<ClosestPoint>(0);
|
||||
}
|
||||
|
||||
for (SpatialQueryResult ptRslt : ptFeatures) {
|
||||
if (ptRslt != null && ptRslt.geometry != null) {
|
||||
Object nameObj = ptRslt.attributes.get(pointConfig
|
||||
.getPointField());
|
||||
if (nameObj != null) {
|
||||
ClosestPoint cp = createClosestPoint(ptFields, ptRslt);
|
||||
points.add(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Retrieve location data for '"
|
||||
+ pointConfig.getVariable() + "' = "
|
||||
+ (System.currentTimeMillis() - t0));
|
||||
} catch (SpatialException e) {
|
||||
throw new VizException("Error querying "
|
||||
+ pointConfig.getPointSource() + " table: "
|
||||
+ e.getLocalizedMessage(), e);
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
protected int getPopulation(Set<String> ptFields,
|
||||
Map<String, Object> attributes) {
|
||||
int population = 0;
|
||||
|
||||
if (ptFields.contains("population")) {
|
||||
try {
|
||||
population = Integer.valueOf(String.valueOf(attributes
|
||||
.get("population")));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
return population;
|
||||
}
|
||||
|
||||
protected int getWangenlev(Set<String> ptFields,
|
||||
Map<String, Object> attributes) {
|
||||
int warngenlev = 0;
|
||||
|
||||
if (ptFields.contains("warngenlev")) {
|
||||
try {
|
||||
warngenlev = Integer.valueOf(String.valueOf(attributes
|
||||
.get("warngenlev")));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
return warngenlev;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,10 +19,8 @@
|
|||
**/
|
||||
package com.raytheon.viz.warngen.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration.PointType;
|
||||
|
||||
/**
|
||||
* Creates data adaptors for PointSource and Pathcast data.
|
||||
|
@ -43,16 +41,17 @@ import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration
|
|||
|
||||
public class DataAdaptorFactory {
|
||||
|
||||
private static Map<Class<?>, IPointSourceDataAdaptor> adapterMap = new HashMap<Class<?>, IPointSourceDataAdaptor>();
|
||||
static {
|
||||
// Only data source config so far
|
||||
adapterMap.put(PointSourceConfiguration.class,
|
||||
new DbPointSourceDataAdaptor());
|
||||
}
|
||||
|
||||
public static IPointSourceDataAdaptor createPointSource(
|
||||
public static AbstractDbSourceDataAdaptor createPointSource(
|
||||
PointSourceConfiguration pointConfig) {
|
||||
return adapterMap.get(pointConfig.getClass());
|
||||
}
|
||||
|
||||
AbstractDbSourceDataAdaptor adaptor = null;
|
||||
|
||||
if (pointConfig.getType() == PointType.AREA) {
|
||||
adaptor = new DbAreaSourceDataAdaptor();
|
||||
} else if (pointConfig.getType() == PointType.POINT) {
|
||||
adaptor = new DbPointSourceDataAdaptor();
|
||||
}
|
||||
|
||||
return adaptor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
package com.raytheon.viz.warngen.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
|
||||
import com.raytheon.viz.warngen.PreferenceUtil;
|
||||
import com.raytheon.viz.warngen.gis.ClosestPoint;
|
||||
import com.raytheon.viz.warngen.gis.GisUtil;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jsanchez
|
||||
*
|
||||
*/
|
||||
public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
|
||||
|
||||
private static final String useDirectionField = "usedirs";
|
||||
|
||||
private static final String suppressedDirectionsField = "supdirs";
|
||||
|
||||
private static final String cwaField = "cwa";
|
||||
|
||||
private GeodeticCalculator gc = new GeodeticCalculator();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected Set<String> createSpatialQueryField() {
|
||||
Set<String> ptFields = new HashSet<String>();
|
||||
ptFields.add(pointConfig.getPointField());
|
||||
ptFields.add(useDirectionField);
|
||||
ptFields.add(suppressedDirectionsField);
|
||||
|
||||
List<String> fields = new ArrayList<String>();
|
||||
if (pointConfig.getSortBy() != null) {
|
||||
fields = Arrays.asList(pointConfig.getSortBy());
|
||||
}
|
||||
|
||||
for (String field : fields) {
|
||||
if (sortFields.contains(field.toLowerCase()) == false) {
|
||||
ptFields.add(field.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
return ptFields;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected ClosestPoint createClosestPoint(Set<String> ptFields,
|
||||
SpatialQueryResult ptRslt) {
|
||||
Map<String, Object> attributes = ptRslt.attributes;
|
||||
|
||||
String name = String
|
||||
.valueOf(attributes.get(pointConfig.getPointField()));
|
||||
Coordinate point = ptRslt.geometry.getCoordinate();
|
||||
int population = getPopulation(ptFields, attributes);
|
||||
int warngenlev = getWangenlev(ptFields, attributes);
|
||||
List<String> partOfArea = getPartOfArea(ptFields, attributes,
|
||||
ptRslt.geometry);
|
||||
|
||||
return new ClosestPoint(name, point, population, warngenlev, partOfArea);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ptFields
|
||||
* @param attributes
|
||||
* @param geom
|
||||
* @return
|
||||
*/
|
||||
private List<String> getPartOfArea(Set<String> ptFields,
|
||||
Map<String, Object> attributes, Geometry geom) {
|
||||
List<String> partOfArea = null;
|
||||
|
||||
boolean userDirections = Boolean.valueOf(String.valueOf(attributes
|
||||
.get(useDirectionField)));
|
||||
if (userDirections) {
|
||||
Geometry intersection = searchArea.intersection(geom);
|
||||
partOfArea = GisUtil.asStringList(GisUtil.calculatePortion(geom,
|
||||
intersection, gc, ""));
|
||||
|
||||
String suppressedDirections = String.valueOf(attributes
|
||||
.get(suppressedDirectionsField));
|
||||
partOfArea.remove(suppressedDirections);
|
||||
}
|
||||
|
||||
return partOfArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, RequestConstraint> processFilterSubstitution() {
|
||||
Map<String, RequestConstraint> filter = pointConfig.getFilter();
|
||||
if (filter != null) {
|
||||
// Process substitutes for filter
|
||||
for (RequestConstraint rc : filter.values()) {
|
||||
rc.setConstraintValue(PreferenceUtil.substitute(
|
||||
rc.getConstraintValue(), localizedSite));
|
||||
}
|
||||
}
|
||||
|
||||
if (filter == null) {
|
||||
filter = new HashMap<String, RequestConstraint>();
|
||||
}
|
||||
|
||||
filter.put(cwaField, new RequestConstraint(localizedSite));
|
||||
|
||||
return filter;
|
||||
}
|
||||
}
|
|
@ -21,23 +21,16 @@ package com.raytheon.viz.warngen.config;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.geospatial.ISpatialQuery.SearchMode;
|
||||
import com.raytheon.uf.common.geospatial.SpatialException;
|
||||
import com.raytheon.uf.common.geospatial.SpatialQueryFactory;
|
||||
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.ClosestPoint;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
/**
|
||||
* PointSource data adaptor for data retrieved from a Database.
|
||||
|
@ -56,24 +49,43 @@ import com.vividsolutions.jts.geom.Geometry;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class DbPointSourceDataAdaptor implements IPointSourceDataAdaptor {
|
||||
public class DbPointSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.warngen.config.IPointSourceDataAdaptor#findClosestPoints
|
||||
* (
|
||||
* com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration
|
||||
* , java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Collection<ClosestPoint> getData(WarngenConfiguration warngenConfig,
|
||||
PointSourceConfiguration pointConfig, Geometry searchArea,
|
||||
String localizedSite) throws VizException {
|
||||
String pointSource = pointConfig.getPointSource();
|
||||
String pointField = pointConfig.getPointField();
|
||||
protected Set<String> createSpatialQueryField() {
|
||||
Set<String> ptFields = new HashSet<String>();
|
||||
ptFields.add(pointConfig.getPointField());
|
||||
|
||||
List<String> fields = new ArrayList<String>();
|
||||
if (pointConfig.getSortBy() != null) {
|
||||
fields = Arrays.asList(pointConfig.getSortBy());
|
||||
}
|
||||
|
||||
for (String field : fields) {
|
||||
if (sortFields.contains(field.toLowerCase()) == false) {
|
||||
ptFields.add(field.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
return ptFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClosestPoint createClosestPoint(Set<String> ptFields,
|
||||
SpatialQueryResult ptRslt) {
|
||||
Map<String, Object> attributes = ptRslt.attributes;
|
||||
|
||||
String name = String
|
||||
.valueOf(attributes.get(pointConfig.getPointField()));
|
||||
Coordinate point = ptRslt.geometry.getCoordinate();
|
||||
int population = getPopulation(ptFields, attributes);
|
||||
int warngenlev = getWangenlev(ptFields, attributes);
|
||||
|
||||
return new ClosestPoint(name, point, population, warngenlev, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, RequestConstraint> processFilterSubstitution() {
|
||||
Map<String, RequestConstraint> filter = pointConfig.getFilter();
|
||||
if (filter != null) {
|
||||
// Process substitutes for filter
|
||||
|
@ -83,64 +95,6 @@ public class DbPointSourceDataAdaptor implements IPointSourceDataAdaptor {
|
|||
}
|
||||
}
|
||||
|
||||
List<String> fields = pointConfig.getSortBy() != null ? Arrays
|
||||
.asList(pointConfig.getSortBy()) : new ArrayList<String>();
|
||||
|
||||
Set<String> ptFields = new HashSet<String>();
|
||||
ptFields.add(pointField);
|
||||
for (String field : fields) {
|
||||
if (!field.equalsIgnoreCase("distance")
|
||||
&& !field.equalsIgnoreCase("area")
|
||||
&& !field.equalsIgnoreCase("parentArea")) {
|
||||
ptFields.add(field.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
List<ClosestPoint> points = new ArrayList<ClosestPoint>();
|
||||
|
||||
try {
|
||||
SpatialQueryResult[] ptFeatures = SpatialQueryFactory.create()
|
||||
.query(pointSource,
|
||||
ptFields.toArray(new String[ptFields.size()]),
|
||||
searchArea, filter, SearchMode.INTERSECTS);
|
||||
for (SpatialQueryResult ptRslt : ptFeatures) {
|
||||
if (ptRslt != null && ptRslt.geometry != null) {
|
||||
Object nameObj = ptRslt.attributes.get(pointField);
|
||||
if (nameObj != null) {
|
||||
int population = 0;
|
||||
int warngenlev = 0;
|
||||
ClosestPoint cp = new ClosestPoint();
|
||||
|
||||
if (ptFields.contains("population")) {
|
||||
try {
|
||||
population = Integer.valueOf(String
|
||||
.valueOf(ptRslt.attributes
|
||||
.get("population")));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
if (ptFields.contains("warngenlev")) {
|
||||
try {
|
||||
warngenlev = Integer.valueOf(String
|
||||
.valueOf(ptRslt.attributes
|
||||
.get("warngenlev")));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
points.add(new ClosestPoint(nameObj.toString(),
|
||||
ptRslt.geometry.getCoordinate(), population,
|
||||
warngenlev));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SpatialException e) {
|
||||
throw new VizException("Error querying " + pointSource + " table: "
|
||||
+ e.getLocalizedMessage(), e);
|
||||
}
|
||||
|
||||
return points;
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +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.config;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.warngen.gis.ClosestPoint;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
||||
/**
|
||||
* PointSource data. Implementations need to be stateless as they will be used
|
||||
* as singletons.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 26, 2011 bgonzale Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bgonzale
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public interface IPointSourceDataAdaptor {
|
||||
|
||||
public Collection<ClosestPoint> getData(WarngenConfiguration warngenConfig,
|
||||
PointSourceConfiguration pointConfig, Geometry searchArea,
|
||||
String localizedSite) throws VizException;
|
||||
|
||||
}
|
|
@ -27,8 +27,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaConfiguration;
|
||||
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.GeospatialConfiguration;
|
||||
|
@ -70,7 +70,7 @@ import com.vividsolutions.jts.geom.Geometry;
|
|||
* MarineZones shapefiles have no FE_AREA.
|
||||
* Apr 13, 2012 #14691 Qinglu lin Added code for two more fe_area: er and nr.
|
||||
* May 4, 2012 #14887 Qinglu lin Changed 0.25 to 0.60 for DEFAULT_PORTION_TOLERANCE;
|
||||
* added code to pass a Envelope calculatePortion().
|
||||
* added code to pass a Envelope calculatePortion().
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -105,14 +105,14 @@ public class Area {
|
|||
GeometryUtil.buildGeometryList(geoms, warningArea);
|
||||
|
||||
GeospatialConfiguration geospatialConfig = config.getGeospatialConfig();
|
||||
AreaConfiguration areaConfig = config.getAreaConfig();
|
||||
AreaSourceConfiguration areaConfig = config.getHatchedAreaSource();
|
||||
|
||||
return findAffectedAreas(areaConfig, geospatialConfig, polygon,
|
||||
localizedSite, geoms);
|
||||
}
|
||||
|
||||
private static AffectedAreas[] findAffectedAreas(
|
||||
AreaConfiguration areaConfig,
|
||||
AreaSourceConfiguration areaConfig,
|
||||
GeospatialConfiguration geospatialConfig, Geometry polygon,
|
||||
String localizedSite, List<Geometry> geoms) throws VizException {
|
||||
String areaSource = areaConfig.getAreaSource();
|
||||
|
@ -172,8 +172,9 @@ public class Area {
|
|||
|
||||
List<String> uniqueFips = new ArrayList<String>();
|
||||
List<AffectedAreas> areas = new ArrayList<AffectedAreas>();
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
for (GeospatialData regionFeature : countyMap.values()) {
|
||||
Geometry regionGeom = regionFeature.geometry;
|
||||
Geometry regionGeom = regionFeature.geometry;
|
||||
AffectedAreas area = new AffectedAreas();
|
||||
area.name = regionFeature.attributes.get(areaField).toString();
|
||||
area.fips = regionFeature.attributes.get(fipsField).toString();
|
||||
|
@ -217,7 +218,8 @@ public class Area {
|
|||
* DEFAULT_PORTION_TOLERANCE;
|
||||
if (areaIntersection < tolerCheck) {
|
||||
area.partOfArea = GisUtil.asStringList(GisUtil
|
||||
.calculatePortion(regionGeom, intersection, area.suppress));
|
||||
.calculatePortion(regionGeom, intersection, gc,
|
||||
area.suppress));
|
||||
}
|
||||
|
||||
// Search the parent region
|
||||
|
@ -225,66 +227,67 @@ public class Area {
|
|||
if (parentRegion != null) {
|
||||
area.parentRegion = String.valueOf(parentRegion.attributes
|
||||
.get(parentAreaField));
|
||||
String feArea = (String)regionFeature.attributes.get("FE_AREA");
|
||||
final List<String> partList = new ArrayList<String>();
|
||||
String feArea = (String) regionFeature.attributes
|
||||
.get("FE_AREA");
|
||||
final List<String> partList = new ArrayList<String>();
|
||||
if (feArea == null) {
|
||||
// Marine warnings
|
||||
partList.add("");
|
||||
// Marine warnings
|
||||
partList.add("");
|
||||
} else {
|
||||
if (feArea.equals("pa"))
|
||||
partList.add("PA");
|
||||
else if(feArea.equals("mi"))
|
||||
partList.add("MI");
|
||||
else if(feArea.equals("pd"))
|
||||
partList.add("PD");
|
||||
else if(feArea.equals("up"))
|
||||
partList.add("UP");
|
||||
else if(feArea.equals("bb"))
|
||||
partList.add("BB");
|
||||
else if(feArea.equals("er"))
|
||||
partList.add("ER");
|
||||
else if(feArea.equals("eu"))
|
||||
partList.add("EU");
|
||||
else if(feArea.equals("sr"))
|
||||
partList.add("SR");
|
||||
else if(feArea.equals("nr"))
|
||||
partList.add("NR");
|
||||
else if(feArea.equals("wu"))
|
||||
partList.add("WU");
|
||||
else if(feArea.equals("ds"))
|
||||
partList.add("DS");
|
||||
else if(feArea.equals("ne"))
|
||||
partList.add("NE");
|
||||
else if(feArea.equals("nw"))
|
||||
partList.add("NW");
|
||||
else if(feArea.equals("se"))
|
||||
partList.add("SE");
|
||||
else if(feArea.equals("sw"))
|
||||
partList.add("SW");
|
||||
else {
|
||||
for (int i=0; i<feArea.length(); i++) {
|
||||
char c = feArea.charAt(i);
|
||||
switch (c) {
|
||||
case 'c':
|
||||
partList.add("CENTRAL");
|
||||
break;
|
||||
case 'w':
|
||||
partList.add("WEST");
|
||||
break;
|
||||
case 'n':
|
||||
partList.add("NORTH");
|
||||
break;
|
||||
case 'e':
|
||||
partList.add("EAST");
|
||||
break;
|
||||
case 's':
|
||||
partList.add("SOUTH");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (feArea.equals("pa"))
|
||||
partList.add("PA");
|
||||
else if (feArea.equals("mi"))
|
||||
partList.add("MI");
|
||||
else if (feArea.equals("pd"))
|
||||
partList.add("PD");
|
||||
else if (feArea.equals("up"))
|
||||
partList.add("UP");
|
||||
else if (feArea.equals("bb"))
|
||||
partList.add("BB");
|
||||
else if (feArea.equals("er"))
|
||||
partList.add("ER");
|
||||
else if (feArea.equals("eu"))
|
||||
partList.add("EU");
|
||||
else if (feArea.equals("sr"))
|
||||
partList.add("SR");
|
||||
else if (feArea.equals("nr"))
|
||||
partList.add("NR");
|
||||
else if (feArea.equals("wu"))
|
||||
partList.add("WU");
|
||||
else if (feArea.equals("ds"))
|
||||
partList.add("DS");
|
||||
else if (feArea.equals("ne"))
|
||||
partList.add("NE");
|
||||
else if (feArea.equals("nw"))
|
||||
partList.add("NW");
|
||||
else if (feArea.equals("se"))
|
||||
partList.add("SE");
|
||||
else if (feArea.equals("sw"))
|
||||
partList.add("SW");
|
||||
else {
|
||||
for (int i = 0; i < feArea.length(); i++) {
|
||||
char c = feArea.charAt(i);
|
||||
switch (c) {
|
||||
case 'c':
|
||||
partList.add("CENTRAL");
|
||||
break;
|
||||
case 'w':
|
||||
partList.add("WEST");
|
||||
break;
|
||||
case 'n':
|
||||
partList.add("NORTH");
|
||||
break;
|
||||
case 'e':
|
||||
partList.add("EAST");
|
||||
break;
|
||||
case 's':
|
||||
partList.add("SOUTH");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
area.partOfParentRegion = partList;
|
||||
}
|
||||
|
@ -339,7 +342,7 @@ public class Area {
|
|||
Map<String, Object> areasMap = new HashMap<String, Object>();
|
||||
|
||||
for (AreaSourceConfiguration asc : config.getAreaSources()) {
|
||||
if (asc.getAreaType() == AreaType.INTERSECT) {
|
||||
if (asc.getType() == AreaType.INTERSECT) {
|
||||
String areaSource = asc.getAreaSource();
|
||||
String key = areaSource + "." + localizedSite;
|
||||
|
||||
|
@ -364,9 +367,9 @@ public class Area {
|
|||
}
|
||||
}
|
||||
|
||||
AffectedAreas[] affectedAreas = findAffectedAreas(
|
||||
asc.getAreaConfig(), config.getGeospatialConfig(),
|
||||
warnPolygon, localizedSite, geoms);
|
||||
AffectedAreas[] affectedAreas = findAffectedAreas(asc,
|
||||
config.getGeospatialConfig(), warnPolygon,
|
||||
localizedSite, geoms);
|
||||
|
||||
areasMap.put(asc.getVariable(), affectedAreas);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package com.raytheon.viz.warngen.gis;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
|
@ -69,36 +70,40 @@ public class ClosestPoint implements Comparable<ClosestPoint> {
|
|||
|
||||
protected Date time;
|
||||
|
||||
protected List<String> partOfArea;
|
||||
|
||||
public ClosestPoint() {
|
||||
|
||||
}
|
||||
|
||||
public ClosestPoint(ClosestPoint o) {
|
||||
this.name = o.name;
|
||||
this.area = o.area;
|
||||
this.parentArea = o.parentArea;
|
||||
this.point = o.point;
|
||||
this.distance = o.distance;
|
||||
this.roundedDistance = o.roundedDistance;
|
||||
this.azimuth = o.azimuth;
|
||||
this.roundedAzimuth = o.roundedAzimuth;
|
||||
this.oppositeAzimuth = o.oppositeAzimuth;
|
||||
this.oppositeRoundedAzimuth = o.oppositeRoundedAzimuth;
|
||||
this.population = o.population;
|
||||
this.warngenlev = o.warngenlev;
|
||||
this.time = o.time;
|
||||
}
|
||||
this.name = o.name;
|
||||
this.area = o.area;
|
||||
this.parentArea = o.parentArea;
|
||||
this.point = o.point;
|
||||
this.distance = o.distance;
|
||||
this.roundedDistance = o.roundedDistance;
|
||||
this.azimuth = o.azimuth;
|
||||
this.roundedAzimuth = o.roundedAzimuth;
|
||||
this.oppositeAzimuth = o.oppositeAzimuth;
|
||||
this.oppositeRoundedAzimuth = o.oppositeRoundedAzimuth;
|
||||
this.population = o.population;
|
||||
this.warngenlev = o.warngenlev;
|
||||
this.time = o.time;
|
||||
this.partOfArea = o.partOfArea;
|
||||
}
|
||||
|
||||
public ClosestPoint(String name, Coordinate point) {
|
||||
this(name, point, 0, 0);
|
||||
public ClosestPoint(String name, Coordinate point) {
|
||||
this(name, point, 0, 0, null);
|
||||
}
|
||||
|
||||
public ClosestPoint(String name, Coordinate point, int population,
|
||||
int warngenlev) {
|
||||
int warngenlev, List<String> partOfArea) {
|
||||
this.name = name;
|
||||
this.point = point;
|
||||
this.population = population;
|
||||
this.warngenlev = warngenlev;
|
||||
this.partOfArea = partOfArea;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,6 +113,10 @@ public class ClosestPoint implements Comparable<ClosestPoint> {
|
|||
return name;
|
||||
}
|
||||
|
||||
public Coordinate getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the distance
|
||||
*/
|
||||
|
@ -160,6 +169,10 @@ public class ClosestPoint implements Comparable<ClosestPoint> {
|
|||
return parentArea;
|
||||
}
|
||||
|
||||
public List<String> getPartOfArea() {
|
||||
return partOfArea;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the angle from -360/360 to be between -180/180
|
||||
*
|
||||
|
|
|
@ -66,27 +66,33 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
public class GisUtil {
|
||||
|
||||
private static final float PORTION_OF_CENTER = 0.16875f;
|
||||
|
||||
|
||||
private static final float DIRECTION_DELTA = 15;
|
||||
|
||||
private static final float EXTREME_DELTA = 0.0625f;
|
||||
|
||||
private static final double CONTAINS_PERCENTAGE = 0.1;
|
||||
|
||||
// When both xDirection and yDirection are Direction.CENTRAL, for a rectangle
|
||||
// polygon, MIN1 is the maximum value of either distanceX or distanceY
|
||||
|
||||
// When both xDirection and yDirection are Direction.CENTRAL, for a
|
||||
// rectangle
|
||||
// polygon, MIN1 is the maximum value of either distanceX or distanceY
|
||||
// for EnumSet.of(xDirection,yDirection) to be returned.
|
||||
private static final float MIN1 = 0.01f;
|
||||
|
||||
// When both xDirection and yDirection are Direction.CENTRAL, for a right triangle
|
||||
// polygon, MIN2 is the maximum value of both distanceX and distanceY
|
||||
|
||||
// When both xDirection and yDirection are Direction.CENTRAL, for a right
|
||||
// triangle
|
||||
// polygon, MIN2 is the maximum value of both distanceX and distanceY
|
||||
// for EnumSet.of(xDirection,yDirection) to be returned.
|
||||
private static final float MIN2 = 0.045f;
|
||||
|
||||
// When yDirection is NORTH or SOUTH, in order to add CENTRAL to retval, required
|
||||
// minimum ratio of width of intersection envelope to that of county envelope;
|
||||
// when xDirection is EAST or WEST, in order to add CENTRAL to retval, required
|
||||
// minimum ratio of height of intersection envelope to that of county envelope;
|
||||
|
||||
// When yDirection is NORTH or SOUTH, in order to add CENTRAL to retval,
|
||||
// required
|
||||
// minimum ratio of width of intersection envelope to that of county
|
||||
// envelope;
|
||||
// when xDirection is EAST or WEST, in order to add CENTRAL to retval,
|
||||
// required
|
||||
// minimum ratio of height of intersection envelope to that of county
|
||||
// envelope;
|
||||
private static final float RATIO = 0.5f;
|
||||
|
||||
public static enum Direction {
|
||||
|
@ -135,12 +141,12 @@ public class GisUtil {
|
|||
}
|
||||
|
||||
public static EnumSet<Direction> calculatePortion(Geometry geom,
|
||||
Geometry geom2) {
|
||||
return calculatePortion(geom, geom2, SuppressMap.NONE);
|
||||
Geometry geom2, GeodeticCalculator gc) {
|
||||
return calculatePortion(geom, geom2, gc, SuppressMap.NONE);
|
||||
}
|
||||
|
||||
public static EnumSet<Direction> calculatePortion(Geometry geom,
|
||||
Geometry intersection, String suppressType) {
|
||||
Geometry intersection, GeodeticCalculator gc, String suppressType) {
|
||||
Direction xDirection = null;
|
||||
Direction yDirection = null;
|
||||
|
||||
|
@ -161,23 +167,25 @@ public class GisUtil {
|
|||
double extremaThresholdY = approximateHeight * EXTREME_DELTA;
|
||||
|
||||
if (distanceX < centerThresholdX) {
|
||||
xDirection = Direction.CENTRAL;
|
||||
if (distanceY < centerThresholdY)
|
||||
yDirection = Direction.CENTRAL;
|
||||
xDirection = Direction.CENTRAL;
|
||||
if (distanceY < centerThresholdY)
|
||||
yDirection = Direction.CENTRAL;
|
||||
}
|
||||
|
||||
if (xDirection != null && yDirection != null) {
|
||||
// Both xDirection equals Direction.CENTRAL and yDirection equals Direction.CENTRAL
|
||||
// calculated above is not always correct for returning EnumSet.of(xDirection,yDirection).
|
||||
// The following 'if statement' filters out some cases.
|
||||
if (distanceX < MIN1 || distanceY < MIN1 || (distanceX < MIN2 && distanceY < MIN2))
|
||||
return EnumSet.of(xDirection,yDirection);
|
||||
// Both xDirection equals Direction.CENTRAL and yDirection equals
|
||||
// Direction.CENTRAL
|
||||
// calculated above is not always correct for returning
|
||||
// EnumSet.of(xDirection,yDirection).
|
||||
// The following 'if statement' filters out some cases.
|
||||
if (distanceX < MIN1 || distanceY < MIN1
|
||||
|| (distanceX < MIN2 && distanceY < MIN2))
|
||||
return EnumSet.of(xDirection, yDirection);
|
||||
}
|
||||
|
||||
|
||||
xDirection = null;
|
||||
yDirection = null;
|
||||
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
|
||||
gc.setStartingGeographicPoint(centroid.x, centroid.y);
|
||||
gc.setDestinationGeographicPoint(point.x, point.y);
|
||||
double azimuth = gc.getAzimuth();
|
||||
|
@ -229,26 +237,32 @@ public class GisUtil {
|
|||
&& !suppressType.equals(SuppressMap.ALL))
|
||||
retVal.add(yDirection);
|
||||
|
||||
if (xDirection != null &&
|
||||
(xDirection.equals(Direction.WEST) || xDirection.equals(Direction.EAST))) {
|
||||
if ( env.getHeight() < RATIO*approximateHeight) {
|
||||
if (xDirection != null
|
||||
&& (xDirection.equals(Direction.WEST) || xDirection
|
||||
.equals(Direction.EAST))) {
|
||||
if (env.getHeight() < RATIO * approximateHeight) {
|
||||
retVal.add(Direction.CENTRAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (yDirection != null &&
|
||||
(yDirection.equals(Direction.NORTH) || yDirection.equals(Direction.SOUTH))) {
|
||||
if ( env.getWidth() < RATIO*approximateWidth) {
|
||||
if (yDirection != null
|
||||
&& (yDirection.equals(Direction.NORTH) || yDirection
|
||||
.equals(Direction.SOUTH))) {
|
||||
if (env.getWidth() < RATIO * approximateWidth) {
|
||||
retVal.add(Direction.CENTRAL);
|
||||
}
|
||||
}
|
||||
|
||||
if ((retVal.contains(Direction.NORTH) && retVal.contains(Direction.WEST)) ||
|
||||
(retVal.contains(Direction.NORTH) && retVal.contains(Direction.EAST)) ||
|
||||
(retVal.contains(Direction.SOUTH) && retVal.contains(Direction.WEST)) ||
|
||||
(retVal.contains(Direction.SOUTH) && retVal.contains(Direction.EAST)) ) {
|
||||
if (retVal.contains(Direction.CENTRAL))
|
||||
retVal.remove(Direction.CENTRAL);
|
||||
|
||||
if ((retVal.contains(Direction.NORTH) && retVal
|
||||
.contains(Direction.WEST))
|
||||
|| (retVal.contains(Direction.NORTH) && retVal
|
||||
.contains(Direction.EAST))
|
||||
|| (retVal.contains(Direction.SOUTH) && retVal
|
||||
.contains(Direction.WEST))
|
||||
|| (retVal.contains(Direction.SOUTH) && retVal
|
||||
.contains(Direction.EAST))) {
|
||||
if (retVal.contains(Direction.CENTRAL))
|
||||
retVal.remove(Direction.CENTRAL);
|
||||
}
|
||||
|
||||
if (isExtreme && !suppressType.equals(SuppressMap.ALL))
|
||||
|
@ -286,11 +300,11 @@ public class GisUtil {
|
|||
coord.x = oldCoord.x;
|
||||
}
|
||||
coord.y = oldCoord.y;
|
||||
|
||||
|
||||
return coord;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static Coordinate[] d2dCoordinates(Coordinate[] oldCoords) {
|
||||
int length = oldCoords.length;
|
||||
Coordinate[] coords = new Coordinate[length];
|
||||
|
@ -327,15 +341,15 @@ public class GisUtil {
|
|||
/**
|
||||
* restoreAlaskaLon()
|
||||
*
|
||||
* Feb 28, 2012 DR13596 Qinglu Lin Created.
|
||||
* Feb 28, 2012 DR13596 Qinglu Lin Created.
|
||||
*
|
||||
* If the longitude of a Coordinate is less than -180 and corresponding
|
||||
* latitude is larger than 45 degree North, convert it to a value
|
||||
* equivalent to (360 + the longitude).
|
||||
* If the longitude of a Coordinate is less than -180 and corresponding
|
||||
* latitude is larger than 45 degree North, convert it to a value equivalent
|
||||
* to (360 + the longitude).
|
||||
*/
|
||||
public static Coordinate restoreAlaskaLon(Coordinate oldCoords) {
|
||||
Coordinate coord = new Coordinate();
|
||||
if (oldCoords.x < -180. && oldCoords.y > 45.) {
|
||||
if (oldCoords.x < -180. && oldCoords.y > 45.) {
|
||||
coord.x = 360. + oldCoords.x;
|
||||
} else {
|
||||
coord.x = oldCoords.x;
|
||||
|
|
|
@ -40,7 +40,6 @@ import javax.measure.converter.UnitConverter;
|
|||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.eclipse.jface.action.IMenuManager;
|
||||
import org.eclipse.swt.events.DisposeEvent;
|
||||
import org.eclipse.swt.events.DisposeListener;
|
||||
|
@ -53,8 +52,6 @@ import org.opengis.referencing.operation.MathTransform;
|
|||
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||
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.BulletActionGroup;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.DialogConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.GridSpacing;
|
||||
|
@ -169,7 +166,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}
|
||||
|
||||
private static Map<String, GeospatialDataList> siteMap = new HashMap<String, GeospatialDataList>();
|
||||
|
||||
|
||||
private static Map<String, Geometry> timezoneMap = new HashMap<String, Geometry>();
|
||||
|
||||
public static final String GID = "gid";
|
||||
|
@ -678,17 +675,6 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
private void init(WarngenConfiguration config) {
|
||||
long t0 = System.currentTimeMillis();
|
||||
|
||||
boolean validAreaSource = false;
|
||||
for (AreaSourceConfiguration as : config.getAreaSources()) {
|
||||
if (as.getAreaType() == AreaType.HATCHING) {
|
||||
validAreaSource = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Validate.isTrue(validAreaSource,
|
||||
"At least one area source should have an areaType 'HATCHING'");
|
||||
|
||||
String site = getLocalizedSite();
|
||||
Map<String, GeospatialMetadata> metadataMap = GeospatialFactory
|
||||
.getMetaDataMap(config);
|
||||
|
@ -746,20 +732,22 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
locals).getEnvelopeInternal();
|
||||
IExtent localExtent = new PixelExtent(env.getMinX(),
|
||||
env.getMaxX(), env.getMinY(), env.getMaxY());
|
||||
|
||||
|
||||
int nx = 600;
|
||||
int ny = 600;
|
||||
// Boolean to change the aspect ratio of the extent to match
|
||||
// Boolean to change the aspect ratio of the extent to
|
||||
// match
|
||||
boolean keepAspectRatio = true;
|
||||
|
||||
|
||||
GridSpacing gridSpacing = dialogConfig.getGridSpacing();
|
||||
|
||||
if (gridSpacing != null && gridSpacing.getNx() != null && gridSpacing != null) {
|
||||
|
||||
if (gridSpacing != null && gridSpacing.getNx() != null
|
||||
&& gridSpacing != null) {
|
||||
nx = gridSpacing.getNx();
|
||||
ny = gridSpacing.getNy();
|
||||
keepAspectRatio = gridSpacing.isKeepAspectRatio();
|
||||
}
|
||||
|
||||
|
||||
double xinc, yinc;
|
||||
double width = localExtent.getWidth();
|
||||
double height = localExtent.getHeight();
|
||||
|
@ -786,20 +774,25 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
System.out.println("Time to lookup geospatial data "
|
||||
+ (System.currentTimeMillis() - tq0));
|
||||
siteMap.put(currKey, gData);
|
||||
|
||||
GeospatialData[] timezones = GeospatialFactory.getTimezones();
|
||||
|
||||
GeospatialData[] timezones = GeospatialFactory
|
||||
.getTimezones();
|
||||
if (timezones != null) {
|
||||
for (GeospatialData timezone : timezones) {
|
||||
if (timezone.attributes.containsKey(gmd.getTimeZoneField())) {
|
||||
String oneLetterTimezone = String.valueOf(
|
||||
timezone.attributes.get(gmd.getTimeZoneField()));
|
||||
if (timezoneMap.containsKey(oneLetterTimezone) == false) {
|
||||
timezoneMap.put(oneLetterTimezone, timezone.geometry);
|
||||
if (timezone.attributes.containsKey(gmd
|
||||
.getTimeZoneField())) {
|
||||
String oneLetterTimezone = String
|
||||
.valueOf(timezone.attributes
|
||||
.get(gmd.getTimeZoneField()));
|
||||
if (timezoneMap
|
||||
.containsKey(oneLetterTimezone) == false) {
|
||||
timezoneMap.put(oneLetterTimezone,
|
||||
timezone.geometry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.WARN,
|
||||
"Error in initializing geometries.", e);
|
||||
|
@ -857,7 +850,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
return new GeospatialData[0];
|
||||
}
|
||||
|
||||
|
||||
public Geometry getTimezoneGeom(String oneLetterTimezone) {
|
||||
return timezoneMap.get(oneLetterTimezone);
|
||||
}
|
||||
|
@ -990,9 +983,10 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
if (polygon != null) {
|
||||
for (GeospatialData r : geoData.features) {
|
||||
PreparedGeometry prepGeom = (PreparedGeometry) r.attributes
|
||||
.get(GeospatialDataList.LOCAL_PREP_GEOM);
|
||||
.get(GeospatialDataList.LOCAL_PREP_GEOM);
|
||||
try {
|
||||
Geometry intersection = GeometryUtil.intersection(polygon, prepGeom);
|
||||
Geometry intersection = GeometryUtil.intersection(polygon,
|
||||
prepGeom);
|
||||
if (intersection.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1035,7 +1029,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
if (configuration.getGeospatialConfig().getAreaSource()
|
||||
.equalsIgnoreCase(MARINE)) {
|
||||
fips = String.valueOf(data.entry.attributes.get(configuration
|
||||
.getAreaConfig().getFipsField()));
|
||||
.getHatchedAreaSource().getFipsField()));
|
||||
if (countyMap.containsKey(fips.substring(0, 2))) {
|
||||
ids = countyMap.get(fips.substring(0, 2));
|
||||
for (String id : ids) {
|
||||
|
@ -1047,12 +1041,13 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}
|
||||
} else {
|
||||
String stateAbbr = String.valueOf(data.entry.attributes
|
||||
.get(configuration.getAreaConfig()
|
||||
.get(configuration.getHatchedAreaSource()
|
||||
.getAreaNotationField()));
|
||||
if (countyMap.containsKey(stateAbbr)) {
|
||||
ids = countyMap.get(stateAbbr);
|
||||
fips = String.valueOf(data.entry.attributes
|
||||
.get(configuration.getAreaConfig().getFipsField()));
|
||||
.get(configuration.getHatchedAreaSource()
|
||||
.getFipsField()));
|
||||
for (String id : ids) {
|
||||
if (fips.endsWith(id)) {
|
||||
newList.add(geom);
|
||||
|
@ -1180,19 +1175,19 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
boolean includeArea = false;
|
||||
if (!determineInclusion) {
|
||||
includeArea = areaInKmSqOfIntersection > 1;
|
||||
} else if (getConfiguration().getAreaConfig()
|
||||
} else if (getConfiguration().getHatchedAreaSource()
|
||||
.getInclusionAndOr().equalsIgnoreCase("AND")) {
|
||||
if ((ratioInPercent >= getConfiguration().getAreaConfig()
|
||||
.getInclusionPercent())
|
||||
if ((ratioInPercent >= getConfiguration()
|
||||
.getHatchedAreaSource().getInclusionPercent())
|
||||
&& (areaInKmSqOfIntersection > getConfiguration()
|
||||
.getAreaConfig().getInclusionArea())) {
|
||||
.getHatchedAreaSource().getInclusionArea())) {
|
||||
includeArea = true;
|
||||
}
|
||||
} else {
|
||||
if ((ratioInPercent >= getConfiguration().getAreaConfig()
|
||||
.getInclusionPercent())
|
||||
if ((ratioInPercent >= getConfiguration()
|
||||
.getHatchedAreaSource().getInclusionPercent())
|
||||
|| (areaInKmSqOfIntersection > getConfiguration()
|
||||
.getAreaConfig().getInclusionArea())) {
|
||||
.getHatchedAreaSource().getInclusionArea())) {
|
||||
includeArea = true;
|
||||
}
|
||||
}
|
||||
|
@ -1356,7 +1351,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
c[2] = new Coordinate(p3.getX(), p3.getY());
|
||||
c[3] = new Coordinate(p4.getX(), p4.getY());
|
||||
c[4] = c[0];
|
||||
|
||||
|
||||
PolygonUtil.truncate(c, 2);
|
||||
|
||||
LinearRing lr = gf.createLinearRing(c);
|
||||
|
@ -1564,7 +1559,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
c[2] = new Coordinate(p3.getX(), p3.getY());
|
||||
c[3] = new Coordinate(p4.getX(), p4.getY());
|
||||
c[4] = c[0];
|
||||
|
||||
|
||||
PolygonUtil.truncate(c, 2);
|
||||
|
||||
LinearRing lr = gf.createLinearRing(c);
|
||||
|
@ -1946,10 +1941,10 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
for (int j = 0; j < ls.length; j++) {
|
||||
if (i != j
|
||||
&& ls[i].intersection(ls[j]) != null
|
||||
&& ls[i].intersection(ls[j]).equals(ls[i]
|
||||
.getCoordinate(0)) == false
|
||||
&& ls[i].intersection(ls[j]).equals(ls[i]
|
||||
.getCoordinate(1)) == false) {
|
||||
&& ls[i].intersection(ls[j]).equals(
|
||||
ls[i].getCoordinate(0)) == false
|
||||
&& ls[i].intersection(ls[j]).equals(
|
||||
ls[i].getCoordinate(1)) == false) {
|
||||
intersectFlag = true;
|
||||
}
|
||||
}
|
||||
|
@ -2150,7 +2145,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
for (GeospatialData f : geoData.features) {
|
||||
Geometry geom = f.geometry;
|
||||
if (prefixes.contains(GeometryUtil.getPrefix(geom.getUserData()))) {
|
||||
Coordinate center = GisUtil.d2dCoordinate(geom.getCentroid().getCoordinate());
|
||||
Coordinate center = GisUtil.d2dCoordinate(geom.getCentroid()
|
||||
.getCoordinate());
|
||||
state.strings.put(center, "W");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,14 +22,17 @@ package com.raytheon.viz.warngen.template;
|
|||
import java.awt.geom.Point2D;
|
||||
import java.io.StringWriter;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
@ -40,12 +43,14 @@ import javax.measure.converter.UnitConverter;
|
|||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.tools.generic.ListTool;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
|
@ -66,6 +71,7 @@ import com.raytheon.uf.common.time.DataTime;
|
|||
import com.raytheon.uf.common.time.SimulatedTime;
|
||||
import com.raytheon.uf.edex.core.EdexException;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.viz.awipstools.ToolsDataManager;
|
||||
import com.raytheon.viz.awipstools.common.StormTrackData;
|
||||
|
@ -94,6 +100,7 @@ import com.raytheon.viz.warnings.DateUtil;
|
|||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
||||
import com.vividsolutions.jts.io.WKTReader;
|
||||
|
||||
/**
|
||||
|
@ -214,7 +221,8 @@ public class TemplateRunner {
|
|||
context.put("dateUtil", new DateUtil());
|
||||
context.put("pointComparator", new ClosestPointComparator());
|
||||
|
||||
String action = followupData != null ? followupData.getAct() : WarningAction.NEW.toString();
|
||||
String action = followupData != null ? followupData.getAct()
|
||||
: WarningAction.NEW.toString();
|
||||
String phen = followupData != null ? followupData.getPhen() : null;
|
||||
String sig = followupData != null ? followupData.getSig() : null;
|
||||
String etn = followupData != null ? followupData.getEtn() : null;
|
||||
|
@ -230,7 +238,7 @@ public class TemplateRunner {
|
|||
threeLetterSiteId);
|
||||
System.out.println("Time to get areas = "
|
||||
+ (System.currentTimeMillis() - t0));
|
||||
context.put(config.getAreaConfig().getVariable(), areas);
|
||||
context.put(config.getHatchedAreaSource().getVariable(), areas);
|
||||
|
||||
t0 = System.currentTimeMillis();
|
||||
intersectAreas = Area.findInsectingAreas(config, warnPolygon,
|
||||
|
@ -242,32 +250,37 @@ public class TemplateRunner {
|
|||
}
|
||||
|
||||
if (areas != null && areas.length > 0) {
|
||||
Set<String> timeZones = new HashSet<String>();
|
||||
Set<String> timeZones = new HashSet<String>();
|
||||
for (AffectedAreas area : areas) {
|
||||
if (area.getTimezone() != null) {
|
||||
// Handles counties that span two counties
|
||||
// Handles counties that span two counties
|
||||
String oneLetterTimeZones = area.getTimezone().trim();
|
||||
if (oneLetterTimeZones.length() == 1) {
|
||||
timeZones.add(String.valueOf(oneLetterTimeZones.charAt(0)));
|
||||
timeZones.add(String.valueOf(oneLetterTimeZones
|
||||
.charAt(0)));
|
||||
} else {
|
||||
for (int i = 0; i < oneLetterTimeZones.length(); i++) {
|
||||
String oneLetterTimeZone = String.valueOf(oneLetterTimeZones.charAt(i));
|
||||
Geometry timezoneGeom = warngenLayer.getTimezoneGeom(oneLetterTimeZone);
|
||||
if (timezoneGeom != null && GeometryUtil.intersects(warningArea, timezoneGeom)) {
|
||||
timeZones.add(oneLetterTimeZone);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < oneLetterTimeZones.length(); i++) {
|
||||
String oneLetterTimeZone = String
|
||||
.valueOf(oneLetterTimeZones.charAt(i));
|
||||
Geometry timezoneGeom = warngenLayer
|
||||
.getTimezoneGeom(oneLetterTimeZone);
|
||||
if (timezoneGeom != null
|
||||
&& GeometryUtil.intersects(warningArea,
|
||||
timezoneGeom)) {
|
||||
timeZones.add(oneLetterTimeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<String> iterator = timeZones.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (context.get("localtimezone") == null) {
|
||||
context.put("localtimezone", iterator.next());
|
||||
} else if (context.get("secondtimezone") == null) {
|
||||
context.put("secondtimezone", iterator.next());
|
||||
}
|
||||
if (context.get("localtimezone") == null) {
|
||||
context.put("localtimezone", iterator.next());
|
||||
} else if (context.get("secondtimezone") == null) {
|
||||
context.put("secondtimezone", iterator.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,8 +347,7 @@ public class TemplateRunner {
|
|||
context.put("movementDirection", motionDirection);
|
||||
// Convert to Point2D representation as Velocity requires
|
||||
// getX() and getY() methods which Coordinate does not have
|
||||
Coordinate[] newStormLocs = GisUtil
|
||||
.d2dCoordinates(stormLocs);
|
||||
Coordinate[] newStormLocs = GisUtil.d2dCoordinates(stormLocs);
|
||||
Point2D.Double[] coords = new Point2D.Double[newStormLocs.length];
|
||||
for (int i = 0; i < newStormLocs.length; i++) {
|
||||
coords[i] = new Point2D.Double(newStormLocs[i].x,
|
||||
|
@ -466,8 +478,10 @@ public class TemplateRunner {
|
|||
if (totalSegments > 1) {
|
||||
al = FollowUpUtil.canceledAreasFromText(originalText);
|
||||
}
|
||||
context.put("cancel"+ config.getAreaConfig().getVariable(), al);
|
||||
context.put("ugclinecan", FollowUpUtil.getUgcLineCanFromText(originalText));
|
||||
context.put("cancel"
|
||||
+ config.getHatchedAreaSource().getVariable(), al);
|
||||
context.put("ugclinecan",
|
||||
FollowUpUtil.getUgcLineCanFromText(originalText));
|
||||
} else if (selectedAction == WarningAction.EXT) {
|
||||
context.put("action", WarningAction.EXT.toString());
|
||||
context.put("etn", etn);
|
||||
|
@ -515,7 +529,8 @@ public class TemplateRunner {
|
|||
}
|
||||
}
|
||||
context.put("cancel"
|
||||
+ config.getAreaConfig().getVariable(), al);
|
||||
+ config.getHatchedAreaSource().getVariable(),
|
||||
al);
|
||||
|
||||
// This may not be efficient enough. Is it possible that
|
||||
// a removed intersected county be in the affected
|
||||
|
@ -583,7 +598,7 @@ public class TemplateRunner {
|
|||
+ (System.currentTimeMillis() - tz0));
|
||||
|
||||
return WarningTextHandler.handle(script.toString().toUpperCase(),
|
||||
areas, cancelareas, selectedAction,
|
||||
areas, cancelareas, selectedAction,
|
||||
WarningAction.valueOf((String) context.get("action")),
|
||||
config.getAutoLockText());
|
||||
}
|
||||
|
@ -659,18 +674,16 @@ public class TemplateRunner {
|
|||
private static WatchUtil getWatches(WarngenLayer warngenLayer,
|
||||
WarngenConfiguration config, Geometry polygon,
|
||||
String fourLetterSiteId) throws Exception {
|
||||
Validate.isTrue(
|
||||
config.getAreaConfig().getIncludedWatchAreaBuffer() >= 0,
|
||||
Validate.isTrue(config.getHatchedAreaSource()
|
||||
.getIncludedWatchAreaBuffer() >= 0,
|
||||
"IncludedWatchAreaBuffer can not be negative");
|
||||
Polygon watchArea = (Polygon) polygon.buffer(milesToKilometer
|
||||
.convert(config.getAreaConfig().getIncludedWatchAreaBuffer())
|
||||
/ KmToDegrees);
|
||||
WatchUtil rval = null;
|
||||
GetActiveTableRequest req = new GetActiveTableRequest();
|
||||
String[] includedWatches = config.getIncludedWatches();
|
||||
|
||||
if (config.getIncludedWatches() != null
|
||||
&& config.getIncludedWatches().length > 0) {
|
||||
if (includedWatches != null && includedWatches.length > 0) {
|
||||
String phensigList = null;
|
||||
for (String includedWatch : config.getIncludedWatches()) {
|
||||
for (String includedWatch : includedWatches) {
|
||||
if (includedWatch.equalsIgnoreCase("torWatches")) {
|
||||
phensigList = phensigList == null ? "TO.A" : phensigList
|
||||
+ ",TO.A";
|
||||
|
@ -679,62 +692,134 @@ public class TemplateRunner {
|
|||
+ ",SV.A";
|
||||
}
|
||||
}
|
||||
|
||||
req.setPhensigList(phensigList);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (CAVEMode.getMode().equals(CAVEMode.PRACTICE)) {
|
||||
req.setMode(ActiveTableMode.PRACTICE);
|
||||
} else {
|
||||
req.setMode(ActiveTableMode.OPERATIONAL);
|
||||
}
|
||||
if (CAVEMode.getMode().equals(CAVEMode.PRACTICE)) {
|
||||
req.setMode(ActiveTableMode.PRACTICE);
|
||||
} else {
|
||||
req.setMode(ActiveTableMode.OPERATIONAL);
|
||||
}
|
||||
|
||||
req.setSiteID(fourLetterSiteId);
|
||||
req.setRequestValidTimes(true);
|
||||
req.setSiteID(fourLetterSiteId);
|
||||
req.setRequestValidTimes(true);
|
||||
|
||||
GetActiveTableResponse resp = (GetActiveTableResponse) ThriftClient
|
||||
.sendRequest(req);
|
||||
java.util.List<ActiveTableRecord> activeTable = resp.getActiveTable();
|
||||
long t0 = System.currentTimeMillis();
|
||||
GetActiveTableResponse resp = (GetActiveTableResponse) ThriftClient
|
||||
.sendRequest(req);
|
||||
long t1 = System.currentTimeMillis();
|
||||
java.util.List<ActiveTableRecord> activeTable = resp
|
||||
.getActiveTable();
|
||||
|
||||
if (activeTable != null && activeTable.isEmpty() == false) {
|
||||
warngenLayer.createGeometryForWatches(watchArea, activeTable);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
System.out.println("getWatches.getActiveTable time: " + (t1 - t0)
|
||||
+ ", found "
|
||||
+ (activeTable != null ? activeTable.size() : "0")
|
||||
+ " watches");
|
||||
boolean val = activeTable != null && !activeTable.isEmpty();
|
||||
if (val) {
|
||||
// Look for ones with valid geometry
|
||||
|
||||
SpatialQueryResult[] parentRegionFeatures = null;
|
||||
try {
|
||||
parentRegionFeatures = SpatialQueryFactory.create().query("States",
|
||||
new String[] { "Name" }, watchArea, null, false,
|
||||
SearchMode.INTERSECTS);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
t0 = System.currentTimeMillis();
|
||||
Polygon watchArea = (Polygon) polygon.buffer(milesToKilometer
|
||||
.convert(config.getHatchedAreaSource()
|
||||
.getIncludedWatchAreaBuffer())
|
||||
/ KmToDegrees);
|
||||
t1 = System.currentTimeMillis();
|
||||
System.out.println("getWatches.polygonBuffer time: "
|
||||
+ (t1 - t0));
|
||||
|
||||
WatchUtil rval = new WatchUtil();
|
||||
WeatherAdvisoryWatch watch = null;
|
||||
t0 = System.currentTimeMillis();
|
||||
warngenLayer.createGeometryForWatches(watchArea, activeTable);
|
||||
t1 = System.currentTimeMillis();
|
||||
System.out.println("getWatches.createWatchGeometry time: "
|
||||
+ (t1 - t0));
|
||||
SpatialQueryResult[] parentRegionFeatures = null;
|
||||
|
||||
for (ActiveTableRecord atr : activeTable) {
|
||||
// For each State in our watchArea...
|
||||
for (int j = 0; j < parentRegionFeatures.length; j++) {
|
||||
watch = new WeatherAdvisoryWatch();
|
||||
watch.setEndTime(atr.getEndTime().getTime());
|
||||
watch.setPhensig(atr.getPhensig());
|
||||
try {
|
||||
String field = "the_geom";
|
||||
t0 = System.currentTimeMillis();
|
||||
List<Double> results = DbMapQueryFactory.getMapQuery(
|
||||
"mapdata.states", field).getLevels();
|
||||
Collections.sort(results, Collections.reverseOrder());
|
||||
Double decimationTolerance = null;
|
||||
for (Double result : results) {
|
||||
if (result <= 0.064) {
|
||||
decimationTolerance = result;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the intersection of watchArea with State.
|
||||
Geometry parentGeom = parentRegionFeatures[j].geometry;
|
||||
if (decimationTolerance != null) {
|
||||
DecimalFormat df = new DecimalFormat("0.######");
|
||||
String suffix = "_"
|
||||
+ StringUtils.replaceChars(df.format(results
|
||||
.get(results.size() - 1)), '.', '_');
|
||||
parentRegionFeatures = SpatialQueryFactory.create()
|
||||
.query("states", field + suffix,
|
||||
new String[] { "Name" }, watchArea,
|
||||
null, false, SearchMode.INTERSECTS);
|
||||
} else {
|
||||
parentRegionFeatures = SpatialQueryFactory.create()
|
||||
.query("states", new String[] { "Name" },
|
||||
watchArea, null, false,
|
||||
SearchMode.INTERSECTS);
|
||||
}
|
||||
|
||||
// If State intersections intersects with out ATR record, add
|
||||
// watch
|
||||
if (GeometryUtil.intersects(parentGeom, atr.getGeometry())) {
|
||||
watch.setParentRegion(parentRegionFeatures[j].attributes
|
||||
.get("Name").toString());
|
||||
|
||||
watch.setPartOfParentRegion(GisUtil.asStringList(GisUtil
|
||||
.calculatePortion(parentGeom, atr.getGeometry())));
|
||||
rval.addWaw(watch);
|
||||
t1 = System.currentTimeMillis();
|
||||
System.out.println("getWatches.stateSpatialQuery time: "
|
||||
+ (t1 - t0) + ", found "
|
||||
+ parentRegionFeatures.length + " states");
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error querying state geometries", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
rval = new WatchUtil();
|
||||
WeatherAdvisoryWatch watch = null;
|
||||
long cumulativeIntersect = 0;
|
||||
long cumulativeCalcPortion = 0;
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
|
||||
// For each State in our watchArea...
|
||||
for (int j = 0; j < parentRegionFeatures.length; j++) {
|
||||
Geometry parentGeom = parentRegionFeatures[j].geometry;
|
||||
List<PreparedGeometry> prepGeoms = new ArrayList<PreparedGeometry>();
|
||||
GeometryUtil.recursivePreparedGeometry(parentGeom,
|
||||
prepGeoms);
|
||||
|
||||
for (ActiveTableRecord atr : activeTable) {
|
||||
// Get the intersection of watchArea with State.
|
||||
watch = new WeatherAdvisoryWatch();
|
||||
watch.setEndTime(atr.getEndTime().getTime());
|
||||
watch.setPhensig(atr.getPhensig());
|
||||
|
||||
// If State intersections intersects with out ATR
|
||||
// record, add watch
|
||||
t0 = System.currentTimeMillis();
|
||||
boolean intersects = GeometryUtil.intersects(prepGeoms,
|
||||
atr.getGeometry());
|
||||
t1 = System.currentTimeMillis();
|
||||
cumulativeIntersect = (t1 - t0);
|
||||
|
||||
if (intersects) {
|
||||
watch.setParentRegion(parentRegionFeatures[j].attributes
|
||||
.get("Name").toString());
|
||||
|
||||
t0 = System.currentTimeMillis();
|
||||
watch.setPartOfParentRegion(GisUtil
|
||||
.asStringList(GisUtil.calculatePortion(
|
||||
parentGeom, atr.getGeometry(), gc)));
|
||||
t1 = System.currentTimeMillis();
|
||||
cumulativeCalcPortion = (t1 - t0);
|
||||
rval.addWaw(watch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("getWatches.cumulativeIntersect: "
|
||||
+ cumulativeIntersect);
|
||||
System.out.println("getWatches.cumulativeCalcPortion: "
|
||||
+ cumulativeCalcPortion);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ import javax.xml.bind.JAXBException;
|
|||
|
||||
import com.raytheon.edex.site.SiteUtil;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningConstants;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.DialogConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.GeospatialConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
|
@ -225,7 +225,8 @@ public class GeospatialDataGenerator {
|
|||
}
|
||||
|
||||
if (dataSet == null) {
|
||||
// If the file does not exist, then geoms need to be deleted.
|
||||
// If the file does not exist, then geoms need to be
|
||||
// deleted.
|
||||
deleteGeomFiles(site, lastRunTime);
|
||||
} else {
|
||||
generate = false;
|
||||
|
@ -298,7 +299,7 @@ public class GeospatialDataGenerator {
|
|||
public static GeospatialMetadata getMetaData(WarngenConfiguration template) {
|
||||
GeospatialMetadata rval = new GeospatialMetadata();
|
||||
GeospatialConfiguration geoConfig = template.getGeospatialConfig();
|
||||
AreaConfiguration areaConfig = template.getAreaConfig();
|
||||
AreaSourceConfiguration areaConfig = template.getHatchedAreaSource();
|
||||
rval.setAreaSource(geoConfig.getAreaSource());
|
||||
List<String> areaFields = new ArrayList<String>();
|
||||
areaFields.add(WarningConstants.GID);
|
||||
|
@ -449,7 +450,7 @@ public class GeospatialDataGenerator {
|
|||
*/
|
||||
private static GeospatialData[] queryTimeZones(GeospatialMetadata metaData,
|
||||
Geometry hull, GeospatialData[] geoData) throws SpatialException {
|
||||
GeospatialData[] rval = null;
|
||||
GeospatialData[] rval = null;
|
||||
String timezonePathcastTable = metaData.getTimeZoneSource();
|
||||
String timezonePathcastField = metaData.getTimeZoneField();
|
||||
|
||||
|
@ -459,7 +460,7 @@ public class GeospatialDataGenerator {
|
|||
.query(timezonePathcastTable,
|
||||
new String[] { timezonePathcastField }, hull, null,
|
||||
false, SearchMode.INTERSECTS);
|
||||
|
||||
|
||||
rval = new GeospatialData[timeZoneResults.length];
|
||||
for (int i = 0; i < timeZoneResults.length; i++) {
|
||||
SpatialQueryResult result = timeZoneResults[i];
|
||||
|
|
|
@ -21,11 +21,11 @@ import com.raytheon.uf.common.dataquery.requests.RequestableMetadataMarshaller;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 29, 2012 #14691 Qinglu Lin Added feAreaField and its getter and setter, etc.
|
||||
* Mar 29, 2012 #14691 Qinglu Lin Added feAreaField and its getter and setter, etc.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author
|
||||
* @author
|
||||
* @version 1
|
||||
*/
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class AreaSourceConfiguration {
|
|||
}
|
||||
|
||||
@XmlElement
|
||||
private AreaType areaType = AreaType.INTERSECT;
|
||||
private AreaType type = AreaType.HATCHING;
|
||||
|
||||
/*
|
||||
* TODO This is for 12.9 to be backwards compatible. This will be removed in
|
||||
|
@ -100,7 +100,6 @@ public class AreaSourceConfiguration {
|
|||
}
|
||||
|
||||
public AreaSourceConfiguration(AreaConfiguration areaConfig) {
|
||||
setAreaType(AreaType.HATCHING);
|
||||
setVariable("areas");
|
||||
setAreaField(areaConfig.getAreaField());
|
||||
setAreaNotationField(areaConfig.getAreaNotationField());
|
||||
|
@ -254,14 +253,6 @@ public class AreaSourceConfiguration {
|
|||
this.includedWatchAreaBuffer = includedWatchAreaBuffer;
|
||||
}
|
||||
|
||||
public AreaType getAreaType() {
|
||||
return areaType;
|
||||
}
|
||||
|
||||
public void setAreaType(AreaType areaType) {
|
||||
this.areaType = areaType;
|
||||
}
|
||||
|
||||
public String getVariable() {
|
||||
return variable;
|
||||
}
|
||||
|
@ -270,13 +261,21 @@ public class AreaSourceConfiguration {
|
|||
this.variable = variable;
|
||||
}
|
||||
|
||||
public String getTimeZoneField() {
|
||||
return timeZoneField;
|
||||
}
|
||||
public String getTimeZoneField() {
|
||||
return timeZoneField;
|
||||
}
|
||||
|
||||
public void setTimeZoneField(String timeZoneField) {
|
||||
this.timeZoneField = timeZoneField;
|
||||
}
|
||||
public void setTimeZoneField(String timeZoneField) {
|
||||
this.timeZoneField = timeZoneField;
|
||||
}
|
||||
|
||||
public AreaType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(AreaType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public AreaType getAreaType() {
|
||||
return areaType;
|
||||
|
|
|
@ -40,12 +40,20 @@ public class PointSourceConfiguration {
|
|||
TRACK, POINTS;
|
||||
}
|
||||
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public static enum PointType {
|
||||
AREA, POINT;
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
private String variable;
|
||||
|
||||
@XmlElement
|
||||
private String pointSource;
|
||||
|
||||
@XmlElement
|
||||
private Double geometryDecimationTolerance;
|
||||
|
||||
@XmlElement
|
||||
private String pointField;
|
||||
|
||||
|
@ -60,6 +68,9 @@ public class PointSourceConfiguration {
|
|||
@XmlElement
|
||||
private SearchMethod searchMethod = SearchMethod.TRACK;
|
||||
|
||||
@XmlElement
|
||||
private PointType type = PointType.POINT;
|
||||
|
||||
@XmlElement
|
||||
private boolean withinPolygon = false;
|
||||
|
||||
|
@ -145,4 +156,21 @@ public class PointSourceConfiguration {
|
|||
this.withinPolygon = withinPolygon;
|
||||
}
|
||||
|
||||
public Double getGeometryDecimationTolerance() {
|
||||
return geometryDecimationTolerance;
|
||||
}
|
||||
|
||||
public void setGeometryDecimationTolerance(
|
||||
Double geometryDecimationTolerance) {
|
||||
this.geometryDecimationTolerance = geometryDecimationTolerance;
|
||||
}
|
||||
|
||||
public PointType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(PointType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue