Issue #2386 fixed spatial overlap rule application.

Amend: updates from peer review.

Change-Id: Icd33c9175f210d864bd5117fc54c76362b76ac22

Former-commit-id: b6e2ce4b74 [formerly 783afb1585] [formerly 8b2b50baaf [formerly 807f278d542bc36331aa83b46a86a3af9dbb6675]]
Former-commit-id: 8b2b50baaf
Former-commit-id: 5ce1939d01
This commit is contained in:
Brad Gonzales 2014-02-24 16:40:41 -06:00
parent 2f58408036
commit f57f472f6a
5 changed files with 142 additions and 78 deletions

View file

@ -40,6 +40,10 @@ import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOver
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 17, 2013 2292 mpduff Initial creation * Oct 17, 2013 2292 mpduff Initial creation
* Feb 13, 2014 2386 bgonzale Change pass comparisons to >= instead of only >. * Feb 13, 2014 2386 bgonzale Change pass comparisons to >= instead of only >.
* Renamed sub1 and sub2 to otherSub and sub to make
* it easier to see what is compared against, and
* changed the spatial check to check the intersection
* coverage of sub, not otherSub.
* *
* </pre> * </pre>
* *
@ -68,49 +72,49 @@ public class GridOverlapData<T extends GriddedTime, C extends GriddedCoverage>
/** /**
* Constructor. * Constructor.
* *
* @param sub1 * @param sub
* @param sub2 * @param otherSub
* @param config * @param config
*/ */
public GridOverlapData(Subscription sub1, Subscription sub2, public GridOverlapData(Subscription sub, Subscription otherSub,
SubscriptionOverlapConfig config) { SubscriptionOverlapConfig config) {
super(sub1, sub2, config); super(sub, otherSub, config);
} }
/** /**
* Calculates the percent, 0-100, of how many cycle hours from sub2 are * Calculates the percent, 0-100, of how many cycle hours from sub are
* satisfied by sub1. * satisfied by otherSub.
* *
* @param sub1 * @param sub
* @param sub2 * @param otherSub
*/ */
public void calculateCycleDuplicationPercent( public void calculateCycleDuplicationPercent(
Subscription<GriddedTime, GriddedCoverage> sub1, Subscription<GriddedTime, GriddedCoverage> sub,
Subscription<GriddedTime, GriddedCoverage> sub2) { Subscription<GriddedTime, GriddedCoverage> otherSub) {
GriddedTime gtime1 = sub1.getTime(); GriddedTime gtimeOther = otherSub.getTime();
GriddedTime gtime2 = sub2.getTime(); GriddedTime gtime = sub.getTime();
cycleDuplication = this.getDuplicationPercent(gtime1.getCycleTimes(), cycleDuplication = this.getDuplicationPercent(
gtime2.getCycleTimes()); gtimeOther.getCycleTimes(), gtime.getCycleTimes());
} }
/** /**
* Calculates the percent, 0-100, of how many forecast hours from sub2 are * Calculates the percent, 0-100, of how many forecast hours from sub are
* satisfied by sub1. * satisfied by otherSub.
* *
* @param sub1 * @param sub
* @param sub2 * @param otherSub
*/ */
public void calculateForecastHourDuplicationPercent( public void calculateForecastHourDuplicationPercent(
Subscription<GriddedTime, GriddedCoverage> sub1, Subscription<GriddedTime, GriddedCoverage> sub,
Subscription<GriddedTime, GriddedCoverage> sub2) { Subscription<GriddedTime, GriddedCoverage> otherSub) {
GriddedTime gtime1 = sub1.getTime(); GriddedTime gtimeOther = otherSub.getTime();
GriddedTime gtime2 = sub2.getTime(); GriddedTime gtime = sub.getTime();
fcstHrDuplication = getDuplicationPercent( fcstHrDuplication = getDuplicationPercent(
gtime1.getSelectedTimeIndices(), gtimeOther.getSelectedTimeIndices(),
gtime2.getSelectedTimeIndices()); gtime.getSelectedTimeIndices());
} }
/** /**
@ -119,8 +123,8 @@ public class GridOverlapData<T extends GriddedTime, C extends GriddedCoverage>
@Override @Override
protected void determineOverlapping() { protected void determineOverlapping() {
super.determineOverlapping(); super.determineOverlapping();
calculateCycleDuplicationPercent(sub1, sub2); calculateCycleDuplicationPercent(sub, otherSub);
calculateForecastHourDuplicationPercent(sub1, sub2); calculateForecastHourDuplicationPercent(sub, otherSub);
GridSubscriptionOverlapConfig config = (GridSubscriptionOverlapConfig) this.config; GridSubscriptionOverlapConfig config = (GridSubscriptionOverlapConfig) this.config;
fcstHrPass = fcstHrDuplication >= config fcstHrPass = fcstHrDuplication >= config

View file

@ -47,6 +47,8 @@ import com.raytheon.uf.common.util.CollectionUtil;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 17, 2013 2292 mpduff Initial creation * Oct 17, 2013 2292 mpduff Initial creation
* Feb 13, 2014 2386 bgonzale Change pass comparisons to >= instead of only >. * Feb 13, 2014 2386 bgonzale Change pass comparisons to >= instead of only >.
* Renamed sub1 and sub2 to otherSub and sub to make
* it easier to see what is compared against.
* *
* </pre> * </pre>
* *
@ -86,54 +88,54 @@ public abstract class OverlapData<T extends Time, C extends Coverage> {
/** The subscription overlap config object */ /** The subscription overlap config object */
protected SubscriptionOverlapConfig config; protected SubscriptionOverlapConfig config;
/** Subscription 1 */ /** Primary Subscription */
protected Subscription<T, C> sub1; protected Subscription<T, C> sub;
/** Subscription 2 */ /** Other Subscription to compare against */
protected Subscription<T, C> sub2; protected Subscription<T, C> otherSub;
/** /**
* Constructor. * Constructor.
* *
* @param sub1 * @param sub
* @param sub2 * @param otherSub
* @param config * @param config
*/ */
public OverlapData(Subscription<T, C> sub1, Subscription<T, C> sub2, public OverlapData(Subscription<T, C> sub, Subscription<T, C> otherSub,
SubscriptionOverlapConfig config) { SubscriptionOverlapConfig config) {
this.sub1 = sub1; this.otherSub = otherSub;
this.sub2 = sub2; this.sub = sub;
this.config = config; this.config = config;
this.matchStrategy = config.getMatchStrategy(); this.matchStrategy = config.getMatchStrategy();
} }
/** /**
* Calculates the percent, 0-100, of how much spatial coverage from sub2 is * Calculates the percent, 0-100, of how much spatial coverage from sub is
* satisfied by sub1. * satisfied by otherSub.
* *
* @param sub1 * @param sub
* @param sub2 * @param otherSub
*/ */
protected void calculateSpatialDuplicationPercent(Subscription<T, C> sub1, protected void calculateSpatialDuplicationPercent(Subscription<T, C> sub,
Subscription<T, C> sub2) { Subscription<T, C> otherSub) {
final Coverage sub1Coverage = sub1.getCoverage(); final Coverage otherSubCoverage = otherSub.getCoverage();
final Coverage sub2Coverage = sub2.getCoverage(); final Coverage subCoverage = sub.getCoverage();
if (sub1Coverage != null && sub2Coverage != null) { if (otherSubCoverage != null && subCoverage != null) {
final ReferencedEnvelope sub1Envelope = sub1Coverage final ReferencedEnvelope otherSubEnvelope = otherSubCoverage
.getRequestEnvelope(); .getRequestEnvelope();
final ReferencedEnvelope sub2Envelope = sub2Coverage final ReferencedEnvelope subEnvelope = subCoverage
.getRequestEnvelope(); .getRequestEnvelope();
if (sub1Envelope != null && sub2Envelope != null) { if (otherSubEnvelope != null && subEnvelope != null) {
// try { // try {
ReferencedEnvelope intersection; ReferencedEnvelope intersection;
try { try {
intersection = MapUtil.reprojectAndIntersect(sub1Envelope, intersection = MapUtil.reprojectAndIntersect(
sub2Envelope); otherSubEnvelope, subEnvelope);
final double intersectionArea = intersection.getArea(); final double intersectionArea = intersection.getArea();
spatialDuplication = (int) ((intersectionArea * 100) / sub2Envelope spatialDuplication = (int) ((intersectionArea * 100) / subEnvelope
.getArea()); .getArea());
} catch (TransformException e) { } catch (TransformException e) {
statusHandler.handle(Priority.PROBLEM, statusHandler.handle(Priority.PROBLEM,
@ -144,24 +146,24 @@ public abstract class OverlapData<T extends Time, C extends Coverage> {
} }
/** /**
* Calculates the percent, 0-100, of how many parameters from sub2 are * Calculates the percent, 0-100, of how many parameters from sub are
* satisfied by sub1. * satisfied by otherSub.
* *
* @param sub1 * @param sub
* @param sub2 * @param otherSub
*/ */
protected void calculateParameterDuplicationPercent( protected void calculateParameterDuplicationPercent(Subscription<T, C> sub,
Subscription<T, C> sub1, Subscription<T, C> sub2) { Subscription<T, C> otherSub) {
parameterDuplication = getDuplicationPercent(sub1.getParameter(), parameterDuplication = getDuplicationPercent(otherSub.getParameter(),
sub2.getParameter()); sub.getParameter());
} }
/** /**
* Determine the overlap values * Determine the overlap values
*/ */
protected void determineOverlapping() { protected void determineOverlapping() {
calculateParameterDuplicationPercent(sub1, sub2); calculateParameterDuplicationPercent(sub, otherSub);
calculateSpatialDuplicationPercent(sub1, sub2); calculateSpatialDuplicationPercent(sub, otherSub);
this.parameterPass = this.parameterDuplication >= config this.parameterPass = this.parameterDuplication >= config
.getMaxAllowedParameterDuplication(); .getMaxAllowedParameterDuplication();

View file

@ -42,6 +42,8 @@ import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOver
* Feb 13, 2014 2386 bgonzale Change pass comparisons to >= instead of only >. * Feb 13, 2014 2386 bgonzale Change pass comparisons to >= instead of only >.
* Change halfNumAttrs comp to a double for comparisons * Change halfNumAttrs comp to a double for comparisons
* against half of uneven numbers of attributes. * against half of uneven numbers of attributes.
* Renamed sub1 and sub2 to otherSub and sub to make
* it easier to see what is compared against.
* *
* </pre> * </pre>
* *
@ -63,34 +65,34 @@ public class PointOverlapData<T extends PointTime, C extends Coverage> extends
/** /**
* Constructor. * Constructor.
* *
* @param sub1 * @param sub
* @param sub2 * @param otherSub
* @param config * @param config
*/ */
public PointOverlapData(Subscription sub1, Subscription sub2, public PointOverlapData(Subscription sub, Subscription otherSub,
SubscriptionOverlapConfig config) { SubscriptionOverlapConfig config) {
super(sub1, sub2, config); super(sub, otherSub, config);
} }
/** /**
* Calculates the percent, 0-100, of how similar the time is from sub2 to * Calculates the percent, 0-100, of how similar the time is from sub2 to
* sub1. * sub1.
* *
* @param sub1 * @param otherSub
* @param sub2 * @param sub
*/ */
private void calculateTimeDuplicationPercent( private void calculateTimeDuplicationPercent(
Subscription<PointTime, Coverage> sub1, Subscription<PointTime, Coverage> sub,
Subscription<PointTime, Coverage> sub2) { Subscription<PointTime, Coverage> otherSub) {
PointTime ptime1 = sub1.getTime(); PointTime ptimeOther = otherSub.getTime();
PointTime ptime2 = sub2.getTime(); PointTime ptime = sub.getTime();
List<Integer> intervalList1 = new ArrayList<Integer>(); List<Integer> intervalListOther = new ArrayList<Integer>();
intervalList1.add(ptime1.getInterval()); intervalListOther.add(ptimeOther.getInterval());
List<Integer> intervalList2 = new ArrayList<Integer>(); List<Integer> intervalList = new ArrayList<Integer>();
intervalList2.add(ptime2.getInterval()); intervalList.add(ptime.getInterval());
timeDuplication = getDuplicationPercent(intervalList1, intervalList2); timeDuplication = getDuplicationPercent(intervalListOther, intervalList);
} }
/** /**
@ -100,7 +102,7 @@ public class PointOverlapData<T extends PointTime, C extends Coverage> extends
protected void determineOverlapping() { protected void determineOverlapping() {
super.determineOverlapping(); super.determineOverlapping();
PointSubscriptionOverlapConfig config = (PointSubscriptionOverlapConfig) this.config; PointSubscriptionOverlapConfig config = (PointSubscriptionOverlapConfig) this.config;
calculateTimeDuplicationPercent(sub1, sub2); calculateTimeDuplicationPercent(sub, otherSub);
this.timeDuplicationPass = this.timeDuplication >= config this.timeDuplicationPass = this.timeDuplication >= config
.getMaxAllowedTimeDuplication(); .getMaxAllowedTimeDuplication();
} }

View file

@ -29,6 +29,7 @@ import java.util.List;
import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.geometry.jts.ReferencedEnvelope;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.datadelivery.registry.DataType; import com.raytheon.uf.common.datadelivery.registry.DataType;
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage; import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
@ -55,6 +56,11 @@ import com.vividsolutions.jts.geom.Envelope;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 18, 2013 2292 mpduff Initial creation * Oct 18, 2013 2292 mpduff Initial creation
* Feb 13, 2014 2386 bgonzale Added test cases to match ticket 2771 test procedures. * Feb 13, 2014 2386 bgonzale Added test cases to match ticket 2771 test procedures.
* Fixed areaLessThan50PercentOverlap bounds.
* Added Test case to match issue of a less than
* 50% overlap for an existing, but more than 50%
* overlap for a new subscription, but still not passing
* a 50% overlap rule.
* *
* </pre> * </pre>
* *
@ -90,7 +96,7 @@ public class GridOverlapDataTest {
matchMeParameters.add(ParameterFixture.INSTANCE.get(1)); matchMeParameters.add(ParameterFixture.INSTANCE.get(1));
areaMatchMe = new Envelope(0, 10, 0, 20); areaMatchMe = new Envelope(0, 10, 0, 20);
areaLessThan50PercentOverlap = new Envelope(0, 25, 0, 15); areaLessThan50PercentOverlap = new Envelope(5, 25, 0, 15);
areaGreaterThan50PercentOverlap = new Envelope(0, 10, 10, 25); areaGreaterThan50PercentOverlap = new Envelope(0, 10, 10, 25);
areaWithNoOverlap = new Envelope(0, 30, 20, 20); areaWithNoOverlap = new Envelope(0, 30, 20, 20);
@ -388,6 +394,55 @@ public class GridOverlapDataTest {
assertTrue("These should overlap", overlapResult.spatialPass); assertTrue("These should overlap", overlapResult.spatialPass);
} }
@Test
public void testMatchAnySpatialOnlyLessThan50PercentOfExistingGreaterThan50PercentOfNew() {
int parameter = 50;
int spatial = 50;
int forecastHours = 100;
int cycles = 100;
final GridSubscriptionOverlapConfig overlap = new GridSubscriptionOverlapConfig(
parameter, forecastHours, cycles, spatial,
SubscriptionOverlapMatchStrategy.MATCH_ANY);
List<Parameter> parameters2 = new ArrayList<Parameter>();
parameters2.addAll(matchMeParameters);
parameters2.add(ParameterFixture.INSTANCE.get(20));
List<Parameter> parameters3 = new ArrayList<Parameter>();
parameters3.add(ParameterFixture.INSTANCE.get(30));
CoordinateReferenceSystem crs = MapUtil.LATLON_PROJECTION;
ReferencedEnvelope matchEnv = new ReferencedEnvelope(
-353287.9146908128, 499474.38945139456, 4064387.3713984187,
4442030.0353220245, crs);
ReferencedEnvelope otherEnvelope = new ReferencedEnvelope(
-584748.4738489623, 487298.1073337787, 4113114.739653571,
4783132.733000439, crs);
SiteSubscription match = getSubscription(
1,
matchEnv,
matchMeParameters,
createGriddedTime(Arrays.asList(0, 1, 2, 3),
Arrays.asList(0, 1, 2, 3)));
SiteSubscription otherSub = getSubscription(
1,
otherEnvelope,
parameters3,
createGriddedTime(Arrays.asList(7, 8, 9),
Arrays.asList(7, 8, 9)));
GridOverlapData<GriddedTime, GriddedCoverage> overlapResult = new GridOverlapData<GriddedTime, GriddedCoverage>(
match, otherSub, overlap);
assertFalse("These should not be duplicates",
overlapResult.isDuplicate());
assertTrue("These should overlap", overlapResult.isOverlapping());
assertFalse("These should not overlap", overlapResult.cyclePass);
assertFalse("These should not overlap", overlapResult.fcstHrPass);
assertFalse("These should not overlap", overlapResult.parameterPass);
assertTrue("These should overlap", overlapResult.spatialPass);
}
@Test @Test
public void testMatchAnyForecastHoursOnly() { public void testMatchAnyForecastHoursOnly() {
int parameter = 50; int parameter = 50;

View file

@ -35,6 +35,7 @@ import com.vividsolutions.jts.geom.Envelope;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 18, 2013 2292 mpduff Initial creation * Oct 18, 2013 2292 mpduff Initial creation
* Feb 13, 2014 2386 bgonzale Added test cases to match ticket 2771 test procedures. * Feb 13, 2014 2386 bgonzale Added test cases to match ticket 2771 test procedures.
* Fixed areaLessThan50PercentOverlap bounds.
* *
* </pre> * </pre>
* *
@ -65,7 +66,7 @@ public class PointOverlapDataTest {
@BeforeClass @BeforeClass
public static void setup() { public static void setup() {
areaMatchPoints = new Envelope(0, 10, 0, 20); areaMatchPoints = new Envelope(0, 10, 0, 20);
areaLessThan50PercentOverlap = new Envelope(0, 25, 0, 15); areaLessThan50PercentOverlap = new Envelope(5, 25, 0, 15);
areaGreaterThan50PercentOverlap = new Envelope(0, 10, 10, 25); areaGreaterThan50PercentOverlap = new Envelope(0, 10, 10, 25);
areaWithNoOverlap = new Envelope(0, 30, 20, 20); areaWithNoOverlap = new Envelope(0, 30, 20, 20);