implement vector rendering menu options

git-svn-id: https://osmand.googlecode.com/svn/trunk@687 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-11-22 19:38:35 +00:00
parent b0a984cc91
commit 1bf926ad69
14 changed files with 288 additions and 51 deletions

View file

@ -2525,7 +2525,7 @@ public class IndexCreator {
// creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/minsk.osm"), new ConsoleProgressImplementation(3), null);
creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/belarus_nodes.tmp.odb"));
creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/belarus.osm.bz2"), new ConsoleProgressImplementation(3), null);
creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/belarus.osm.pbf"), 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);

View file

@ -88,7 +88,7 @@ public class OsmandRenderingRulesParser {
*/
public void visitRule(int state, FilterState filter);
public void rendering(String name, String depends);
public void rendering(String name, String depends, int defaultColor);
}
@ -143,7 +143,12 @@ public class OsmandRenderingRulesParser {
FilterState st = parseFilterAttributes(attributes);
((SwitchState)stack.peek()).filters.add(st);
} else if("renderer".equals(name)){ //$NON-NLS-1$
visitor.rendering(attributes.getValue("name"), attributes.getValue("depends")); //$NON-NLS-1$ //$NON-NLS-2$
String dc = attributes.getValue("defaultColor");
int defaultColor = 0;
if(dc != null && dc.length() > 0){
defaultColor = parseColor(dc);
}
visitor.rendering(attributes.getValue("name"), attributes.getValue("depends"), defaultColor); //$NON-NLS-1$ //$NON-NLS-2$
} else {
log.warn("Unknown tag" + name); //$NON-NLS-1$
}
@ -427,7 +432,7 @@ public class OsmandRenderingRulesParser {
new RenderingRuleVisitor() {
@Override
public void rendering(String name, String depends) {
public void rendering(String name, String depends, int defColor) {
System.out.println("Renderer " + name); //$NON-NLS-1$
}

View file

@ -0,0 +1,3 @@
<renderer name="default-night" depends="default" defaultColor="#08314b">
</renderer>

View file

@ -1,4 +1,4 @@
<renderer name="default" depends="">
<renderer name="default" depends="" defaultColor="#f1eee8">
<!--
Currently available icons : aerodrome, airport, alpinehut, atm, bank, bar, beach, bollard, bus_station, bus_stop_small, bus_stop,
cable_car, cafe, camp_site, car_share, caravan_park, cave_entrance, chair_lift, cinema, cliff, cliff2, danger, department_store, embassy,

View file

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="renderer_load_sucess">Стиль успешно загружен</string>
<string name="renderer_load_exception">Произошла ошибка во время загрузки данного стиля</string>
<string name="renderers">Рендеринг карты</string>
<string name="renderers_descr">Выберите стиль для рендеринга карты</string>
<string name="reload">Перезагрузить</string>
<string name="poi_context_menu_website">Просмотреть вебсайт POI</string>
<string name="poi_context_menu_call">Показать телефон POI</string>

View file

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="renderer_load_sucess">Renderer was sucessfully loaded</string>
<string name="renderer_load_exception">Exception occured: renderer was not loaded</string>
<string name="renderers">Vector renderer</string>
<string name="renderers_descr">Choose vector rendering style</string>
<string name="reload">reload</string>
<string name="poi_context_menu_website">See POI website</string>
<string name="poi_context_menu_call">Show POI phone</string>

View file

@ -24,6 +24,7 @@
<Preference android:title="@string/reload_indexes" android:key="reload_indexes" android:summary="@string/reload_indexes_descr"></Preference>
<Preference android:title="@string/download_indexes" android:key="download_indexes" android:summary="@string/download_indexes_descr"></Preference>
<ListPreference android:title="@string/voice_provider" android:key="voice_provider" android:summary="@string/voice_provider_descr"></ListPreference>
<ListPreference android:key="renderer" android:title="@string/renderers" android:summary="@string/renderers_descr"></ListPreference>
</PreferenceScreen>
<PreferenceScreen android:title="@string/routing_settings" android:summary="@string/routing_settings_descr">

View file

@ -619,6 +619,13 @@ public class OsmandSettings {
return prefs.getString(VOICE_PROVIDER, null);
}
// this value string is synchronized with settings_pref.xml preference name
public static final String RENDERER = "renderer"; //$NON-NLS-1$
public static String getVectorRenderer(SharedPreferences prefs){
return prefs.getString(RENDERER, null);
}
public static final String VOICE_MUTE = "voice_mute"; //$NON-NLS-1$
public static final boolean VOICE_MUTE_DEF = false;

View file

@ -24,7 +24,9 @@ import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
import net.osmand.map.ITileSource;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.render.BaseOsmandRender;
import net.osmand.render.MapRenderRepositories;
import net.osmand.render.RendererRegistry;
import net.osmand.views.POIMapLayer;
import org.apache.commons.logging.Log;
@ -98,7 +100,6 @@ public class ResourceManager {
public ResourceManager(OsmandApplication context) {
this.context = context;
this.renderer = new MapRenderRepositories(context);
// TODO start/stop this thread when needed?
asyncLoadingTiles.start();
dirWithTiles = new File(Environment.getExternalStorageDirectory(), TILES_PATH);
if(Environment.getExternalStorageDirectory().canRead()){
@ -333,12 +334,6 @@ public class ResourceManager {
}
if (cacheOfImages.get(req.tileId) == null && req.url != null) {
// TODO we could check that network is available (context is required)
// ConnectivityManager mgr = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
// NetworkInfo info = mgr.getActiveNetworkInfo();
// if (info != null && info.isConnected()) {
// downloader.requestToDownload(req);
// }
downloader.requestToDownload(req);
}
@ -350,6 +345,7 @@ public class ResourceManager {
public List<String> reloadIndexes(IProgress progress){
close();
initRenderers(progress);
// do it lazy
// indexingImageTiles(progress);
List<String> warnings = new ArrayList<String>();
@ -360,6 +356,27 @@ public class ResourceManager {
return warnings;
}
private void initRenderers(IProgress progress) {
File file = new File(Environment.getExternalStorageDirectory(), APP_DIR + IndexConstants.RENDERERS_DIR);
Map<String, File> externalRenderers = new LinkedHashMap<String, File>();
if (file.exists() && file.canRead()) {
for (File f : file.listFiles()) {
if (f.getName().endsWith(IndexConstants.RENDERER_INDEX_EXT)) {
String name = f.getName().substring(0, f.getName().length() - IndexConstants.RENDERER_INDEX_EXT.length());
externalRenderers.put(name, f);
}
}
}
RendererRegistry.getRegistry().setExternalRenderers(externalRenderers);
String r = OsmandSettings.getVectorRenderer(OsmandSettings.getPrefs(context));
if(r != null){
BaseOsmandRender obj = RendererRegistry.getRegistry().getRenderer(r);
if(obj != null){
RendererRegistry.getRegistry().setCurrentSelectedRender(obj);
}
}
}
public List<String> indexingMaps(final IProgress progress) {
File file = new File(Environment.getExternalStorageDirectory(), MAPS_PATH);
List<String> warnings = new ArrayList<String>();

View file

@ -111,7 +111,7 @@ public class OsmandApplication extends Application {
public void startApplication() {
startDialog = new ProgressDialogImplementation(this, null, false);
startDialog.setRunnable("Initializing app", new Runnable() { //$NON-NLS-1$
@Override
@ -121,14 +121,14 @@ public class OsmandApplication extends Application {
warnings = manager.reloadIndexes(startDialog);
String voice = OsmandSettings.getVoiceProvider(OsmandSettings.getPrefs(OsmandApplication.this));
player = null;
if(voice != null){
if (voice != null) {
startDialog.startTask(getString(R.string.voice_data_initializing), -1);
String w = initCommandPlayer();
if (w != null) {
warnings.add(w);
}
}
SavingTrackHelper helper = new SavingTrackHelper(OsmandApplication.this);
if (helper.hasDataToSave()) {
startDialog.startTask(getString(R.string.saving_gpx_tracks), -1);

View file

@ -2,6 +2,7 @@ package net.osmand.activities;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -20,6 +21,8 @@ import net.osmand.OsmandSettings.ApplicationMode;
import net.osmand.activities.RouteProvider.RouteService;
import net.osmand.map.TileSourceManager;
import net.osmand.map.TileSourceManager.TileSourceTemplate;
import net.osmand.render.BaseOsmandRender;
import net.osmand.render.RendererRegistry;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@ -88,6 +91,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
private ListPreference maxLevelToDownload;
private ListPreference mapScreenOrientation;
private ListPreference voicePreference;
private ListPreference rendererPreference;
private ListPreference routeServiceInterval;
private ListPreference routeServiceWaitInterval;
private ListPreference routeServiceProvider;
@ -154,6 +158,8 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
routerPreference.setOnPreferenceChangeListener(this);
voicePreference =(ListPreference) screen.findPreference(OsmandSettings.VOICE_PROVIDER);
voicePreference.setOnPreferenceChangeListener(this);
rendererPreference =(ListPreference) screen.findPreference(OsmandSettings.RENDERER);
rendererPreference.setOnPreferenceChangeListener(this);
routeServiceInterval =(ListPreference) screen.findPreference(OsmandSettings.SERVICE_OFF_INTERVAL);
routeServiceInterval.setOnPreferenceChangeListener(this);
routeServiceWaitInterval =(ListPreference) screen.findPreference(OsmandSettings.SERVICE_OFF_WAIT_INTERVAL);
@ -298,6 +304,21 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
voicePreference.setValueIndex(0);
}
String vectorRenderer = OsmandSettings.getVectorRenderer(prefs);
Collection<String> rendererNames = RendererRegistry.getRegistry().getRendererNames();
entries = new String[rendererNames.size()];
k = 0;
for(String s : rendererNames){
entries[k++] = s;
}
rendererPreference.setEntries(entries);
rendererPreference.setEntryValues(entries);
if(rendererNames.contains(vectorRenderer)){
rendererPreference.setValue(vectorRenderer);
} else {
rendererPreference.setValueIndex(0);
}
int startZoom = 12;
int endZoom = 19;
entries = new String[endZoom - startZoom + 1];
@ -452,6 +473,17 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
edit.putInt(OsmandSettings.ROUTER_SERVICE, s.ordinal());
}
edit.commit();
} else if (preference == rendererPreference) {
BaseOsmandRender loaded = RendererRegistry.getRegistry().getRenderer((String) newValue);
if(loaded == null){
Toast.makeText(this, R.string.renderer_load_exception, Toast.LENGTH_SHORT).show();
} else {
RendererRegistry.getRegistry().setCurrentSelectedRender(loaded);
edit.putString(OsmandSettings.RENDERER, (String) newValue);
Toast.makeText(this, R.string.renderer_load_sucess, Toast.LENGTH_SHORT).show();
((OsmandApplication)getApplication()).getResourceManager().getRenderer().clearCache();
}
edit.commit();
} else if (preference == voicePreference) {
int i = voicePreference.findIndexOfValue((String) newValue);
if(i==0){

View file

@ -32,27 +32,23 @@ public class BaseOsmandRender implements RenderingRuleVisitor {
private Map<String, Map<String, List<FilterState>>>[] rules = new LinkedHashMap[6];
private static BaseOsmandRender defaultRender = null;
public static BaseOsmandRender defaultRender() throws IOException, SAXException{
if(defaultRender == null){
defaultRender = new BaseOsmandRender(OsmandRenderingRulesParser.class.getResourceAsStream("default.render.xml")); //$NON-NLS-1$
}
return defaultRender;
}
private int defaultColor;
public BaseOsmandRender(InputStream is) throws IOException, SAXException {
public void init(InputStream is) throws IOException, SAXException{
long time = System.currentTimeMillis();
OsmandRenderingRulesParser parser = new OsmandRenderingRulesParser();
parser.parseRenderingRules(is, this);
log.info("Init render " + name + " for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
}
protected BaseOsmandRender(){
public BaseOsmandRender(){
}
@Override
public void rendering(String name, String depends) {
public void rendering(String name, String depends, int defaultColor) {
this.name = name;
this.defaultColor = defaultColor;
if(depends != null && depends.length() > 0){
for(String s : depends.split(",")) { //$NON-NLS-1$
if(s.trim().length() > 0){
@ -61,6 +57,19 @@ public class BaseOsmandRender implements RenderingRuleVisitor {
}
}
}
public int getDefaultColor() {
int r = defaultColor;
if (r == 0) {
for (BaseOsmandRender d : dependRenderers) {
r = d.getDefaultColor();
if (r != 0) {
break;
}
}
}
return r;
}
@Override
public void visitRule(int state, FilterState filter) {
@ -190,13 +199,15 @@ public class BaseOsmandRender implements RenderingRuleVisitor {
}
private float getObjectOrderImpl(String tag, String val, int type, int layer) {
Map<String, List<FilterState>> map = rules[OsmandRenderingRulesParser.ORDER_STATE].get(tag);
if (map != null) {
List<FilterState> list = map.get(val);
if (list != null) {
for (FilterState f : list) {
if(f.orderType == type && f.layer == layer){
return f.order;
if (rules[OsmandRenderingRulesParser.ORDER_STATE] != null) {
Map<String, List<FilterState>> map = rules[OsmandRenderingRulesParser.ORDER_STATE].get(tag);
if (map != null) {
List<FilterState> list = map.get(val);
if (list != null) {
for (FilterState f : list) {
if (f.orderType == type && f.layer == layer) {
return f.order;
}
}
}
}
@ -205,13 +216,15 @@ public class BaseOsmandRender implements RenderingRuleVisitor {
}
private Integer getPointIconImpl(String tag, String val, int zoom) {
Map<String, List<FilterState>> map = rules[OsmandRenderingRulesParser.POINT_STATE].get(tag);
if (map != null) {
List<FilterState> list = map.get(val);
if (list != null) {
for (FilterState f : list) {
if (f.minzoom <= zoom && (zoom <= f.maxzoom || f.maxzoom == -1)) {
return RenderingIcons.getIcons().get(f.icon);
if (rules[OsmandRenderingRulesParser.POINT_STATE] != null) {
Map<String, List<FilterState>> map = rules[OsmandRenderingRulesParser.POINT_STATE].get(tag);
if (map != null) {
List<FilterState> list = map.get(val);
if (list != null) {
for (FilterState f : list) {
if (f.minzoom <= zoom && (zoom <= f.maxzoom || f.maxzoom == -1)) {
return RenderingIcons.getIcons().get(f.icon);
}
}
}
}
@ -220,6 +233,9 @@ public class BaseOsmandRender implements RenderingRuleVisitor {
}
private boolean renderPolylineImpl(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o, int layer) {
if(rules[OsmandRenderingRulesParser.LINE_STATE] == null){
return false;
}
Map<String, List<FilterState>> map = rules[OsmandRenderingRulesParser.LINE_STATE].get(tag);
if (map != null) {
List<FilterState> list = map.get(val);
@ -266,6 +282,9 @@ public class BaseOsmandRender implements RenderingRuleVisitor {
private boolean renderPolygonImpl(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o) {
if(rules[OsmandRenderingRulesParser.POLYGON_STATE] == null){
return false;
}
Map<String, List<FilterState>> map = rules[OsmandRenderingRulesParser.POLYGON_STATE].get(tag);
if (map != null) {
List<FilterState> list = map.get(val);
@ -326,6 +345,9 @@ public class BaseOsmandRender implements RenderingRuleVisitor {
}
private String renderObjectTextImpl(String name, String tag, String val, RenderingContext rc, boolean ref) {
if(rules[OsmandRenderingRulesParser.TEXT_STATE] == null){
return null;
}
Map<String, List<FilterState>> map = rules[OsmandRenderingRulesParser.TEXT_STATE].get(tag);
if (map != null) {
List<FilterState> list = map.get(val);

View file

@ -3,7 +3,6 @@ package net.osmand.render;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.map.hash.TFloatObjectHashMap;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -21,7 +20,6 @@ import net.osmand.osm.MultyPolygon;
import net.sf.junidecode.Junidecode;
import org.apache.commons.logging.Log;
import org.xml.sax.SAXException;
import android.content.Context;
import android.graphics.Bitmap;
@ -48,6 +46,8 @@ import android.util.FloatMath;
public class OsmandRenderer {
private static final Log log = LogUtil.getLog(OsmandRenderer.class);
private final int clFillScreen = Color.rgb(241, 238, 232);
private TextPaint paintText;
private Paint paint;
@ -56,9 +56,6 @@ public class OsmandRenderer {
public static final int TILE_SIZE = 256;
/// Colors
private int clFillScreen = Color.rgb(241, 238, 232);
private Map<String, PathEffect> dashEffect = new LinkedHashMap<String, PathEffect>();
private Map<Integer, Shader> shaders = new LinkedHashMap<Integer, Shader>();
private Map<Integer, Bitmap> cachedIcons = new LinkedHashMap<Integer, Bitmap>();
@ -233,13 +230,7 @@ public class OsmandRenderer {
paintFillEmpty = new Paint();
paintFillEmpty.setStyle(Style.FILL);
paintFillEmpty.setColor(clFillScreen);
try {
render = BaseOsmandRender.defaultRender();
} catch (IOException e) {
log.error("Exception initialize renderer", e); //$NON-NLS-1$
} catch (SAXException e) {
log.error("Exception initialize renderer", e); //$NON-NLS-1$
}
render = RendererRegistry.getRegistry().defaultRender();
}
public PathEffect getDashEffect(String dashes){
@ -273,6 +264,7 @@ public class OsmandRenderer {
public Bitmap generateNewBitmap(RenderingContext rc, List<BinaryMapDataObject> objects, boolean useEnglishNames) {
long now = System.currentTimeMillis();
render = RendererRegistry.getRegistry().getCurrentSelectedRenderer();
// put in order map
int sz = objects.size();
int init = sz / 4;
@ -318,6 +310,12 @@ public class OsmandRenderer {
bmp = Bitmap.createBitmap(rc.width, rc.height, Config.RGB_565);
Canvas cv = new Canvas(bmp);
if(render != null){
int dc = render.getDefaultColor();
if(dc != 0){
paintFillEmpty.setColor(dc);
}
}
cv.drawRect(0, 0, bmp.getWidth(), bmp.getHeight(), paintFillEmpty);
float[] keys = orderMap.keys();
Arrays.sort(keys);

View file

@ -0,0 +1,143 @@
package net.osmand.render;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.osmand.LogUtil;
import org.apache.commons.logging.Log;
import org.xml.sax.SAXException;
public class RendererRegistry {
private final static RendererRegistry registry = new RendererRegistry();
private final static Log log = LogUtil.getLog(RendererRegistry.class);
public final static String DEFAULT_RENDER = "default"; //$NON-NLS-1$
public final static String NIGHT_SUFFIX = "-night"; //$NON-NLS-1$
public final static String DEFAULT_NIGHT_RENDER = DEFAULT_RENDER + NIGHT_SUFFIX;
public static RendererRegistry getRegistry() {
return registry;
}
public RendererRegistry(){
internalRenderers.put(DEFAULT_RENDER, "default.render.xml"); //$NON-NLS-1$
internalRenderers.put(DEFAULT_NIGHT_RENDER, "default-night.render.xml"); //$NON-NLS-1$
}
private BaseOsmandRender defaultRender = null;
private BaseOsmandRender currentSelectedRender = null;
private Map<String, File> externalRenderers = new LinkedHashMap<String, File>();
private Map<String, String> internalRenderers = new LinkedHashMap<String, String>();
private Map<String, BaseOsmandRender> renderers = new LinkedHashMap<String, BaseOsmandRender>();
public BaseOsmandRender defaultRender() {
if(defaultRender == null){
defaultRender = getRenderer(DEFAULT_RENDER);
if (defaultRender == null) {
try {
defaultRender = new BaseOsmandRender();
defaultRender.init(OsmandRenderingRulesParser.class.getResourceAsStream("default.render.xml")); //$NON-NLS-1$
} catch (IOException e) {
log.error("Exception initialize renderer", e); //$NON-NLS-1$
} catch (SAXException e) {
log.error("Exception initialize renderer", e); //$NON-NLS-1$
}
}
}
return defaultRender;
}
public BaseOsmandRender getRenderer(String name){
if(renderers.containsKey(name)){
return renderers.get(name);
}
if(!externalRenderers.containsKey(name) && !internalRenderers.containsKey(name)){
return null;
}
return getRenderer(name, new LinkedHashSet<String>());
}
private BaseOsmandRender getRenderer(String name, Set<String> loadedRenderers) {
try {
return loadRenderer(name);
} catch (IOException e) {
log.error("Error loading renderer", e); //$NON-NLS-1$
} catch (SAXException e) {
log.error("Error loading renderer", e); //$NON-NLS-1$
}
return null;
}
public BaseOsmandRender loadRenderer(String name) throws IOException, SAXException {
return loadRenderer(name, new LinkedHashSet<String>());
}
private BaseOsmandRender loadRenderer(String name, Set<String> loadedRenderers) throws IOException, SAXException {
InputStream is = null;
if(externalRenderers.containsKey(name)){
is = new FileInputStream(externalRenderers.get(name));
} else if(internalRenderers.containsKey(name)){
is = OsmandRenderingRulesParser.class.getResourceAsStream("default.render.xml"); //$NON-NLS-1$
} else {
throw new IllegalArgumentException("Not found " + name); //$NON-NLS-1$
}
BaseOsmandRender b = new BaseOsmandRender();
b.init(is);
loadedRenderers.add(name);
List<BaseOsmandRender> dependencies = new ArrayList<BaseOsmandRender>();
for (String s : b.getDepends()) {
if (loadedRenderers.contains(s)) {
log.warn("Circular dependencies found " + name); //$NON-NLS-1$
} else {
BaseOsmandRender dep = getRenderer(s, loadedRenderers);
if (dep == null) {
log.warn("Dependent renderer not found : " + name); //$NON-NLS-1$
} else{
dependencies.add(dep);
}
}
}
b.setDependRenderers(dependencies);
renderers.put(name, b);
return b;
}
public void setExternalRenderers(Map<String, File> externalRenderers) {
this.externalRenderers = externalRenderers;
}
public Collection<String> getRendererNames(){
LinkedHashSet<String> names = new LinkedHashSet<String>();
names.add(DEFAULT_RENDER);
names.addAll(internalRenderers.keySet());
names.addAll(externalRenderers.keySet());
return names;
}
public BaseOsmandRender getCurrentSelectedRenderer() {
if(currentSelectedRender == null){
return defaultRender();
}
return currentSelectedRender;
}
public void setCurrentSelectedRender(BaseOsmandRender currentSelectedRender) {
this.currentSelectedRender = currentSelectedRender;
}
}