fix multitype sort

git-svn-id: https://osmand.googlecode.com/svn/trunk@526 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-09-26 22:37:21 +00:00
parent 1a52d0fb51
commit ca47dc056f
5 changed files with 171 additions and 163 deletions

View file

@ -8,49 +8,40 @@ package net.osmand;
public class ToDoConstants {
// TODO max 94
// TODO max 96
// FOR 0.4 beta RELEASE
// ! 89. Transport redesign UI (enable run from context menu, switch go to goal/not) !
// ! 95. Show progress while map rendered and loaded
// 90. Use Junidecode library on the client for english translation (for map rendering and other save disk space)
//
// !_25. Add all attributes needed for routing (highway attributes, turn_restrictions)
// !_22. Verify all POI has a point_type (in order to search them)
// !_1 . VELCOM
// !_18. Fix loading map data in rotated mode (check properly boundaries) +/-
// not required
// ! 81. Add some objects to POI category (1) to add them into OSM 2) to help navigation)
// highway (?), traffic_calming (?), barrier(?), military(?-), landuse (?), office(?), man_made(?), power(?),
// railway( station, subway?) - issue 17
// ! 87. Use network availability for defining loading tiles from internet.
// ! 89. Transport redesign UI (enable run from context menu, switch go to goal/not) !
// ! 95. Show progress while map rendered and loaded
// 90. Use Junidecode library on the client for english translation (for map rendering and other save disk space)
// outside base 0.4 release
// _19. colors for road trunk and motorway
// _12. Fix : find proper location for streets ! centralize them (when create index)?
// _28. Fix freeze while map downloading (?)
// Outside base 0.4 release
// 86. Allow to add/edit custom tags to POI objects.
// 91. Invent binary format (minimize disk space, maximize speed)
// 92. Replace poi index with standard map index and unify POI categories
// 93. Implement multitype vector objects (?) - building with fence, road & tram ... (binary format)
// 94. Revise index to decrease their size (especially address) - replace to float lat/lon
// TODO small improvements for release :
// 19. colors for road trunk and motorway
// 12. Fix : find proper location for streets ! centralize them (when create index)?
// 24. +! define clockwise/anticlockwise on android for closed path to understand area outised or inside
// fix Rendering for incompleted rings,
// fix Index Creator : 1) determine clockwise area (inverse if needed)+ 2) index low level multipolygon pass param +
// 3) pass inverse to low level indexes+ 4) coastline / add area +
// 5) identify case when there is only inner boundary (!!!!) +
// 26. Move leisure below forest and grass layer (footway/cycleway below unspecified)
// 25. Add all attributes needed for routing (highway attributes, turn_restrictions)
// 27. Fix bug with some buildings in AMS (WTC) that have fence(?)
// 28. Fix freeze while map downloading
// TODO Improvements :
// 1! VELCOM
// +17. Implement multipolygons to polygons (!?) + coastline - (todo indexCreator)
// +23! Remove one bit from type!
//+-18. Fix loading map data in rotated mode (check properly boundaries)
// 22. Verify all POI has a point_type (in order to search them)
// 94. Revise index to decrease their size (especially address) - replace to float lat/lon and remove for POI
// eng_name, possibly remove en part for adress
///////////////////////////// UNKNOWN STATE ////////////////////
// Unscheduled (complex)
// 65. Intermediate points - for better control routing, to avoid traffic jams ...(?)
// 63. Support simple offline routing(require new index file) (?)
// 63. Support simple offline routing(require index file with turn restrictions etc) (?)
// Not clear if it is really needed
// 69. Add phone information to POI
@ -59,6 +50,7 @@ public class ToDoConstants {
// 83. Add monitoring service to send locations to internet (?)
// DONE ANDROID :
// 93. Implement multitype vector objects - building with fence, road & tram ...
// DONE SWING
// 12. Reinvent UI of swing app (remove Region object and clear other MapObject)

View file

@ -1710,11 +1710,11 @@ public class IndexCreator {
// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/belarus_nodes.tmp.odb"));
// creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/belarus_2010_09_03.osm.bz2"), new ConsoleProgressImplementation(3), null);
// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/ams.tmp.odb"));
// creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/ams_part_map.osm"), new ConsoleProgressImplementation(3), null);
creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/ams.tmp.odb"));
creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/ams_part_map.osm"), new ConsoleProgressImplementation(3), null);
creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/den_haag.tmp.odb"));
creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/den_haag.osm"), new ConsoleProgressImplementation(3), null);
// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/den_haag.tmp.odb"));
// creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/den_haag.osm"), new ConsoleProgressImplementation(3), null);
// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/one.tmp.odb"));
// creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/one_multipolygon.osm"), new ConsoleProgressImplementation(3), null);

View file

@ -93,23 +93,47 @@ public class MapRenderObject {
public float getMapOrder(){
if (order == -1) {
int oType = MapRenderingTypes.getMainObjectType(type >> 1);
int sType = MapRenderingTypes.getObjectSubType(type >> 1);
if (isMultiPolygon() || isPolygon()) {
// 1 - 9
if (oType == MapRenderingTypes.MAN_MADE && sType == MapRenderingTypes.SUBTYPE_BUILDING) {
// draw over lines
order = getOrder(getMainType());
}
return order;
}
public static float getOrder(int wholeType) {
float order = 0;
int t = wholeType & 3;
int oType = MapRenderingTypes.getMainObjectType(wholeType);
int sType = MapRenderingTypes.getObjectSubType(wholeType);
int layer = MapRenderingTypes.getWayLayer(wholeType);
if (t == MapRenderingTypes.MULTY_POLYGON_TYPE || t == MapRenderingTypes.POLYGON_TYPE) {
// 1 - 9
if (oType == MapRenderingTypes.MAN_MADE && sType == MapRenderingTypes.SUBTYPE_BUILDING) {
// draw over lines
if(layer != 1){
order = 64;
} else {
order = 2;
}
} else {
if(layer == 1){
order = 0.5f;
} else if(layer == 2){
// over lines
order = 64;
} else if (oType == MapRenderingTypes.LANDUSE) {
switch (sType) {
case 5: case 6: case 15: case 18: case 20: case 23:
case 5:
case 6:
case 15:
case 18:
case 20:
case 23:
order = 1;
break;
case 22:
order = 5;
break;
default:
order = 1.5f;
order = 1f;
break;
}
} else if (oType == MapRenderingTypes.LEISURE) {
@ -117,66 +141,66 @@ public class MapRenderObject {
case 3:
case 10:
case 13:
order = 4;
order = 2;
break;
case 6:
order = 4;
default:
order = 1;
order = 2;
break;
}
} else if (oType == MapRenderingTypes.POWER) {
order = 4;
} else if (oType == MapRenderingTypes.WATERWAY || oType == MapRenderingTypes.NATURAL) {
} else if (oType == MapRenderingTypes.NATURAL) {
if (order == 5) {
// coastline
order = 0.5f;
} else if (order == 21) {
// water
order = 5;
} else {
order = 1;
}
} else if (oType == MapRenderingTypes.WATERWAY) {
// water 5
order = 5;
} else {
order = 1;
}
} else if (isPolyLine()) {
// 10 - 68
int layer = MapRenderingTypes.getWayLayer(type >> 1);
if(layer == 1 && oType != MapRenderingTypes.RAILWAY){
// not subway especially
order = 10;
} else if(layer == 2) {
order = 67; // over buildings
} else if (oType == MapRenderingTypes.HIGHWAY) {
order = 32 - sType + 24;
if(sType == MapRenderingTypes.PL_HW_MOTORWAY){
// TODO ? that was done only to have good overlay
// but really it should be motorway_link have -= 10
order -= 2;
}
} else if (oType == MapRenderingTypes.RAILWAY) {
order = 58;
} else if (oType == MapRenderingTypes.AERIALWAY) {
order = 68; // over buildings
} else if (oType == MapRenderingTypes.POWER) {
order = 68; // over buildings
} else if (oType == MapRenderingTypes.ADMINISTRATIVE) {
order = 62;
} else if (oType == MapRenderingTypes.WATERWAY) {
order = 18;
} else {
order = 10;
}
} else {
order = 128;
}
} else if (t == MapRenderingTypes.POLYLINE_TYPE) {
// 10 - 68
if(layer == 1 && oType != MapRenderingTypes.RAILWAY){
// not subway especially
order = 10;
} else if(layer == 2) {
order = 67; // over buildings
} else if (oType == MapRenderingTypes.HIGHWAY) {
order = 32 - sType + 24;
if(sType == MapRenderingTypes.PL_HW_MOTORWAY){
// TODO ? that was done only to have good overlay
// but really it should be motorway_link have -= 10
order -= 2;
}
} else if (oType == MapRenderingTypes.RAILWAY) {
order = 58;
} else if (oType == MapRenderingTypes.AERIALWAY) {
order = 68; // over buildings
} else if (oType == MapRenderingTypes.POWER) {
order = 68; // over buildings
} else if (oType == MapRenderingTypes.ADMINISTRATIVE) {
order = 62;
} else if (oType == MapRenderingTypes.WATERWAY) {
order = 18;
} else {
order = 10;
}
} else {
order = 128;
}
return order;
}
private boolean isMultiPolygon(){
return ((type >> 1) & 3) == MapRenderingTypes.MULTY_POLYGON_TYPE;
}
private boolean isPolygon(){
return ((type >> 1) & 3) == MapRenderingTypes.POLYGON_TYPE;
}
private boolean isPolyLine(){
return ((type >> 1) & 3) == MapRenderingTypes.POLYLINE_TYPE;
}
}

View file

@ -17,16 +17,16 @@ import net.osmand.osm.OSMSettings.OSMTagKey;
*/
public class MapRenderingTypes {
// TODO Internet access bits for point, polygon
/** standard schema :
Last bit describe whether types additional exist
polygon : aaaaa ttttt 11 : 26 bits + 6 bits for special info
t - object type, a - area subtype, p - point object type, s - point object subtype
multi :
polyline : ppppp ttttt 10 : 13 bits + 19 bits for special info
t - object type, p - polyline object type,
point : ssssssss ttttt 10 : 16 bits + 16 bits for special info
t - object type, a - subtype
Last bit describe whether types additional exist (it is needed only for main type, other consists only from 15 bits)
polygon : aaaaa ttttt 11 _ : 15 bits
multi : aaaaa ttttt 00 _ : 15 bits
t - object type, a - area subtype,l - layer
polyline : ll ppppp ttttt 10 _ : 15 bits + 2 bits for special info (+16)
t - object type, p - polyline object type, l - layer
point : ssssssss ttttt 10 _ : 16 bits
t - object type, a - subtype
*/
public final static int MULTY_POLYGON_TYPE = 0;
@ -53,7 +53,6 @@ public class MapRenderingTypes {
public final static char REF_CHAR = ((char)0x0019);
// TODO Internet access bits for point
public final static int HIGHWAY = 1;
public final static int BARRIER = 2;
public final static int WATERWAY = 3;
@ -128,26 +127,6 @@ public class MapRenderingTypes {
}
}
/*public static int getPolygonSubType(int type) {
}
public static int getPolygonPointType(int type) {
return (type >> (TYPE_MASK_LEN + OBJ_TYPE_MASK_LEN + PG_SUBTYPE_MASK_LEN)) & OBJ_TYPE_MASK;
}
public static int getPolygonPointSubType(int type) {
return (type >> (TYPE_MASK_LEN + OBJ_TYPE_MASK_LEN + PG_SUBTYPE_MASK_LEN + OBJ_TYPE_MASK_LEN)) & PO_SUBTYPE_MASK;
}
public static int getPolylineSubType(int type) {
return (type >> (TYPE_MASK_LEN + OBJ_TYPE_MASK_LEN)) & PL_SUBTYPE_MASK;
}
public static int getPointSubType(int type) {
return (type >> (TYPE_MASK_LEN + OBJ_TYPE_MASK_LEN)) & PO_SUBTYPE_MASK;
}
*/
// stored information to convert from osm tags to int type
private static Map<String, MapRulType> types = null;
@ -300,7 +279,8 @@ public class MapRenderingTypes {
}
} else if (polygon && (pr == POLYGON_WITH_CENTER_TYPE || pr == POLYGON_TYPE)) {
boolean prevPoint = (polylineType == 0 && polygonType == 0);
polygonType = (multipolygon ? MULTY_POLYGON_TYPE : POLYGON_TYPE) | (typeVal & MASK_12);
int attr = getLayerAttributes(e) << 12;
polygonType = (multipolygon ? MULTY_POLYGON_TYPE : POLYGON_TYPE) | (typeVal & MASK_12) | attr;
if (prevPoint){
addTypes.add(0, polygonType);
} else {
@ -351,7 +331,7 @@ public class MapRenderingTypes {
}
public static boolean isOneWayWay(int type){
return ((1 << 14) & type) > 0;
return ((1 << 15) & type) > 0;
}
// 0 - normal, 1 - under, 2 - bridge,over
@ -591,6 +571,7 @@ public class MapRenderingTypes {
register("barrier", "hedge", BARRIER, 1, POLYLINE_TYPE); //$NON-NLS-1$ //$NON-NLS-2$
register("natural", "hedge", BARRIER, 1, POLYLINE_TYPE); //$NON-NLS-1$ //$NON-NLS-2$
register("barrier", "fence", BARRIER, 2, POLYLINE_TYPE); //$NON-NLS-1$ //$NON-NLS-2$
register("fenced", "yes", BARRIER, 2, POLYLINE_TYPE); //$NON-NLS-1$ //$NON-NLS-2$
register("barrier", "wall", BARRIER, 3, POLYLINE_TYPE); //$NON-NLS-1$ //$NON-NLS-2$
register("barrier", "ditch", BARRIER, 1, POLYLINE_TYPE); //$NON-NLS-1$ //$NON-NLS-2$
register("barrier", "retaining_wall", BARRIER, 4, POLYLINE_TYPE); //$NON-NLS-1$ //$NON-NLS-2$

View file

@ -7,6 +7,7 @@ import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import net.osmand.LogUtil;
import net.osmand.R;
@ -38,7 +39,7 @@ import android.graphics.Shader.TileMode;
import android.text.TextPaint;
import android.util.FloatMath;
public class OsmandRenderer implements Comparator<MapRenderObject> {
public class OsmandRenderer {
private static final Log log = LogUtil.getLog(OsmandRenderer.class);
private TextPaint paintText;
@ -244,20 +245,36 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
return shaders.get(resId);
}
@Override
public int compare(MapRenderObject object1, MapRenderObject object2) {
float o1 = object1.getMapOrder();
float o2 = object2.getMapOrder();
return o1 < o2 ? -1 : (o1 == o2 ? 0 : 1);
private <K,T>void put(Map<K, List<T>> map, K k, T v, int init){
if(!map.containsKey(k)){
map.put(k, new ArrayList<T>(init));
}
map.get(k).add(v);
}
public Bitmap generateNewBitmap(int width, int height, float leftTileX, float topTileY,
List<MapRenderObject> objects, int zoom, float rotate) {
long now = System.currentTimeMillis();
// put in order map
int sz = objects.size();
int init = sz / 4;
TreeMap<Float, List<Integer>> orderMap = new TreeMap<Float, List<Integer>>();
for (int i = 0; i < sz; i++) {
MapRenderObject o = objects.get(i);
int mt = o.getMainType();
int sh = i << 8;
put(orderMap, MapRenderObject.getOrder(mt), sh + 1, init);
int s = o.getSecondType();
if (s != 0) {
put(orderMap, MapRenderObject.getOrder(s), sh + 2, init);
}
byte multiTypes = o.getMultiTypes();
for (int j = 0; j < multiTypes; j++) {
put(orderMap, MapRenderObject.getOrder(o.getAdditionalType(j)), sh + (j + 3), init);
}
}
Collections.sort(objects, this);
Bitmap bmp = null;
if (objects != null && !objects.isEmpty() && width > 0 && height > 0) {
// init rendering context
@ -275,8 +292,20 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
Canvas cv = new Canvas(bmp);
cv.drawRect(0, 0, bmp.getWidth(), bmp.getHeight(), paintFillEmpty);
for (MapRenderObject o : objects) {
draw(o, cv, rc);
for (List<Integer> list : orderMap.values()) {
for (Integer i : list) {
int ind = i >> 8;
int l = i & 0xff;
MapRenderObject obj = objects.get(ind);
if (l == 1) {
// show text only for main type
drawObj(obj, cv, rc, obj.getMainType(), true);
} else if (l == 2) {
drawObj(obj, cv, rc, obj.getSecondType(), false);
} else {
drawObj(obj, cv, rc, obj.getAdditionalType(l - 3), false);
}
}
}
for(IconDrawInfo icon : rc.iconsToDraw){
if(icon.resId != 0){
@ -451,22 +480,19 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
}
protected PointF drawObj(MapRenderObject obj, Canvas canvas, RenderingContext rc, int mainType, boolean renderText, PointF center) {
if(mainType == 0){
return center;
}
protected void drawObj(MapRenderObject obj, Canvas canvas, RenderingContext rc, int mainType, boolean renderText) {
int t = mainType & 3;
int type = MapRenderingTypes.getMainObjectType(mainType);
int subtype = MapRenderingTypes.getObjectSubType(mainType);
if(t == MapRenderingTypes.POINT_TYPE){
drawPoint(obj, canvas, rc, null, type, subtype, renderText);
drawPoint(obj, canvas, rc, type, subtype, renderText);
} else if(t == MapRenderingTypes.POLYLINE_TYPE){
drawPolyline(obj, canvas, rc, type, subtype, mainType);
} else {
if(t == MapRenderingTypes.MULTY_POLYGON_TYPE && !(obj instanceof MultyPolygon)){
return center;
return;
}
center = drawPolygon(obj, canvas, rc, type, subtype, t == MapRenderingTypes.MULTY_POLYGON_TYPE);
PointF center = drawPolygon(obj, canvas, rc, type, subtype, t == MapRenderingTypes.MULTY_POLYGON_TYPE);
String name = obj.getName();
if(name != null && center != null){
rc.clearText();
@ -479,31 +505,8 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
}
}
return center;
}
protected void draw(MapRenderObject obj, Canvas canvas, RenderingContext rc) {
int mainType = obj.getMainType();
int t = mainType & 3;
int sz = rc.textToDraw.size();
PointF center = null;
center = drawObj(obj, canvas, rc, mainType, sz == rc.textToDraw.size(), center);
if (t != MapRenderingTypes.POINT_TYPE) {
int second = obj.getSecondType();
if (second != 0) {
center = drawObj(obj, canvas, rc, second, sz == rc.textToDraw.size(), center);
}
if (obj.isMultitype()) {
byte ts = obj.getMultiTypes();
for (int k = 0; k < ts; k++) {
center = drawObj(obj, canvas, rc, obj.getAdditionalType(k), sz == rc.textToDraw.size(), center);
}
}
}
}
private PointF calcPoint(MapRenderObject o, int ind, RenderingContext rc){
rc.pointCount ++;
@ -613,16 +616,24 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
shaders.clear();
}
private void drawPoint(MapRenderObject obj, Canvas canvas, RenderingContext rc, PointF p, int type, int subtype, boolean renderText) {
if (p == null) {
p = calcPoint(obj, 0, rc);
private void drawPoint(MapRenderObject obj, Canvas canvas, RenderingContext rc, int type, int subtype, boolean renderText) {
int len = obj.getPointsLength();
PointF ps = new PointF(0, 0);
for (int i = 0; i < len; i++) {
PointF p = calcPoint(obj, i, rc);
ps.x += p.x;
ps.y += p.y;
}
if(len > 1){
ps.x /= len;
ps.y /= len;
}
int zoom = rc.zoom;
int resId = PointRenderer.getPointBitmap(zoom, type, subtype);
if(resId != 0){
IconDrawInfo ico = new IconDrawInfo();
ico.x = p.x;
ico.y = p.y;
ico.x = ps.x;
ico.y = ps.y;
ico.resId = resId;
rc.iconsToDraw.add(ico);
}
@ -633,7 +644,7 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
n = renderObjectText(n, subtype, type, zoom, true, rc);
if (rc.textSize > 0 && n != null) {
TextDrawInfo info = new TextDrawInfo(n);
info.fillProperties(rc, p.x, p.y);
info.fillProperties(rc, ps.x, ps.y);
rc.textToDraw.add(info);
}
}