Android 中的 osm 地图中出现未知标记
Unknown marker appearing in osm maps in Android
我正在使用 Open Street View Maps 创建一个 Android 应用程序。我正在使用下面的库。
implementation 'org.osmdroid:osmdroid-android:6.0.2'
我也在使用集群机制对集群中的标记进行分组。为此,我正在使用下面的奖励包库。
implementation 'com.github.MKergall:osmbonuspack:6.5.2'
到目前为止一切正常。我有自己的集群图标和标记图标。下面是相同的代码
private void populateMarkers(final List<Datum> datumList) {
if (datumList != null) {
CustomMarkerClusterer poiMarkers = new CustomMarkerClusterer(this);
map.getOverlays().add(poiMarkers);
for (int i = 0; i < datumList.size(); i++) {
Marker marker = new Marker(map);
marker.setPosition(new GeoPoint(Double.parseDouble(datumList.get(i).getLat()), Double.parseDouble(datumList.get(i).getLng())));
Drawable currentDraw = ResourcesCompat.getDrawable(getResources(), R.drawable.location_marker, null);
marker.setIcon(currentDraw);
final int finalI = i;
marker.setOnMarkerClickListener((marker1, mapView) -> {
if (marker1.isInfoWindowShown()) {
InfoWindow.closeAllInfoWindowsOn(mapView);
} else {
mapView.getController().animateTo(new GeoPoint(marker1.getPosition().getLatitude(), marker1.getPosition().getLongitude()));
getMarkerDetails(marker1, datumList.get(finalI).getId());
}
return false;
});
poiMarkers.add(marker);
poiMarkers.setRadius(300);
poiMarkers.getTextPaint().setColor(Color.BLACK);
map.invalidate();
}
}
progressDialog.dismiss();
}
现在的问题是,当我放大查看集群中的标记时,地图上出现了未知类型的标记。未知我的意思是我没有为那种类型的标记编写任何代码,我的项目中也没有那种标记图标图像。
我目前不知道那个标记图标出现在哪里。看截图
查看屏幕截图中的绿色手形图标。我问的是那个图标。这个东西既不可点击也不会在点击时显示任何信息窗口,而我在标记点击时打开了一个信息窗口。
CustomMarkerClusterer class 代码
public class CustomMarkerClusterer extends MarkerClusterer {
private int mMaxClusteringZoomLevel = 17;
private int mRadiusInPixels = 100;
private double mRadiusInMeters;
private Paint mTextPaint;
private ArrayList<Marker> mClonedMarkers;
private Context context;
private long firstClick;
private long lastClick;
private int count;
/**
* cluster icon anchor
*/
public float mAnchorU = Marker.ANCHOR_CENTER, mAnchorV = Marker.ANCHOR_CENTER;
/**
* anchor point to draw the number of markers inside the cluster icon
*/
public float mTextAnchorU = Marker.ANCHOR_CENTER, mTextAnchorV = Marker.ANCHOR_CENTER;
public CustomMarkerClusterer(Context ctx) {
super();
mTextPaint = new Paint();
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextSize(15 * ctx.getResources().getDisplayMetrics().density);
mTextPaint.setFakeBoldText(true);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setAntiAlias(true);
this.context = ctx;
Drawable clusterIconD = ctx.getResources().getDrawable(R.drawable.cluster2);
Bitmap clusterIcon = ((BitmapDrawable) clusterIconD).getBitmap();
setIcon(clusterIcon);
}
/**
* If you want to change the default text paint (color, size, font)
*/
public Paint getTextPaint() {
return mTextPaint;
}
/**
* Set the radius of clustering in pixels. Default is 100px.
*/
public void setRadius(int radius) {
mRadiusInPixels = radius;
}
/**
* Set max zoom level with clustering. When zoom is higher or equal to this level, clustering is disabled.
* You can put a high value to disable this feature.
*/
public void setMaxClusteringZoomLevel(int zoom) {
mMaxClusteringZoomLevel = zoom;
}
/**
* Radius-Based clustering algorithm
*/
@Override
public ArrayList<StaticCluster> clusterer(MapView mapView) {
ArrayList<StaticCluster> clusters = new ArrayList<StaticCluster>();
convertRadiusToMeters(mapView);
mClonedMarkers = new ArrayList<Marker>(mItems); //shallow copy
while (!mClonedMarkers.isEmpty()) {
Marker m = mClonedMarkers.get(0);
m.setIcon(context.getResources().getDrawable(R.drawable.location_marker));
StaticCluster cluster = createCluster(m, mapView);
clusters.add(cluster);
}
return clusters;
}
private StaticCluster createCluster(Marker m, MapView mapView) {
GeoPoint clusterPosition = m.getPosition();
StaticCluster cluster = new StaticCluster(clusterPosition);
cluster.add(m);
mClonedMarkers.remove(m);
if (mapView.getZoomLevel() > mMaxClusteringZoomLevel) {
//above max level => block clustering:
return cluster;
}
Iterator<Marker> it = mClonedMarkers.iterator();
while (it.hasNext()) {
Marker neighbour = it.next();
double distance = clusterPosition.distanceToAsDouble(neighbour.getPosition());
if (distance <= mRadiusInMeters) {
cluster.add(neighbour);
it.remove();
}
}
return cluster;
}
@Override
public Marker buildClusterMarker(StaticCluster cluster, MapView mapView) {
Marker m = new Marker(mapView);
m.setPosition(cluster.getPosition());
m.setInfoWindow(null);
m.setAnchor(mAnchorU, mAnchorV);
Bitmap mutableBitmap=null;
if (cluster.getSize() < 10) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster1)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
// iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
} else if (cluster.getSize() > 10 && cluster.getSize() < 100) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster3)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
//iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
} else if (cluster.getSize() > 100) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster2)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
//iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
}
m.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker, MapView mapView) {
mapView.getController().setZoom(mapView.getZoomLevelDouble()+2);
return true;
}
});
// m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
return m;
}
@Override
public void renderer(ArrayList<StaticCluster> clusters, Canvas canvas, MapView mapView) {
for (StaticCluster cluster : clusters) {
if (cluster.getSize() == 1) {
//cluster has only 1 marker => use it as it is:
cluster.setMarker(cluster.getItem(0));
} else {
//only draw 1 Marker at Cluster center, displaying number of Markers contained
Marker m = buildClusterMarker(cluster, mapView);
cluster.setMarker(m);
}
}
}
private void convertRadiusToMeters(MapView mapView) {
Rect mScreenRect = mapView.getIntrinsicScreenRect(null);
int screenWidth = mScreenRect.right - mScreenRect.left;
int screenHeight = mScreenRect.bottom - mScreenRect.top;
BoundingBox bb = mapView.getBoundingBox();
double diagonalInMeters = bb.getDiagonalLengthInMeters();
double diagonalInPixels = Math.sqrt(screenWidth * screenWidth + screenHeight * screenHeight);
double metersInPixel = diagonalInMeters / diagonalInPixels;
mRadiusInMeters = mRadiusInPixels * metersInPixel;
}
}
您的 buildClusterMarker 有问题:
看看当簇大小为 = 10 或 = 100 时会发生什么:
两种情况下都没有 "if"。所以 m.setIcon 没有被调用,你仍然有默认的 osmdroid 标记图标:这个有趣的 "green color hand icon"。
顺便说一句,为什么你复制整个 RadiusMarkerClusterer 代码,当你可以从它继承并(正确地)实现你自己的 buildClusterMarker ???永远不应该做的事情的完美例子。
我正在使用 Open Street View Maps 创建一个 Android 应用程序。我正在使用下面的库。
implementation 'org.osmdroid:osmdroid-android:6.0.2'
我也在使用集群机制对集群中的标记进行分组。为此,我正在使用下面的奖励包库。
implementation 'com.github.MKergall:osmbonuspack:6.5.2'
到目前为止一切正常。我有自己的集群图标和标记图标。下面是相同的代码
private void populateMarkers(final List<Datum> datumList) {
if (datumList != null) {
CustomMarkerClusterer poiMarkers = new CustomMarkerClusterer(this);
map.getOverlays().add(poiMarkers);
for (int i = 0; i < datumList.size(); i++) {
Marker marker = new Marker(map);
marker.setPosition(new GeoPoint(Double.parseDouble(datumList.get(i).getLat()), Double.parseDouble(datumList.get(i).getLng())));
Drawable currentDraw = ResourcesCompat.getDrawable(getResources(), R.drawable.location_marker, null);
marker.setIcon(currentDraw);
final int finalI = i;
marker.setOnMarkerClickListener((marker1, mapView) -> {
if (marker1.isInfoWindowShown()) {
InfoWindow.closeAllInfoWindowsOn(mapView);
} else {
mapView.getController().animateTo(new GeoPoint(marker1.getPosition().getLatitude(), marker1.getPosition().getLongitude()));
getMarkerDetails(marker1, datumList.get(finalI).getId());
}
return false;
});
poiMarkers.add(marker);
poiMarkers.setRadius(300);
poiMarkers.getTextPaint().setColor(Color.BLACK);
map.invalidate();
}
}
progressDialog.dismiss();
}
现在的问题是,当我放大查看集群中的标记时,地图上出现了未知类型的标记。未知我的意思是我没有为那种类型的标记编写任何代码,我的项目中也没有那种标记图标图像。
我目前不知道那个标记图标出现在哪里。看截图
查看屏幕截图中的绿色手形图标。我问的是那个图标。这个东西既不可点击也不会在点击时显示任何信息窗口,而我在标记点击时打开了一个信息窗口。
CustomMarkerClusterer class 代码
public class CustomMarkerClusterer extends MarkerClusterer {
private int mMaxClusteringZoomLevel = 17;
private int mRadiusInPixels = 100;
private double mRadiusInMeters;
private Paint mTextPaint;
private ArrayList<Marker> mClonedMarkers;
private Context context;
private long firstClick;
private long lastClick;
private int count;
/**
* cluster icon anchor
*/
public float mAnchorU = Marker.ANCHOR_CENTER, mAnchorV = Marker.ANCHOR_CENTER;
/**
* anchor point to draw the number of markers inside the cluster icon
*/
public float mTextAnchorU = Marker.ANCHOR_CENTER, mTextAnchorV = Marker.ANCHOR_CENTER;
public CustomMarkerClusterer(Context ctx) {
super();
mTextPaint = new Paint();
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextSize(15 * ctx.getResources().getDisplayMetrics().density);
mTextPaint.setFakeBoldText(true);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setAntiAlias(true);
this.context = ctx;
Drawable clusterIconD = ctx.getResources().getDrawable(R.drawable.cluster2);
Bitmap clusterIcon = ((BitmapDrawable) clusterIconD).getBitmap();
setIcon(clusterIcon);
}
/**
* If you want to change the default text paint (color, size, font)
*/
public Paint getTextPaint() {
return mTextPaint;
}
/**
* Set the radius of clustering in pixels. Default is 100px.
*/
public void setRadius(int radius) {
mRadiusInPixels = radius;
}
/**
* Set max zoom level with clustering. When zoom is higher or equal to this level, clustering is disabled.
* You can put a high value to disable this feature.
*/
public void setMaxClusteringZoomLevel(int zoom) {
mMaxClusteringZoomLevel = zoom;
}
/**
* Radius-Based clustering algorithm
*/
@Override
public ArrayList<StaticCluster> clusterer(MapView mapView) {
ArrayList<StaticCluster> clusters = new ArrayList<StaticCluster>();
convertRadiusToMeters(mapView);
mClonedMarkers = new ArrayList<Marker>(mItems); //shallow copy
while (!mClonedMarkers.isEmpty()) {
Marker m = mClonedMarkers.get(0);
m.setIcon(context.getResources().getDrawable(R.drawable.location_marker));
StaticCluster cluster = createCluster(m, mapView);
clusters.add(cluster);
}
return clusters;
}
private StaticCluster createCluster(Marker m, MapView mapView) {
GeoPoint clusterPosition = m.getPosition();
StaticCluster cluster = new StaticCluster(clusterPosition);
cluster.add(m);
mClonedMarkers.remove(m);
if (mapView.getZoomLevel() > mMaxClusteringZoomLevel) {
//above max level => block clustering:
return cluster;
}
Iterator<Marker> it = mClonedMarkers.iterator();
while (it.hasNext()) {
Marker neighbour = it.next();
double distance = clusterPosition.distanceToAsDouble(neighbour.getPosition());
if (distance <= mRadiusInMeters) {
cluster.add(neighbour);
it.remove();
}
}
return cluster;
}
@Override
public Marker buildClusterMarker(StaticCluster cluster, MapView mapView) {
Marker m = new Marker(mapView);
m.setPosition(cluster.getPosition());
m.setInfoWindow(null);
m.setAnchor(mAnchorU, mAnchorV);
Bitmap mutableBitmap=null;
if (cluster.getSize() < 10) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster1)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
// iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
} else if (cluster.getSize() > 10 && cluster.getSize() < 100) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster3)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
//iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
} else if (cluster.getSize() > 100) {
Bitmap icon = Bitmap.createBitmap(((BitmapDrawable) context.getResources().getDrawable(R.drawable.cluster2)).getBitmap());
mutableBitmap = icon.copy(Bitmap.Config.ARGB_8888, true);
Canvas iconCanvas = new Canvas(mutableBitmap);
//iconCanvas.drawBitmap(mClusterIcon, 0, 0, null);
String text = "" + cluster.getSize();
int textHeight = (int) (mTextPaint.descent() + mTextPaint.ascent());
iconCanvas.drawText(text,
mTextAnchorU * icon.getWidth(),
mTextAnchorV * icon.getHeight() - textHeight / 2,
mTextPaint);
m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
}
m.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker, MapView mapView) {
mapView.getController().setZoom(mapView.getZoomLevelDouble()+2);
return true;
}
});
// m.setIcon(new BitmapDrawable(mapView.getContext().getResources(), mutableBitmap));
return m;
}
@Override
public void renderer(ArrayList<StaticCluster> clusters, Canvas canvas, MapView mapView) {
for (StaticCluster cluster : clusters) {
if (cluster.getSize() == 1) {
//cluster has only 1 marker => use it as it is:
cluster.setMarker(cluster.getItem(0));
} else {
//only draw 1 Marker at Cluster center, displaying number of Markers contained
Marker m = buildClusterMarker(cluster, mapView);
cluster.setMarker(m);
}
}
}
private void convertRadiusToMeters(MapView mapView) {
Rect mScreenRect = mapView.getIntrinsicScreenRect(null);
int screenWidth = mScreenRect.right - mScreenRect.left;
int screenHeight = mScreenRect.bottom - mScreenRect.top;
BoundingBox bb = mapView.getBoundingBox();
double diagonalInMeters = bb.getDiagonalLengthInMeters();
double diagonalInPixels = Math.sqrt(screenWidth * screenWidth + screenHeight * screenHeight);
double metersInPixel = diagonalInMeters / diagonalInPixels;
mRadiusInMeters = mRadiusInPixels * metersInPixel;
}
}
您的 buildClusterMarker 有问题: 看看当簇大小为 = 10 或 = 100 时会发生什么: 两种情况下都没有 "if"。所以 m.setIcon 没有被调用,你仍然有默认的 osmdroid 标记图标:这个有趣的 "green color hand icon"。
顺便说一句,为什么你复制整个 RadiusMarkerClusterer 代码,当你可以从它继承并(正确地)实现你自己的 buildClusterMarker ???永远不应该做的事情的完美例子。