improve rendering

git-svn-id: https://osmand.googlecode.com/svn/trunk@514 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-09-20 19:23:55 +00:00
parent 5d851e8e6b
commit 56e60979b0
4 changed files with 79 additions and 30 deletions

View file

@ -266,7 +266,8 @@ public class MapRenderRepositories {
} }
try { try {
int count = 0; int count = 0;
List<MapRenderObject> local = new ArrayList<MapRenderObject>(); cObjects = new ArrayList<MapRenderObject>();
System.gc(); // to clear previous objects
Set<Long> ids = new LinkedHashSet<Long>(); Set<Long> ids = new LinkedHashSet<Long>();
for (Connection c : connections.keySet()) { for (Connection c : connections.keySet()) {
RectF r = connections.get(c); RectF r = connections.get(c);
@ -294,24 +295,25 @@ public class MapRenderRepositories {
try { try {
while (result.next()) { while (result.next()) {
long id = result.getLong(1); long id = result.getLong(1);
if(ids.contains(id)){ if (PerformanceFlags.checkForDuplicateObjectIds) {
// do not add object twice if (ids.contains(id)) {
continue; // do not add object twice
continue;
}
ids.add(id);
} }
ids.add(id);
MapRenderObject obj = new MapRenderObject(id); MapRenderObject obj = new MapRenderObject(id);
obj.setData(result.getBytes(2)); obj.setData(result.getBytes(2));
obj.setName(result.getString(3)); obj.setName(result.getString(3));
obj.setType(result.getInt(4)); obj.setType(result.getInt(4));
count++; count++;
local.add(obj); cObjects.add(obj);
} }
} finally { } finally {
result.close(); result.close();
} }
} }
cObjects = local;
log.info(String log.info(String
.format("Search has been done in %s ms. %s results were found.", System.currentTimeMillis() - now, count)); //$NON-NLS-1$ .format("Search has been done in %s ms. %s results were found.", System.currentTimeMillis() - now, count)); //$NON-NLS-1$
} catch (java.sql.SQLException e) { } catch (java.sql.SQLException e) {

View file

@ -100,8 +100,8 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
// use to calculate points // use to calculate points
PointF tempPoint = new PointF(); PointF tempPoint = new PointF();
float cosRotate; float cosRotateTileSize;
float sinRotate; float sinRotateTileSize;
// These properties are used for rendering one object // These properties are used for rendering one object
// polyline props // polyline props
@ -255,8 +255,8 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
rc.width = width; rc.width = width;
rc.height = height; rc.height = height;
rc.tileDivisor = (int) (1 << (31 - zoom)); rc.tileDivisor = (int) (1 << (31 - zoom));
rc.cosRotate = FloatMath.cos((float) Math.toRadians(rotate)); rc.cosRotateTileSize = FloatMath.cos((float) Math.toRadians(rotate)) * TILE_SIZE;
rc.sinRotate = FloatMath.sin((float) Math.toRadians(rotate)); rc.sinRotateTileSize = FloatMath.sin((float) Math.toRadians(rotate)) * TILE_SIZE;
bmp = Bitmap.createBitmap(width, height, Config.RGB_565); bmp = Bitmap.createBitmap(width, height, Config.RGB_565);
Canvas cv = new Canvas(bmp); Canvas cv = new Canvas(bmp);
@ -287,6 +287,13 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
List<RectF> boundsNotPathIntersect = new ArrayList<RectF>(); List<RectF> boundsNotPathIntersect = new ArrayList<RectF>();
List<RectF> boundsPathIntersect = new ArrayList<RectF>(); List<RectF> boundsPathIntersect = new ArrayList<RectF>();
int size = rc.textToDraw.size(); int size = rc.textToDraw.size();
Comparator<RectF> c = new Comparator<RectF>(){
@Override
public int compare(RectF object1, RectF object2) {
return Float.compare(object1.left, object2.left);
}
};
next: for (int i = 0; i < size; i++) { next: for (int i = 0; i < size; i++) {
TextDrawInfo text = rc.textToDraw.get(i); TextDrawInfo text = rc.textToDraw.get(i);
if(text.text != null){ if(text.text != null){
@ -303,18 +310,51 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
bounds.set(text.centerX - 3 * text.textSize / 2, text.centerY - mes/2, bounds.set(text.centerX - 3 * text.textSize / 2, text.centerY - mes/2,
text.centerX + 3 * text.textSize / 2, text.centerY + mes/2); text.centerX + 3 * text.textSize / 2, text.centerY + mes/2);
} }
List<RectF> boundsIntersect = text.drawOnPath == null ? boundsNotPathIntersect : boundsPathIntersect; List<RectF> boundsIntersect = text.drawOnPath == null ? boundsNotPathIntersect : boundsPathIntersect;
final int diff = 3; if(boundsIntersect.isEmpty()){
final int diff2 = 15; boundsIntersect.add(bounds);
for(int j = 0; j < boundsIntersect.size() ; j++){ } else {
RectF b = boundsIntersect.get(j); final int diff = 3;
float x = Math.min(bounds.right, b.right) - Math.max(b.left, bounds.left); final int diff2 = 15;
float y = Math.min(bounds.bottom, b.bottom) - Math.max(b.top, bounds.top); // implement binary search
if((x > diff && y > diff2) || (x > diff2 && y > diff)){ int index = Collections.binarySearch(boundsIntersect, bounds, c);
continue next; if (index < 0) {
index = -(index + 1);
} }
// find sublist that is appropriate
int e = index;
while (e < boundsIntersect.size()) {
if (boundsIntersect.get(e).left < bounds.right) {
e++;
} else {
break;
}
}
int st = index - 1;
while (st >= 0) {
// that's not exact algorithm that replace comparison rect with each other
// because of that comparison that is not obvious
// (we store array sorted by left boundary, not by right) - that's euristic
if (boundsIntersect.get(st).right > bounds.left) {
st--;
} else {
break;
}
}
if (st < 0) {
st = 0;
}
for (int j = st; j < e; j++) {
RectF b = boundsIntersect.get(j);
float x = Math.min(bounds.right, b.right) - Math.max(b.left, bounds.left);
float y = Math.min(bounds.bottom, b.bottom) - Math.max(b.top, bounds.top);
if ((x > diff && y > diff2) || (x > diff2 && y > diff)) {
continue next;
}
}
// store in list sorted by left boundary
boundsIntersect.add(index, bounds);
} }
boundsIntersect.add(bounds);
// paintText.setShadowLayer(text.textShadow, 0, 0, Color.WHITE); // paintText.setShadowLayer(text.textShadow, 0, 0, Color.WHITE);
@ -446,12 +486,11 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
rc.pointCount ++; rc.pointCount ++;
float tx = o.getPoint31XTile(ind) / rc.tileDivisor; float tx = o.getPoint31XTile(ind) / rc.tileDivisor;
float ty = o.getPoint31YTile(ind) / rc.tileDivisor; float ty = o.getPoint31YTile(ind) / rc.tileDivisor;
float dTileX = tx - rc.leftX; float dTileX = tx - rc.leftX;
float dTileY = ty - rc.topY; float dTileY = ty - rc.topY;
float x = (rc.cosRotate * dTileX - rc.sinRotate * dTileY) * TILE_SIZE ; float x = rc.cosRotateTileSize * dTileX - rc.sinRotateTileSize * dTileY;
float y = (rc.sinRotate * dTileX + rc.cosRotate * dTileY) * TILE_SIZE ; float y = rc.sinRotateTileSize * dTileX + rc.cosRotateTileSize * dTileY;
rc.tempPoint.set(x, y); rc.tempPoint.set(x, y);
// rc.tempPoint.set(dTileX * TILE_SIZE, dTileY * TILE_SIZE);
if(rc.tempPoint.x >= 0 && rc.tempPoint.x < rc.width && if(rc.tempPoint.x >= 0 && rc.tempPoint.x < rc.width &&
rc.tempPoint.y >= 0 && rc.tempPoint.y < rc.height){ rc.tempPoint.y >= 0 && rc.tempPoint.y < rc.height){
rc.pointInsideCount++; rc.pointInsideCount++;

View file

@ -0,0 +1,12 @@
package net.osmand.render;
public class PerformanceFlags {
// TimeLoadingMap = Rendering (%25) + Searching(%40) + Other
// It is needed to not draw object twice if user have map index that intersects by boundaries
// Takes 25% TimeLoadingMap (?) - Long.valueOf - 12, add - 10, contains - 3.
public static boolean checkForDuplicateObjectIds = true;
}

View file

@ -25,7 +25,6 @@ public class GPXLayer implements OsmandMapLayer {
private RectF tileRect; private RectF tileRect;
private List<List<Location>> points = new ArrayList<List<Location>>(); private List<List<Location>> points = new ArrayList<List<Location>>();
private Paint paint; private Paint paint;
private Paint paintPoint;
private Path path; private Path path;
@ -38,7 +37,7 @@ public class GPXLayer implements OsmandMapLayer {
boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight()); boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight());
tileRect = new RectF(); tileRect = new RectF();
paint = new Paint(); paint = new Paint();
paint.setColor(Color.argb(190, 160, 10, 215)); paint.setColor(Color.argb(180, 160, 10, 215));
paint.setStyle(Style.STROKE); paint.setStyle(Style.STROKE);
paint.setStrokeWidth(14); paint.setStrokeWidth(14);
paint.setAntiAlias(true); paint.setAntiAlias(true);
@ -46,9 +45,6 @@ public class GPXLayer implements OsmandMapLayer {
paint.setStrokeJoin(Join.ROUND); paint.setStrokeJoin(Join.ROUND);
paintPoint = new Paint();
paintPoint.setColor(Color.argb(190, 160, 10, 215));
paintPoint.setStyle(Style.FILL_AND_STROKE);
path = new Path(); path = new Path();
} }