/* * Copyright 2016 NAVER Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.nhn.android.mapviewer; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.Log; import android.widget.ImageView; import android.widget.ListView; import com.nhn.android.maps.NMapOverlayItem; import com.nhn.android.maps.overlay.NMapPOIitem; import com.nhn.android.mapviewer.overlay.NMapResourceProvider; /** * Wrapper class to provider resources on map view. * * @author kyjkim */ public class NMapViewerResourceProvider extends NMapResourceProvider implements NMapCalloutCustomOldOverlay.ResourceProvider { private static final String LOG_TAG = "NMapViewerResourceProvider"; private static final boolean DEBUG = false; private static final Bitmap.Config BITMAP_CONFIG_DEFAULT = Bitmap.Config.ARGB_8888; private static final int POI_FONT_COLOR_NUMBER = 0xFF909090; private static final float POI_FONT_SIZE_NUMBER = 10.0F; private static final int POI_FONT_COLOR_ALPHABET = 0xFFFFFFFF; private static final float POI_FONT_OFFSET_ALPHABET = 6.0F; private static final Typeface POI_FONT_TYPEFACE = null;//Typeface.DEFAULT_BOLD; private static final int CALLOUT_TEXT_COLOR_NORMAL = 0xFFFFFFFF; private static final int CALLOUT_TEXT_COLOR_PRESSED = 0xFF9CA1AA; private static final int CALLOUT_TEXT_COLOR_SELECTED = 0xFFFFFFFF; private static final int CALLOUT_TEXT_COLOR_FOCUSED = 0xFFFFFFFF; private final Rect mTempRect = new Rect(); private final Paint mTextPaint = new Paint(); public NMapViewerResourceProvider(Context context) { super(context); mTextPaint.setAntiAlias(true); } /** * Get drawable for markerId at focused state * * @param markerId unique id for POI or Number icons. * @param focused true for focused state, false otherwise. * @return */ public Drawable getDrawable(int markerId, boolean focused, NMapOverlayItem item) { Drawable marker = null; int resourceId = findResourceIdForMarker(markerId, focused); if (resourceId > 0) { marker = mContext.getResources().getDrawable(resourceId); } else { resourceId = 4 * markerId; if (focused) { resourceId += 1; } marker = getDrawableForMarker(markerId, focused, item); } // set bounds if (marker != null) { setBounds(marker, markerId, item); } return marker; } public Bitmap getBitmap(int markerId, boolean focused, NMapOverlayItem item) { Bitmap bitmap = null; Drawable marker = getDrawable(markerId, focused, item); if (marker != null) { bitmap = getBitmap(marker); } return bitmap; } public Bitmap getBitmap(Drawable marker) { Bitmap bitmap = null; if (marker != null) { int width = marker.getIntrinsicWidth(); int height = marker.getIntrinsicHeight(); bitmap = Bitmap.createBitmap(width, height, BITMAP_CONFIG_DEFAULT); marker.setBounds(0, 0, width, height); Canvas canvas = new Canvas(bitmap); canvas.drawColor(0x00000000); marker.draw(canvas); } return bitmap; } public Bitmap getBitmap(int resourceId) { Bitmap bitmap = null; Drawable marker = null; if (resourceId > 0) { marker = mContext.getResources().getDrawable(resourceId); } if (marker != null) { bitmap = getBitmap(marker); } return bitmap; } public Bitmap getBitmapWithNumber(int resourceId, String strNumber, float offsetY, int fontColor, float fontSize) { Bitmap bitmap = null; Drawable marker = getDrawableWithNumber(resourceId, strNumber, offsetY, fontColor, fontSize); if (marker != null) { bitmap = getBitmap(marker); } return bitmap; } @Override public Drawable getDrawableForInfoLayer(NMapOverlayItem item) { return null; } /** * Class to find resource Ids on map view */ private class ResourceIdsOnMap { int markerId; int resourceId; int resourceIdFocused; ResourceIdsOnMap(int markerId, int resourceId, int resourceIdFocused) { this.markerId = markerId; this.resourceId = resourceId; this.resourceIdFocused = resourceIdFocused; } } // Resource Ids for single icons private final ResourceIdsOnMap mResourceIdsForMarkerOnMap[] = { // Spot, Pin icons new ResourceIdsOnMap(NMapPOIflagType.PIN, R.drawable.ic_pin_01, R.drawable.ic_pin_02), new ResourceIdsOnMap(NMapPOIflagType.SPOT, R.drawable.ic_pin_01, R.drawable.ic_pin_02), // Direction POI icons: From, To new ResourceIdsOnMap(NMapPOIflagType.FROM, R.drawable.ic_map_start, R.drawable.ic_map_start_over), new ResourceIdsOnMap(NMapPOIflagType.TO, R.drawable.ic_map_arrive, R.drawable.ic_map_arrive_over), }; /** * Find resource id corresponding to the markerId. * * @param markerId marker id for a NMapPOIitem. * @param focused flag to indicated focused or normal state of this marker. * * @return resource id for the given markerId. * * @see NMapPOIflagType */ @Override protected int findResourceIdForMarker(int markerId, boolean focused) { int resourceId = 0; if (DEBUG) { Log.i(LOG_TAG, "getResourceIdForMarker: markerId=" + markerId + ", focused=" + focused); } if (markerId < NMapPOIflagType.SINGLE_MARKER_END) { resourceId = getResourceIdOnMapView(markerId, focused, mResourceIdsForMarkerOnMap); if (resourceId > 0) { return resourceId; } } if (markerId >= NMapPOIflagType.NUMBER_BASE && markerId < NMapPOIflagType.NUMBER_END) { // Direction Number icons } else if (markerId >= NMapPOIflagType.CUSTOM_BASE && markerId < NMapPOIflagType.CUSTOM_END) { // Custom POI icons } return resourceId; } /** * Set bounds for this marker depending on its shape. * */ @Override protected void setBounds(Drawable marker, int markerId, NMapOverlayItem item) { // check shape of the marker to set bounds correctly. if (NMapPOIflagType.isBoundsCentered(markerId)) { if (marker.getBounds().isEmpty()) { NMapOverlayItem.boundCenter(marker); } if (null != item) { item.setAnchorRatio(0.5f, 0.5f); } } else { if (marker.getBounds().isEmpty()) { NMapOverlayItem.boundCenterBottom(marker); } if (null != item) { item.setAnchorRatio(0.5f, 1.0f); } } } @Override public Drawable[] getLocationDot() { Drawable[] drawable = new Drawable[2]; drawable[0] = mContext.getResources().getDrawable(R.drawable.pubtrans_ic_mylocation_off); drawable[1] = mContext.getResources().getDrawable(R.drawable.pubtrans_ic_mylocation_on); for (int i = 0; i < drawable.length; i++) { int w = drawable[i].getIntrinsicWidth() / 2; int h = drawable[i].getIntrinsicHeight() / 2; drawable[i].setBounds(-w, -h, w, h); } return drawable; } @Override public Drawable getDirectionArrow() { Drawable drawable = mContext.getResources().getDrawable(R.drawable.ic_angle); if (drawable != null) { int w = drawable.getIntrinsicWidth() / 2; int h = drawable.getIntrinsicHeight() / 2; drawable.setBounds(-w, -h, w, h); } return drawable; } public Drawable getDrawableWithNumber(int resourceId, String strNumber, float offsetY, int fontColor, float fontSize) { Bitmap textBitmap = getBitmapWithText(resourceId, strNumber, fontColor, fontSize, offsetY); //Log.i(LOG_TAG, "getDrawableWithNumber: width=" + textBitmap.getWidth() + ", height=" + textBitmap.getHeight() + ", density=" + textBitmap.getDensity()); // set bounds Drawable marker = new BitmapDrawable(mContext.getResources(), textBitmap); if (marker != null) { NMapOverlayItem.boundCenter(marker); } //Log.i(LOG_TAG, "getDrawableWithNumber: width=" + marker.getIntrinsicWidth() + ", height=" + marker.getIntrinsicHeight()); return marker; } public Drawable getDrawableWithAlphabet(int resourceId, String strAlphabet, int fontColor, float fontSize) { Bitmap textBitmap = getBitmapWithText(resourceId, strAlphabet, fontColor, fontSize, POI_FONT_OFFSET_ALPHABET); // set bounds Drawable marker = new BitmapDrawable(mContext.getResources(), textBitmap); if (marker != null) { NMapOverlayItem.boundCenterBottom(marker); } return marker; } @Override protected Drawable getDrawableForMarker(int markerId, boolean focused, NMapOverlayItem item) { Drawable drawable = null; if (markerId >= NMapPOIflagType.NUMBER_BASE && markerId < NMapPOIflagType.NUMBER_END) { // Direction Number icons int resourceId = (focused) ? R.drawable.ic_map_no_02 : R.drawable.ic_map_no_01; int fontColor = (focused) ? POI_FONT_COLOR_ALPHABET : POI_FONT_COLOR_NUMBER; String strNumber = String.valueOf(markerId - NMapPOIflagType.NUMBER_BASE); drawable = getDrawableWithNumber(resourceId, strNumber, 0.0F, fontColor, POI_FONT_SIZE_NUMBER); } else if (markerId >= NMapPOIflagType.CUSTOM_BASE && markerId < NMapPOIflagType.CUSTOM_END) { // Custom POI icons } return drawable; } private Bitmap getBitmapWithText(int resourceId, String strNumber, int fontColor, float fontSize, float offsetY) { Bitmap bitmapBackground = BitmapFactory.decodeResource(mContext.getResources(), resourceId); int width = bitmapBackground.getWidth(); int height = bitmapBackground.getHeight(); //Log.i(LOG_TAG, "getBitmapWithText: width=" + width + ", height=" + height + ", density=" + bitmapBackground.getDensity()); Bitmap textBitmap = Bitmap.createBitmap(width, height, BITMAP_CONFIG_DEFAULT); Canvas canvas = new Canvas(textBitmap); canvas.drawBitmap(bitmapBackground, 0, 0, null); // set font style mTextPaint.setColor(fontColor); // set font size mTextPaint.setTextSize(fontSize * mScaleFactor); // set font type if (POI_FONT_TYPEFACE != null) { mTextPaint.setTypeface(POI_FONT_TYPEFACE); } // get text offset mTextPaint.getTextBounds(strNumber, 0, strNumber.length(), mTempRect); float offsetX = (width - mTempRect.width()) / 2 - mTempRect.left; if (offsetY == 0.0F) { offsetY = (height - mTempRect.height()) / 2 + mTempRect.height(); } else { offsetY = offsetY * mScaleFactor + mTempRect.height(); } //Log.i(LOG_TAG, "getBitmapWithText: number=" + number + ", focused=" + focused); //Log.i(LOG_TAG, "getBitmapWithText: offsetX=" + offsetX + ", offsetY=" + offsetY + ", boundsWidth=" + mTempRect.width() + ", boundsHeight=" + mTempRect.height()); // draw text canvas.drawText(strNumber, offsetX, offsetY, mTextPaint); return textBitmap; } @Override public Drawable getCalloutBackground(NMapOverlayItem item) { if (item instanceof NMapPOIitem) { NMapPOIitem poiItem = (NMapPOIitem)item; if (poiItem.showRightButton()) { Drawable drawable = mContext.getResources().getDrawable(R.drawable.bg_speech); return drawable; } } Drawable drawable = mContext.getResources().getDrawable(R.drawable.pin_ballon_bg); return drawable; } @Override public String getCalloutRightButtonText(NMapOverlayItem item) { if (item instanceof NMapPOIitem) { NMapPOIitem poiItem = (NMapPOIitem)item; if (poiItem.showRightButton()) { return mContext.getResources().getString(R.string.str_done); } } return null; } @Override public Drawable[] getCalloutRightButton(NMapOverlayItem item) { if (item instanceof NMapPOIitem) { NMapPOIitem poiItem = (NMapPOIitem)item; if (poiItem.showRightButton()) { Drawable[] drawable = new Drawable[3]; drawable[0] = mContext.getResources().getDrawable(R.drawable.btn_green_normal); drawable[1] = mContext.getResources().getDrawable(R.drawable.btn_green_pressed); drawable[2] = mContext.getResources().getDrawable(R.drawable.btn_green_highlight); return drawable; } } return null; } @Override public Drawable[] getCalloutRightAccessory(NMapOverlayItem item) { if (item instanceof NMapPOIitem) { NMapPOIitem poiItem = (NMapPOIitem)item; if (poiItem.hasRightAccessory() && (poiItem.getRightAccessoryId() > 0)) { Drawable[] drawable = new Drawable[3]; switch (poiItem.getRightAccessoryId()) { case NMapPOIflagType.CLICKABLE_ARROW: drawable[0] = mContext.getResources().getDrawable(R.drawable.pin_ballon_arrow); drawable[1] = mContext.getResources().getDrawable(R.drawable.pin_ballon_on_arrow); drawable[2] = mContext.getResources().getDrawable(R.drawable.pin_ballon_on_arrow); break; } return drawable; } } return null; } /** * 말풍선의 텍스트 색상을 customize한다. * * @param item * @return * @see com.nhn.android.mapviewer.overlay.NMapCalloutCustomOverlay.ResourceProvider#getCalloutTextColors(com.nhn.android.maps.NMapOverlayItem) */ @Override public int[] getCalloutTextColors(NMapOverlayItem item) { int[] colors = new int[4]; colors[0] = CALLOUT_TEXT_COLOR_NORMAL; colors[1] = CALLOUT_TEXT_COLOR_PRESSED; colors[2] = CALLOUT_TEXT_COLOR_SELECTED; colors[3] = CALLOUT_TEXT_COLOR_FOCUSED; return colors; } @Override public int getParentLayoutIdForOverlappedListView() { // not supported return 0; } @Override public int getOverlappedListViewId() { // not supported return 0; } @Override public int getLayoutIdForOverlappedListView() { // not supported return 0; } @Override public int getListItemLayoutIdForOverlappedListView() { // not supported return 0; } @Override public int getListItemTextViewId() { // not supported return 0; } @Override public int getListItemTailTextViewId() { // not supported return 0; } @Override public int getListItemImageViewId() { // not supported return 0; } @Override public int getListItemDividerId() { // not supported return 0; } @Override public void setOverlappedListViewLayout(ListView listView, int itemCount, int width, int height) { // not supported } @Override public void setOverlappedItemResource(NMapPOIitem poiItem, ImageView imageView) { // not supported } private int getResourceIdOnMapView(int markerId, boolean focused, ResourceIdsOnMap resourceIdsArray[]) { int resourceId = 0; for (ResourceIdsOnMap resourceIds : resourceIdsArray) { if (resourceIds.markerId == markerId) { resourceId = (focused) ? resourceIds.resourceIdFocused : resourceIds.resourceId; break; } } return resourceId; } }