Change-Id: I52293e2148fdc1fbfd22ad01e03d6d628cd1c09a

Former-commit-id: 50732574aa [formerly db66cbb605] [formerly 5dc466443b [formerly 6f197a78afa6a8760f852e94861950a230eaedcc]]
Former-commit-id: 5dc466443b
Former-commit-id: 5026332931
This commit is contained in:
Qinglu.Lin 2013-12-20 14:21:54 -05:00
parent a23db3e2d8
commit 66f60fc4a7
3 changed files with 160 additions and 12 deletions

View file

@ -76,6 +76,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
* 10/01/2013 DR 16632 Qinglu Lin Fixed the bug in for loop range.
* 10/17/2013 DR 16632 Qinglu Lin Updated removeOverlaidLinesegments().
* 10/18/2013 DR 16632 Qinglu Lin Catch exception thrown when coords length is less than 4 and doing createLinearRing(coords).
* 12/17/2013 DR 16567 Qinglu Lin Added createPolygonByPoints(). Gerrit testing
* </pre>
*
* @author mschenke
@ -1523,4 +1524,24 @@ public class PolygonUtil {
}
return slope;
}
/**
* Create a polygon whose two diagonal coordinates are a and b.
**/
static public Geometry createPolygonByPoints(Coordinate a, Coordinate b) {
double maxX, minX, maxY, minY;
maxX = Math.max(a.x, b.x);
minX = Math.min(a.x, b.x);
maxY = Math.max(a.y, b.y);
minY = Math.min(a.y, b.y);
Coordinate[] coord = new Coordinate[5];
coord[0] = new Coordinate(minX, minY);
coord[1] = new Coordinate(maxX, minY);
coord[2] = new Coordinate(maxX, maxY);
coord[3] = new Coordinate(minX, maxY);
coord[4] = new Coordinate(coord[0]);
GeometryFactory gf = new GeometryFactory();
LinearRing lr = gf.createLinearRing(coord);
return gf.createPolygon(lr, null);
}
}

View file

