Skip to content

Different device resolutions

jaakla edited this page Sep 24, 2014 · 17 revisions

Nutiteq SDK does not do automatic reconfiguration based on device screen size and display density, so with new "full HD" / XXHDPI screen you may see too small texts.

Map tile adjustment

Many tile sources is that their texts and other styles are designed based on web usage, and do not support higher resolution tiles. Desktop DPI is much lower than mobile device, so the texts are too small. So if you show the tiles with 1:1 pixels (as Nutiteq SDK by default also does) then you may see get something like (click on image to see full screenshot):

![Default map with XXHDPI device](https://dl.dropboxusercontent.com/u/3573333/public_web/noadjustmap%20copy.png)

There are two ways to solve this problem: using special tiles, or rescale existing tiles.

Use special "high-resolution" tiles

Some tile sources support "high resolution" or "retina" tile versions, which look nicer in most smartphones (except LDPI), so we suggest to use these. Note that the actual resolution of the tiles is still technically the same: they are 256x256 pixels, but they have larger styles (especially texts) to be better rendered with higher DPI screen.

a) MapBox tiles can be configured for 2x tiles in map settings. For example Nutiteq account has variations for "normal" and "retina" tiles for both Streets and Satellite tilesets, so you just use different map ID.

Non-retina vs retina tiles with MapBox Satellite:

Non-retina MapBox Satellite   Retina MapBox Satellite

See AdvancedMapActivity.java in AdvancedMap for code sample.

Use "digital zoom"

Sometimes you do not have higher DPI tiles available, e.g. with MapQuest tiles. For this case Nutiteq SDK has special method mapView.getOptions().setTileZoomLevelBias() to enforce loading lower zoom (therefore lower resolution) tiles. This looks like tiles are "digitally zoomed" or rescaled 2x. You can turn it on with following code:

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    float dpi = metrics.densityDpi;

    // you may want to adjust multipliers based on your tile source
    // default adjustment is 0.0, use -1.0 to get tiles from 1 zoom level down, 1.0 for one zoom up.
    // following is equal to  -log2(dpi / Base_DPI). For Base we use HIGH as it seems to give good results
    float adjustment = (float) - (Math.log(dpi / DisplayMetrics.DENSITY_HIGH) / Math.log(2));
    Log.debug("adjust DPI = "+dpi+" as zoom adjustment = "+adjustment);
    mapView.getOptions().setTileZoomLevelBias(adjustment);

Result:

![DPI adjusted map](https://dl.dropboxusercontent.com/u/3573333/public_web/dpiadjustmap%20copy.png)

DefaultLabel text size adjustment

If you use DefaultLabels, then you have similar problem, texts are quite hard to read:

Label without DPI adjustment

There are two elements in this label: title and description. You should set increased font size for both:

 // get relative scale from Activity
 final float scale = getResources().getDisplayMetrics().density;
 // style for marker labels
   LabelStyle labelStyle = LabelStyle.builder()
                       .setBackgroundColor(Color.BLACK)
                       .setTitleColor(Color.WHITE)
                       .setEdgePadding((int) (12 * scale))
                       .setLinePadding((int) (12 * scale)) // not used here
                       .setTipSize((int) (15 * scale))
                       .setTitleFont(Typeface.create("Arial", Typeface.BOLD), 19 * scale)
                       .setDescriptionFont(Typeface.create("Arial", Typeface.NORMAL), 17 * scale) 
                       .build();
        
   Label markerLabel = new DefaultLabel("San Francisco", "Here is a marker", labelStyle);

  // ... now create Marker with the markerLabel

In your case you may want to adjust the size based on real DPI, or use sample from this stackoverflow question, knowing that setTextSize is used from Paint.

The result:

adjusted font in Label

Text sizes

For vector texts on map there is simply texts size parameter TextStyle.setSize(), so you may want to adjust it based on DPI.

 // get relative scale from Activity
 final float scale = getResources().getDisplayMetrics().density;
 // style for marker labels
        TextStyle textStyle = TextStyle.builder()
            .setSize((int) (16 * scale))
            .setOffset2DY(0.2f).setColor(Color.BLACK)
            .build();
  // ... now you can create Text with the textStyle

Marker sizes

To set Marker size use MarkerStyle.setSize() parameter, but this size is in OpenGL units, not in pixels, and therefore generally no Marker size adjustment is needed for different resolution screens, something between 0.5 and 1.0 should work fine always. You may want to adjust this size based on physical screen size, not DPI, so it is smaller on small screens where too big screen portion would be taken otherwise.

Use higher resolution images, at least 64x64 pixels, so it looks good on XXHDPI screen also. We suggest to use UnscaledBitmapLoader.decodeResource() method, as in code samples to avoid Android builder to downscale the image. Put the image to drawable folder, without density selection.

Clone this wiki locally