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

Factor out common vector tile code #796

Merged
merged 6 commits into from
Mar 31, 2022

Conversation

trevorgerhardt
Copy link
Member

@trevorgerhardt trevorgerhardt commented Mar 28, 2022

This change factors out common code across the GtfsVectorTileMaker and the NetworkTileController. It moves many common functions into the MapTile util. This was done because many operations are dependent on the envelope that is produced by that util. Additionally, the remaining functionality of the GtfsVectorTileMaker was boiled down to just creating and querying the caches, so I renamed it GtfsGeometryCache and moved it into the com.conveyal.gtfs package.

Note: the naming could certainly be improved. Suggestions welcome.

This change factors out common code across the `GtfsVectorTileMaker` and the `NetworkTileController`. It moves manny common functions into the `MapTile` util. This is because many operations are dependent on the `envelope` that is produced by that util. Additionally, the remaining functionality of the `GtfsVectorTileMaker` was eseentially boiled down to just creating and querying the caches.
@trevorgerhardt trevorgerhardt requested a review from abyrd March 28, 2022 05:40
Since the cache can be used for anything, not just vector tiles. Also, factors out the "GeometryCache" part.
Creates a buffered envelope that can be re-used while clipping.
Also, add comments.
Copy link
Member

@abyrd abyrd left a comment

Choose a reason for hiding this comment

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

Comments mostly reflect things already discussed on a call. I will make the planned changes after merge.

@@ -39,11 +41,15 @@
* A basic example client for browsing the tiles is at src/main/resources/vector-client
*/
public class GtfsController implements HttpController {
Copy link
Member

Choose a reason for hiding this comment

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

We should rename this to something more specific like GtfsVectorTileController, especially since we actually serve up the contents of GTFS feeds on other endpoints.

private final GTFSCache gtfsCache;
private final GtfsVectorTileMaker gtfsVectorTileMaker;
private final GtfsGeometryCache gtfsGeometryCache;
Copy link
Member

Choose a reason for hiding this comment

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

I would probably want to rename this to something like GtfsSpatialIndexCache but we decided to merge it into GtfsCache so won't need to decide on a new name.

final int x = Integer.parseInt(req.params("x"));
final int y = Integer.parseInt(req.params("y"));
byte[] pbfMessage = this.gtfsVectorTileMaker.getTile(bundleScopedFeedId, z, x, y);
MapTile tile = new MapTile(Integer.parseInt(req.params("z")), Integer.parseInt(req.params("x")), Integer.parseInt(req.params("y")));
Copy link
Member

Choose a reason for hiding this comment

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

Embedding these method calls as parameters in another method call can degrade debugging experience. I often create variables like this just for readability and debugging (if you pause on the MapTile constructor call, you can very easily see the z/x/y parameter values). The human eye is really good at seeing repeated patterns in stacked lines - stacking these vertically makes it apparent that the exact same thing is happening three times with different parameter names. The JVM should optimize all of this out anyway in non-debug operation, and even if it doesn't this does not execute frequently enough to be a performance issue. Alternate point of view is that adding identifiers creates more places to make a typing mistake, but I actually think the redundancy makes this more readable and maintainable.

final int y = Integer.parseInt(req.params("y"));
byte[] pbfMessage = this.gtfsVectorTileMaker.getTile(bundleScopedFeedId, z, x, y);
MapTile tile = new MapTile(Integer.parseInt(req.params("z")), Integer.parseInt(req.params("x")), Integer.parseInt(req.params("y")));
var patterns = tile.clipAndSimplifyLinesToTile(
Copy link
Member

Choose a reason for hiding this comment

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

These identifiers could be more specific - they're not just the patterns and stops, but maybe the patternGeometries and stopGeometries.

* than this many tile units. These are minuscule at 1/4096 of the tile width or height.
*/
private static final int LINE_SIMPLIFY_TOLERANCE = 5;
// This must match UI code.
Copy link
Member

Choose a reason for hiding this comment

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

Comment can be expanded to make it clear what it matches in the UI code.

import java.util.List;

/**
* Utilities for creating a slippy map tile and generating it's enveloper. Also for encapsulating it's properties that
Copy link
Member

Choose a reason for hiding this comment

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

Javadoc should be updated to reflect the fact that this is now vector tile specific, but could eventually be combined with raster tile uses, or be made a subclass of a general tile (not raster or vector specific). It's kind of surprising that we define tile2lat() here and apparently nowhere else in the project - maybe we really don't deal with any raster tiles in the Java code.

*/
private static final int LINE_SIMPLIFY_TOLERANCE = 5;

// Add a buffer to the tile envelope to make sure any artifacts are outside it.
Copy link
Member

Choose a reason for hiding this comment

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

I will expand this comment a bit.

/**
* Cache sets of geometry in a JTS STRtree using a Caffeine LoadingCache.
*/
public class GeometryCache<T extends Geometry> {
Copy link
Member

Choose a reason for hiding this comment

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

Should be renamed - it caches spatial indexes, not just geometries. Summarizing discussion: this may be "premature abstraction" (not optimization) since long term we're not certain to maintain two separate spatial index caches. Most reasons that would lead us to maintain two or more of them would also mean they potentially benefit from having different expiration and size eviction parameters. These hard-wired constants are not really constant across all potential spatial index caches, so this doesn't quite match the implied level of abstraction.

It's also not clear whether factoring this code out makes it easier or harder to read. If we retain this abstraction I'll update the Javadoc to include the above comments.

}

/**
* Find a List of all geometry within a given envelope.
Copy link
Member

Choose a reason for hiding this comment

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

Update comment to clarify that this overselects, and finds things that intersect the envelope (rather than contained within the envelope).

import java.util.Objects;

/**
* This class maintains spatial indexes of data from GTFS feeds.
Copy link
Member

Choose a reason for hiding this comment

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

It's important that this indexes only geometries for display from the GTFS feeds and does not attempt to provide full indexing for everything available in the GTFS API. Will update Javadoc to clarify.

@abyrd abyrd merged commit 3b8f4c7 into cost-rasters-and-lts Mar 31, 2022
@abyrd abyrd deleted the cost-rasters-and-lts-refactor branch March 31, 2022 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants