com.mapbox.mapboxsdk.maps.IconManager Maven / Gradle / Ivy
package com.mapbox.mapboxsdk.maps;
import android.graphics.Bitmap;
import android.util.DisplayMetrics;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerView;
import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* Responsible for managing icons added to the Map.
*
* Maintains a {@link List} of {@link Icon} and is responsible for initialising default markers and
* setting up {@link MarkerView} annotation ghosting.
*
*
* Keep track of icons added and the resulting average icon size. This is used internally by our
* gestures detection to calculate the size of a touch target.
*
*/
class IconManager {
private NativeMapView nativeMapView;
private List icons;
private int averageIconHeight;
private int averageIconWidth;
IconManager(NativeMapView nativeMapView) {
this.nativeMapView = nativeMapView;
this.icons = new ArrayList<>();
// load transparent icon for MarkerView to trace actual markers, see #6352
loadIcon(IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, IconFactory.ICON_MARKERVIEW_BITMAP));
}
Icon loadIconForMarker(Marker marker) {
Icon icon = marker.getIcon();
// calculating average before adding
int iconSize = icons.size() + 1;
// TODO replace former if case with anchor implementation,
// current workaround for having extra pixels is diving height by 2
if (icon == null) {
icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker();
Bitmap bitmap = icon.getBitmap();
averageIconHeight = averageIconHeight + (bitmap.getHeight() / 2 - averageIconHeight) / iconSize;
averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
marker.setIcon(icon);
} else {
Bitmap bitmap = icon.getBitmap();
averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
}
if (!icons.contains(icon)) {
icons.add(icon);
loadIcon(icon);
} else {
Icon oldIcon = icons.get(icons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
return icon;
}
int getTopOffsetPixelsForIcon(Icon icon) {
return (int) (nativeMapView.getTopOffsetPixelsForAnnotationSymbol(icon.getId()) * nativeMapView.getPixelRatio());
}
void loadIcon(Icon icon) {
Bitmap bitmap = icon.getBitmap();
String id = icon.getId();
if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
}
ByteBuffer buffer = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight());
bitmap.copyPixelsToBuffer(buffer);
float density = bitmap.getDensity();
if (density == Bitmap.DENSITY_NONE) {
density = DisplayMetrics.DENSITY_DEFAULT;
}
float scale = density / DisplayMetrics.DENSITY_DEFAULT;
nativeMapView.addAnnotationIcon(
id,
bitmap.getWidth(),
bitmap.getHeight(),
scale, buffer.array());
}
void reloadIcons() {
int count = icons.size();
for (int i = 0; i < count; i++) {
Icon icon = icons.get(i);
loadIcon(icon);
}
}
void ensureIconLoaded(Marker marker, MapboxMap mapboxMap) {
Icon icon = marker.getIcon();
if (icon == null) {
icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker();
marker.setIcon(icon);
}
if (!icons.contains(icon)) {
icons.add(icon);
loadIcon(icon);
} else {
Icon oldIcon = icons.get(icons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
// this seems to be a costly operation according to the profiler so I'm trying to save some calls
Marker previousMarker = marker.getId() != -1 ? (Marker) mapboxMap.getAnnotation(marker.getId()) : null;
if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
}
}
int getAverageIconHeight() {
return averageIconHeight;
}
int getAverageIconWidth() {
return averageIconWidth;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy