コード例 #1
0
  @Override
  public void onListItemClick(ListView parent, View v, int position, long id) {
    final RouteInfoLocation item = ((TransportStopAdapter) getListAdapter()).getItem(position);
    Builder builder = new AlertDialog.Builder(this);
    List<String> items = new ArrayList<String>();
    final List<TransportStop> stops =
        item.getDirection()
            ? item.getRoute().getForwardStops()
            : item.getRoute().getBackwardStops();
    LatLon locationToGo = getLocationToGo();
    LatLon locationToStart = getLocationToStart();
    builder.setTitle(
        getString(R.string.transport_stop_to_go_out)
            + "\n"
            + getInformation(item, stops, getCurrentRouteLocation(), true)); // $NON-NLS-1$
    int ind = 0;
    for (TransportStop st : stops) {
      StringBuilder n = new StringBuilder(50);
      n.append(ind++);
      if (st == item.getStop()) {
        n.append("!! "); // $NON-NLS-1$
      } else {
        n.append(". "); // $NON-NLS-1$
      }
      String name = st.getName(settings.usingEnglishNames());
      if (locationToGo != null) {
        n.append(name).append(" - ["); // $NON-NLS-1$
        n.append(
                OsmAndFormatter.getFormattedDistance(
                    (int) MapUtils.getDistance(locationToGo, st.getLocation()),
                    SearchTransportActivity.this))
            .append("]"); // $NON-NLS-1$
      } else if (locationToStart != null) {
        n.append("[")
            .append(
                OsmAndFormatter.getFormattedDistance(
                    (int) MapUtils.getDistance(locationToStart, st.getLocation()),
                    SearchTransportActivity.this))
            .append("] - "); // $NON-NLS-1$ //$NON-NLS-2$
        n.append(name);
      } else {
        n.append(name);
      }
      items.add(n.toString());
    }
    builder.setItems(
        items.toArray(new String[items.size()]),
        new DialogInterface.OnClickListener() {

          @Override
          public void onClick(DialogInterface dialog, int which) {
            int i = which;
            if (i >= 0) {
              TransportStop stop = stops.get(i);
              showContextMenuOnStop(stop, item, i);
            }
          }
        });
    builder.show();
  }
コード例 #2
0
  public String getInformation(
      RouteInfoLocation route, List<TransportStop> stops, int position, boolean part) {
    StringBuilder text = new StringBuilder(200);
    double dist = 0;
    int ind = 0;
    int stInd = stops.size();
    int eInd = stops.size();
    for (TransportStop s : stops) {
      if (s == route.getStart()) {
        stInd = ind;
      }
      if (s == route.getStop()) {
        eInd = ind;
      }
      if (ind > stInd && ind <= eInd) {
        dist += MapUtils.getDistance(stops.get(ind - 1).getLocation(), s.getLocation());
      }
      ind++;
    }
    text.append(getString(R.string.transport_route_distance))
        .append(" ")
        .append(OsmAndFormatter.getFormattedDistance((int) dist, this)); // $NON-NLS-1$/
    if (!part) {
      text.append(", ")
          .append(getString(R.string.transport_stops_to_pass))
          .append(" ")
          .append(eInd - stInd); // $NON-NLS-1$ //$NON-NLS-2$
      LatLon endStop = getEndStop(position - 1);
      if (endStop != null) {
        String before =
            OsmAndFormatter.getFormattedDistance(
                (int) MapUtils.getDistance(endStop, route.getStart().getLocation()),
                SearchTransportActivity.this);
        text.append(", ")
            .append(getString(R.string.transport_to_go_before))
            .append(" ")
            .append(before); // $NON-NLS-2$//$NON-NLS-1$
      }

      LatLon stStop = getStartStop(position + 1);
      if (stStop != null) {
        String after =
            OsmAndFormatter.getFormattedDistance(
                (int) MapUtils.getDistance(stStop, route.getStop().getLocation()),
                SearchTransportActivity.this);
        text.append(", ")
            .append(getString(R.string.transport_to_go_after))
            .append(" ")
            .append(after); // $NON-NLS-1$ //$NON-NLS-2$
      }
    }

    return text.toString();
  }
