diff --git a/docs/Changelog.md b/docs/Changelog.md
index ea3c5f3a..a143367d 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -2,6 +2,7 @@
## New since 0.16.0
+- Move cluster experiment in samples [#858](https://github.com/mapsforge/vtm/pull/858)
- Many other minor improvements and bug fixes
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.17.0)
diff --git a/vtm/src/org/oscim/layers/marker/ClusterMarkerRenderer.java b/vtm-android-example/src/org/oscim/android/cluster/ClusterMarkerRenderer.java
similarity index 94%
rename from vtm/src/org/oscim/layers/marker/ClusterMarkerRenderer.java
rename to vtm-android-example/src/org/oscim/android/cluster/ClusterMarkerRenderer.java
index c81a6abd..e56fac0f 100644
--- a/vtm/src/org/oscim/layers/marker/ClusterMarkerRenderer.java
+++ b/vtm-android-example/src/org/oscim/android/cluster/ClusterMarkerRenderer.java
@@ -19,13 +19,13 @@
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see .
*/
-package org.oscim.layers.marker;
+package org.oscim.android.cluster;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MercatorProjection;
import org.oscim.core.PointF;
import org.oscim.core.Tile;
-import org.oscim.layers.marker.utils.ScreenUtils;
+import org.oscim.layers.marker.*;
import org.oscim.layers.marker.utils.SparseIntArray;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.bucket.SymbolItem;
@@ -45,7 +45,7 @@ public class ClusterMarkerRenderer extends MarkerRenderer {
/**
* default color of number inside the icon. Would be super-cool to cook this into the map theme
*/
- private static int CLUSTER_COLORTEXT = 0xff8000c0;
+ private static final int CLUSTER_COLORTEXT = 0xff8000c0;
/**
* default color of circle background
@@ -84,12 +84,12 @@ public class ClusterMarkerRenderer extends MarkerRenderer {
* We use a flat Sparse array to calculate the clusters. The sparse array models a 2D map where every (x,y) denotes
* a grid slot, ie. 64x64dp. For efficiency I use a linear sparsearray with ARRindex = SLOTypos * max_x + SLOTxpos"
*/
- private SparseIntArray mGridMap = new SparseIntArray(200); // initial space for 200 markers, that's not a lot of memory, and in most cases will avoid resizing the array
+ private final SparseIntArray mGridMap = new SparseIntArray(200); // initial space for 200 markers, that's not a lot of memory, and in most cases will avoid resizing the array
/**
* Whether to enable clustering or disable the functionality
*/
- private boolean mClusteringEnabled = false;
+ private final boolean mClusteringEnabled;
/**
* Constructs a clustered marker renderer
@@ -139,18 +139,18 @@ public class ClusterMarkerRenderer extends MarkerRenderer {
*/
private void repopulateCluster(int size, double scale) {
/* the grid slot size in px. increase to group more aggressively. currently set to marker size */
- final int GRIDSIZE = ScreenUtils.getPixels(MAP_GRID_SIZE_DP);
+ final int GRIDSIZE = ClusterUtils.getPixels(MAP_GRID_SIZE_DP);
/* the factor to map into Grid Coordinates (discrete squares of GRIDSIZE x GRIDSIZE) */
final double factor = (scale / GRIDSIZE);
- InternalItem.Clustered[] tmp = new InternalItem.Clustered[size];
+ Clustered[] tmp = new Clustered[size];
// clear grid map to count items that share the same "grid slot"
mGridMap.clear();
for (int i = 0; i < size; i++) {
- InternalItem.Clustered it = tmp[i] = new InternalItem.Clustered();
+ Clustered it = tmp[i] = new Clustered();
it.item = mMarkerLayer.createItem(i);
@@ -160,7 +160,7 @@ public class ClusterMarkerRenderer extends MarkerRenderer {
it.py = mMapPoint.y;
// items can be declared non-clusterable
- if (!(it.item instanceof MarkerItem.NonClusterable)) {
+ if (!(it.item instanceof NonClusterable)) {
final int
absposx = (int) (it.px * factor), // absolute item X position in the grid
@@ -244,7 +244,7 @@ public class ClusterMarkerRenderer extends MarkerRenderer {
int numVisible = 0;
// Increase view to show items that are partially visible
- mMarkerLayer.map().viewport().getMapExtents(mBox, Tile.SIZE / 2);
+ mMarkerLayer.map().viewport().getMapExtents(mBox, Tile.SIZE >> 1);
long flip = (long) (Tile.SIZE * v.pos.scale) >> 1;
@@ -262,7 +262,7 @@ public class ClusterMarkerRenderer extends MarkerRenderer {
/* check visibility */
for (InternalItem itm : mItems) {
- InternalItem.Clustered it = (InternalItem.Clustered) itm;
+ Clustered it = (Clustered) itm;
it.changes = false;
it.x = (float) ((it.px - mx) * scale);
@@ -318,7 +318,7 @@ public class ClusterMarkerRenderer extends MarkerRenderer {
//log.debug(Arrays.toString(mItems));
for (InternalItem itm : mItems) {
- InternalItem.Clustered it = (InternalItem.Clustered) itm;
+ Clustered it = (Clustered) itm;
// skip invisible AND clustered-out
if ((!it.visible) || (it.clusteredOut))
@@ -387,7 +387,7 @@ public class ClusterMarkerRenderer extends MarkerRenderer {
// create and cache bitmap. This is unacceptable inside the GL thread,
// so we'll call this routine at the beginning to pre-cache all bitmaps
- ScreenUtils.ClusterDrawable drawable = new ScreenUtils.ClusterDrawable(
+ ClusterUtils.ClusterDrawable drawable = new ClusterUtils.ClusterDrawable(
MAP_MARKER_CLUSTER_SIZE_DP - CLUSTER_MAXSIZE + size, // make size dependent on cluster size
mStyleForeground,
mStyleBackground,
diff --git a/vtm/src/org/oscim/layers/marker/utils/ScreenUtils.java b/vtm-android-example/src/org/oscim/android/cluster/ClusterUtils.java
similarity index 89%
rename from vtm/src/org/oscim/layers/marker/utils/ScreenUtils.java
rename to vtm-android-example/src/org/oscim/android/cluster/ClusterUtils.java
index b62a0c24..b36ae1bd 100644
--- a/vtm/src/org/oscim/layers/marker/utils/ScreenUtils.java
+++ b/vtm-android-example/src/org/oscim/android/cluster/ClusterUtils.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see .
*/
-package org.oscim.layers.marker.utils;
+package org.oscim.android.cluster;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Bitmap;
@@ -25,7 +25,7 @@ import org.oscim.backend.canvas.Paint;
* A simple utility class to make clustered markers functionality self-contained.
* Includes a method to translate between DPs and PXs and a circular icon generator.
*/
-public class ScreenUtils {
+public class ClusterUtils {
/**
* Get pixels from DPs
@@ -38,8 +38,9 @@ public class ScreenUtils {
}
public static class ClusterDrawable {
- private Paint mPaintText = CanvasAdapter.newPaint();
- private Paint mPaintCircle = CanvasAdapter.newPaint(), mPaintBorder = CanvasAdapter.newPaint();
+ private final Paint mPaintText = CanvasAdapter.newPaint();
+ private final Paint mPaintCircle = CanvasAdapter.newPaint();
+ private final Paint mPaintBorder = CanvasAdapter.newPaint();
private int mSize;
private String mText;
@@ -57,8 +58,8 @@ public class ScreenUtils {
}
private void setup(int sizedp, int foregroundColor, int backgroundColor) {
- mSize = ScreenUtils.getPixels(sizedp);
- mPaintText.setTextSize(ScreenUtils.getPixels((int) (sizedp * 0.6666666)));
+ mSize = ClusterUtils.getPixels(sizedp);
+ mPaintText.setTextSize(ClusterUtils.getPixels((int) (sizedp * 0.6666666)));
mPaintText.setColor(foregroundColor);
mPaintCircle.setColor(backgroundColor);
diff --git a/vtm-android-example/src/org/oscim/android/cluster/Clustered.java b/vtm-android-example/src/org/oscim/android/cluster/Clustered.java
new file mode 100644
index 00000000..509dd5f3
--- /dev/null
+++ b/vtm-android-example/src/org/oscim/android/cluster/Clustered.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017 nebular
+ * Copyright 2017 devemux86
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see .
+ */
+package org.oscim.android.cluster;
+
+import org.oscim.layers.marker.InternalItem;
+
+/**
+ * Extension for clustered items.
+ */
+public class Clustered extends InternalItem {
+ /**
+ * If this is >0, this item will be displayed as a cluster circle, with size clusterSize+1.
+ */
+ public int clusterSize;
+
+ /**
+ * If this is true, this item is hidden (because it's represented by another InternalItem acting as cluster.
+ */
+ public boolean clusteredOut;
+}
diff --git a/vtm-android-example/src/org/oscim/android/cluster/NonClusterable.java b/vtm-android-example/src/org/oscim/android/cluster/NonClusterable.java
new file mode 100644
index 00000000..9feb8353
--- /dev/null
+++ b/vtm-android-example/src/org/oscim/android/cluster/NonClusterable.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017 nebular
+ * Copyright 2017 devemux86
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see .
+ */
+package org.oscim.android.cluster;
+
+import org.oscim.core.GeoPoint;
+import org.oscim.layers.marker.MarkerItem;
+
+/**
+ * If a MarkerItem is created using this convenience class instead of MarkerItem,
+ * this specific item will not be clusterable.
+ */
+public class NonClusterable extends MarkerItem {
+ public NonClusterable(String title, String description, GeoPoint geoPoint) {
+ super(null, title, description, geoPoint);
+ }
+
+ public NonClusterable(Object uid, String title, String description, GeoPoint geoPoint) {
+ super(uid, title, description, geoPoint);
+ }
+}
diff --git a/vtm-android-example/src/org/oscim/android/test/ClusterMarkerOverlayActivity.java b/vtm-android-example/src/org/oscim/android/test/ClusterMarkerOverlayActivity.java
index 9f89ebda..ba78168a 100644
--- a/vtm-android-example/src/org/oscim/android/test/ClusterMarkerOverlayActivity.java
+++ b/vtm-android-example/src/org/oscim/android/test/ClusterMarkerOverlayActivity.java
@@ -17,6 +17,7 @@ package org.oscim.android.test;
import android.graphics.BitmapFactory;
import org.oscim.android.canvas.AndroidBitmap;
+import org.oscim.android.cluster.ClusterMarkerRenderer;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.backend.canvas.Color;
import org.oscim.core.GeoPoint;
diff --git a/vtm-playground/src/org/oscim/test/ClusterMarkerLayerTest.java b/vtm-playground/src/org/oscim/test/ClusterMarkerLayerTest.java
deleted file mode 100644
index 07988e20..00000000
--- a/vtm-playground/src/org/oscim/test/ClusterMarkerLayerTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2016-2020 devemux86
- * Copyright 2017 nebular
- *
- * This program is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.test;
-
-import org.oscim.backend.CanvasAdapter;
-import org.oscim.backend.canvas.Bitmap;
-import org.oscim.backend.canvas.Color;
-import org.oscim.core.GeoPoint;
-import org.oscim.gdx.GdxMapApp;
-import org.oscim.layers.marker.*;
-import org.oscim.layers.tile.bitmap.BitmapTileLayer;
-import org.oscim.tiling.source.OkHttpEngine;
-import org.oscim.tiling.source.UrlTileSource;
-import org.oscim.tiling.source.bitmap.DefaultSources;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class ClusterMarkerLayerTest extends MarkerLayerTest {
-
- private static final int COUNT = 5;
- private static final float STEP = 100f / 110000f; // roughly 100 meters
-
- @Override
- public void createLayers() {
- try {
- // Map events receiver
- mMap.layers().add(new MapEventsReceiver(mMap));
-
- UrlTileSource tileSource = DefaultSources.OPENSTREETMAP
- .httpFactory(new OkHttpEngine.OkHttpFactory())
- .build();
- tileSource.setHttpRequestHeaders(Collections.singletonMap("User-Agent", "vtm-playground"));
- mMap.layers().add(new BitmapTileLayer(mMap, tileSource));
-
- mMap.setMapPosition(53.08, 8.83, 1 << 15);
-
- Bitmap bitmapPoi = CanvasAdapter.decodeBitmap(getClass().getResourceAsStream("/res/marker_poi.png"));
- final MarkerSymbol symbol;
- if (BILLBOARDS)
- symbol = new MarkerSymbol(bitmapPoi, MarkerSymbol.HotspotPlace.BOTTOM_CENTER);
- else
- symbol = new MarkerSymbol(bitmapPoi, MarkerSymbol.HotspotPlace.CENTER, false);
-
- MarkerRendererFactory markerRendererFactory = new MarkerRendererFactory() {
- @Override
- public MarkerRenderer create(MarkerLayer markerLayer) {
- return new ClusterMarkerRenderer(markerLayer, symbol, new ClusterMarkerRenderer.ClusterStyle(Color.WHITE, Color.BLUE)) {
- @Override
- protected Bitmap getClusterBitmap(int size) {
- // Can customize cluster bitmap here
- return super.getClusterBitmap(size);
- }
- };
- }
- };
- mMarkerLayer = new ItemizedLayer(
- mMap,
- new ArrayList(),
- markerRendererFactory,
- this);
- mMap.layers().add(mMarkerLayer);
-
- // Create some markers spaced STEP degrees
- List pts = new ArrayList<>();
- GeoPoint center = mMap.getMapPosition().getGeoPoint();
- for (int x = -COUNT; x < COUNT; x++) {
- for (int y = -COUNT; y < COUNT; y++) {
- double random = STEP * Math.random() * 2;
- MarkerItem item = new MarkerItem(y + ", " + x, "",
- new GeoPoint(center.getLatitude() + y * STEP + random, center.getLongitude() + x * STEP + random)
- );
- pts.add(item);
- }
- }
- mMarkerLayer.addItems(pts);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public static void main(String[] args) {
- GdxMapApp.init();
- GdxMapApp.run(new ClusterMarkerLayerTest());
- }
-}
diff --git a/vtm/src/org/oscim/layers/marker/InternalItem.java b/vtm/src/org/oscim/layers/marker/InternalItem.java
index 405166dd..caabb9d6 100644
--- a/vtm/src/org/oscim/layers/marker/InternalItem.java
+++ b/vtm/src/org/oscim/layers/marker/InternalItem.java
@@ -3,7 +3,6 @@
* Copyright 2016 Izumi Kawashima
* Copyright 2017 Longri
* Copyright 2017-2020 devemux86
- * Copyright 2017 nebular
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -36,22 +35,4 @@ public class InternalItem {
public String toString() {
return "\n" + x + ":" + y + " / " + dy + " " + visible;
}
-
- /**
- * Extension to the above class for clustered items. This could be a separate 1st level class,
- * but it is included here not to pollute the source tree with tiny new files.
- * It only adds a couple properties to InternalItem, and the semantics "InternalItem.Clustered"
- * are not bad.
- */
- public static class Clustered extends InternalItem {
- /**
- * If this is >0, this item will be displayed as a cluster circle, with size clusterSize+1.
- */
- public int clusterSize;
-
- /**
- * If this is true, this item is hidden (because it's represented by another InternalItem acting as cluster.
- */
- public boolean clusteredOut;
- }
}
diff --git a/vtm/src/org/oscim/layers/marker/ItemizedLayer.java b/vtm/src/org/oscim/layers/marker/ItemizedLayer.java
index 0e65a1f0..d447ad0a 100644
--- a/vtm/src/org/oscim/layers/marker/ItemizedLayer.java
+++ b/vtm/src/org/oscim/layers/marker/ItemizedLayer.java
@@ -2,7 +2,7 @@
* Copyright 2012 osmdroid authors: Nicolas Gramlich, Theodore Hong, Fred Eisele
*
* Copyright 2013 Hannes Janetzek
- * Copyright 2016-2020 devemux86
+ * Copyright 2016-2021 devemux86
* Copyright 2016 Stephan Leuschner
* Copyright 2016 Pedinel
* Copyright 2019 Carlos Alberto MartÃnez Gadea
@@ -78,7 +78,7 @@ public class ItemizedLayer extends MarkerLayer implements GestureListener {
}
@Override
- protected synchronized MarkerInterface createItem(int index) {
+ public synchronized MarkerInterface createItem(int index) {
return mItemList.get(index);
}
diff --git a/vtm/src/org/oscim/layers/marker/MarkerItem.java b/vtm/src/org/oscim/layers/marker/MarkerItem.java
index c5e88e61..de5380ee 100644
--- a/vtm/src/org/oscim/layers/marker/MarkerItem.java
+++ b/vtm/src/org/oscim/layers/marker/MarkerItem.java
@@ -8,7 +8,6 @@
* Copyright 2016 devemux86
* Copyright 2016 Erik Duisters
* Copyright 2017 Longri
- * Copyright 2017 nebular
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -82,18 +81,4 @@ public class MarkerItem implements MarkerInterface {
if (mMarker != null)
mMarker.setRotation(rotation);
}
-
- /**
- * If a MarkerItem is created using this convenience class instead of MarkerItem,
- * this specific item will not be clusterable.
- */
- public static class NonClusterable extends MarkerItem {
- public NonClusterable(String title, String description, GeoPoint geoPoint) {
- super(null, title, description, geoPoint);
- }
-
- public NonClusterable(Object uid, String title, String description, GeoPoint geoPoint) {
- super(uid, title, description, geoPoint);
- }
- }
}
diff --git a/vtm/src/org/oscim/layers/marker/MarkerLayer.java b/vtm/src/org/oscim/layers/marker/MarkerLayer.java
index abc5acc6..3dec2801 100644
--- a/vtm/src/org/oscim/layers/marker/MarkerLayer.java
+++ b/vtm/src/org/oscim/layers/marker/MarkerLayer.java
@@ -6,7 +6,7 @@
*
* Copyright 2013 Hannes Janetzek
* Copyright 2016 Stephan Leuschner
- * Copyright 2016-2020 devemux86
+ * Copyright 2016-2021 devemux86
* Copyright 2017 Longri
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
@@ -43,7 +43,7 @@ public abstract class MarkerLayer extends Layer {
* Method by which subclasses create the actual Items. This will only be
* called from populate() we'll cache them for later use.
*/
- protected abstract MarkerInterface createItem(int i);
+ public abstract MarkerInterface createItem(int i);
/**
* The number of items in this overlay.