@ -194,6 +194,8 @@ import com.vividsolutions.jts.io.WKTReader;
* 10/21/2013 DR 16632 D. Friedman Modify areaPercent exception handling. Fix an NPE.
* Use A1 hatching behavior when no county passes the inclusion filter.
* 10/29/2013 DR 16734 D. Friedman If redraw-from-hatched-area fails, don't allow the pollygon the be used.
* 12/17/2013 DR 16567 Qinglu Lin Added findLargestGeometry() and findLargestQuadrant(), and updated
* populateStrings() and paintText(). TEST gerrit!!!
* </pre>
*
* @author mschenke
@ -959,11 +961,11 @@ public class WarngenLayer extends AbstractStormTrackResource {
double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width;
double minX = paintProps.getView().getExtent().getMinX();
double maxX = paintProps.getView().getExtent().getMaxX();
double minY = paintProps.getView().getExtent().getMinY();
double maxY = paintProps.getView().getExtent().getMaxY();
double boundary = 40 * ratio;
double minX = paintProps.getView().getExtent().getMinX() + boundary;
double maxX = paintProps.getView().getExtent().getMaxX() - boundary;
double minY = paintProps.getView().getExtent().getMinY() + boundary;
double maxY = paintProps.getView().getExtent().getMaxY() - boundary;
List<DrawableString> strings = new ArrayList<DrawableString>();
if (state.strings != null && state.strings.size() > 0) {
Iterator<Coordinate> coords = state.strings.keySet().iterator();
@ -976,14 +978,14 @@ public class WarngenLayer extends AbstractStormTrackResource {
in[2] = c.z;
double[] out = this.descriptor.worldToPixel(in);
if (out[0] > maxX) {
out[0] = maxX;
out[0] = maxX - boundary;
} else if (out[0] < minX) {
out[0] = minX;
out[0] = minX + boundary;
}
if (out[1] > maxY) {
out[1] = maxY;
out[1] = maxY - boundary;
} else if (out[1] < minY) {
out[1] = minY;
out[1] = minY + boundary;
}
DrawableString string = new DrawableString(text, textColor);
string.magnification = magnification;
@ -3018,10 +3020,52 @@ 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());
state.strings.put(center, "W");
Geometry geom2 = null;
Geometry warningAreaN = null;
Coordinate populatePt = null;
Geometry populatePtGeom;
boolean contained = false, closeTo = false;
double shift = 1.E-8, distance, minDistance = 10.0;
int loop, maxLoop = 10;
Geometry warningArea = state.getWarningArea();
String prefix = GeometryUtil.getPrefix(geom.getUserData());
if (prefixes.contains(prefix)) {
loop = 0;
warningAreaN = findLargestGeometry(GeometryUtil.intersection(geom, warningArea));
do {
if (!warningAreaN.isEmpty()) {
populatePt = GisUtil.d2dCoordinate(warningAreaN.getCentroid()
.getCoordinate());
for (GeospatialData f2 : geoData.features) {
geom2 = f2.getGeometry();
if (!GeometryUtil.getPrefix(geom2.getUserData()).equals(prefix)) {
contained = false;
closeTo = false;
populatePtGeom = PolygonUtil.createPolygonByPoints(populatePt,
new Coordinate(populatePt.x + shift, populatePt.y + shift));
if (GeometryUtil.contains(geom2, populatePtGeom)) {
// populatePt is in another county/zone.
warningAreaN = findLargestQuadrant(warningAreaN, geom);
contained = true;
break;
} else {
distance = populatePtGeom.distance(geom2);
if (distance < minDistance) {
// populatePt is very close to the boundary of another county/zone.
warningAreaN = findLargestQuadrant(warningAreaN, geom);
closeTo = true;
break;
}
}
}
}
} else {
// use the existing populatePt
break;
}
loop += 1;
} while ((contained || closeTo) && loop <= maxLoop);
state.strings.put(populatePt, "W");
}
}
}
@ -3252,4 +3296,65 @@ public class WarngenLayer extends AbstractStormTrackResource {
}
}
}
/**
* If g is a GeometryCollection, find the largest Geomery in it; otherwise (i.e., g is Geometry), return g.
*
* @param g
* A Geometry or a GeometryCollection.
* @return Geometry
*/
private Geometry findLargestGeometry(Geometry g) {
int size = g.getNumGeometries();
if (size == 1)
return g;
double area, maxArea = -1.0;
int index = 0;
for (int i = 0; i < size; i++) {
area = g.getGeometryN(i).getArea();
if (area > maxArea) {
maxArea = area;
index = i;
}
}
return g.getGeometryN(index);
}
/**
* Split the hatched area into four quadrants, and return the largest one.
*
* @param hatchedArea
* The initial hatched area or its a sub area.
* @param geom
* The geometry of a county/zone.
* @return Geometry
* The geometey of largest quadrant among the four, which are the result of
* splitting of hatchedArea.
*/
private Geometry findLargestQuadrant(Geometry hatchedArea, Geometry geom) {
Geometry envelope = hatchedArea.getEnvelope();
Coordinate centroidCoord = GisUtil.d2dCoordinate(envelope.getCentroid()
.getCoordinate());
Coordinate[] envCoords = envelope.getCoordinates();
int size = 4;
Geometry quadrants[] = new Geometry[size];
Geometry intersections[] = new Geometry[size];
double largestArea = -1.0, area = -1.0;
int index = -1;
for (int i = 0; i < size; i++) {
quadrants[i] = PolygonUtil.createPolygonByPoints(envCoords[i], centroidCoord);
intersections[i] = GeometryUtil.intersection(quadrants[i], hatchedArea);
area = intersections[i].getArea();
if (area > largestArea) {
largestArea = area;
index = i;
}
}
if (intersections[index].isValid())
return intersections[index];
else {
// "intersections[" + index + "] is invalid"
return hatchedArea;
}
}
}

View file

@ -27,6 +27,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometry;
* Nov 15, 2010 mschenke Initial creation
* Apr 28, 2013 1955 jsanchez Added an ignoreUserData flag to intersection method.
* Oct 21, 2013 DR 16632 D. Friedman Handle zero-length input in union.
* Dec 13, 2013 DR 16567 Qinglu Lin Added contains(). TEST gerrit!
*
* </pre>
*
@ -299,4 +300,25 @@ public class GeometryUtil {
}
return str;
}
/**
* Determine if one geometry contains any portion of the other.
* @param g1
* @param g2
*/
public static boolean contains(Geometry g1, Geometry g2) {
int m = g1.getNumGeometries();
int n = g2.getNumGeometries();
Geometry geom1 = null;
Geometry geom2 = null;
for (int i = 0; i < m; i++) {
geom1 = g1.getGeometryN(i);
for (int j = 0; j < n; j++) {
geom2 = g2.getGeometryN(j);
if (geom1.contains(geom2))
return true;
}
}
return false;
}
}