コード例 #3
0
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      View row = convertView;
      if (row == null) {
        LayoutInflater inflater = getLayoutInflater();
        row = inflater.inflate(R.layout.search_transport_list_item, parent, false);
      }
      LatLon locationToGo = getLocationToGo();
      LatLon locationToStart = getLocationToStart();

      TextView label = (TextView) row.findViewById(R.id.label);
      ImageView icon = (ImageView) row.findViewById(R.id.search_icon);
      RouteInfoLocation stop = getItem(position);

      TransportRoute route = stop.getRoute();
      StringBuilder labelW = new StringBuilder(150);
      labelW.append(route.getType()).append(" ").append(route.getRef()); // $NON-NLS-1$
      labelW.append(" - ["); // $NON-NLS-1$

      if (locationToGo != null) {
        labelW.append(
            OsmAndFormatter.getFormattedDistance(
                stop.getDistToLocation(), SearchTransportActivity.this));
      } else {
        labelW.append(getString(R.string.transport_search_none));
      }
      labelW.append("]\n").append(route.getName(settings.usingEnglishNames())); // $NON-NLS-1$

      // TODO icons
      if (locationToGo != null && stop.getDistToLocation() < 400) {
        icon.setImageResource(R.drawable.opened_poi);
      } else {
        icon.setImageResource(R.drawable.poi);
      }

      int dist =
          locationToStart == null
              ? 0
              : (int) (MapUtils.getDistance(stop.getStart().getLocation(), locationToStart));
      String distance =
          OsmAndFormatter.getFormattedDistance(dist, SearchTransportActivity.this)
              + " "; //$NON-NLS-1$
      label.setText(distance + labelW.toString(), TextView.BufferType.SPANNABLE);
      ((Spannable) label.getText())
          .setSpan(
              new ForegroundColorSpan(getResources().getColor(R.color.color_distance)),
              0,
              distance.length() - 1,
              0);
      return (row);
    }
コード例 #4
0
ファイル: POIMapLayer.java プロジェクト: rogere66/Osmand
 private StringBuilder buildPoiInformation(StringBuilder res, Amenity n) {
   String format =
       OsmAndFormatter.getPoiSimpleFormat(
           n, view.getContext(), view.getSettings().USE_ENGLISH_NAMES.get());
   res.append(" " + format);
   if (n.getOpeningHours() != null) {
     res.append("\n")
         .append(view.getContext().getString(R.string.opening_hours))
         .append(" : ")
         .append(n.getOpeningHours()); // $NON-NLS-1$ //$NON-NLS-2$
   }
   if (n.getPhone() != null) {
     res.append("\n")
         .append(view.getContext().getString(R.string.phone))
         .append(" : ")
         .append(n.getPhone()); // $NON-NLS-1$ //$NON-NLS-2$
   }
   if (n.getSite() != null && n.getType() != AmenityType.OSMWIKI) {
     res.append("\n")
         .append(view.getContext().getString(R.string.website))
         .append(" : ")
         .append(n.getSite()); // $NON-NLS-1$ //$NON-NLS-2$
   }
   return res;
 }
コード例 #5
0
ファイル: MapControlsLayer.java プロジェクト: borceg/Osmand
  private void drawRuler(Canvas canvas) {
    // update cache
    if (view.isZooming()) {
      cacheRulerText = null;
    } else if (view.getFloatZoom() != cacheRulerZoom
        || Math.abs(view.getXTile() - cacheRulerTileX) + Math.abs(view.getYTile() - cacheRulerTileY)
            > 1) {
      cacheRulerZoom = view.getFloatZoom();
      cacheRulerTileX = view.getXTile();
      cacheRulerTileY = view.getYTile();
      double latitude = view.getLatitude();
      double leftLon = view.calcLongitude(-view.getWidth() / 2);
      double rightLon = view.calcLongitude(+view.getWidth() / 2);
      double dist = MapUtils.getDistance(latitude, leftLon, latitude, rightLon);
      double pixDensity = view.getWidth() / dist;

      double roundedDist =
          OsmAndFormatter.calculateRoundedDist(dist * screenRulerPercent, view.getContext());

      int cacheRulerDistPix = (int) (pixDensity * roundedDist);
      cacheRulerText =
          ShadowText.create(
              OsmAndFormatter.getFormattedDistance((float) roundedDist, view.getContext()));
      cacheRulerTextLen = zoomTextPaint.measureText(cacheRulerText.getText());

      Rect bounds = rulerDrawable.getBounds();
      bounds.right = (int) (view.getWidth() - 7 * scaleCoefficient);
      bounds.bottom =
          (int)
              (view.getHeight()
                  - view.getResources().getDrawable(R.drawable.map_zoom_in).getMinimumHeight());
      bounds.top = bounds.bottom - rulerDrawable.getMinimumHeight();
      bounds.left = bounds.right - cacheRulerDistPix;
      rulerDrawable.setBounds(bounds);
    }
    if (cacheRulerText != null) {
      rulerDrawable.draw(canvas);
      Rect bounds = rulerDrawable.getBounds();
      cacheRulerText.draw(
          canvas,
          bounds.left + (bounds.width() - cacheRulerTextLen) / 2,
          bounds.bottom - 8 * scaleCoefficient,
          rulerTextPaint,
          shadowColor);
    }
  }
コード例 #6
0
ファイル: POIMapLayer.java プロジェクト: rogere66/Osmand
 private void showDescriptionDialog(Amenity a) {
   Builder bs = new AlertDialog.Builder(view.getContext());
   bs.setTitle(
       OsmAndFormatter.getPoiSimpleFormat(
           a, view.getContext(), view.getSettings().USE_ENGLISH_NAMES.get()));
   bs.setMessage(a.getDescription());
   bs.show();
 }
コード例 #7
0
ファイル: MapInfoLayer.java プロジェクト: Muxagen/Osmand
  private void drawRuler(Canvas canvas) {
    // occupy length over screen
    double screenPercent = 0.2;

    // update cache
    if (view.isZooming()) {
      rulerDistName = null;
    } else if (view.getZoom() != rulerCZoom
        || Math.abs(view.getXTile() - rulerCTileX) + Math.abs(view.getYTile() - rulerCTileY) > 1) {
      rulerCZoom = view.getZoom();
      rulerCTileX = view.getXTile();
      rulerCTileY = view.getYTile();
      double latitude = view.getLatitude();
      double tileNumberLeft = rulerCTileX - ((double) view.getWidth()) / (2d * view.getTileSize());
      double tileNumberRight = rulerCTileX + ((double) view.getWidth()) / (2d * view.getTileSize());
      double dist =
          MapUtils.getDistance(
              latitude,
              MapUtils.getLongitudeFromTile(view.getZoom(), tileNumberLeft),
              latitude,
              MapUtils.getLongitudeFromTile(view.getZoom(), tileNumberRight));

      dist *= screenPercent;
      int baseDist = 5;
      byte pointer = 0;
      while (dist > baseDist) {
        if (pointer++ % 3 == 2) {
          baseDist = baseDist * 5 / 2;
        } else {
          baseDist *= 2;
        }
      }

      rulerDistPix = (int) (view.getWidth() * screenPercent / dist * baseDist);
      rulerDistName = OsmAndFormatter.getFormattedDistance(baseDist, map);
      rulerBaseLine = (int) (view.getHeight() - 50 * dm.density);
      rulerTextLen = paintBlack.measureText(rulerDistName);
    }
    if (rulerDistName != null) {
      int w2 = (int) (view.getWidth() - 5 * dm.density);
      canvas.drawLine(w2 - rulerDistPix, rulerBaseLine, w2, rulerBaseLine, paintBlack);
      canvas.drawLine(
          w2 - rulerDistPix,
          rulerBaseLine,
          w2 - rulerDistPix,
          rulerBaseLine - 10 * dm.density,
          paintBlack);
      canvas.drawLine(w2, rulerBaseLine, w2, rulerBaseLine - 10 * dm.density, paintBlack);
      canvas.drawText(
          rulerDistName,
          w2 - (rulerDistPix + rulerTextLen) / 2 + 1,
          rulerBaseLine - 5 * dm.density,
          paintBlack);
    }
  }
コード例 #8
0
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
      View row = convertView;
      if (row == null) {
        LayoutInflater inflater = getLayoutInflater();
        row = inflater.inflate(R.layout.search_history_list_item, parent, false);
      }
      TextView label = (TextView) row.findViewById(R.id.label);
      TextView distanceLabel = (TextView) row.findViewById(R.id.distance_label);
      ImageButton icon = (ImageButton) row.findViewById(R.id.remove);
      final HistoryEntry model = getItem(position);
      if (location != null) {
        int dist = (int) (MapUtils.getDistance(location, model.lat, model.lon));
        distanceLabel.setText(
            OsmAndFormatter.getFormattedDistance(dist, SearchHistoryActivity.this));
      } else {
        distanceLabel.setText(""); // $NON-NLS-1$
      }
      label.setText(model.name);
      icon.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              helper.remove(model, SearchHistoryActivity.this);
              setListAdapter(
                  new HistoryAdapter(helper.getHistoryEntries(SearchHistoryActivity.this)));
            }
          });
      View.OnClickListener clickListener =
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              selectModel(model);
            }
          };

      View.OnLongClickListener longClickListener =
          new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
              return onItemLongClick(position);
            }
          };
      distanceLabel.setOnLongClickListener(longClickListener);
      label.setOnLongClickListener(longClickListener);
      distanceLabel.setOnClickListener(clickListener);
      label.setOnClickListener(clickListener);
      return row;
    }
コード例 #9
0
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      View row = convertView;
      if (row == null) {
        LayoutInflater inflater = getLayoutInflater();
        row = inflater.inflate(R.layout.favourites_list_item, parent, false);
      }

      TextView label = (TextView) row.findViewById(R.id.favourite_label);
      TextView distanceLabel = (TextView) row.findViewById(R.id.favouritedistance_label);
      ImageView icon = (ImageView) row.findViewById(R.id.favourite_icon);
      final FavouritePoint model = getItem(position);
      if (model.isStored()) {
        icon.setImageResource(R.drawable.favorites);
      } else {
        icon.setImageResource(R.drawable.opened_poi);
      }
      if (location != null) {
        int dist =
            (int)
                (MapUtils.getDistance(
                    model.getLatitude(),
                    model.getLongitude(),
                    location.getLatitude(),
                    location.getLongitude()));
        distanceLabel.setText(
            OsmAndFormatter.getFormattedDistance(dist, FavouritesListActivity.this));
        distanceLabel.setVisibility(View.VISIBLE);
      } else {
        distanceLabel.setVisibility(View.GONE);
      }

      label.setText(getName(model));
      final CheckBox ch = (CheckBox) row.findViewById(R.id.check_item);
      row.findViewById(R.id.favourite_icon).setVisibility(View.VISIBLE);
      ch.setVisibility(View.GONE);
      return row;
    }
