Merge "Issue #1275 Merged code from 1225 on top of SS changes." into development

Former-commit-id: fa7a0ef83d [formerly dde9d4b802] [formerly fa7a0ef83d [formerly dde9d4b802] [formerly ea61e22d2e [formerly ca3b359ba6a8b3131f32b9341781d19378240402]]]
Former-commit-id: ea61e22d2e
Former-commit-id: c3d4eca33c [formerly fd9338320f]
Former-commit-id: db8be823fc
This commit is contained in:
Lee Venable 2012-10-18 11:16:37 -05:00 committed by Gerrit Code Review
commit 9aa92e0d99
7 changed files with 650 additions and 290 deletions

View file

@ -10,8 +10,14 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils; import javax.measure.converter.UnitConverter;
import org.apache.commons.lang.StringUtils;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.GeodeticCalculator;
import org.opengis.referencing.operation.MathTransform;
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.config.WarngenConfiguration; import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
@ -21,62 +27,115 @@ import com.raytheon.uf.common.geospatial.SpatialQueryFactory;
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.uf.viz.core.maps.rsc.DbMapQueryFactory; import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory;
import com.raytheon.viz.core.map.GeoUtil;
import com.raytheon.viz.warngen.gis.ClosestPoint; import com.raytheon.viz.warngen.gis.ClosestPoint;
import com.raytheon.viz.warngen.gis.ClosestPointComparator;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
/** /**
*
* TODO Add Description
*
* <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* pre-history * pre-history
* Sep 25, 2012 #15425 Qinglu Lin Added getGid(). * Sep 25, 2012 #15425 Qinglu Lin Added getGid().
* Oct 17, 2012 jsanchez Added pathcast algorithm.
* *
* </pre>
*
* @author jsanchez
* @version 1.0
*/ */
abstract public class AbstractDbSourceDataAdaptor { abstract public class AbstractDbSourceDataAdaptor {
protected Set<String> sortFields = new HashSet<String>( private static final String transformedKey = "com.raytheon.transformed";
Arrays.asList(new String[] { "distance", "area", "parentArea" }));
protected PointSourceConfiguration pointConfig; private static final String GEOM_FIELD = "the_geom";
protected Set<String> undatabasedSortableFields = new HashSet<String>(
Arrays.asList(new String[] {
ClosestPointComparator.Sort.DISTANCE.toString(),
ClosestPointComparator.Sort.AREA.toString(),
ClosestPointComparator.Sort.PARENTAREA.toString() }));
protected GeodeticCalculator gc = new GeodeticCalculator();
protected Geometry searchArea; protected Geometry searchArea;
protected String localizedSite; protected String localizedSite;
abstract protected Set<String> createSpatialQueryField(); protected SpatialQueryResult[] ptFeatures;
abstract protected ClosestPoint createClosestPoint(Set<String> ptFields, protected Map<String, RequestConstraint> filter;
SpatialQueryResult ptRslt);
abstract protected Map<String, RequestConstraint> processFilterSubstitution(); protected Set<String> ptFields;
public Collection<ClosestPoint> getData(WarngenConfiguration config, protected String[] sortBy;
PointSourceConfiguration pointConfig, Geometry searchArea,
abstract protected Set<String> createSpatialQueryField(String pointField,
String[] sortBy);
abstract protected ClosestPoint createClosestPoint(String pointField,
Set<String> ptFields, SpatialQueryResult ptRslt);
abstract protected Map<String, RequestConstraint> processFilterSubstitution(
Map<String, RequestConstraint> filter);
public AbstractDbSourceDataAdaptor(
PathcastConfiguration pathcastConfiguration,
UnitConverter distanceToMeters, Geometry searchArea,
String localizedSite) throws VizException { String localizedSite) throws VizException {
this.pointConfig = pointConfig;
this.searchArea = searchArea;
this.localizedSite = localizedSite; this.localizedSite = localizedSite;
this.sortBy = pathcastConfiguration.getSortBy();
this.searchArea = searchArea;
this.ptFields = createSpatialQueryField(
pathcastConfiguration.getPointField(), sortBy);
this.filter = processFilterSubstitution(pathcastConfiguration
.getFilter());
this.ptFeatures = spatialQuery(pathcastConfiguration.getPointSource(),
null);
}
Map<String, RequestConstraint> filter = processFilterSubstitution(); public AbstractDbSourceDataAdaptor(
Set<String> ptFields = createSpatialQueryField(); PointSourceConfiguration pointSourceConfiguration,
List<ClosestPoint> points = null; Geometry searchArea, String localizedSite) throws VizException {
this.localizedSite = localizedSite;
this.sortBy = pointSourceConfiguration.getSortBy();
this.searchArea = searchArea;
this.ptFields = createSpatialQueryField(
pointSourceConfiguration.getPointField(), sortBy);
this.filter = processFilterSubstitution(pointSourceConfiguration
.getFilter());
this.ptFeatures = spatialQuery(
pointSourceConfiguration.getPointSource(), null);
}
/**
* Queries the maps database depending on the point source set in the
* config.
*
* @param pointSource
* @param decimationTolerance
* @return
* @throws VizException
*/
private SpatialQueryResult[] spatialQuery(String pointSource,
Double decimationTolerance) throws VizException {
SpatialQueryResult[] ptFeatures = null;
long t0 = System.currentTimeMillis();
try { try {
long t0 = System.currentTimeMillis();
SpatialQueryResult[] ptFeatures = null;
Double decimationTolerance = pointConfig
.getGeometryDecimationTolerance();
String field = "the_geom";
if (decimationTolerance != null && decimationTolerance > 0) { if (decimationTolerance != null && decimationTolerance > 0) {
// find available tolerances // find available tolerances
List<Double> results = DbMapQueryFactory List<Double> results = DbMapQueryFactory.getMapQuery(
.getMapQuery( "mapdata." + pointSource.toLowerCase(), GEOM_FIELD)
"mapdata."
+ pointConfig.getPointSource()
.toLowerCase(), field)
.getLevels(); .getLevels();
Collections.sort(results, Collections.reverseOrder()); Collections.sort(results, Collections.reverseOrder());
@ -99,53 +158,212 @@ abstract public class AbstractDbSourceDataAdaptor {
String suffix = "_" String suffix = "_"
+ StringUtils.replaceChars( + StringUtils.replaceChars(
df.format(decimationTolerance), '.', '_'); df.format(decimationTolerance), '.', '_');
ptFeatures = SpatialQueryFactory.create().query( ptFeatures = SpatialQueryFactory.create().query(pointSource,
pointConfig.getPointSource(), field + suffix, GEOM_FIELD + suffix,
ptFields.toArray(new String[ptFields.size()]), ptFields.toArray(new String[ptFields.size()]),
searchArea, filter, SearchMode.INTERSECTS); searchArea, filter, SearchMode.INTERSECTS);
} else { } else {
ptFeatures = SpatialQueryFactory.create().query( ptFeatures = SpatialQueryFactory.create().query(pointSource,
pointConfig.getPointSource(),
ptFields.toArray(new String[ptFields.size()]), ptFields.toArray(new String[ptFields.size()]),
searchArea, filter, SearchMode.INTERSECTS); searchArea, filter, SearchMode.INTERSECTS);
} }
System.out.println("Retrieve location data for '" + pointSource
+ "' = " + (System.currentTimeMillis() - t0));
} catch (SpatialException e) {
throw new VizException("Error querying " + pointSource + " table: "
+ e.getLocalizedMessage(), e);
}
if (ptFeatures != null) { return ptFeatures;
points = new ArrayList<ClosestPoint>(ptFeatures.length); }
} else {
points = new ArrayList<ClosestPoint>(0);
}
for (SpatialQueryResult ptRslt : ptFeatures) { /**
if (ptRslt != null && ptRslt.geometry != null) { * Returns the data of the points/areas relative to the searchArea
Object nameObj = ptRslt.attributes.get(pointConfig *
.getPointField()); * @param config
if (nameObj != null) { * @param pointConfig
ClosestPoint cp = createClosestPoint(ptFields, ptRslt); * @param localizedSite
points.add(cp); * @return
} * @throws VizException
*/
public Collection<ClosestPoint> getData(WarngenConfiguration config,
PointSourceConfiguration pointConfig, String localizedSite)
throws VizException {
List<ClosestPoint> points = null;
String pointField = pointConfig.getPointField();
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(pointField, ptFields,
ptRslt);
cp.setGid(getGid(ptFields, ptRslt.attributes));
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; return points;
} }
/**
* Returns a list of implacted points/areas that are relative to the
* centroid.
*
* @param pcGeom
* @param centroid
* @param areaFeatures
* @param pcArea
* @param pcParentArea
* @return
* @throws Exception
*/
public List<ClosestPoint> getPathcastData(
PathcastConfiguration pathcastConfiguration,
UnitConverter distanceToMeters, MathTransform latLonToLocal,
Geometry pcGeom, Point centroid, SpatialQueryResult[] areaFeatures,
String pcArea, String pcParentArea) throws Exception {
String pointField = pathcastConfiguration.getPointField();
String areaField = pathcastConfiguration.getAreaField();
String parentAreaField = pathcastConfiguration.getParentAreaField();
double thresholdInMeters = distanceToMeters
.convert(pathcastConfiguration.getDistanceThreshold());
if (latLonToLocal != null) {
for (SpatialQueryResult rslt : ptFeatures) {
rslt.attributes.put(transformedKey,
JTS.transform(rslt.geometry, latLonToLocal));
}
}
Geometry localPCGeom = null;
if (pcGeom != null) {
localPCGeom = JTS.transform(pcGeom, latLonToLocal);
}
// Find closest points
List<ClosestPoint> points = new ArrayList<ClosestPoint>(
ptFeatures.length);
for (SpatialQueryResult pointRslt : ptFeatures) {
Geometry localPt = (Geometry) pointRslt.attributes
.get(transformedKey);
double minDist = Double.MAX_VALUE;
Coordinate closestCoord = null;
if (localPCGeom != null) {
Coordinate[] localPts = localPCGeom.getCoordinates();
Coordinate[] latLonPts = pcGeom.getCoordinates();
for (int i = 0; i < localPts.length; ++i) {
Coordinate loc = localPts[i];
double distance = loc.distance(localPt.getCoordinate());
if (distance <= thresholdInMeters && distance < minDist) {
minDist = distance;
closestCoord = latLonPts[i];
}
}
} else {
closestCoord = centroid.getCoordinate();
minDist = 0;
}
if (closestCoord != null) {
boolean found = false;
String area = null;
String parentArea = null;
for (SpatialQueryResult areaRslt : areaFeatures) {
if (areaRslt.geometry.contains(pointRslt.geometry)) {
area = String.valueOf(areaRslt.attributes
.get(areaField));
parentArea = String.valueOf(areaRslt.attributes
.get(parentAreaField));
found = true;
break;
}
}
if (!found) {
area = pcArea;
parentArea = pcParentArea;
}
ClosestPoint cp = createClosestPoint(pointField, pointRslt,
minDist, closestCoord, area, parentArea,
distanceToMeters.inverse());
points.add(cp);
}
}
List<String> fields = null;
if (pathcastConfiguration.getSortBy() != null) {
fields = Arrays.asList(pathcastConfiguration.getSortBy());
} else {
fields = new ArrayList<String>(0);
}
if (!fields.isEmpty()) {
// Sort the points based on sortBy fields
Collections.sort(points, new ClosestPointComparator(fields));
}
return points;
}
/**
* Creates a closestPoint setting the distance, azimuth, etc. Used for
* pathcast calculations
*
* @param pointRslt
* @param minDist
* @param closestCoord
* @param area
* @param parentArea
* @return
*/
private ClosestPoint createClosestPoint(String pointField,
SpatialQueryResult pointRslt, double minDist,
Coordinate closestCoord, String area, String parentArea,
UnitConverter metersToDistance) {
ClosestPoint cp = createClosestPoint(pointField, ptFields, pointRslt);
cp.setDistance(minDist);
cp.setRoundedDistance((int) metersToDistance.convert(minDist));
gc.setStartingGeographicPoint(cp.getPoint().x, cp.getPoint().y);
gc.setDestinationGeographicPoint(closestCoord.x, closestCoord.y);
cp.setAzimuth(gc.getAzimuth());
cp.setOppositeAzimuth(ClosestPoint.adjustAngle(cp.getAzimuth() + 180));
cp.setRoundedAzimuth(GeoUtil.roundAzimuth(cp.getAzimuth()));
cp.setOppositeRoundedAzimuth(ClosestPoint.adjustAngle(cp
.getRoundedAzimuth() + 180));
cp.setArea(area);
cp.setParentArea(parentArea);
cp.setGid(getGid(ptFields, pointRslt.attributes));
return cp;
}
/**
* Retrieves the population from the attributes.
*
* @param ptFields
* @param attributes
* @return
*/
protected int getPopulation(Set<String> ptFields, protected int getPopulation(Set<String> ptFields,
Map<String, Object> attributes) { Map<String, Object> attributes) {
int population = 0; int population = 0;
if (ptFields.contains("population")) { if (ptFields.contains(String
.valueOf(ClosestPointComparator.Sort.POPULATION))) {
try { try {
population = Integer.valueOf(String.valueOf(attributes population = Integer
.get("population"))); .valueOf(String.valueOf(attributes.get(String
.valueOf(ClosestPointComparator.Sort.POPULATION))));
} catch (Exception e) { } catch (Exception e) {
// Ignore // Ignore
} }
@ -154,14 +372,23 @@ abstract public class AbstractDbSourceDataAdaptor {
return population; return population;
} }
/**
* Retrieves the warngenlev from the attributes.
*
* @param ptFields
* @param attributes
* @return
*/
protected int getWangenlev(Set<String> ptFields, protected int getWangenlev(Set<String> ptFields,
Map<String, Object> attributes) { Map<String, Object> attributes) {
int warngenlev = 0; int warngenlev = 3;
if (ptFields.contains("warngenlev")) { if (ptFields.contains(String
.valueOf(ClosestPointComparator.Sort.WARNGENLEV))) {
try { try {
warngenlev = Integer.valueOf(String.valueOf(attributes warngenlev = Integer
.get("warngenlev"))); .valueOf(String.valueOf(attributes.get(String
.valueOf(ClosestPointComparator.Sort.WARNGENLEV))));
} catch (Exception e) { } catch (Exception e) {
// Ignore // Ignore
} }
@ -170,16 +397,22 @@ abstract public class AbstractDbSourceDataAdaptor {
return warngenlev; return warngenlev;
} }
protected int getGid(Set<String> ptFields, /**
Map<String, Object> attributes) { * Returns the gid.
*
* @param ptFields
* @param attributes
* @return
*/
protected int getGid(Set<String> ptFields, Map<String, Object> attributes) {
int gid = 0; int gid = 0;
if (ptFields.contains("gid")) { if (ptFields.contains(String.valueOf(ClosestPointComparator.Sort.GID))) {
try { try {
gid = Integer.valueOf(String.valueOf(attributes gid = Integer.valueOf(String.valueOf(attributes.get(String
.get("gid"))); .valueOf(ClosestPointComparator.Sort.GID))));
} catch (Exception e) { } catch (Exception e) {
// Ignore // Ignore
} }
} }

View file

@ -19,11 +19,16 @@
**/ **/
package com.raytheon.viz.warngen.config; package com.raytheon.viz.warngen.config;
import javax.measure.converter.UnitConverter;
import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration;
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration; import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration.PointType; import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration.PointType;
import com.raytheon.uf.viz.core.exception.VizException;
import com.vividsolutions.jts.geom.Geometry;
/** /**
* Creates data adaptors for PointSource and Pathcast data. * Creates data adaptors for PointSource data.
* *
* <pre> * <pre>
* *
@ -32,6 +37,7 @@ import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 26, 2011 bgonzale Initial creation * Oct 26, 2011 bgonzale Initial creation
* Oct 17, 2012 jsanchez Allowed adaptor to be used for pathcast.
* *
* </pre> * </pre>
* *
@ -41,15 +47,32 @@ import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration
public class DataAdaptorFactory { public class DataAdaptorFactory {
public static AbstractDbSourceDataAdaptor createPointSource( public static AbstractDbSourceDataAdaptor createDataAdaptor(
PointSourceConfiguration pointConfig) { PointSourceConfiguration pointConfig, Geometry searchArea,
String localizedSite) throws VizException {
AbstractDbSourceDataAdaptor adaptor = null;
if (pointConfig.getType() == PointType.AREA) {
adaptor = new DbAreaSourceDataAdaptor(pointConfig, searchArea,
localizedSite);
} else if (pointConfig.getType() == PointType.POINT) {
adaptor = new DbPointSourceDataAdaptor(pointConfig, searchArea,
localizedSite);
}
return adaptor;
}
public static AbstractDbSourceDataAdaptor createPathcastDataAdaptor(
PathcastConfiguration pathcastConfiguration,
UnitConverter distanceToMeters, Geometry searchArea,
String localizedSite) throws VizException {
AbstractDbSourceDataAdaptor adaptor = null; AbstractDbSourceDataAdaptor adaptor = null;
if (pointConfig.getType() == PointType.AREA) { if (pathcastConfiguration.getType() == PointType.AREA) {
adaptor = new DbAreaSourceDataAdaptor(); adaptor = new DbAreaSourceDataAdaptor(pathcastConfiguration,
} else if (pointConfig.getType() == PointType.POINT) { distanceToMeters, searchArea, localizedSite);
adaptor = new DbPointSourceDataAdaptor(); } else if (pathcastConfiguration.getType() == PointType.POINT) {
adaptor = new DbPointSourceDataAdaptor(pathcastConfiguration,
distanceToMeters, searchArea, localizedSite);
} }
return adaptor; return adaptor;

View file

@ -2,31 +2,40 @@ package com.raytheon.viz.warngen.config;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.measure.converter.UnitConverter;
import org.geotools.referencing.GeodeticCalculator; import org.geotools.referencing.GeodeticCalculator;
import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration;
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
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.viz.warngen.PreferenceUtil; import com.raytheon.viz.warngen.PreferenceUtil;
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;
import com.raytheon.viz.warngen.gis.GisUtil.Direction; 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.Envelope;
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.PreparedGeometryFactory;
/** /**
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description ------------ ---------- -----------
* ------------ ---------- ----------- -------------------------- * --------------------------
* @author jsanchez *
* Sep 25, 2012 #15425 Qinglu Lin Updated createClosestPoint(). * @author jsanchez Sep 25, 2012 #15425 Qinglu Lin Updated createClosestPoint().
* *
*/ */
public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor { public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
@ -37,26 +46,41 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
private static final String cwaField = "cwa"; private static final String cwaField = "cwa";
private GeodeticCalculator gc = new GeodeticCalculator(); public DbAreaSourceDataAdaptor(PathcastConfiguration pathcastConfiguration,
UnitConverter distanceToMeters, Geometry searchArea,
String localizedSite) throws VizException {
super(pathcastConfiguration, distanceToMeters, searchArea,
localizedSite);
}
public DbAreaSourceDataAdaptor(
PointSourceConfiguration pointSourceConfiguration,
Geometry searchArea, String localizedSite) throws VizException {
super(pointSourceConfiguration, searchArea, localizedSite);
}
/** /**
* *
*/ */
@Override @Override
protected Set<String> createSpatialQueryField() { protected Set<String> createSpatialQueryField(String pointField,
String[] sortBy) {
Set<String> ptFields = new HashSet<String>(); Set<String> ptFields = new HashSet<String>();
ptFields.add(pointConfig.getPointField()); ptFields.add(pointField);
ptFields.add(useDirectionField); ptFields.add(useDirectionField);
ptFields.add(suppressedDirectionsField); ptFields.add(suppressedDirectionsField);
List<String> fields = new ArrayList<String>(); List<String> fields = null;
if (pointConfig.getSortBy() != null) { if (sortBy != null && sortBy.length > 0) {
fields = Arrays.asList(pointConfig.getSortBy()); fields = Arrays.asList(sortBy);
} else {
fields = new ArrayList<String>(0);
} }
// Sort fields don't exist in the db.
for (String field : fields) { for (String field : fields) {
if (sortFields.contains(field.toLowerCase()) == false) { if (undatabasedSortableFields.contains(field.toUpperCase()) == false) {
ptFields.add(field.toLowerCase()); ptFields.add(field.toUpperCase());
} }
} }
@ -64,15 +88,14 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
} }
/** /**
* * Creates a closest point object.
*/ */
@Override @Override
protected ClosestPoint createClosestPoint(Set<String> ptFields, protected ClosestPoint createClosestPoint(String pointField,
SpatialQueryResult ptRslt) { Set<String> ptFields, SpatialQueryResult ptRslt) {
Map<String, Object> attributes = ptRslt.attributes; Map<String, Object> attributes = ptRslt.attributes;
String name = String String name = String.valueOf(attributes.get(pointField));
.valueOf(attributes.get(pointConfig.getPointField()));
Coordinate point = ptRslt.geometry.getCoordinate(); Coordinate point = ptRslt.geometry.getCoordinate();
int population = getPopulation(ptFields, attributes); int population = getPopulation(ptFields, attributes);
int warngenlev = getWangenlev(ptFields, attributes); int warngenlev = getWangenlev(ptFields, attributes);
@ -80,62 +103,16 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
ptRslt.geometry); ptRslt.geometry);
int gid = getGid(ptFields, attributes); int gid = getGid(ptFields, attributes);
return new ClosestPoint(name, point, population, warngenlev, partOfArea, gid); return new ClosestPoint(name, point, population, warngenlev,
partOfArea, gid);
} }
/** /**
* * Processes the filter to set the localized site.
* @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, ""));
if (attributes.get(suppressedDirectionsField) != null) {
String suppressedDirections = String.valueOf(
attributes.get(suppressedDirectionsField))
.toLowerCase();
// supdirs can be 'nse', for example
// TODO create an enum constructor for Directions
for (int i = 0; i < suppressedDirections.length(); i++) {
switch (suppressedDirections.charAt(i)) {
case 'n':
partOfArea.remove(Direction.NORTH.toString());
break;
case 's':
partOfArea.remove(Direction.SOUTH.toString());
break;
case 'e':
partOfArea.remove(Direction.EAST.toString());
break;
case 'w':
partOfArea.remove(Direction.WEST.toString());
break;
case 'c':
partOfArea.remove(Direction.CENTRAL.toString());
break;
}
}
}
}
return partOfArea;
}
@Override @Override
protected Map<String, RequestConstraint> processFilterSubstitution() { protected Map<String, RequestConstraint> processFilterSubstitution(
Map<String, RequestConstraint> filter = pointConfig.getFilter(); Map<String, RequestConstraint> filter) {
if (filter != null) { if (filter != null) {
// Process substitutes for filter // Process substitutes for filter
for (RequestConstraint rc : filter.values()) { for (RequestConstraint rc : filter.values()) {
@ -152,4 +129,139 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
return filter; return filter;
} }
/**
* Determines the part of area impacted if the userDirectionField is set to
* true.
*
* @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) {
PreparedGeometry prepGeom = PreparedGeometryFactory.prepare(geom);
if (prepGeom.intersects(searchArea) && !prepGeom.within(searchArea)) {
Geometry intersection = searchArea.intersection(geom);
partOfArea = GisUtil.asStringList(calculateLocationPortion(
geom, intersection, gc));
if (attributes.get(suppressedDirectionsField) != null) {
String suppressedDirections = String.valueOf(
attributes.get(suppressedDirectionsField))
.toLowerCase();
// supdirs can be 'nse', for example
// TODO create an enum constructor for Directions
for (int i = 0; i < suppressedDirections.length(); i++) {
switch (suppressedDirections.charAt(i)) {
case 'n':
partOfArea.remove(Direction.NORTH.toString());
break;
case 's':
partOfArea.remove(Direction.SOUTH.toString());
break;
case 'e':
partOfArea.remove(Direction.EAST.toString());
break;
case 'w':
partOfArea.remove(Direction.WEST.toString());
break;
}
}
}
}
}
if (partOfArea != null && !partOfArea.isEmpty()) {
return partOfArea;
}
return null;
}
/**
* Helper class to store cardinal ranges
*
* @author jsanchez
*
*/
private static class CardinalRange {
public EnumSet<Direction> directions;
public double lowRange;
public double highRange;
public CardinalRange(EnumSet<Direction> directions, double lowRange,
double highRange) {
this.directions = directions;
this.lowRange = lowRange;
this.highRange = highRange;
}
}
private static CardinalRange[] ranges = new CardinalRange[] {
new CardinalRange(EnumSet.of(Direction.NORTH), 0, 22.5),
new CardinalRange(EnumSet.of(Direction.NORTH, Direction.EAST),
22.5, 67.5),
new CardinalRange(EnumSet.of(Direction.EAST), 67.5, 112.5),
new CardinalRange(EnumSet.of(Direction.SOUTH, Direction.EAST),
112.5, 157.5),
new CardinalRange(EnumSet.of(Direction.SOUTH), 157.5, 202.5),
new CardinalRange(EnumSet.of(Direction.SOUTH, Direction.WEST),
202.5, 247.5),
new CardinalRange(EnumSet.of(Direction.WEST), 247.5, 292.5),
new CardinalRange(EnumSet.of(Direction.NORTH, Direction.WEST),
292.5, 337.5),
new CardinalRange(EnumSet.of(Direction.NORTH), 337.5, 360) };
/**
* Calculates the cardinal directions of a location.
*
* @param geom
* @param intersection
* @param gc
* @return
*/
private static EnumSet<Direction> calculateLocationPortion(Geometry geom,
Geometry intersection, GeodeticCalculator gc) {
EnumSet<Direction> directions = EnumSet.noneOf(Direction.class);
Coordinate geomCentroid = geom.convexHull().getCentroid()
.getCoordinate();
Coordinate intersectCentroid = intersection.convexHull().getCentroid()
.getCoordinate();
gc.setStartingGeographicPoint(geomCentroid.x, geomCentroid.y);
gc.setDestinationGeographicPoint(intersectCentroid.x,
intersectCentroid.y);
Envelope envelope = geom.getEnvelopeInternal();
double centerThresholdX = envelope.getWidth() * 0.10;
double centerThresholdY = envelope.getHeight() * 0.10;
double distanceX = Math.abs(intersectCentroid.x - geomCentroid.x);
double distanceY = Math.abs(intersectCentroid.y - geomCentroid.y);
if (distanceX > centerThresholdX || distanceY > centerThresholdY) {
// Convert azimuth from -180/180 to 0/360
double degrees = gc.getAzimuth();
if (degrees < 0) {
degrees += 360;
}
for (CardinalRange range : ranges) {
if (degrees > range.lowRange && degrees <= range.highRange) {
directions = range.directions;
break;
}
}
}
return directions;
}
} }

View file

@ -19,23 +19,24 @@
**/ **/
package com.raytheon.viz.warngen.config; package com.raytheon.viz.warngen.config;
import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils; import javax.measure.converter.UnitConverter;
import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration;
import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration;
import com.raytheon.uf.common.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.maps.rsc.DbMapQueryFactory; 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.ClosestPoint; import com.raytheon.viz.warngen.gis.ClosestPoint;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
/** /**
* PointSource data adaptor for data retrieved from a Database. * PointSource data adaptor for data retrieved from a Database.
@ -57,19 +58,35 @@ import com.vividsolutions.jts.geom.Coordinate;
public class DbPointSourceDataAdaptor extends AbstractDbSourceDataAdaptor { public class DbPointSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
public DbPointSourceDataAdaptor(
PathcastConfiguration pathcastConfiguration,
UnitConverter distanceToMeters, Geometry searchArea,
String localizedSite) throws VizException {
super(pathcastConfiguration, distanceToMeters, searchArea,
localizedSite);
}
public DbPointSourceDataAdaptor(
PointSourceConfiguration pointSourceConfiguration,
Geometry searchArea, String localizedSite) throws VizException {
super(pointSourceConfiguration, searchArea, localizedSite);
}
@Override @Override
protected Set<String> createSpatialQueryField() { protected Set<String> createSpatialQueryField(String pointField,
String[] sortBy) {
Set<String> ptFields = new HashSet<String>(); Set<String> ptFields = new HashSet<String>();
ptFields.add(pointConfig.getPointField()); ptFields.add(pointField);
List<String> fields = new ArrayList<String>(); List<String> fields = new ArrayList<String>();
if (pointConfig.getSortBy() != null) { if (sortBy != null) {
fields = Arrays.asList(pointConfig.getSortBy()); fields = Arrays.asList(sortBy);
} }
// Sort fields don't exist in the db.
for (String field : fields) { for (String field : fields) {
if (sortFields.contains(field.toLowerCase()) == false) { if (undatabasedSortableFields.contains(field.toUpperCase()) == false) {
ptFields.add(field.toLowerCase()); ptFields.add(field.toUpperCase());
} }
} }
@ -77,12 +94,11 @@ public class DbPointSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
} }
@Override @Override
protected ClosestPoint createClosestPoint(Set<String> ptFields, protected ClosestPoint createClosestPoint(String pointField,
SpatialQueryResult ptRslt) { Set<String> ptFields, SpatialQueryResult ptRslt) {
Map<String, Object> attributes = ptRslt.attributes; Map<String, Object> attributes = ptRslt.attributes;
String name = String String name = String.valueOf(attributes.get(pointField));
.valueOf(attributes.get(pointConfig.getPointField()));
Coordinate point = ptRslt.geometry.getCoordinate(); Coordinate point = ptRslt.geometry.getCoordinate();
int population = getPopulation(ptFields, attributes); int population = getPopulation(ptFields, attributes);
int warngenlev = getWangenlev(ptFields, attributes); int warngenlev = getWangenlev(ptFields, attributes);
@ -92,8 +108,8 @@ public class DbPointSourceDataAdaptor extends AbstractDbSourceDataAdaptor {
} }
@Override @Override
protected Map<String, RequestConstraint> processFilterSubstitution() { protected Map<String, RequestConstraint> processFilterSubstitution(
Map<String, RequestConstraint> filter = pointConfig.getFilter(); Map<String, RequestConstraint> filter) {
if (filter != null) { if (filter != null) {
// Process substitutes for filter // Process substitutes for filter
for (RequestConstraint rc : filter.values()) { for (RequestConstraint rc : filter.values()) {

View file

@ -38,6 +38,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* APr 18, 2012 #14733 Qinglu Lin David's fix is used, which adds * APr 18, 2012 #14733 Qinglu Lin David's fix is used, which adds
* a copy constructor. * a copy constructor.
* Sep 25, 2012 #15425 Qinglu Lin Updated two ClosestPoint() and added getGid(). * Sep 25, 2012 #15425 Qinglu Lin Updated two ClosestPoint() and added getGid().
* Oct 17, 2012 jsanchez Added setter methods.
* *
* </pre> * </pre>
* *
@ -178,10 +179,74 @@ public class ClosestPoint implements Comparable<ClosestPoint> {
return partOfArea; return partOfArea;
} }
public int getGid() { public int getGid() {
return gid; return gid;
} }
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public void setName(String name) {
this.name = name;
}
public void setArea(String area) {
this.area = area;
}
public void setParentArea(String parentArea) {
this.parentArea = parentArea;
}
public void setPoint(Coordinate point) {
this.point = point;
}
public void setDistance(double distance) {
this.distance = distance;
}
public void setRoundedDistance(int roundedDistance) {
this.roundedDistance = roundedDistance;
}
public void setAzimuth(double azimuth) {
this.azimuth = azimuth;
}
public void setRoundedAzimuth(double roundedAzimuth) {
this.roundedAzimuth = roundedAzimuth;
}
public void setOppositeAzimuth(double oppositeAzimuth) {
this.oppositeAzimuth = oppositeAzimuth;
}
public void setOppositeRoundedAzimuth(double oppositeRoundedAzimuth) {
this.oppositeRoundedAzimuth = oppositeRoundedAzimuth;
}
public void setPopulation(int population) {
this.population = population;
}
public void setWarngenlev(int warngenlev) {
this.warngenlev = warngenlev;
}
public void setPartOfArea(List<String> partOfArea) {
this.partOfArea = partOfArea;
}
public void setGid(int gid) {
this.gid = gid;
}
/** /**
* Adjusts the angle from -360/360 to be between -180/180 * Adjusts the angle from -360/360 to be between -180/180
* *

View file

@ -38,6 +38,7 @@ import org.apache.commons.lang.ArrayUtils;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Mar 3, 2011 jsanchez Initial creation * Mar 3, 2011 jsanchez Initial creation
* Sep 25, 2012 15425 Qinglu Lin Implemented sorting on 'gid' in ascending order. * Sep 25, 2012 15425 Qinglu Lin Implemented sorting on 'gid' in ascending order.
* Oct 17, 2012 jsanchez Refactored the enum sort to be more flexible.
* *
* </pre> * </pre>
* *
@ -47,11 +48,11 @@ import org.apache.commons.lang.ArrayUtils;
public class ClosestPointComparator implements Comparator<ClosestPoint> { public class ClosestPointComparator implements Comparator<ClosestPoint> {
private enum Sort { public static enum Sort {
NAME, POPULATION, DISTANCE, LEVEL, LAT, LON, AREA, PARENT_AREA, GID NAME, POPULATION, DISTANCE, WARNGENLEV, LAT, LON, AREA, PARENTAREA, GID
} }
private ArrayList<Sort> list; private final ArrayList<Sort> list;
private int counter; private int counter;
@ -64,25 +65,25 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
counter = 0; counter = 0;
list = new ArrayList<Sort>(); list = new ArrayList<Sort>();
for (String field : fields) { for (String field : fields) {
if (field.equalsIgnoreCase("name")) { if (field.equalsIgnoreCase(Sort.NAME.toString())) {
list.add(Sort.NAME); list.add(Sort.NAME);
} else if (field.equalsIgnoreCase("population")) { } else if (field.equalsIgnoreCase(Sort.POPULATION.toString())) {
list.add(Sort.POPULATION); list.add(Sort.POPULATION);
} else if (field.equalsIgnoreCase("distance")) { } else if (field.equalsIgnoreCase(Sort.DISTANCE.toString())) {
list.add(Sort.DISTANCE); list.add(Sort.DISTANCE);
} else if (field.equalsIgnoreCase("warngenlev") } else if (field.equalsIgnoreCase(Sort.WARNGENLEV.toString())
|| field.equalsIgnoreCase("watch_warn")) { || field.equalsIgnoreCase("watch_warn")) {
list.add(Sort.LEVEL); list.add(Sort.WARNGENLEV);
} else if (field.equalsIgnoreCase("lat")) { } else if (field.equalsIgnoreCase(Sort.LAT.toString())) {
list.add(Sort.LAT); list.add(Sort.LAT);
} else if (field.equalsIgnoreCase("lon")) { } else if (field.equalsIgnoreCase(Sort.LON.toString())) {
list.add(Sort.LON); list.add(Sort.LON);
} else if (field.equalsIgnoreCase("area")) { } else if (field.equalsIgnoreCase(Sort.AREA.toString())) {
list.add(Sort.AREA); list.add(Sort.AREA);
} else if (field.equalsIgnoreCase("parentArea")) { } else if (field.equalsIgnoreCase(Sort.PARENTAREA.toString())) {
list.add(Sort.PARENT_AREA); list.add(Sort.PARENTAREA);
} else if (field.equalsIgnoreCase("gid")) { } else if (field.equalsIgnoreCase(Sort.GID.toString())) {
list.add(Sort.GID); list.add(Sort.GID);
} }
} }
} }
@ -105,13 +106,13 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
list.clear(); list.clear();
ClosestPointComparator comparator = new ClosestPointComparator( ClosestPointComparator comparator = new ClosestPointComparator(
(ArrayList<String>) Arrays.asList(fields)); Arrays.asList(fields));
Collections Collections.sort(Arrays.asList(points), comparator);
.sort((List<ClosestPoint>) Arrays.asList(points), comparator);
return points; return points;
} }
@Override
public int compare(ClosestPoint cp1, ClosestPoint cp2) { public int compare(ClosestPoint cp1, ClosestPoint cp2) {
if (list.isEmpty()) { if (list.isEmpty()) {
return cp1.compareTo(cp2); return cp1.compareTo(cp2);
@ -121,7 +122,7 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
switch (list.get(counter)) { switch (list.get(counter)) {
case NAME: case NAME:
if (cp1.name.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+") if (cp1.name.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")
&& cp1.name.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) { && cp2.name.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) {
value = Double.valueOf(cp1.name).compareTo( value = Double.valueOf(cp1.name).compareTo(
Double.valueOf(cp2.name)); Double.valueOf(cp2.name));
} else { } else {
@ -131,7 +132,7 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
case POPULATION: case POPULATION:
value = -1 * Double.compare(cp1.population, cp2.population); value = -1 * Double.compare(cp1.population, cp2.population);
break; break;
case LEVEL: case WARNGENLEV:
value = Double.compare(cp1.warngenlev, cp2.warngenlev); value = Double.compare(cp1.warngenlev, cp2.warngenlev);
break; break;
case LAT: case LAT:
@ -143,7 +144,7 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
case AREA: case AREA:
value = cp1.area.compareTo(cp2.area); value = cp1.area.compareTo(cp2.area);
break; break;
case PARENT_AREA: case PARENTAREA:
value = cp1.parentArea.compareTo(cp2.parentArea); value = cp1.parentArea.compareTo(cp2.parentArea);
break; break;
case DISTANCE: case DISTANCE:
@ -151,8 +152,7 @@ public class ClosestPointComparator implements Comparator<ClosestPoint> {
.compareTo(cp2.roundedDistance); .compareTo(cp2.roundedDistance);
break; break;
case GID: case GID:
value = new Integer(cp1.gid) value = new Integer(cp1.gid).compareTo(cp2.gid);
.compareTo(cp2.gid);
break; break;
} }

View file

@ -71,6 +71,7 @@ import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
import com.raytheon.viz.core.map.GeoUtil; import com.raytheon.viz.core.map.GeoUtil;
import com.raytheon.viz.warngen.PreferenceUtil; import com.raytheon.viz.warngen.PreferenceUtil;
import com.raytheon.viz.warngen.WarngenException; import com.raytheon.viz.warngen.WarngenException;
import com.raytheon.viz.warngen.config.AbstractDbSourceDataAdaptor;
import com.raytheon.viz.warngen.config.DataAdaptorFactory; import com.raytheon.viz.warngen.config.DataAdaptorFactory;
import com.raytheon.viz.warngen.util.Abbreviation; import com.raytheon.viz.warngen.util.Abbreviation;
import com.raytheon.viz.warnings.DateUtil; import com.raytheon.viz.warnings.DateUtil;
@ -99,6 +100,7 @@ import com.vividsolutions.jts.geom.Point;
* in pathcast. * in pathcast.
* Oct 05, 2012 DR15429 Qinglu Lin Updated code to keep duplicate names of cities * Oct 05, 2012 DR15429 Qinglu Lin Updated code to keep duplicate names of cities
* which are at different locations in pathcast. * which are at different locations in pathcast.
* Oct 17, 2012 jsanchez Moved the path cast data collecting to a seperate class.
* *
* </pre> * </pre>
* *
@ -109,8 +111,6 @@ public class Wx {
private static final transient IUFStatusHandler statusHandler = UFStatus private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(Wx.class); .getHandler(Wx.class);
private static final String transformedKey = "com.raytheon.transformed";
private long wwaStopTime; private long wwaStopTime;
private long wwaStartTime; private long wwaStartTime;
@ -184,7 +184,6 @@ public class Wx {
.getPathcastConfig(); .getPathcastConfig();
UnitConverter distanceToMeters = config.getUnitDistance() UnitConverter distanceToMeters = config.getUnitDistance()
.getConverterTo(SI.METER); .getConverterTo(SI.METER);
UnitConverter metersToDistance = distanceToMeters.inverse();
int maxCount = pathcastConfiguration.getMaxResults(); int maxCount = pathcastConfiguration.getMaxResults();
int maxGroup = pathcastConfiguration.getMaxGroup(); int maxGroup = pathcastConfiguration.getMaxGroup();
@ -196,7 +195,6 @@ public class Wx {
String areaNotationField = pathcastConfiguration.getAreaNotationField(); String areaNotationField = pathcastConfiguration.getAreaNotationField();
String areaNotationAbbrevField = pathcastConfiguration String areaNotationAbbrevField = pathcastConfiguration
.getAreaNotationTranslationFile(); .getAreaNotationTranslationFile();
String timezoneTable = geospatialConfig.getTimezoneSource();
String timezoneField = geospatialConfig.getTimezoneField(); String timezoneField = geospatialConfig.getTimezoneField();
String pointSource = pathcastConfiguration.getPointSource(); String pointSource = pathcastConfiguration.getPointSource();
String pointField = pathcastConfiguration.getPointField().toLowerCase(); String pointField = pathcastConfiguration.getPointField().toLowerCase();
@ -344,18 +342,12 @@ public class Wx {
} }
} }
SpatialQueryResult[] ptFeatures = null; AbstractDbSourceDataAdaptor pathcastDataAdaptor = null;
if (pointSource != null) { if (pointSource != null) {
ptFeatures = SpatialQueryFactory.create().query(pointSource, pathcastDataAdaptor = DataAdaptorFactory
ptFields.toArray(new String[ptFields.size()]), .createPathcastDataAdaptor(pathcastConfiguration,
bufferedPathCastArea, pointFilter, distanceToMeters, bufferedPathCastArea,
SearchMode.INTERSECTS); localizedSite);
if (latLonToLocal != null) {
for (SpatialQueryResult rslt : ptFeatures) {
rslt.attributes.put(transformedKey,
JTS.transform(rslt.geometry, latLonToLocal));
}
}
} }
SpatialQueryResult[] areaFeatures = null; SpatialQueryResult[] areaFeatures = null;
@ -432,99 +424,14 @@ public class Wx {
.get(timezoneField)); .get(timezoneField));
} }
Geometry localPCGeom = null; List<ClosestPoint> points = null;
if (pcGeom != null) { if (pathcastDataAdaptor != null) {
localPCGeom = JTS.transform(pcGeom, latLonToLocal); points = pathcastDataAdaptor.getPathcastData(
} pathcastConfiguration, distanceToMeters,
latLonToLocal, pcGeom, centroid, areaFeatures,
// Find closest points pc.area, pc.parentArea);
GeodeticCalculator gc = new GeodeticCalculator(); } else {
List<ClosestPoint> points = new ArrayList<ClosestPoint>( points = new ArrayList<ClosestPoint>(0);
ptFeatures.length);
for (SpatialQueryResult pointRslt : ptFeatures) {
Geometry localPt = (Geometry) pointRslt.attributes
.get(transformedKey);
double minDist = Double.MAX_VALUE;
Coordinate closestCoord = null;
if (localPCGeom != null) {
Coordinate[] localPts = localPCGeom.getCoordinates();
Coordinate[] latLonPts = pcGeom.getCoordinates();
for (int i = 0; i < localPts.length; ++i) {
Coordinate loc = localPts[i];
double distance = loc.distance(localPt
.getCoordinate());
if (distance <= thresholdInMeters
&& distance < minDist) {
minDist = distance;
closestCoord = latLonPts[i];
}
}
} else {
closestCoord = centroid.getCoordinate();
minDist = 0;
}
if (closestCoord != null) {
ClosestPoint cp = new ClosestPoint();
cp.point = pointRslt.geometry.getCoordinate();
cp.name = String.valueOf(pointRslt.attributes
.get(pointField));
cp.distance = minDist;
cp.roundedDistance = (int) metersToDistance
.convert(minDist);
gc.setStartingGeographicPoint(cp.point.x, cp.point.y);
gc.setDestinationGeographicPoint(closestCoord.x,
closestCoord.y);
cp.azimuth = gc.getAzimuth();
cp.oppositeAzimuth = ClosestPoint
.adjustAngle(cp.azimuth + 180);
cp.roundedAzimuth = GeoUtil.roundAzimuth(cp.azimuth);
cp.oppositeRoundedAzimuth = ClosestPoint
.adjustAngle(cp.roundedAzimuth + 180);
boolean found = false;
for (SpatialQueryResult areaRslt : areaFeatures) {
if (areaRslt.geometry.contains(pointRslt.geometry)) {
cp.area = String.valueOf(areaRslt.attributes
.get(areaField));
cp.parentArea = String
.valueOf(areaRslt.attributes
.get(parentAreaField));
found = true;
break;
}
}
if (!found) {
cp.area = pc.area;
cp.parentArea = pc.parentArea;
}
if (ptFields.contains("population")) {
try {
cp.population = Integer.valueOf(String
.valueOf(pointRslt.attributes
.get("population")));
} catch (Exception e) {
cp.population = 0;
}
}
if (ptFields.contains("warngenlev")) {
try {
cp.warngenlev = Integer.valueOf(String
.valueOf(pointRslt.attributes
.get("warngenlev")));
} catch (Exception e) {
cp.warngenlev = 3;
}
}
points.add(cp);
}
}
if (fields.isEmpty() == false) {
// Sort the points based on sortBy fields
Collections
.sort(points, new ClosestPointComparator(fields));
} }
pcPoints.put(pc, points); pcPoints.put(pc, points);
} }
@ -773,9 +680,13 @@ public class Wx {
List<ClosestPoint> availablePoints = new ArrayList<ClosestPoint>(); List<ClosestPoint> availablePoints = new ArrayList<ClosestPoint>();
for (PointSourceConfiguration pointConfig : pointConfigs) { for (PointSourceConfiguration pointConfig : pointConfigs) {
long t0 = System.currentTimeMillis(); long t0 = System.currentTimeMillis();
availablePoints.addAll(DataAdaptorFactory.createPointSource( AbstractDbSourceDataAdaptor adaptor = DataAdaptorFactory
pointConfig).getData(config, pointConfig, .createDataAdaptor(pointConfig, bufferedSearchArea,
bufferedSearchArea, localizedSite)); localizedSite);
if (adaptor != null) {
availablePoints.addAll(adaptor.getData(config, pointConfig,
localizedSite));
}
long t1 = System.currentTimeMillis(); long t1 = System.currentTimeMillis();
System.out.println("getClosestPoint.dbQuery took " + (t1 - t0) System.out.println("getClosestPoint.dbQuery took " + (t1 - t0)
+ " for point source " + pointConfig.getPointSource()); + " for point source " + pointConfig.getPointSource());