Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
polygon drawing optimizations at low numerical zoom levels #1409
[ ] Performance
When there is a sufficient quantity of small polygons on screen and the user zooms out, draw speed can drop to a crawl. #937 mitigates this somewhat by enabling and using the feature requested by @MKergall which uses an overlay bounds as a faster mechanism to skip draw cycles on overlays that are not in view. This makes rendering quick if nothing is in view.
i think using the point reducer at lower numerical zoom levels may reduce complex polygons from potentially 1000s of points down to 4 or less, which should help draw speed significantly.
the reduced point set can be cached for panning operations to reducing the recalculation necessary and the cache invalidated on zoom events.
see pr #937 for esri shape file download link, then import the shape file, specifically the "shapes" within the shape file. after its imported, the performance issue is obvious
I managed to reproduce the poor performances using https://catalog.data.gov/dataset/military-installations-ranges-and-training-areas
For what it's worth, I've just run some tests on my smartphone. We're talking about 2035 ESRI Polygons, to be displayed in the world map.
Test 1 was the target test, without editing anything.
Test 2: I removed the actual "canvas.drawPath" call, in order to understand if we are slow computing things or Android is slow drawing Paths.
Test 3: I removed the "display this Polygon" calls.
Test 4, 5 and 6 are the same as 1, 2 and 3, but pretending that we use
Let's say that drawing involves 3 steps: the init phase (around 3s in those examples), the draw precomputation phase (around 1s) and the actual draw.
The first tests are very encouraging ("if the boundingbox is too small, don't even try to display it").
…ed poly is too small The downgrade management works with 2 methods: * `PolyOverlayWithIW.setDowngradeMaximumPixelSize(int)` - if the poly projected at the screen is too small (width or height lower than this value), either we don't display the poly or we display a rectangle instead * `PolyOverlayWithIW.setDowngradeDisplay(boolean)` - should we display the rectangle when the poly is too small? It can be tested in `SampleShapeFile`. Deleted class: * `PathOverlay`, which was deprecated 4 years ago Impacted classes: * `BoundBoxTest`: unrelated refactoring * `Counters`: added a more flexible access to counter features with methods `reset(String)`, `increment(String)` and `get(String)` * `CustomPaintingSurface`: used the new method `PolyOverlayWithIW.getBounds`; unrelated performance refactoring * `DefaultOverlayManager`: unrelated display optimization for MapSnapshots * `LinearRing`: now computing the bounding box ASAP, in method `computeProjected`, which simplifies method `getCenter`; created another version of `getBestOffset`; created method `getCloserValue`; created methods `getBoundingBox` and `clear` * `LineDrawer`: optimized the display * `MilestoneLineDisplayer`: fixed a minor unrelated bug, where the last point was added as (X0,Y0), but without a correspnding (X1,Y1) * `OsmMapShapeConverter`: used method `PolyOverlayWithIW.getActualPoints` instead of deprecated `Polygon.getPoints()` * `Polygon`: deprecated method `getPoints()`, to be replaced by `PolyOverlayWithIW.getActualPoints`; moved methods `setPoints` and `addPoint` to `PolyOverlayWithIW` * `Polyline`: deprecated method `getPoints()`, to be replaced by `PolyOverlayWithIW.getActualPoints`; moved methods `setPoints` and `addPoint` to `PolyOverlayWithIW` * `PolyOverlayWithIW`: added in the `draw` the downgrade management; created methods `setDowngradeMaximumPixelSize`, `setDowngradeDisplay`, `isWorthDisplaying` and `displayDowngrade` for the downgrade management; moved `Polygon` and `Polyline` methods here - `getBounds`, `setPoints`, `addPoint` and `getActualPoints` * `Projection`: computed `mProjectedMapSize` regardless of the tile size; created method `getWorldMapSize()` * `SampleOsmPath`: removed the "deprecated 4 years ago" `PathOverlay` sample; refactored * `SampleShapeFile`: set up the display (downgrade and style) * `ShapeConverter`: used the new method `PolyOverlayWithIW.getBounds` * `TileSystem`: deprecated now useless member `projectionZoomLevel`