Refactor yandex traffic layer as map tile layer
This commit is contained in:
parent
4b93b76341
commit
0b68af3e7d
11 changed files with 118 additions and 274 deletions
|
@ -17,6 +17,8 @@ public interface ITileSource {
|
|||
|
||||
public int getBitDensity();
|
||||
|
||||
public boolean isEllipticYTile();
|
||||
|
||||
public boolean couldBeDownloadedFromInternet();
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public class TileSourceManager {
|
|||
protected String ext;
|
||||
private int avgSize;
|
||||
private int bitDensity;
|
||||
private boolean ellipticYTile;
|
||||
|
||||
public TileSourceTemplate(File dir, String name, String urlToLoad) {
|
||||
this(name, urlToLoad, determineExt(dir,".jpg"), 18, 1, 256, 16, 20000); //$NON-NLS-1$
|
||||
|
@ -77,6 +78,16 @@ public class TileSourceManager {
|
|||
this.avgSize = avgSize;
|
||||
this.bitDensity = bitDensity;
|
||||
}
|
||||
|
||||
|
||||
public void setEllipticYTile(boolean ellipticYTile) {
|
||||
this.ellipticYTile = ellipticYTile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEllipticYTile() {
|
||||
return ellipticYTile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBitDensity() {
|
||||
|
|
|
@ -547,7 +547,7 @@ public class OsmandSettings {
|
|||
if(dir.exists()){
|
||||
if(tileName.endsWith(SQLiteTileSource.EXT)){
|
||||
return new SQLiteTileSource(dir);
|
||||
} else if (dir.isDirectory()) {
|
||||
} else if (dir.isDirectory() && !dir.getName().startsWith(".")) {
|
||||
String url = null;
|
||||
File readUrl = new File(dir, "url"); //$NON-NLS-1$
|
||||
try {
|
||||
|
|
|
@ -646,19 +646,6 @@ public class ResourceManager {
|
|||
}
|
||||
|
||||
|
||||
public synchronized void updateMapSource(boolean useVectorMap, ITileSource source){
|
||||
log.info("Clear cache with new source " + cacheOfImages.size()); //$NON-NLS-1$
|
||||
cacheOfImages.clear();
|
||||
renderer.clearCache();
|
||||
if(source == null || source.getBitDensity() == 0){
|
||||
maxImgCacheSize = 32;
|
||||
} else {
|
||||
maxImgCacheSize = Math.max(384 / source.getBitDensity() , 32);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected synchronized void clearTiles(){
|
||||
log.info("Cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$
|
||||
ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet());
|
||||
|
|
|
@ -250,6 +250,11 @@ public class SQLiteTileSource implements ITileSource {
|
|||
}
|
||||
return urlTemplate != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEllipticYTile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -532,7 +532,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
if(locationLayer.getLastKnownLocation() != null){
|
||||
Location lastKnownLocation = locationLayer.getLastKnownLocation();
|
||||
AnimateDraggingMapThread thread = mapView.getAnimatedDraggingThread();
|
||||
int fZoom = mapView.getZoom() < 15 ? 15 : mapView.getZoom();
|
||||
int fZoom = mapView.getZoom() < 14 ? 14 : mapView.getZoom();
|
||||
thread.startMoving( lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), fZoom, false);
|
||||
}
|
||||
}
|
||||
|
@ -853,7 +853,6 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
if(oldMap instanceof SQLiteTileSource){
|
||||
((SQLiteTileSource)oldMap).closeDB();
|
||||
}
|
||||
rm.updateMapSource(vectorData, newSource);
|
||||
mapTileLayer.setMap(newSource);
|
||||
mapTileLayer.setVisible(!vectorData);
|
||||
mapVectorLayer.setVisible(vectorData);
|
||||
|
|
|
@ -88,6 +88,7 @@ public class MapVectorLayer extends BaseMapLayer {
|
|||
}
|
||||
if(!isVectorDataVisible() && tileLayer != null){
|
||||
tileLayer.drawTileMap(canvas, tilesRect);
|
||||
resourceManager.getRenderer().interruptLoadingMap();
|
||||
} else {
|
||||
if (!view.isZooming()){
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
|
|
|
@ -8,7 +8,6 @@ import org.apache.commons.logging.Log;
|
|||
import android.os.SystemClock;
|
||||
import android.util.FloatMath;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
|
||||
|
@ -23,7 +22,7 @@ public class AnimateDraggingMapThread {
|
|||
private final static float DRAGGING_ANIMATION_TIME = 1900f;
|
||||
private final static float ZOOM_ANIMATION_TIME = 800f;
|
||||
private final static float ZOOM_MOVE_ANIMATION_TIME = 650f;
|
||||
private final static float MOVE_MOVE_ANIMATION_TIME = 1300f;
|
||||
private final static float MOVE_MOVE_ANIMATION_TIME = 2000f;
|
||||
private final static int DEFAULT_SLEEP_TO_REDRAW = 55;
|
||||
|
||||
private volatile boolean stopped;
|
||||
|
@ -143,6 +142,8 @@ public class AnimateDraggingMapThread {
|
|||
final float mMoveX = FloatMath.cos(rad) * mStX - FloatMath.sin(rad) * mStY;
|
||||
final float mMoveY = FloatMath.sin(rad) * mStX + FloatMath.cos(rad) * mStY;
|
||||
|
||||
final float animationTime = Math.max(450, (Math.abs(mStX) + Math.abs(mStY)) / 1200f * MOVE_MOVE_ANIMATION_TIME);
|
||||
|
||||
startThreadAnimating(new Runnable() {
|
||||
|
||||
@Override
|
||||
|
@ -153,7 +154,7 @@ public class AnimateDraggingMapThread {
|
|||
}
|
||||
|
||||
if(!stopped){
|
||||
animatingMoveInThread(mMoveX, mMoveY, MOVE_MOVE_ANIMATION_TIME, notifyListener);
|
||||
animatingMoveInThread(mMoveX, mMoveY, animationTime, notifyListener);
|
||||
}
|
||||
if(!stopped){
|
||||
tileView.setLatLonAnimate(finalLat, finalLon, notifyListener);
|
||||
|
@ -202,6 +203,7 @@ public class AnimateDraggingMapThread {
|
|||
|
||||
private void animatingZoomInThread(int zoomStart, int zoomEnd, float animationTime, boolean notifyListener){
|
||||
float curZoom = zoomStart;
|
||||
animationTime *= Math.abs(zoomEnd - zoomStart);
|
||||
// AccelerateInterpolator interpolator = new AccelerateInterpolator(1);
|
||||
LinearInterpolator interpolator = new LinearInterpolator();
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ public class MapTileLayer extends BaseMapLayer {
|
|||
protected final int emptyTileDivisor = 16;
|
||||
public static final int OVERZOOM_IN = 2;
|
||||
|
||||
private ITileSource map = null;
|
||||
protected ITileSource map = null;
|
||||
|
||||
Paint paintBitmap;
|
||||
|
||||
|
@ -26,8 +26,8 @@ public class MapTileLayer extends BaseMapLayer {
|
|||
protected RectF bitmapToDraw = new RectF();
|
||||
protected Rect bitmapToZoom = new Rect();
|
||||
|
||||
private OsmandMapTileView view;
|
||||
private ResourceManager resourceManager;
|
||||
protected OsmandMapTileView view;
|
||||
protected ResourceManager resourceManager;
|
||||
private OsmandSettings settings;
|
||||
private boolean visible = true;
|
||||
|
||||
|
@ -63,7 +63,7 @@ public class MapTileLayer extends BaseMapLayer {
|
|||
ResourceManager mgr = resourceManager;
|
||||
int nzoom = view.getZoom();
|
||||
float tileX = view.getXTile();
|
||||
float tileY = view.getYTile();
|
||||
float tileY = map.isEllipticYTile() ? view.getEllipticYTile() : view.getYTile();
|
||||
float w = view.getCenterPointX();
|
||||
float h = view.getCenterPointY();
|
||||
float ftileSize = view.getTileSize();
|
||||
|
@ -82,7 +82,13 @@ public class MapTileLayer extends BaseMapLayer {
|
|||
for (int j = 0; j < height; j++) {
|
||||
int leftPlusI = (int) FloatMath.floor((float) MapUtils
|
||||
.getTileNumberX(nzoom, MapUtils.getLongitudeFromTile(nzoom, left + i)));
|
||||
int topPlusJ = (int) FloatMath.floor((float) MapUtils.getTileNumberY(nzoom, MapUtils.getLatitudeFromTile(nzoom, top + j)));
|
||||
float topTileY;
|
||||
if(map.isEllipticYTile()){
|
||||
topTileY = (float) MapUtils.getTileEllipsoidNumberY(nzoom, MapUtils.getLatitudeFromTile(nzoom, top + j));
|
||||
} else {
|
||||
topTileY = (float) MapUtils.getTileNumberY(nzoom, MapUtils.getLatitudeFromTile(nzoom, top + j));
|
||||
}
|
||||
int topPlusJ = (int) FloatMath.floor(topTileY);
|
||||
float x1 = (left + i - tileX) * ftileSize + w;
|
||||
float y1 = (top + j - tileY) * ftileSize + h;
|
||||
String ordImgTile = mgr.calculateTileId(map, leftPlusI, topPlusJ, nzoom);
|
||||
|
|
|
@ -247,6 +247,13 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
return (float) MapUtils.getTileNumberY(getZoom(), latitude);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return y tile based on (int) zoom
|
||||
*/
|
||||
public float getEllipticYTile() {
|
||||
return (float) MapUtils.getTileEllipsoidNumberY(getZoom(), latitude);
|
||||
}
|
||||
|
||||
public void setZoom(float zoom) {
|
||||
if (mainLayer != null && zoom <= mainLayer.getMaximumShownMapZoom() && zoom >= mainLayer.getMinimumShownMapZoom()) {
|
||||
animatedDraggingThread.stopAnimating();
|
||||
|
@ -436,19 +443,19 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
try {
|
||||
boundsRect.set(0, 0, getWidth(), getHeight());
|
||||
calculateTileRectangle(boundsRect, w, h, tileX, tileY, tilesRect);
|
||||
int left = (int) FloatMath.floor(tilesRect.left);
|
||||
int top = (int) FloatMath.floor(tilesRect.top);
|
||||
latlonRect.top = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.top);
|
||||
latlonRect.left = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.left);
|
||||
latlonRect.bottom = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.bottom);
|
||||
latlonRect.right = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.right);
|
||||
if(nightMode){
|
||||
canvas.drawARGB(255, 220, 220, 220);
|
||||
canvas.drawARGB(255, 100, 100, 100);
|
||||
} else {
|
||||
canvas.drawARGB(255, 240, 240, 240);
|
||||
canvas.drawARGB(255, 225, 225, 225);
|
||||
}
|
||||
// TODO map
|
||||
// float ftileSize = getTileSize();
|
||||
// int left = (int) FloatMath.floor(tilesRect.left);
|
||||
// int top = (int) FloatMath.floor(tilesRect.top);
|
||||
// int width = (int) FloatMath.ceil(tilesRect.right - left);
|
||||
// int height = (int) FloatMath.ceil(tilesRect.bottom - top);
|
||||
// for (int i = 0; i < width; i++) {
|
||||
|
|
|
@ -3,290 +3,114 @@ package net.osmand.plus.views;
|
|||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.map.TileSourceManager.TileSourceTemplate;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.ResourceManager;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.BitmapFactory.Options;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.util.FloatMath;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class YandexTrafficLayer implements OsmandMapLayer {
|
||||
public class YandexTrafficLayer extends MapTileLayer {
|
||||
|
||||
private static final long DELTA = 60000;
|
||||
private OsmandMapTileView view;
|
||||
private static final long DELTA = 10 * 60 * 1000;
|
||||
|
||||
private long lastTimestampUpdated;
|
||||
private String mTimestamp = null;
|
||||
private Rect pixRect;
|
||||
private RectF tileRect;
|
||||
private boolean visible = false;
|
||||
private Handler handler = null;
|
||||
private static final Log log = LogUtil.getLog(YandexTrafficLayer.class);
|
||||
|
||||
private Map<String, Bitmap> tiles = new LinkedHashMap<String, Bitmap>();
|
||||
|
||||
private Rect srcImageRect = new Rect(0, 0, 256, 256);
|
||||
private RectF dstImageRect = new RectF();
|
||||
|
||||
protected int cMinX;
|
||||
protected int cMaxX;
|
||||
protected int cMinY;
|
||||
protected int cMaxY;
|
||||
protected int cZoom;
|
||||
private Paint paint;
|
||||
|
||||
@Override
|
||||
public void initLayer(OsmandMapTileView view) {
|
||||
this.view = view;
|
||||
pixRect = new Rect();
|
||||
tileRect = new RectF();
|
||||
if(isVisible()){
|
||||
startThread();
|
||||
}
|
||||
paint = new Paint();
|
||||
paint.setFilterBitmap(true);
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
private final static Log log = LogUtil.getLog(MapTileLayer.class);
|
||||
private final static String YANDEX_PREFFIX = ".YandexTraffic_";
|
||||
private boolean updateThreadRan = false;
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
if(this.visible != visible){
|
||||
if(isVisible() != visible){
|
||||
if(visible){
|
||||
Toast.makeText(view.getContext(), R.string.thanks_yandex_traffic, Toast.LENGTH_LONG).show();
|
||||
startThread();
|
||||
} else {
|
||||
stopThread();
|
||||
}
|
||||
this.visible = visible;
|
||||
}
|
||||
super.setVisible(visible);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void startThread(){
|
||||
if (handler == null) {
|
||||
new Thread("Yandex traffic") { //$NON-NLS-1$
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RectF latlonRect, RectF tilesRect, boolean nightMode) {
|
||||
updateTimeStamp();
|
||||
super.onDraw(canvas, latlonRect, tilesRect, nightMode);
|
||||
}
|
||||
|
||||
protected void updateTimeStamp() {
|
||||
if ((mTimestamp == null || (System.currentTimeMillis() - lastTimestampUpdated) > DELTA) && !updateThreadRan) {
|
||||
updateThreadRan = true;
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
handler = new Handler();
|
||||
Looper.loop();
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private synchronized void stopThread(){
|
||||
if (handler != null) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.myLooper().quit();
|
||||
}
|
||||
});
|
||||
handler = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void checkedCachedImages(int zoom){
|
||||
boolean inside = cMinX <= tileRect.left && tileRect.right <= cMaxX && cMinY <= tileRect.top && tileRect.bottom <= cMaxY ;
|
||||
if (!inside || (cZoom != zoom)) {
|
||||
cMinX = ((int) tileRect.left);
|
||||
cMaxX = ((int) tileRect.right ) + 1;
|
||||
cMinY = ((int) tileRect.top);
|
||||
cMaxY = ((int) tileRect.bottom ) + 1;
|
||||
if (cZoom != zoom) {
|
||||
cZoom = zoom;
|
||||
clearCache();
|
||||
}
|
||||
if (handler != null) {
|
||||
if (!handler.hasMessages(1)) {
|
||||
Message msg = Message.obtain(handler, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateCachedImages(cMinX, cMaxX, cMinY, cMaxY, cZoom, 0);
|
||||
}
|
||||
});
|
||||
msg.what = 1;
|
||||
handler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateCachedImages(int tMinX, int tMaxX, int tMinY, int tMaxY, int tZoom, int callInd){
|
||||
try {
|
||||
updateTimeStamp();
|
||||
if (mTimestamp != null) {
|
||||
// clear before to save memory
|
||||
Set<String> unusedTiles = new HashSet<String>(tiles.keySet());
|
||||
for (int i = cMinX; i <= cMaxX; i++) {
|
||||
for (int j = cMinY; j <= cMaxY; j++) {
|
||||
String tileId = calculateTileId(i, j, cZoom);
|
||||
unusedTiles.remove(tileId);
|
||||
try {
|
||||
updateTimeStampImpl();
|
||||
} finally {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
for(String s : unusedTiles){
|
||||
tiles.remove(s);
|
||||
}
|
||||
for (int i = tMinX; i <= tMaxX; i++) {
|
||||
for (int j = tMinY; j <= tMaxY; j++) {
|
||||
String tileId = calculateTileId(i, j, tZoom);
|
||||
if(tiles.get(tileId) == null){
|
||||
downloadTile(tileId, i, j, tZoom, mTimestamp);
|
||||
if(tMaxX != cMaxX || tMinX!= cMinX || tMaxY != cMaxY || tMinY!= cMinY || tZoom !=cZoom){
|
||||
return;
|
||||
}
|
||||
view.refreshMap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("IOException", e); //$NON-NLS-1$
|
||||
} catch (OutOfMemoryError e) {
|
||||
tiles.clear();
|
||||
System.gc();
|
||||
if(callInd == 0){
|
||||
updateCachedImages(tMinX, tMaxX, tMinY, tMaxY, tZoom, 1);
|
||||
}
|
||||
}, "UpdateYandexTraffic").start();
|
||||
}
|
||||
}
|
||||
|
||||
private StringBuilder builder = new StringBuilder(50);
|
||||
protected synchronized String calculateTileId(int tileX, int tileY, int zoom){
|
||||
builder.setLength(0);
|
||||
builder.append(zoom).append('/').append(tileX).append('/').append(tileY);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
protected void downloadTile(String tileId, int tileX, int tileY, int zoom, String timeStamp) {
|
||||
if (zoom > 17) {
|
||||
return;
|
||||
}
|
||||
String u = "http://jgo.maps.yandex.net/tiles?l=trf&x=" + tileX + "&y=" + tileY + "&z=" + zoom + "&tm=" + timeStamp; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
|
||||
long time = System.currentTimeMillis();
|
||||
try {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Start loading traffic : " + u); //$NON-NLS-1$
|
||||
|
||||
protected void updateTimeStampImpl() {
|
||||
if (mTimestamp == null || (System.currentTimeMillis() - lastTimestampUpdated) > DELTA) {
|
||||
log.info("Updating timestamp"); //$NON-NLS-1$
|
||||
try {
|
||||
BufferedInputStream in = new BufferedInputStream(new URL("http://jgo.maps.yandex.net/trf/stat.js").openStream(), 1024); //$NON-NLS-1$
|
||||
ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
|
||||
BufferedOutputStream out = new BufferedOutputStream(dataStream, 1024);
|
||||
Algoritms.streamCopy(in, out);
|
||||
out.flush();
|
||||
String str = dataStream.toString();
|
||||
// JSONObject json = new JSONObject(str.replace("YMaps.TrafficLoader.onLoad(\"stat\",", "").replace("});", "}"));
|
||||
int start = str.indexOf("timestamp:"); //$NON-NLS-1$
|
||||
start = str.indexOf("\"", start) + 1; //$NON-NLS-1$
|
||||
int end = str.indexOf("\"", start); //$NON-NLS-1$
|
||||
// exception case
|
||||
if (start < 0 || end < 0) {
|
||||
return;
|
||||
}
|
||||
String newTimestamp = str.substring(start, end);
|
||||
lastTimestampUpdated = System.currentTimeMillis();
|
||||
Algoritms.closeStream(in);
|
||||
Algoritms.closeStream(out);
|
||||
log.info("Timestamp updated"); //$NON-NLS-1$
|
||||
if (!newTimestamp.equals(mTimestamp)) {
|
||||
mTimestamp = newTimestamp;
|
||||
TileSourceTemplate template = new TileSourceTemplate(YANDEX_PREFFIX + mTimestamp,
|
||||
"http://jgo.maps.yandex.net/tiles?l=trf&x={1}&y={2}&z={3}&tm" + mTimestamp, ".png", 17, 7, 256, 8, 18000);
|
||||
clearCache();
|
||||
this.map = template;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.info("Exception while updating yandex traffic template", e);
|
||||
}
|
||||
InputStream is = new URL(u).openStream();
|
||||
Options opt = new BitmapFactory.Options();
|
||||
Bitmap bmp = BitmapFactory.decodeStream(is, null, opt);
|
||||
is.close();
|
||||
tiles.put(tileId, bmp);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Loaded traffic : " + tileId + " " + (System.currentTimeMillis() - time) + "ms " + tiles.size()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// File not found very often exception
|
||||
log.error("Traffic loading failed " + e.getMessage()); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, boolean nightMode) {
|
||||
if (visible) {
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
float tileY = (float) MapUtils.getTileEllipsoidNumberY(view.getZoom(), view.getLatitude());
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(), view.getCenterPointY(), view.getXTile(), tileY, tileRect);
|
||||
double topLat = MapUtils.getLatitudeFromEllipsoidTileY(view.getZoom(), (int) tileRect.top);
|
||||
double leftLon = MapUtils.getLongitudeFromTile(view.getZoom(), (int) tileRect.left);
|
||||
int x = view.getMapXForPoint(leftLon);
|
||||
int y = view.getMapYForPoint(topLat);
|
||||
checkedCachedImages(view.getZoom());
|
||||
float right = FloatMath.ceil(tileRect.right);
|
||||
float bottom = FloatMath.ceil(tileRect.bottom);
|
||||
for (int i = (int) tileRect.left; i <= right; i++) {
|
||||
for (int j = (int) tileRect.top; j <= bottom; j++) {
|
||||
String tId = calculateTileId(i, j, view.getZoom());
|
||||
if (tiles.get(tId) != null) {
|
||||
dstImageRect.top = y + (j - (int) tileRect.top) * view.getTileSize();
|
||||
dstImageRect.left = x + (i - (int) tileRect.left) * view.getTileSize();
|
||||
dstImageRect.bottom = dstImageRect.top + view.getTileSize();
|
||||
dstImageRect.right = dstImageRect.left + view.getTileSize();
|
||||
canvas.drawBitmap(tiles.get(tId), srcImageRect, dstImageRect, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateTimeStamp() throws IOException {
|
||||
if (mTimestamp == null || (System.currentTimeMillis() - lastTimestampUpdated) > DELTA) {
|
||||
log.info("Updating timestamp"); //$NON-NLS-1$
|
||||
BufferedInputStream in = new BufferedInputStream(new URL("http://jgo.maps.yandex.net/trf/stat.js").openStream(), 1024); //$NON-NLS-1$
|
||||
ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
|
||||
BufferedOutputStream out = new BufferedOutputStream(dataStream, 1024);
|
||||
Algoritms.streamCopy(in, out);
|
||||
out.flush();
|
||||
String str = dataStream.toString();
|
||||
// JSONObject json = new JSONObject(str.replace("YMaps.TrafficLoader.onLoad(\"stat\",", "").replace("});", "}"));
|
||||
int start = str.indexOf("timestamp:"); //$NON-NLS-1$
|
||||
start = str.indexOf("\"", start) + 1; //$NON-NLS-1$
|
||||
int end = str.indexOf("\"", start); //$NON-NLS-1$
|
||||
// exception case
|
||||
if (start < 0 || end < 0) {
|
||||
return;
|
||||
}
|
||||
mTimestamp = str.substring(start, end);
|
||||
lastTimestampUpdated = System.currentTimeMillis();
|
||||
Algoritms.closeStream(in);
|
||||
Algoritms.closeStream(out);
|
||||
log.info("Timestamp updated"); //$NON-NLS-1$
|
||||
clearCache();
|
||||
}
|
||||
public void destroyLayer() {
|
||||
super.destroyLayer();
|
||||
clearCache();
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
tiles.clear();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean drawInScreenPixels() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongPressEvent(PointF point) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(PointF point) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyLayer() {
|
||||
if(isVisible()){
|
||||
stopThread();
|
||||
File dir = view.getSettings().extendOsmandPath(ResourceManager.TILES_PATH);
|
||||
for (File ds : dir.listFiles()) {
|
||||
if (ds.isDirectory() && ds.getName().startsWith(YANDEX_PREFFIX)) {
|
||||
Algoritms.removeAllFiles(ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue