use of net.osmand.data.QuadPointDouble in project Osmand by osmandapp.
the class MapRenderRepositories method loadMap.
public synchronized void loadMap(RotatedTileBox tileRect, MapTileDownloader mapTileDownloader) {
boolean prevInterrupted = interrupted;
interrupted = false;
// added to avoid zoomAnimation != 0 which produces wrong map position on the screen
tileRect.setZoomAndAnimation(tileRect.getZoom(), 0);
// prevent editing
requestedBox = new RotatedTileBox(tileRect);
log.info("RENDER MAP: new request " + tileRect);
if (currentRenderingContext != null) {
currentRenderingContext = null;
}
try {
// find selected rendering type
OsmandApplication app = ((OsmandApplication) context.getApplicationContext());
boolean nightMode = app.getDaynightHelper().isNightMode();
// boolean moreDetail = prefs.SHOW_MORE_MAP_DETAIL.get();
RenderingRulesStorage storage = app.getRendererRegistry().getCurrentSelectedRenderer();
RenderingRuleSearchRequest renderingReq = new RenderingRuleSearchRequest(storage);
renderingReq.setBooleanFilter(renderingReq.ALL.R_NIGHT_MODE, nightMode);
for (RenderingRuleProperty customProp : storage.PROPS.getCustomRules()) {
if (customProp.isBoolean()) {
if (customProp.getAttrName().equals(RenderingRuleStorageProperties.A_ENGINE_V1)) {
renderingReq.setBooleanFilter(customProp, true);
} else if (RenderingRuleStorageProperties.UI_CATEGORY_HIDDEN.equals(customProp.getCategory())) {
renderingReq.setBooleanFilter(customProp, false);
} else {
CommonPreference<Boolean> pref = prefs.getCustomRenderBooleanProperty(customProp.getAttrName());
renderingReq.setBooleanFilter(customProp, pref.get());
}
} else if (RenderingRuleStorageProperties.UI_CATEGORY_HIDDEN.equals(customProp.getCategory())) {
if (customProp.isString()) {
renderingReq.setStringFilter(customProp, "");
} else {
renderingReq.setIntFilter(customProp, 0);
}
} else {
CommonPreference<String> settings = prefs.getCustomRenderProperty(customProp.getAttrName());
String res = settings.get();
if (!Algorithms.isEmpty(res)) {
if (customProp.isString()) {
renderingReq.setStringFilter(customProp, res);
} else {
try {
renderingReq.setIntFilter(customProp, Integer.parseInt(res));
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
} else {
if (customProp.isString()) {
renderingReq.setStringFilter(customProp, "");
}
}
}
}
renderingReq.saveState();
NativeOsmandLibrary nativeLib = !prefs.SAFE_MODE.get() ? NativeOsmandLibrary.getLibrary(storage, context) : null;
// calculate data box
QuadRect dataBox = requestedBox.getLatLonBounds();
int dataBoxZoom = requestedBox.getZoom();
long now = System.currentTimeMillis();
if (cObjectsBox.left > dataBox.left || cObjectsBox.top < dataBox.top || cObjectsBox.right < dataBox.right || cObjectsBox.bottom > dataBox.bottom || (nativeLib != null) == (cNativeObjects == null) || dataBoxZoom != cObjectsZoom || prevInterrupted) {
// increase data box in order for rotate
if ((dataBox.right - dataBox.left) > (dataBox.top - dataBox.bottom)) {
double wi = (dataBox.right - dataBox.left) * .05;
dataBox.left -= wi;
dataBox.right += wi;
} else {
double hi = (dataBox.top - dataBox.bottom) * .05;
dataBox.top += hi;
dataBox.bottom -= hi;
}
validateLatLonBox(dataBox);
renderedState = 0;
boolean loaded;
if (nativeLib != null) {
cObjects = new LinkedList<BinaryMapDataObject>();
loaded = loadVectorDataNative(dataBox, requestedBox.getZoom(), renderingReq, nativeLib);
} else {
cNativeObjects = null;
loaded = loadVectorData(dataBox, requestedBox.getZoom(), renderingReq);
}
if (!loaded || checkWhetherInterrupted()) {
return;
}
}
final long searchTime = System.currentTimeMillis() - now;
currentRenderingContext = new OsmandRenderer.RenderingContext(context);
renderingReq.clearState();
renderingReq.setIntFilter(renderingReq.ALL.R_MINZOOM, requestedBox.getZoom());
if (renderingReq.searchRenderingAttribute(RenderingRuleStorageProperties.A_DEFAULT_COLOR)) {
currentRenderingContext.defaultColor = renderingReq.getIntPropertyValue(renderingReq.ALL.R_ATTR_COLOR_VALUE);
}
renderingReq.clearState();
renderingReq.setIntFilter(renderingReq.ALL.R_MINZOOM, requestedBox.getZoom());
if (renderingReq.searchRenderingAttribute(RenderingRuleStorageProperties.A_SHADOW_RENDERING)) {
currentRenderingContext.shadowRenderingMode = renderingReq.getIntPropertyValue(renderingReq.ALL.R_ATTR_INT_VALUE);
currentRenderingContext.shadowRenderingColor = renderingReq.getIntPropertyValue(renderingReq.ALL.R_SHADOW_COLOR);
}
if (renderingReq.searchRenderingAttribute("polygonMinSizeToDisplay")) {
currentRenderingContext.polygonMinSizeToDisplay = renderingReq.getIntPropertyValue(renderingReq.ALL.R_ATTR_INT_VALUE);
}
final QuadPointDouble lt = requestedBox.getLeftTopTile(requestedBox.getZoom());
double cfd = MapUtils.getPowZoom(requestedBox.getZoomFloatPart()) * requestedBox.getMapDensity();
lt.x *= cfd;
lt.y *= cfd;
// LatLon ltn = requestedBox.getLeftTopLatLon();
final double tileDivisor = MapUtils.getPowZoom(31 - requestedBox.getZoom()) / cfd;
currentRenderingContext.leftX = lt.x;
currentRenderingContext.topY = lt.y;
currentRenderingContext.zoom = requestedBox.getZoom();
currentRenderingContext.rotate = requestedBox.getRotate();
currentRenderingContext.width = requestedBox.getPixWidth();
currentRenderingContext.height = requestedBox.getPixHeight();
currentRenderingContext.nightMode = nightMode;
if (requestedBox.getZoom() <= zoomOnlyForBasemaps && "".equals(prefs.MAP_PREFERRED_LOCALE.get())) {
currentRenderingContext.preferredLocale = app.getLanguage();
currentRenderingContext.transliterate = !"ru".equals(app.getLanguage()) && !"uk".equals(app.getLanguage()) && !"be".equals(app.getLanguage()) && !"bg".equals(app.getLanguage()) && !"mk".equals(app.getLanguage()) && !"sr".equals(app.getLanguage());
} else {
currentRenderingContext.preferredLocale = prefs.MAP_PREFERRED_LOCALE.get();
currentRenderingContext.transliterate = prefs.MAP_TRANSLITERATE_NAMES.get();
if (currentRenderingContext.preferredLocale.equals("en")) {
currentRenderingContext.transliterate = true;
}
}
final float mapDensity = (float) requestedBox.getMapDensity();
currentRenderingContext.setDensityValue(mapDensity);
// Text/icon scales according to mapDensity (so text is size of road)
// currentRenderingContext.textScale = (requestedBox.getDensity()*app.getSettings().TEXT_SCALE.get());
// Text/icon stays same for all sizes
currentRenderingContext.textScale = (requestedBox.getDensity() * app.getSettings().TEXT_SCALE.get()) / mapDensity;
currentRenderingContext.screenDensityRatio = 1 / Math.max(1, requestedBox.getDensity());
// init rendering context
currentRenderingContext.tileDivisor = tileDivisor;
if (checkWhetherInterrupted()) {
return;
}
now = System.currentTimeMillis();
Bitmap bmp;
boolean transparent = false;
RenderingRuleProperty rr = storage.PROPS.get("noPolygons");
if (rr != null) {
transparent = renderingReq.getIntPropertyValue(rr) > 0;
}
// 1. generate image step by step
Bitmap reuse = prevBmp;
this.prevBmp = this.bmp;
this.prevBmpLocation = this.bmpLocation;
// necessary for transparent, otherwise 2 times smaller
Config cfg = transparent ? Config.ARGB_8888 : Config.RGB_565;
if (reuse != null && reuse.getWidth() == currentRenderingContext.width && reuse.getHeight() == currentRenderingContext.height && cfg == reuse.getConfig()) {
bmp = reuse;
bmp.eraseColor(currentRenderingContext.defaultColor);
} else {
if (reuse != null) {
log.warn(String.format("Create new image ? %d != %d (w) %d != %d (h) ", currentRenderingContext.width, reuse.getWidth(), currentRenderingContext.height, reuse.getHeight()));
}
bmp = Bitmap.createBitmap(currentRenderingContext.width, currentRenderingContext.height, cfg);
if (reuse != null) {
reuse.recycle();
}
}
this.bmp = bmp;
this.bmpLocation = tileRect;
if (nativeLib != null) {
renderer.generateNewBitmapNative(currentRenderingContext, nativeLib, cNativeObjects, bmp, renderingReq, mapTileDownloader);
} else {
renderer.generateNewBitmap(currentRenderingContext, cObjects, bmp, renderingReq, mapTileDownloader);
}
// Force to use rendering request in order to prevent Garbage Collector when it is used in C++
if (renderingReq != null) {
log.info("Debug :" + renderingReq != null);
}
String renderingDebugInfo = currentRenderingContext.renderingDebugInfo;
currentRenderingContext.ended = true;
if (checkWhetherInterrupted()) {
// (be smart a bit do not revert if road already drawn)
if (currentRenderingContext.lastRenderedKey < OsmandRenderer.DEFAULT_LINE_MAX) {
reuse = this.bmp;
this.bmp = this.prevBmp;
this.bmpLocation = this.prevBmpLocation;
this.prevBmp = reuse;
this.prevBmpLocation = null;
}
currentRenderingContext = null;
return;
} else {
visibleRenderingContext = currentRenderingContext;
this.checkedRenderedState = renderedState;
this.checkedBox = this.bmpLocation;
}
currentRenderingContext = null;
// 2. replace whole image
// keep cache
// this.prevBmp = null;
this.prevBmpLocation = null;
if (prefs.DEBUG_RENDERING_INFO.get() && OsmandPlugin.getEnabledPlugin(OsmandDevelopmentPlugin.class) != null) {
// $NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
String timeInfo = "Searching: " + searchTime + " ms";
if (renderingDebugInfo != null) {
timeInfo += "\n" + renderingDebugInfo;
}
final String msg = timeInfo;
log.info(msg);
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
});
}
} catch (RuntimeException e) {
// $NON-NLS-1$
log.error("Runtime memory exception", e);
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, R.string.rendering_exception, Toast.LENGTH_SHORT).show();
}
});
} catch (OutOfMemoryError e) {
// $NON-NLS-1$
log.error("Out of memory error", e);
cObjects = new ArrayList<BinaryMapDataObject>();
cObjectsBox = new QuadRect();
handler.post(new Runnable() {
@Override
public void run() {
// ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
// ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
// activityManager.getMemoryInfo(memoryInfo);
// int avl = (int) (memoryInfo.availMem / (1 << 20));
int max = (int) (Runtime.getRuntime().maxMemory() / (1 << 20));
int avl = (int) (Runtime.getRuntime().freeMemory() / (1 << 20));
String s = " (" + avl + " MB available of " + max + ") ";
Toast.makeText(context, context.getString(R.string.rendering_out_of_memory) + s, Toast.LENGTH_SHORT).show();
}
});
} finally {
if (currentRenderingContext != null) {
currentRenderingContext.ended = true;
}
}
}
use of net.osmand.data.QuadPointDouble in project Osmand by osmandapp.
the class MapillaryImageDialog method acquireSequenceImages.
private void acquireSequenceImages() {
fetchTiles();
List<MapillaryImage> sequenceImages = new ArrayList<>();
if (!Algorithms.isEmpty(sKey)) {
double px, py;
for (Pair<QuadPointDouble, GeometryTile> pt : tiles) {
QuadPointDouble point = pt.first;
GeometryTile tile = pt.second;
for (Geometry g : tile.getData()) {
if (g instanceof Point && !g.isEmpty() && g.getUserData() != null && g.getUserData() instanceof HashMap) {
HashMap userData = (HashMap) g.getUserData();
String sKey = (String) userData.get("skey");
if (this.sKey.equals(sKey)) {
Point p = (Point) g;
px = p.getCoordinate().x / EXTENT;
py = p.getCoordinate().y / EXTENT;
MapillaryImage image = new MapillaryImage(MapUtils.getLatitudeFromTile(TILE_ZOOM, point.y + py), MapUtils.getLongitudeFromTile(TILE_ZOOM, point.x + px));
if (image.setData(userData)) {
sequenceImages.add(image);
}
}
}
}
}
}
Collections.sort(sequenceImages, new Comparator<MapillaryImage>() {
@Override
public int compare(MapillaryImage img1, MapillaryImage img2) {
return img1.getCapturedAt() < img2.getCapturedAt() ? -1 : (img1.getCapturedAt() == img2.getCapturedAt() ? 0 : 1);
}
});
this.sequenceImages = sequenceImages;
}
use of net.osmand.data.QuadPointDouble in project Osmand by osmandapp.
the class MapillaryImageDialog method acquireSequenceKey.
private void acquireSequenceKey() {
fetchTiles();
for (Pair<QuadPointDouble, GeometryTile> pt : tiles) {
GeometryTile tile = pt.second;
for (Geometry g : tile.getData()) {
if (g instanceof Point && !g.isEmpty() && g.getUserData() != null && g.getUserData() instanceof HashMap) {
HashMap userData = (HashMap) g.getUserData();
String key = (String) userData.get("key");
if (this.key.equals(key)) {
sKey = (String) userData.get("skey");
return;
}
}
}
}
}
use of net.osmand.data.QuadPointDouble in project Osmand by osmandapp.
the class MapillaryVectorLayer method getImagesFromPoint.
private void getImagesFromPoint(RotatedTileBox tb, PointF point, List<? super MapillaryImage> images) {
Map<QuadPointDouble, Map> points = this.visiblePoints;
if (points != null) {
float ex = point.x;
float ey = point.y;
final int rp = getRadius(tb);
int radius = rp * 3 / 2;
float x, y;
double minSqDist = Double.NaN;
double sqDist;
MapillaryImage img = null;
for (Entry<QuadPointDouble, Map> entry : points.entrySet()) {
x = tb.getPixXFromTile(entry.getKey().x, entry.getKey().y, TILE_ZOOM);
y = tb.getPixYFromTile(entry.getKey().x, entry.getKey().y, TILE_ZOOM);
if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) {
sqDist = (x - ex) * (x - ex) + (y - ey) * (y - ey);
if (img == null || minSqDist > sqDist) {
minSqDist = sqDist;
img = new MapillaryImage(MapUtils.getLatitudeFromTile(TILE_ZOOM, entry.getKey().y), MapUtils.getLongitudeFromTile(TILE_ZOOM, entry.getKey().x));
if (!img.setData(entry.getValue())) {
img = null;
}
}
}
}
if (img != null) {
images.add(img);
}
}
}
use of net.osmand.data.QuadPointDouble in project Osmand by osmandapp.
the class MapillaryVectorLayer method drawPoints.
protected void drawPoints(Canvas canvas, RotatedTileBox tileBox, int tileX, int tileY, GeometryTile tile, Map<QuadPointDouble, Map> visiblePoints) {
int dzoom = tileBox.getZoom() - TILE_ZOOM;
int mult = (int) Math.pow(2.0, dzoom);
QuadRect tileBounds = tileBox.getTileBounds();
double px, py, tx, ty;
float x, y;
float pw = point.getWidth();
float ph = point.getHeight();
float pwd = pw / 2;
float phd = ph / 2;
for (Geometry g : tile.getData()) {
if (g instanceof Point && !g.isEmpty() && g.getUserData() != null && g.getUserData() instanceof HashMap) {
Point p = (Point) g;
px = p.getCoordinate().x / EXTENT;
py = p.getCoordinate().y / EXTENT;
tx = (tileX + px) * mult;
ty = (tileY + py) * mult;
if (tileBounds.contains(tx, ty, tx, ty)) {
if (settings.USE_MAPILLARY_FILTER.get()) {
if (filtered(p.getUserData()))
continue;
}
x = tileBox.getPixXFromTile(tileX + px, tileY + py, TILE_ZOOM);
y = tileBox.getPixYFromTile(tileX + px, tileY + py, TILE_ZOOM);
canvas.drawBitmap(point, x - pwd, y - phd, paintPoint);
visiblePoints.put(new QuadPointDouble(tileX + px, tileY + py), (Map) p.getUserData());
}
}
}
}
Aggregations