Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SubAtlas cut type functionality #276

Merged
merged 21 commits into from
Nov 28, 2018
Merged

SubAtlas cut type functionality #276

merged 21 commits into from
Nov 28, 2018

Conversation

MikeGost
Copy link
Contributor

@MikeGost MikeGost commented Nov 20, 2018

Description:

  • The original intent was to add more granularity to the type of cutting performed when creating a subAtlas. Specifically, the intent was to keep the existing soft-cut option and add two new "hard-cut" and "hard-cut-relations-only" options. Both of these have been added for the subAtlas with predicate call and their examples and logic is documented in the code.

  • Updated the Polygon sub-atlas functionality to follow the same model as the Predicate sub-atlas call.

  • Refactored all sub-atlas creation out of BareAtlas and into SubAtlasCreator, for cleaner behavior separation.

  • Several new Atlas APIs checking for full feature containment within a given Polygon.

  • Minor optimizations surrounding relation handling, leveraging relationsLowerOrderFirst method to remove the looping in the existing subAtlas code.

  • Found an bug in the Rectangle.forCorners method. The method takes in a lower left and an upper right location. However, if we pass in an upper left and lower right, the Rectangle creation will succeed, however, successive fullyGeometricallyEncloses method calls will fail because they will use member variable fields for what they think is the lower left and upper right and compare the latitude and longitude of those locations to some target location, leading to an invalid result. I've added constraints to verify that the lower left and upper right are actually that.

DNM: There is more refactor possible. Possible improvements include:

  1. More documentation
  2. Apply the same logic to the subAtlas with Polygon method
  3. Refactor to move all subAtlas code away from BareAtlas - that class has grown too large

Potential Impact:

None - subAtlas logic did not change. There are now more Atlas APIs available and a finer granularity for all users to specify a cut type when creating sub atlases.

Unit Test Approach:

All existing unit tests pass. I've created new unit tests to capture all entity within behavior, new subAtlas behavior and to verify the Rectangle forCorners fix.

Test Results:

All integration tests pass.


In doubt: Contributing Guidelines

@MikeGost MikeGost changed the title SubAtlas cut type functionality DNM: SubAtlas cut type functionality Nov 20, 2018
Copy link
Contributor

@lucaspcram lucaspcram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes look good, still digesting a lot of it. Good tests!

@@ -60,6 +60,15 @@ public static Rectangle forCorners(final Location lowerLeft, final Location uppe
{
throw new CoreException("Cannot build a Rectangle with one of the corners being null.");
}
// Sanity check to avoid invalid Rectangles
else if (lowerLeft.isNorthOf(upperRight))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. This is a bug in pyatlas as well.

*
* @author mgostintsev
*/
public enum AtlasCutType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

*/
Optional<Atlas> subAtlas(Predicate<AtlasEntity> matcher);
Optional<Atlas> subAtlas(Predicate<AtlasEntity> matcher, AtlasCutType cutType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please leave the backwards compatible function in the interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why? The function is still available for use in the BareAtlas, marked as deprecated. So it will be backward compatible until all downstream code is migrated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any algorithms operating on the Atlas interface won't be able to use the old function without casting or converting to a specific implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave it open for discussion, could go either why on this. Updating the API as a breaking change with the new signature makes sense to me, but if this causes too much churn, we can leave it as is, just not as clean, having two subAtlas methods here, with one doing the same thing as the other.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you can make a default implementation of the original signature that uses the newer signature. Then with you put a @depricated on the old signature, and remove at the next major version increment. That would be my preference. Gives all the users a longer time to adjust for the same result.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I'll give that a shot.

@MikeGost
Copy link
Contributor Author

More changes incoming.

Assert.assertTrue("Rectangle 3 fully contains rectangle 2",
this.rectangle3.fullyGeometricallyEncloses(this.rectangle2));
Assert.assertTrue("That means, it should also cover it partially",
this.rectangle3.overlaps(this.rectangle4));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this supposed to be

this.rectangle3.overlaps(this.rectangle2)

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! This code was re-ordered, hadn't noticed this. Fixed!

public Iterable<Area> areasWithin(final Polygon polygon)
{
final Iterable<Area> areas = this.getAreaSpatialIndex().get(polygon.bounds());
return Iterables.filter(areas, area ->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: This is the old way of filtering. How about bringing new changes with Iterables.stream(...).filter(...)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saw this too, wanted to stay consistent to the rest of the class. Let me go ahead and re-write the rest of the function to follow the same format.

adahn6
adahn6 previously approved these changes Nov 26, 2018
Copy link
Contributor

@AlexHsieh22 AlexHsieh22 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! A couple questions:

  1. Would it ever be possible to have subAtlas(Polygon) call subAtlas(matcher) underneath? It feels like the should really do the same thing, but subAtlas(Polygon) is a convenience method.
  2. Does it make sense to have a subAtlas base class or interface? If 1 above can be done, there can be a default implementation for subAtlas(Polygon) and there could be a centralized source for logging and the packaging of the packed atlas.

@MikeGost
Copy link
Contributor Author

@AlexHsieh22 - great ideas!

  1. I believe we chatted about this briefly last week - I totally agree, this would make everything a lot cleaner.
  2. Good idea! This can be added.

I'll create an issue to track these ideas and get them implemented!

AlexHsieh22
AlexHsieh22 previously approved these changes Nov 27, 2018
Copy link
Contributor

@AlexHsieh22 AlexHsieh22 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for filing the Github issue @MikeGost !

@MikeGost MikeGost changed the title DNM: SubAtlas cut type functionality SubAtlas cut type functionality Nov 27, 2018
@matthieun matthieun merged commit 4066587 into osmlab:dev Nov 28, 2018
@matthieun matthieun added this to the 5.2.9 milestone Dec 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants