private void refreshMapInternal(DrawSettings drawSettings) { handler.removeMessages(MAP_REFRESH_MESSAGE); SurfaceHolder holder = getHolder(); long ms = SystemClock.elapsedRealtime(); synchronized (holder) { Canvas canvas = holder.lockCanvas(); if (canvas != null) { try { final float ratioy = mapPosition == OsmandSettings.BOTTOM_CONSTANT ? 0.8f : 0.5f; final int cy = (int) (ratioy * getHeight()); if (currentViewport.getPixWidth() != getWidth() || currentViewport.getPixHeight() != getHeight() || currentViewport.getCenterPixelY() != cy) { currentViewport.setPixelDimensions(getWidth(), getHeight(), 0.5f, ratioy); refreshBufferImage(drawSettings); } // make copy to avoid concurrency RotatedTileBox viewportToDraw = currentViewport.copy(); fillCanvas(canvas, drawSettings); drawOverMap(canvas, viewportToDraw, drawSettings); } finally { holder.unlockCanvasAndPost(canvas); } } if (MEASURE_FPS) { main.calculateFPS(ms, SystemClock.elapsedRealtime()); } } }
private void showOnMap(LatLon latLon, boolean updateCoords, boolean ignoreCoef) { AnimateDraggingMapThread thread = map.getAnimatedDraggingThread(); int fZoom = map.getZoom(); double flat = latLon.getLatitude(); double flon = latLon.getLongitude(); RotatedTileBox cp = map.getCurrentRotatedTileBox().copy(); if (ignoreCoef) { cp.setCenterLocation(0.5f, 0.5f); } else { cp.setCenterLocation( 0.5f, map.getMapPosition() == OsmandSettings.BOTTOM_CONSTANT ? 0.15f : 0.5f); } cp.setLatLonCenter(flat, flon); flat = cp.getLatFromPixel(cp.getPixWidth() / 2, cp.getPixHeight() / 2); flon = cp.getLonFromPixel(cp.getPixWidth() / 2, cp.getPixHeight() / 2); if (updateCoords) { mapCenter = new LatLon(flat, flon); menu.setMapCenter(mapCenter); origMarkerX = cp.getCenterPixelX(); origMarkerY = cp.getCenterPixelY(); } thread.startMoving(flat, flon, fZoom, true); }
@Override public void onZoomEnded(double relativeToStart, float angleRelative) { // 1.5 works better even on dm.density=1 devices float dz = (float) (Math.log(relativeToStart) / Math.log(2)) * 1.5f; setIntZoom(Math.round(dz) + initialViewport.getZoom()); if (Math.abs(angleRelative) < ANGLE_THRESHOLD) { angleRelative = 0; } rotateToAnimate(initialViewport.getRotate() + angleRelative); final int newZoom = getZoom(); if (application.getInternalAPI().accessibilityEnabled()) { if (newZoom != initialViewport.getZoom()) { showMessage(getContext().getString(R.string.zoomIs) + " " + newZoom); // $NON-NLS-1$ } else { final LatLon p1 = initialViewport.getLatLonFromPixel(x1, y1); final LatLon p2 = initialViewport.getLatLonFromPixel(x2, y2); showMessage( OsmAndFormatter.getFormattedDistance( (float) MapUtils.getDistance( p1.getLatitude(), p1.getLongitude(), p2.getLatitude(), p2.getLongitude()), application)); } } }
private void drawOverMap(Canvas canvas, RotatedTileBox tileBox, DrawSettings drawSettings) { final QuadPoint c = tileBox.getCenterPixelPoint(); synchronized (this) { if (bufferBitmap != null && !bufferBitmap.isRecycled()) { canvas.save(); canvas.rotate(tileBox.getRotate(), c.x, c.y); drawBasemap(canvas); canvas.restore(); } } for (int i = 0; i < layers.size(); i++) { try { OsmandMapLayer layer = layers.get(i); canvas.save(); // rotate if needed if (!layer.drawInScreenPixels()) { canvas.rotate(tileBox.getRotate(), c.x, c.y); } layer.onDraw(canvas, tileBox, drawSettings); canvas.restore(); } catch (IndexOutOfBoundsException e) { // skip it } } if (showMapPosition) { canvas.drawCircle(c.x, c.y, 3 * dm.density, paintCenter); canvas.drawCircle(c.x, c.y, 7 * dm.density, paintCenter); } }
public void updateMapCenter(LatLon mapCenter) { customMapCenter = true; menu.setMapCenter(mapCenter); this.mapCenter = mapCenter; RotatedTileBox box = map.getCurrentRotatedTileBox().copy(); origMarkerX = box.getCenterPixelX(); origMarkerY = box.getCenterPixelY(); }
@Override public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> objects) { int radius = (int) (VICINITY_RADIUS * tileBox.getDensity()); final QuadPoint p = tileBox.getCenterPixelPoint(); int dx = (int) Math.abs(point.x - p.x); int dy = (int) Math.abs(point.y - p.y); if ((dx < radius) && (dy < radius)) objects.add(this); }
public void moveTo(float dx, float dy) { final QuadPoint cp = currentViewport.getCenterPixelPoint(); final LatLon latlon = currentViewport.getLatLonFromPixel(cp.x + dx, cp.y + dy); currentViewport.setLatLonCenter(latlon.getLatitude(), latlon.getLongitude()); refreshMap(); // do not notify here listener }
@Override public boolean onDoubleTap(MotionEvent e) { final RotatedTileBox tb = getCurrentRotatedTileBox(); final double lat = tb.getLatFromPixel(e.getX(), e.getY()); final double lon = tb.getLonFromPixel(e.getX(), e.getY()); getAnimatedDraggingThread().startMoving(lat, lon, getZoom() + 1, true); return true; }
public int getRadiusPoi(RotatedTileBox tb) { int r = 0; if (tb.getZoom() < startZoom) { r = 0; } else { r = 15; } return (int) (r * tb.getDensity()); }
public void setComplexZoom(int zoom, float scale) { if (mainLayer != null && zoom <= mainLayer.getMaximumShownMapZoom() && zoom >= mainLayer.getMinimumShownMapZoom()) { animatedDraggingThread.stopAnimating(); currentViewport.setZoom(zoom, scale, 0); currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0); refreshMap(); } }
@Override public boolean onLongClick(PointF point, RotatedTileBox tileBox) { if (activity.getMyApplication().accessibilityEnabled() && activity.getMapViewTrackingUtilities().isMapLinkedToLocation()) { activity .getMapLayers() .getContextMenuLayer() .showContextMenu(tileBox.getLatitude(), tileBox.getLongitude(), true); return true; } return false; }
public void setMainLayer(BaseMapLayer mainLayer) { this.mainLayer = mainLayer; int zoom = currentViewport.getZoom(); if (mainLayer.getMaximumShownMapZoom() < zoom) { zoom = mainLayer.getMaximumShownMapZoom(); } if (mainLayer.getMinimumShownMapZoom() > zoom) { zoom = mainLayer.getMinimumShownMapZoom(); } currentViewport.setZoomAndAnimation(zoom, 0); refreshMap(); }
public void getFavoriteFromPoint( RotatedTileBox tb, PointF point, List<? super FavouritePoint> res) { int r = (int) (15 * tb.getDensity()); int ex = (int) point.x; int ey = (int) point.y; for (FavouritePoint n : favorites.getFavouritePoints()) { int x = (int) tb.getPixXFromLatLon(n.getLatitude(), n.getLongitude()); int y = (int) tb.getPixYFromLatLon(n.getLatitude(), n.getLongitude()); if (calculateBelongs(ex, ey, x, y, r)) { res.add(n); } } }
private String getZoomLevel(RotatedTileBox tb) { String zoomText = tb.getZoom() + ""; double frac = tb.getMapDensity(); if (frac != 0) { int ifrac = (int) (frac * 10); zoomText += " "; zoomText += Math.abs(ifrac) / 10; if (ifrac % 10 != 0) { zoomText += "." + Math.abs(ifrac) % 10; } } return zoomText; }
public void getRecordingsFromPoint( PointF point, RotatedTileBox tileBox, List<? super Recording> am) { int ex = (int) point.x; int ey = (int) point.y; int compare = getRadiusPoi(tileBox); int radius = compare * 3 / 2; for (Recording n : plugin.getAllRecordings()) { int x = (int) tileBox.getPixXFromLatLon(n.getLatitude(), n.getLongitude()); int y = (int) tileBox.getPixYFromLatLon(n.getLatitude(), n.getLongitude()); if (calculateBelongs(ex, ey, x, y, compare)) { compare = radius; am.add(n); } } }
protected void rotateToAnimate(float rotate) { if (isMapRotateEnabled()) { this.rotate = MapUtils.unifyRotationTo360(rotate); currentViewport.setRotate(this.rotate); refreshMap(); } }
protected void setLatLonAnimate(double latitude, double longitude, boolean notify) { currentViewport.setLatLonCenter(latitude, longitude); refreshMap(); if (locationListener != null && notify) { locationListener.locationChanged(latitude, longitude, this); } }
protected void setZoomAnimate(int zoom, float zoomScale, boolean notify) { currentViewport.setZoom(zoom, zoomScale, 0); refreshMap(); if (locationListener != null && notify) { locationListener.locationChanged(getLatitude(), getLongitude(), this); } }
private void changeZoomPosition(float dz, float angle) { final QuadPoint cp = initialViewport.getCenterPixelPoint(); float dx = cp.x - initialMultiTouchCenterPoint.x; float dy = cp.y - initialMultiTouchCenterPoint.y; final RotatedTileBox calc = initialViewport.copy(); calc.setLatLonCenter(initialCenterLatLon.getLatitude(), initialCenterLatLon.getLongitude()); float calcZoom = initialViewport.getZoom() + dz + initialViewport.getZoomScale(); float calcRotate = calc.getRotate() + angle; calc.setRotate(calcRotate); calc.setZoomAnimation(dz); final LatLon r = calc.getLatLonFromPixel(cp.x + dx, cp.y + dy); setLatLon(r.getLatitude(), r.getLongitude()); zoomToAnimate(calcZoom, true); rotateToAnimate(calcRotate); }
public int getRadiusBug(RotatedTileBox tb) { int z; final double zoom = tb.getZoom(); if (zoom < startZoom) { z = 0; } else if (zoom <= 12) { z = 8; } else if (zoom <= 15) { z = 10; } else if (zoom == 16) { z = 13; } else if (zoom == 17) { z = 15; } else { z = 16; } return (int) (z * tb.getDensity()); }
// ///////////////////////////// INITIALIZING UI PART /////////////////////////////////// public void initView() { paintGrayFill = new Paint(); paintGrayFill.setColor(Color.GRAY); paintGrayFill.setStyle(Style.FILL); // when map rotate paintGrayFill.setAntiAlias(true); paintBlackFill = new Paint(); paintBlackFill.setColor(Color.BLACK); paintBlackFill.setStyle(Style.FILL); // when map rotate paintBlackFill.setAntiAlias(true); paintWhiteFill = new Paint(); paintWhiteFill.setColor(Color.WHITE); paintWhiteFill.setStyle(Style.FILL); // when map rotate paintWhiteFill.setAntiAlias(true); paintCenter = new Paint(); paintCenter.setStyle(Style.STROKE); paintCenter.setColor(Color.rgb(60, 60, 60)); paintCenter.setStrokeWidth(2); paintCenter.setAntiAlias(true); paintImg = new Paint(); // paintImg.setFilterBitmap(true); // paintImg.setDither(true); setClickable(true); setLongClickable(true); setFocusable(true); handler = new Handler(); baseHandler = new Handler(application.getResourceManager().getRenderingBufferImageThread().getLooper()); getHolder().addCallback(this); animatedDraggingThread = new AnimateDraggingMapThread(this); gestureDetector = new GestureDetector( getContext(), new MapExplorer(this, new MapTileViewOnGestureListener())); multiTouchSupport = new MultiTouchSupport(getContext(), new MapTileViewMultiTouchZoomListener()); gestureDetector.setOnDoubleTapListener(new MapTileViewOnDoubleTapListener()); WindowManager mgr = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); dm = new DisplayMetrics(); mgr.getDefaultDisplay().getMetrics(dm); currentViewport = new RotatedTileBox.RotatedTileBoxBuilder() .setLocation(0, 0) .setZoomAndScale(3, 0) .setPixelDimensions(getWidth(), getHeight()) .build(); currentViewport.setDensity(dm.density); }
@Override public void onZoomStarted(PointF centerPoint) { initialMultiTouchCenterPoint = centerPoint; initialViewport = getCurrentRotatedTileBox().copy(); initialCenterLatLon = initialViewport.getLatLonFromPixel( initialMultiTouchCenterPoint.x, initialMultiTouchCenterPoint.y); startRotating = false; }
@Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { if (tileBox.getZoom() >= startZoom) { // request to load data.queryNewData(tileBox); List<OpenStreetNote> objects = data.getResults(); if (objects != null) { for (OpenStreetNote o : objects) { int x = tileBox.getPixXFromLonNoRot(o.getLongitude()); int y = tileBox.getPixYFromLatNoRot(o.getLatitude()); canvas.drawCircle( x, y, getRadiusBug(tileBox), o.isLocal() ? pointNotSubmitedUI : (o.isOpened() ? pointOpenedUI : pointClosedUI)); } } } }
@Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { if (tileBox.getZoom() >= startZoom) { DataTileManager<Recording> recs = plugin.getRecordings(); final QuadRect latlon = tileBox.getLatLonBounds(); List<Recording> objects = recs.getObjects(latlon.top, latlon.left, latlon.bottom, latlon.right); for (Recording o : objects) { int x = (int) tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude()); int y = (int) tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude()); Bitmap b; if (o.isPhoto()) { b = photo; } else if (o.isAudio()) { b = audio; } else { b = video; } canvas.drawBitmap(b, x - b.getWidth() / 2, y - b.getHeight() / 2, paintIcon); } } }
@Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { if (tileBox.getZoom() >= startZoom) { // request to load final QuadRect latLonBounds = tileBox.getLatLonBounds(); for (FavouritePoint o : favorites.getFavouritePoints()) { if (o.getLatitude() >= latLonBounds.bottom && o.getLatitude() <= latLonBounds.top && o.getLongitude() >= latLonBounds.left && o.getLongitude() <= latLonBounds.right) { int x = (int) tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude()); int y = (int) tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude()); FavoriteImageDrawable fid = FavoriteImageDrawable.getOrCreate(view.getContext(), o.getColor()); fid.drawBitmapInCenter(canvas, x, y); // canvas.drawBitmap(favoriteIcon, x - favoriteIcon.getWidth() / 2, // y - favoriteIcon.getHeight(), paint); } } } }
// for internal usage protected void zoomToAnimate(float tzoom, boolean notify) { int zoom = getZoom(); float zoomToAnimate = tzoom - zoom - getZoomScale(); if (zoomToAnimate >= 1) { zoom += (int) zoomToAnimate; zoomToAnimate -= (int) zoomToAnimate; } while (zoomToAnimate < 0) { zoom--; zoomToAnimate += 1; } if (mainLayer != null && mainLayer.getMaximumShownMapZoom() >= zoom && mainLayer.getMinimumShownMapZoom() <= zoom) { currentViewport.setZoomAndAnimation(zoom, zoomToAnimate); currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0); refreshMap(); if (notify && locationListener != null) { locationListener.locationChanged(getLatitude(), getLongitude(), this); } } }
public void getBugFromPoint(RotatedTileBox tb, PointF point, List<? super OpenStreetNote> res) { List<OpenStreetNote> objects = data.getResults(); if (objects != null && view != null) { int ex = (int) point.x; int ey = (int) point.y; final int rad = getRadiusBug(tb); int radius = rad * 3 / 2; int small = rad * 3 / 4; try { for (int i = 0; i < objects.size(); i++) { OpenStreetNote n = objects.get(i); int x = (int) tb.getPixXFromLatLon(n.getLatitude(), n.getLongitude()); int y = (int) tb.getPixYFromLatLon(n.getLatitude(), n.getLongitude()); if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) { radius = small; res.add(n); } } } catch (IndexOutOfBoundsException e) { // that's really rare case, but is much efficient than introduce synchronized block } } }
private void showOnMap( LatLon latLon, boolean updateCoords, boolean needMove, boolean alreadyAdjusted) { // AnimateDraggingMapThread thread = map.getAnimatedDraggingThread(); todo amimation int fZoom = getZoom(); double flat = latLon.getLatitude(); double flon = latLon.getLongitude(); RotatedTileBox cp = getBox(); // cp.setCenterLocation(0.5f, map.getMapPosition() == OsmandSettings.BOTTOM_CONSTANT ? 0.15f : // 0.5f); cp.setLatLonCenter(flat, flon); cp.setZoom(fZoom); flat = cp.getLatFromPixel(cp.getPixWidth() / 2, cp.getPixHeight() / 2); flon = cp.getLonFromPixel(cp.getPixWidth() / 2, cp.getPixHeight() / 2); if (updateCoords) { mapCenter = new LatLon(flat, flon); menu.setMapCenter(mapCenter); origMarkerX = cp.getCenterPixelX(); origMarkerY = cp.getCenterPixelY(); } if (!alreadyAdjusted) { LatLon adjustedLatLon = getAdjustedMarkerLocation(getPosY(), new LatLon(flat, flon), true, fZoom); flat = adjustedLatLon.getLatitude(); flon = adjustedLatLon.getLongitude(); } if (needMove) { // thread.startMoving(flat, flon, fZoom, true); todo animation PointI targetI = Utilities.convertLatLonTo31(new net.osmand.core.jni.LatLon(flat, flon)); getMainActivity().setTarget(targetI); getMainActivity().setZoom(fZoom); } }
private void adjustMapPosition(int y, boolean animated) { double markerLat = menu.getLatLon().getLatitude(); double markerLon = menu.getLatLon().getLongitude(); RotatedTileBox box = map.getCurrentRotatedTileBox().copy(); LatLon latlon = mapCenter; if (menu.isLandscapeLayout()) { int markerX = (int) box.getPixXFromLatLon(markerLat, markerLon); int x = dpToPx(menu.getLandscapeWidthDp()); if (markerX - markerPaddingXPx < x || markerX > origMarkerX) { int dx = (x + markerPaddingXPx) - markerX; if (markerX - dx <= origMarkerX) { QuadPoint cp = box.getCenterPixelPoint(); latlon = box.getLatLonFromPixel(cp.x - dx, cp.y); } else { latlon = box.getCenterLatLon(); } } } else { int markerY = (int) box.getPixYFromLatLon(markerLat, markerLon); if (markerY + markerPaddingPx > y || markerY < origMarkerY) { int dy = markerY - (y - markerPaddingPx); if (markerY - dy <= origMarkerY) { QuadPoint cp = box.getCenterPixelPoint(); latlon = box.getLatLonFromPixel(cp.x + 0, cp.y + dy); } } } if (map.getLatitude() == latlon.getLatitude() && map.getLongitude() == latlon.getLongitude()) { return; } if (animated) { showOnMap(latlon, false, true); } else { map.setLatLon(latlon.getLatitude(), latlon.getLongitude()); } }
private void refreshBaseMapInternal(RotatedTileBox tileBox, DrawSettings drawSettings) { if (tileBox.getPixHeight() == 0 || tileBox.getPixWidth() == 0) { return; } if (bufferBitmapTmp == null || tileBox.getPixHeight() != bufferBitmapTmp.getHeight() || tileBox.getPixWidth() != bufferBitmapTmp.getWidth()) { bufferBitmapTmp = Bitmap.createBitmap(tileBox.getPixWidth(), tileBox.getPixHeight(), Config.RGB_565); } long start = SystemClock.elapsedRealtime(); final QuadPoint c = tileBox.getCenterPixelPoint(); Canvas canvas = new Canvas(bufferBitmapTmp); fillCanvas(canvas, drawSettings); for (int i = 0; i < layers.size(); i++) { try { OsmandMapLayer layer = layers.get(i); canvas.save(); // rotate if needed if (!layer.drawInScreenPixels()) { canvas.rotate(tileBox.getRotate(), c.x, c.y); } layer.onPrepareBufferImage(canvas, tileBox, drawSettings); canvas.restore(); } catch (IndexOutOfBoundsException e) { // skip it } } Bitmap t = bufferBitmap; synchronized (this) { bufferImgLoc = tileBox; bufferBitmap = bufferBitmapTmp; bufferBitmapTmp = t; } long end = SystemClock.elapsedRealtime(); additional.calculateFPS(start, end); }