コード例 #10
0
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
      View row = convertView;
      final RouteInfoLocation info = getItem(position);
      if (info == null) {
        TextView text = new TextView(getContext());
        LatLon st = getStartStop(position + 1);
        LatLon end = getEndStop(position - 1);

        if (st != null && end != null) {
          int dist = (int) MapUtils.getDistance(st, end);
          text.setText(
              MessageFormat.format(
                  getString(R.string.transport_searching_route),
                  OsmAndFormatter.getFormattedDistance(dist, SearchTransportActivity.this)));
        } else {
          text.setText(getString(R.string.transport_searching_transport));
        }
        text.setTextSize(21);
        text.setTypeface(null, Typeface.ITALIC);
        text.setOnClickListener(
            new View.OnClickListener() {

              @Override
              public void onClick(View v) {
                if (intermediateListAdapater.getCount() > 1) {
                  intermediateListAdapater.remove(null);
                  searchTransport();
                } else {
                  if (selectedDestinationLocation == null) {
                    selectedDestinationLocation = destinationLocation;
                  } else {
                    selectedDestinationLocation = null;
                  }
                  searchTransport();
                }
              }
            });
        return text;
      }
      int currentRouteLocation = getCurrentRouteLocation();
      if (row == null || row instanceof TextView) {
        LayoutInflater inflater = getLayoutInflater();
        row = inflater.inflate(R.layout.search_transport_route_item, parent, false);
      }

      TextView label = (TextView) row.findViewById(R.id.label);
      ImageButton icon = (ImageButton) row.findViewById(R.id.remove);

      TransportRoute route = info.getRoute();
      icon.setVisibility(View.VISIBLE);
      StringBuilder labelW = new StringBuilder(150);
      labelW.append(route.getType()).append(" ").append(route.getRef()); // $NON-NLS-1$
      boolean en = settings.usingEnglishNames();
      labelW
          .append(" : ")
          .append(info.getStart().getName(en))
          .append(" - ")
          .append(info.getStop().getName(en)); // $NON-NLS-1$ //$NON-NLS-2$
      // additional information  if route is calculated
      if (currentRouteLocation == -1) {
        labelW.append(" ("); // $NON-NLS-1$
        labelW
            .append(info.getStopNumbers())
            .append(" ")
            .append(getString(R.string.transport_stops))
            .append(", "); // $NON-NLS-1$ //$NON-NLS-2$
        int startDist =
            (int) MapUtils.getDistance(getEndStop(position - 1), info.getStart().getLocation());
        labelW
            .append(getString(R.string.transport_to_go_before))
            .append(" ")
            .append(
                OsmAndFormatter.getFormattedDistance(
                    startDist, SearchTransportActivity.this)); // $NON-NLS-1$
        if (position == getCount() - 1) {
          LatLon stop = getStartStop(position + 1);
          if (stop != null) {
            int endDist = (int) MapUtils.getDistance(stop, info.getStop().getLocation());
            labelW
                .append(", ")
                .append(getString(R.string.transport_to_go_after))
                .append(" ")
                .append(
                    OsmAndFormatter.getFormattedDistance(
                        endDist, SearchTransportActivity.this)); // $NON-NLS-1$ //$NON-NLS-2$
          }
        }

        labelW.append(")"); // $NON-NLS-1$
      }
      label.setText(labelW.toString());
      icon.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              int p = position;
              intermediateListAdapater.remove(null);
              if (!isRouteCalculated() && getCurrentRouteLocation() < p) {
                p--;
              }
              intermediateListAdapater.insert(null, p);
              intermediateListAdapater.remove(info);
              intermediateListAdapater.notifyDataSetChanged();
              zoom = initialZoom;
              searchTransport();
            }
          });
      View.OnClickListener clickListener =
          new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              showContextMenuOnRoute(info, position);
            }
          };
      label.setOnClickListener(clickListener);
      return row;
    }
