private void triggerCacheWaypointLongTapContextMenu(final GeoitemRef item) {
        final long mapSize = MercatorProjection.getMapSize(mapView.getModel().mapViewPosition.getZoomLevel(), mapView.getModel().displayModel.getTileSize());
        Geopoint geopoint = null;
        if (item.getType() == CoordinateType.CACHE) {
            final Geocache cache = DataStore.loadCache(item.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB);
            if (cache != null) {
                geopoint = cache.getCoords();
            }
        } else {
            final Waypoint waypoint = DataStore.loadWaypoint(item.getId());
            if (waypoint != null) {
                geopoint = waypoint.getCoords();
            }
        }
        if (geopoint == null) {
            geopoint = mapView.getViewport().center;
        }

        final RouteItem routeItem = new RouteItem(item);
        if (Settings.isShowRouteMenu()) {
            final int tapX = (int) (MercatorProjection.longitudeToPixelX(geopoint.getLongitude(), mapSize) - MercatorProjection.longitudeToPixelX(mapView.getViewport().bottomLeft.getLongitude(), mapSize));
            final int tapY = (int) (MercatorProjection.latitudeToPixelY(geopoint.getLatitude(), mapSize) - MercatorProjection.latitudeToPixelY(mapView.getViewport().topRight.getLatitude(), mapSize));
            MapUtils.createCacheWaypointLongClickPopupMenu(this, routeItem, tapX, tapY, individualRoute, routeLayer, this::updateRouteTrackButtonVisibility)
                    .setOnDismissListener(menu -> tapHandlerLayer.resetLongTapLatLong())
                    .show();
        } else {
            toggleRouteItem(item);
        }
    }
Repaint position overlay but only with a max frequency and if position or heading changes sufficiently.
main/src/main/java/cgeo/geocaching/maps/mapsforge/v6/NewMap.java