From f4dcb7ff5819514b962e1c5f1d22c759d4b30b62 Mon Sep 17 00:00:00 2001 From: Andrey Novikov Date: Tue, 13 Feb 2024 16:00:37 +0300 Subject: [PATCH] Draw place titles --- .../main/java/mobi/maptrek/MainActivity.java | 7 +-- .../maptrek/layers/marker/MarkerItem.java | 8 +++ .../maptrek/layers/marker/MarkerRenderer.java | 51 +++++++++++++++---- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/mobi/maptrek/MainActivity.java b/app/src/main/java/mobi/maptrek/MainActivity.java index 6258a8b6..12f8677f 100644 --- a/app/src/main/java/mobi/maptrek/MainActivity.java +++ b/app/src/main/java/mobi/maptrek/MainActivity.java @@ -677,7 +677,7 @@ public void onChildViewRemoved(View parent, View child) { marker = null; } if (markerState.isShown()) { - marker = new MarkerItem(markerState.getName(), null, markerState.getCoordinates()); + marker = new MarkerItem(null, null, markerState.getCoordinates()); int drawable = markerState.isAmenity() ? R.drawable.circle_marker : R.drawable.round_marker; Bitmap markerBitmap = new AndroidBitmap(MarkerFactory.getMarkerSymbol(this, drawable, mColorAccent)); marker.setMarker(new MarkerSymbol(markerBitmap, MarkerItem.HotspotPlace.CENTER)); @@ -2498,7 +2498,7 @@ public void onWaypointCreate(GeoPoint point, String name, boolean locked, boolea waypoint.date = new Date(); waypoint.locked = locked; dataSourceViewModel.waypointDbDataSource.saveWaypoint(waypoint); - MarkerItem marker = new MarkerItem(waypoint, name, null, point); + MarkerItem marker = new MarkerItem(waypoint, name, null, point, waypoint.style.color); mMarkerLayer.addItem(marker); mMap.updateMap(true); if (!customize) @@ -4243,7 +4243,7 @@ private void removeSourceFromMap(FileDataSource source) { } private void addWaypointMarker(Waypoint waypoint) { - MarkerItem marker = new MarkerItem(waypoint, waypoint.name, waypoint.description, waypoint.coordinates); + MarkerItem marker = new MarkerItem(waypoint, waypoint.name, waypoint.description, waypoint.coordinates, waypoint.style.color); if (waypoint.style.color != 0 && waypoint.style.color != MarkerStyle.DEFAULT_COLOR) { Bitmap bitmap = new AndroidBitmap(MarkerFactory.getMarkerSymbol(this, waypoint.style.color)); marker.setMarker(new MarkerSymbol(bitmap, MarkerItem.HotspotPlace.BOTTOM_CENTER)); @@ -4645,6 +4645,7 @@ private void setMapTheme() { CanvasAdapter.userScale = mapScale; IRenderTheme theme = ThemeLoader.load(themeFile); mMap.setTheme(theme, true); + mMarkerLayer.updateItems(); mapViewModel.shieldFactory.setFontSize(fontSize); mapViewModel.shieldFactory.dispose(); mapViewModel.osmcSymbolFactory.dispose(); diff --git a/app/src/main/java/mobi/maptrek/layers/marker/MarkerItem.java b/app/src/main/java/mobi/maptrek/layers/marker/MarkerItem.java index b4a357c3..350abfca 100644 --- a/app/src/main/java/mobi/maptrek/layers/marker/MarkerItem.java +++ b/app/src/main/java/mobi/maptrek/layers/marker/MarkerItem.java @@ -22,6 +22,8 @@ package mobi.maptrek.layers.marker; +import android.graphics.Color; + import org.oscim.core.GeoPoint; /** @@ -49,6 +51,7 @@ public enum HotspotPlace { public String title; public String description; public GeoPoint geoPoint; + public int color; protected MarkerSymbol mMarker; /** @@ -62,10 +65,15 @@ public MarkerItem(String title, String description, GeoPoint geoPoint) { } public MarkerItem(Object uid, String title, String description, GeoPoint geoPoint) { + this(uid, title, description, geoPoint, Color.BLACK); + } + + public MarkerItem(Object uid, String title, String description, GeoPoint geoPoint, int color) { this.title = title; this.description = description; this.geoPoint = geoPoint; this.uid = uid; + this.color = color; } public Object getUid() { diff --git a/app/src/main/java/mobi/maptrek/layers/marker/MarkerRenderer.java b/app/src/main/java/mobi/maptrek/layers/marker/MarkerRenderer.java index 2b896875..63d88b7c 100644 --- a/app/src/main/java/mobi/maptrek/layers/marker/MarkerRenderer.java +++ b/app/src/main/java/mobi/maptrek/layers/marker/MarkerRenderer.java @@ -17,7 +17,10 @@ package mobi.maptrek.layers.marker; +import org.oscim.backend.CanvasAdapter; import org.oscim.backend.GL; +import org.oscim.backend.canvas.Bitmap; +import org.oscim.backend.canvas.Color; import org.oscim.core.MercatorProjection; import org.oscim.core.Point; import org.oscim.core.Tile; @@ -28,19 +31,26 @@ import org.oscim.renderer.MapRenderer; import org.oscim.renderer.bucket.SymbolBucket; import org.oscim.renderer.bucket.SymbolItem; +import org.oscim.renderer.bucket.TextBucket; +import org.oscim.renderer.bucket.TextItem; +import org.oscim.theme.styles.TextStyle; import org.oscim.utils.TimSort; import org.oscim.utils.geom.GeometryUtils; import java.util.Comparator; +import java.util.HashMap; import static org.oscim.backend.GLAdapter.gl; +import androidx.annotation.NonNull; + class MarkerRenderer extends BucketRenderer { private static final float FOCUS_CIRCLE_SIZE = 8; final MarkerSymbol mDefaultMarker; - private final SymbolBucket mSymbolLayer; + private final SymbolBucket mSymbolBucket; + private final TextBucket mTextBucket; private final float[] mBox = new float[8]; private final MarkerLayer mMarkerLayer; private final Point mMapPoint = new Point(); @@ -75,6 +85,7 @@ private static class InternalItem { double px, py; float dy; + @NonNull @Override public String toString() { return "\n" + x + ":" + y + " / " + dy + " " + visible; @@ -82,7 +93,9 @@ public String toString() { } MarkerRenderer(MarkerLayer markerLayer, MarkerSymbol defaultSymbol, float scale) { - mSymbolLayer = new SymbolBucket(); + mSymbolBucket = new SymbolBucket(); + mTextBucket = new TextBucket(); + mSymbolBucket.next = mTextBucket; mMarkerLayer = markerLayer; mDefaultMarker = defaultSymbol; mScale = scale; @@ -91,8 +104,7 @@ public String toString() { @Override public synchronized void update(GLViewport v) { if (!mInitialized) { - init(); - mInitialized = true; + mInitialized = init(); } if (!v.changed() && !mUpdate) @@ -176,7 +188,7 @@ else if (it.x < -flip) mMapPosition.bearing = -mMapPosition.bearing; sort(mItems, 0, mItems.length); - //log.debug(Arrays.toString(mItems)); + HashMap textStyles = new HashMap<>(); for (InternalItem it : mItems) { if (!it.visible) continue; @@ -190,14 +202,35 @@ else if (it.x < -flip) if (marker == null) marker = mDefaultMarker; + Bitmap bitmap = marker.getBitmap(); + SymbolItem s = SymbolItem.pool.get(); - s.set(it.x, it.y, marker.getBitmap(), true); + s.set(it.x, it.y, bitmap, true); s.offset = marker.getHotspot(); s.billboard = marker.isBillboard(); - mSymbolLayer.pushSymbol(s); + mSymbolBucket.pushSymbol(s); + + if (it.item.title != null) { + float dy = -s.offset.y * bitmap.getHeight() - 10 * mScale * CanvasAdapter.textScale; + long k = (((long) dy) << 32) | (it.item.color & 0xffffffffL); + TextStyle textStyle = textStyles.get(k); + if (textStyle == null) { + textStyle = TextStyle.builder() + .fontSize(20 * mScale * CanvasAdapter.textScale) + .color(it.item.color) + .outline(Color.WHITE, 3f * mScale * CanvasAdapter.textScale) + .isCaption(true) + .offsetY(dy) + .build(); + textStyles.put(k, textStyle); + } + TextItem t = TextItem.pool.get(); + t.set(it.x, it.y, it.item.title, textStyle); + mTextBucket.addText(t); + } } - buckets.set(mSymbolLayer); + buckets.set(mSymbolBucket); buckets.prepare(); compile(); @@ -257,7 +290,7 @@ public void update() { mUpdate = true; } - private static TimSort ZSORT = new TimSort<>(); + private static final TimSort ZSORT = new TimSort<>(); private static void sort(InternalItem[] a, int lo, int hi) { int nRemaining = hi - lo;