コード例 #11
0
ファイル: MapInfoLayer.java プロジェクト: Muxagen/Osmand
  private void drawRouteInfo(Canvas canvas) {
    if (routeLayer != null && routeLayer.getHelper().isRouterEnabled()) {
      if (routeLayer.getHelper().isFollowingMode()) {
        int d = routeLayer.getHelper().getDistanceToNextRouteDirection();
        if (showMiniMap || d == 0) {
          if (!routeLayer.getPath().isEmpty()) {
            canvas.save();
            canvas.clipRect(boundsForMiniRoute);
            canvas.drawRoundRect(boundsForMiniRoute, roundCorner, roundCorner, paintAlphaGray);
            canvas.drawRoundRect(boundsForMiniRoute, roundCorner, roundCorner, paintBlack);
            canvas.translate(
                centerMiniRouteX - view.getCenterPointX(),
                centerMiniRouteY - view.getCenterPointY());
            canvas.scale(
                scaleMiniRoute, scaleMiniRoute, view.getCenterPointX(), view.getCenterPointY());
            canvas.rotate(view.getRotate(), view.getCenterPointX(), view.getCenterPointY());
            canvas.drawCircle(
                view.getCenterPointX(), view.getCenterPointY(), 3 / scaleMiniRoute, fillBlack);
            canvas.drawPath(routeLayer.getPath(), paintMiniRoute);
            canvas.restore();
          }
        } else {
          canvas.drawRoundRect(boundsForMiniRoute, roundCorner, roundCorner, paintAlphaGray);
          canvas.drawRoundRect(boundsForMiniRoute, roundCorner, roundCorner, paintBlack);
          RouteDirectionInfo next = routeLayer.getHelper().getNextRouteDirectionInfo();
          if (next != null) {
            if (!Algoritms.objectEquals(cachedTurnType, next.turnType)) {
              cachedTurnType = next.turnType;
              calcTurnPath(pathForTurn, cachedTurnType, pathTransform);
              if (cachedTurnType.getExitOut() > 0) {
                cachedExitOut = cachedTurnType.getExitOut() + ""; // $NON-NLS-1$
              } else {
                cachedExitOut = null;
              }
            }
            canvas.drawPath(pathForTurn, paintRouteDirection);
            canvas.drawPath(pathForTurn, paintBlack);
            if (cachedExitOut != null) {
              canvas.drawText(
                  cachedExitOut,
                  boundsForMiniRoute.centerX() - 6 * scaleCoefficient,
                  boundsForMiniRoute.centerY() - 9 * scaleCoefficient,
                  paintBlack);
            }
            canvas.drawText(
                OsmAndFormatter.getFormattedDistance(d, map),
                boundsForMiniRoute.left + 10 * scaleCoefficient,
                boundsForMiniRoute.bottom - 9 * scaleCoefficient,
                paintBlack);
          }
        }
      }

      boolean followingMode = routeLayer.getHelper().isFollowingMode();
      int time = routeLayer.getHelper().getLeftTime();
      if (time == 0) {
        cachedLeftTime = 0;
        cachedLeftTimeString = null;
      } else {
        if (followingMode && showArrivalTime) {
          long toFindTime = time * 1000 + System.currentTimeMillis();
          if (Math.abs(toFindTime - cachedLeftTime) > 30000) {
            cachedLeftTime = toFindTime;
            if (DateFormat.is24HourFormat(map)) {
              cachedLeftTimeString =
                  DateFormat.format("kk:mm", toFindTime).toString(); // $NON-NLS-1$
            } else {
              cachedLeftTimeString =
                  DateFormat.format("k:mm aa", toFindTime).toString(); // $NON-NLS-1$
            }
            boundsForLeftTime.left =
                -paintBlack.measureText(cachedLeftTimeString)
                    - 10 * scaleCoefficient
                    + boundsForLeftTime.right;
          }
        } else {
          if (Math.abs(time - cachedLeftTime) > 30) {
            cachedLeftTime = time;
            int hours = time / (60 * 60);
            int minutes = (time / 60) % 60;
            cachedLeftTimeString = String.format("%d:%02d", hours, minutes); // $NON-NLS-1$
            boundsForLeftTime.left =
                -paintBlack.measureText(cachedLeftTimeString)
                    - 10 * scaleCoefficient
                    + boundsForLeftTime.right;
          }
        }
      }
      if (cachedLeftTimeString != null) {
        int w = (int) (boundsForLeftTime.right - boundsForLeftTime.left);
        boundsForLeftTime.right = view.getWidth();
        boundsForLeftTime.left = view.getWidth() - w;
        canvas.drawRoundRect(boundsForLeftTime, roundCorner, roundCorner, paintAlphaGray);
        canvas.drawRoundRect(boundsForLeftTime, roundCorner, roundCorner, paintBlack);
        canvas.drawText(
            cachedLeftTimeString,
            boundsForLeftTime.left + 5 * scaleCoefficient,
            boundsForLeftTime.bottom - 9 * scaleCoefficient,
            paintBlack);
      }
    }
  }
