From af61106c7dbba973202baa4b20120f73d05f19f7 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sat, 26 Feb 2011 15:37:53 +0100 Subject: [PATCH] Improve index reading --- .../render/OsmandRenderingRulesParser.java | 7 ++-- .../net/osmand/render/BaseOsmandRender.java | 37 ++++++++++++++++ .../osmand/render/MapRenderRepositories.java | 33 ++++++++------- .../src/net/osmand/render/OsmandRenderer.java | 42 ++++++++----------- 4 files changed, 76 insertions(+), 43 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/render/OsmandRenderingRulesParser.java b/DataExtractionOSM/src/net/osmand/render/OsmandRenderingRulesParser.java index 4d500ee1ca..aa9166226f 100644 --- a/DataExtractionOSM/src/net/osmand/render/OsmandRenderingRulesParser.java +++ b/DataExtractionOSM/src/net/osmand/render/OsmandRenderingRulesParser.java @@ -12,6 +12,7 @@ import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import net.osmand.LogUtil; +import net.osmand.osm.MapRenderingTypes; import org.apache.commons.logging.Log; import org.xml.sax.Attributes; @@ -92,9 +93,9 @@ public class OsmandRenderingRulesParser { } - public final static int POINT_STATE = 1; - public final static int POLYGON_STATE = 2; - public final static int LINE_STATE = 3; + public final static int POINT_STATE = MapRenderingTypes.POINT_TYPE; + public final static int LINE_STATE = MapRenderingTypes.POLYLINE_TYPE; + public final static int POLYGON_STATE = MapRenderingTypes.POLYGON_TYPE; public final static int TEXT_STATE = 4; public final static int ORDER_STATE = 5; diff --git a/OsmAnd/src/net/osmand/render/BaseOsmandRender.java b/OsmAnd/src/net/osmand/render/BaseOsmandRender.java index 8a18e4493d..cce4c36636 100644 --- a/OsmAnd/src/net/osmand/render/BaseOsmandRender.java +++ b/OsmAnd/src/net/osmand/render/BaseOsmandRender.java @@ -198,6 +198,43 @@ public class BaseOsmandRender implements RenderingRuleVisitor { return ret; } + + public boolean isObjectVisible(String tag, String val, int zoom, int type) { + if (type == 0) { + // replace multipolygon with polygon + type = 3; + } + if (isObjectVisibleImpl(tag, val, zoom, type)) { + return true; + } + if (isObjectVisibleImpl(tag, null, zoom, type)) { + return true; + } + for (BaseOsmandRender d : dependRenderers) { + if (d.isObjectVisibleImpl(tag, val, zoom, type)) { + return true; + } + } + return false; + } + + + private boolean isObjectVisibleImpl(String tag, String val, int zoom, int type) { + if (rules[type] != null) { + Map> map = rules[type].get(tag); + if (map != null) { + List list = map.get(val); + if (list != null) { + for (FilterState f : list) { + if (f.minzoom <= zoom && (zoom <= f.maxzoom || f.maxzoom == -1)) { + return true; + } + } + } + } + } + return false; + } private float getObjectOrderImpl(String tag, String val, int type, int layer) { if (rules[OsmandRenderingRulesParser.ORDER_STATE] != null) { diff --git a/OsmAnd/src/net/osmand/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/render/MapRenderRepositories.java index a6a1d4c7c0..caab9f620e 100644 --- a/OsmAnd/src/net/osmand/render/MapRenderRepositories.java +++ b/OsmAnd/src/net/osmand/render/MapRenderRepositories.java @@ -24,6 +24,7 @@ import net.osmand.LogUtil; import net.osmand.OsmandSettings; import net.osmand.R; import net.osmand.RotatedTileBox; +import net.osmand.activities.OsmandApplication; import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; @@ -73,7 +74,6 @@ public class MapRenderRepositories { private RenderingContext currentRenderingContext; private SearchRequest searchRequest; private SharedPreferences prefs; - public MapRenderRepositories(Context context){ this.context = context; this.renderer = new OsmandRenderer(context); @@ -196,7 +196,7 @@ public class MapRenderRepositories { return false; } - private boolean loadVectorData(RectF dataBox, final int zoom){ + private boolean loadVectorData(RectF dataBox, final int zoom, BaseOsmandRender renderingType){ double cBottomLatitude = dataBox.bottom; double cTopLatitude = dataBox.top; double cLeftLongitude = dataBox.left; @@ -225,23 +225,14 @@ public class MapRenderRepositories { searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom); if (zoom < 15) { searchRequest.setSearchFilter(new BinaryMapIndexReader.SearchFilter() { - // not correct should be used map from rendering to display minzoom - TIntByteMap map = MapRenderingTypes.getDefault().getObjectTypeMinZoom(); @Override public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex root) { for (int j = 0; j < types.size(); j++) { int type = types.get(j); - if ((type & 3) == MapRenderingTypes.POINT_TYPE) { - // keep 13 bit after last 2 bits and - // 0111 1111 1111 1100 - type &= 0x7ffc; - } else { - // 0000 1111 1111 1100 - type &= 0xffc; - } - byte b = map.get(type); - if (b != 0 && b <= zoom) { + int mask = type & 3; + TagValuePair pair = root.decodeType(type); + if (renderingType.isObjectVisible(pair.tag, pair.value, zoom, mask)) { return true; } } @@ -311,12 +302,20 @@ public class MapRenderRepositories { currentRenderingContext = null; } try { + // find selected rendering type + Boolean renderDay = ((OsmandApplication)context.getApplicationContext()).getDaynightHelper().getDayNightRenderer(); + BaseOsmandRender renderingType = RendererRegistry.getRegistry().getCurrentSelectedRenderer(); + if(renderDay != null && renderingType != null && renderDay.booleanValue() != renderingType.isDayRender()){ + renderingType = RendererRegistry.getRegistry().getOppositeRendererForDayNight(renderingType); + } + // prevent editing requestedBox = new RotatedTileBox(tileRect); // calculate data box RectF dataBox = requestedBox.calculateLatLonBox(new RectF()); long now = System.currentTimeMillis(); + if (cObjectsBox.left > dataBox.left || cObjectsBox.top > dataBox.top || cObjectsBox.right < dataBox.right || cObjectsBox.bottom < dataBox.bottom) { // increase data box in order for rotate @@ -329,7 +328,7 @@ public class MapRenderRepositories { dataBox.top -= hi; dataBox.bottom += hi; } - boolean loaded = loadVectorData(dataBox, requestedBox.getZoom()); + boolean loaded = loadVectorData(dataBox, requestedBox.getZoom(), MapRenderingTypes.getDefault()); if (!loaded || checkWhetherInterrupted()) { return; } @@ -359,8 +358,10 @@ public class MapRenderRepositories { this.bmpLocation = tileRect; } + + renderer.generateNewBitmap(currentRenderingContext, cObjects, bmp, - OsmandSettings.usingEnglishNames(prefs), stepByStep ? notifyList : null); + OsmandSettings.usingEnglishNames(prefs), renderingType, stepByStep ? notifyList : null); if (checkWhetherInterrupted()) { currentRenderingContext = null; return; diff --git a/OsmAnd/src/net/osmand/render/OsmandRenderer.java b/OsmAnd/src/net/osmand/render/OsmandRenderer.java index 2ffb7e134e..36fa136e95 100644 --- a/OsmAnd/src/net/osmand/render/OsmandRenderer.java +++ b/OsmAnd/src/net/osmand/render/OsmandRenderer.java @@ -12,7 +12,6 @@ import java.util.List; import java.util.Map; import net.osmand.LogUtil; -import net.osmand.activities.OsmandApplication; import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapIndexReader.TagValuePair; import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; @@ -64,7 +63,6 @@ public class OsmandRenderer { private final Context context; - private BaseOsmandRender render; private DisplayMetrics dm; private static class TextDrawInfo { @@ -235,7 +233,6 @@ public class OsmandRenderer { paintFillEmpty = new Paint(); paintFillEmpty.setStyle(Style.FILL); paintFillEmpty.setColor(clFillScreen); - render = RendererRegistry.getRegistry().defaultRender(); dm = new DisplayMetrics(); WindowManager wmgr = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); wmgr.getDefaultDisplay().getMetrics(dm); @@ -270,18 +267,15 @@ public class OsmandRenderer { } - public Bitmap generateNewBitmap(RenderingContext rc, List objects, Bitmap bmp, boolean useEnglishNames, List notifyList) { + public Bitmap generateNewBitmap(RenderingContext rc, List objects, Bitmap bmp, boolean useEnglishNames, + BaseOsmandRender renderer, + List notifyList) { long now = System.currentTimeMillis(); - Boolean renderDay = ((OsmandApplication)context.getApplicationContext()).getDaynightHelper().getDayNightRenderer(); - render = RendererRegistry.getRegistry().getCurrentSelectedRenderer(); - if(renderDay != null && renderDay.booleanValue() != render.isDayRender()){ - render = RendererRegistry.getRegistry().getOppositeRendererForDayNight(render); - } // fill area Canvas cv = new Canvas(bmp); - if(render != null){ - int dc = render.getDefaultColor(); + if(renderer != null){ + int dc = renderer.getDefaultColor(); if(dc != 0){ paintFillEmpty.setColor(dc); } @@ -292,7 +286,7 @@ public class OsmandRenderer { int sz = objects.size(); int init = sz / 4; TFloatObjectHashMap orderMap = new TFloatObjectHashMap(); - if (render != null) { + if (renderer != null) { for (int i = 0; i < sz; i++) { BinaryMapDataObject o = objects.get(i); int sh = i << 8; @@ -300,7 +294,7 @@ public class OsmandRenderer { if (o instanceof MultyPolygon) { int mask = MapRenderingTypes.MULTY_POLYGON_TYPE; int layer = ((MultyPolygon) o).getLayer(); - put(orderMap, render.getObjectOrder(((MultyPolygon) o).getTag(), ((MultyPolygon) o).getValue(), + put(orderMap, renderer.getObjectOrder(((MultyPolygon) o).getTag(), ((MultyPolygon) o).getValue(), mask, layer), sh, init); } else { for (int j = 0; j < o.getTypes().length; j++) { @@ -315,7 +309,7 @@ public class OsmandRenderer { TagValuePair pair = o.getMapIndex().decodeType(MapRenderingTypes.getMainObjectType(wholeType), MapRenderingTypes.getObjectSubType(wholeType)); if (pair != null) { - put(orderMap, render.getObjectOrder(pair.tag, pair.value, mask, layer), sh + j, init); + put(orderMap, renderer.getObjectOrder(pair.tag, pair.value, mask, layer), sh + j, init); } } @@ -346,7 +340,7 @@ public class OsmandRenderer { BinaryMapDataObject obj = objects.get(ind); // show text only for main type - drawObj(obj, cv, rc, l, l == 0); + drawObj(obj, renderer, cv, rc, l, l == 0); objCount++; } @@ -575,10 +569,10 @@ public class OsmandRenderer { } - protected void drawObj(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int l, boolean renderText) { + protected void drawObj(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc, int l, boolean renderText) { rc.allObjects++; if (obj instanceof MultyPolygon) { - drawMultiPolygon(obj, canvas, rc); + drawMultiPolygon(obj, render,canvas, rc); } else { int mainType = obj.getTypes()[l]; int t = mainType & 3; @@ -586,12 +580,12 @@ public class OsmandRenderer { int subtype = MapRenderingTypes.getObjectSubType(mainType); TagValuePair pair = obj.getMapIndex().decodeType(type, subtype); if (t == MapRenderingTypes.POINT_TYPE) { - drawPoint(obj, canvas, rc, pair, renderText); + drawPoint(obj, render, canvas, rc, pair, renderText); } else if (t == MapRenderingTypes.POLYLINE_TYPE) { int layer = MapRenderingTypes.getNegativeWayLayer(mainType); - drawPolyline(obj, canvas, rc, pair, layer); + drawPolyline(obj, render, canvas, rc, pair, layer); } else if (t == MapRenderingTypes.POLYGON_TYPE) { - drawPolygon(obj, canvas, rc, pair); + drawPolygon(obj, render, canvas, rc, pair); } else { if (t == MapRenderingTypes.MULTY_POLYGON_TYPE && !(obj instanceof MultyPolygon)) { // log this situation @@ -645,7 +639,7 @@ public class OsmandRenderer { shaders.clear(); } - private void drawMultiPolygon(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc) { + private void drawMultiPolygon(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc) { String tag = ((MultyPolygon)obj).getTag(); String value = ((MultyPolygon)obj).getValue(); if(render == null || tag == null){ @@ -701,7 +695,7 @@ public class OsmandRenderer { } - private void drawPolygon(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, TagValuePair pair) { + private void drawPolygon(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc, TagValuePair pair) { if(render == null || pair == null){ return; @@ -757,7 +751,7 @@ public class OsmandRenderer { return; } - private void drawPoint(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, TagValuePair pair, boolean renderText) { + private void drawPoint(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc, TagValuePair pair, boolean renderText) { if(render == null || pair == null){ return; } @@ -804,7 +798,7 @@ public class OsmandRenderer { - private void drawPolyline(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, TagValuePair pair, int layer) { + private void drawPolyline(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc, TagValuePair pair, int layer) { if(render == null || pair == null){ return; }