コード例 #12
0
ファイル: MapInfoLayer.java プロジェクト: Muxagen/Osmand
  @Override
  public void onDraw(Canvas canvas, RectF latlonBounds, RectF tilesRect, boolean nightMode) {
    // prepare data (left distance, speed)
    if (map.getPointToNavigate() != null) {
      int d = 0;
      if (map.getRoutingHelper().isRouterEnabled()) {
        d = map.getRoutingHelper().getLeftDistance();
      }
      if (d == 0) {
        Location.distanceBetween(
            view.getLatitude(),
            view.getLongitude(),
            map.getPointToNavigate().getLatitude(),
            map.getPointToNavigate().getLongitude(),
            calculations);
        d = (int) calculations[0];
      }
      if (distChanged(cachedMeters, d)) {
        cachedMeters = d;
        if (cachedMeters <= 20) {
          cachedMeters = 0;
          cachedDistString = null;
        } else {
          cachedDistString = OsmAndFormatter.getFormattedDistance(cachedMeters, map);
          float right =
              paintBlack.measureText(cachedDistString) + 25 * scaleCoefficient + boundsForDist.left;
          if (cachedSpeedString != null) {
            boundsForSpeed.right = boundsForDist.right = Math.max(right, boundsForDist.right);
          } else {
            boundsForDist.right = right;
          }
        }
      }
    } else {
      cachedMeters = 0;
      cachedDistString = null;
    }
    if (view.getZoom() != cachedZoom) {
      cachedZoom = view.getZoom();
      cachedZoomString = view.getZoom() + ""; // $NON-NLS-1$
    }
    // draw zoom
    canvas.drawRoundRect(boundsForZoom, roundCorner, roundCorner, paintAlphaGray);
    canvas.drawRoundRect(boundsForZoom, roundCorner, roundCorner, paintBlack);
    canvas.drawText(
        cachedZoomString,
        boundsForZoom.left + 5 * scaleCoefficient,
        boundsForZoom.bottom - 8 * scaleCoefficient,
        paintBlack);

    // draw speed
    if (map.getLastKnownLocation() != null && map.getLastKnownLocation().hasSpeed()) {
      if (Math.abs(map.getLastKnownLocation().getSpeed() - cachedSpeed) > .3f) {
        cachedSpeed = map.getLastKnownLocation().getSpeed();
        cachedSpeedString = OsmAndFormatter.getFormattedSpeed(cachedSpeed, map);
        float right =
            paintBlack.measureText(cachedSpeedString) + 8 * scaleCoefficient + boundsForSpeed.left;
        boundsForSpeed.right = boundsForDist.right = Math.max(right, boundsForDist.right);
      }
      if (cachedSpeed > 0) {
        canvas.drawRoundRect(boundsForSpeed, roundCorner, roundCorner, paintAlphaGray);
        canvas.drawRoundRect(boundsForSpeed, roundCorner, roundCorner, paintBlack);
        canvas.drawText(
            cachedSpeedString,
            boundsForSpeed.left + 8 * scaleCoefficient,
            boundsForSpeed.bottom - 9f * scaleCoefficient,
            paintBlack);
      }
    }
    // draw distance to point
    if (cachedDistString != null) {
      canvas.drawRoundRect(boundsForDist, roundCorner, roundCorner, paintAlphaGray);
      canvas.drawRoundRect(boundsForDist, roundCorner, roundCorner, paintBlack);
      canvas.drawCircle(
          boundsForDist.left + 8 * scaleCoefficient,
          boundsForDist.bottom - 15 * scaleCoefficient,
          4 * scaleCoefficient,
          fillRed);
      canvas.drawText(
          cachedDistString,
          boundsForDist.left + 15 * scaleCoefficient,
          boundsForDist.bottom - 9f * scaleCoefficient,
          paintBlack);
    }

    // draw ruler
    drawRuler(canvas);

    // draw route information
    drawRouteInfo(canvas);

    // draw compass the last (!) because it use rotating
    canvas.drawRoundRect(boundsForCompass, roundCorner, roundCorner, paintAlphaGray);
    canvas.drawRoundRect(boundsForCompass, roundCorner, roundCorner, paintBlack);
    canvas.rotate(view.getRotate(), 15 * scaleCoefficient, 15 * scaleCoefficient);
    canvas.drawPath(pathForCompass2, fillRed);
    canvas.drawPath(pathForCompass, fillBlack);
  }