高德地图五:室内地图功能

高德地图五:室内地图功能

什么是室内地图

室内地图一般指大型室内建筑的内部地图,与室外地图相比,更注重小区域、大比例尺、高精度和精细化的内部元素展现。

室内地图涉及商业设施、交通设施、文化设施、教育设施、医疗设施、演出场馆等大型室内场馆的地图深度精细数据,天然具备丰富多样的应用场景和业务,
可基于室内地图扩展各种行业的业务应用。

室内地图数据
室内地图数据,较之室外,更加精细;且室内建筑类型多样,使得室内地图数据更加复杂。既包括吸烟室、充电处、问讯处、ATM、母婴室等在内的室内公共设施,
也包括扶梯、电梯、楼梯、商铺门、出入口等在内的室内通行设施;既包括详细的属性信息,也包括精准位置的空间信息。与此同时,室内地图数据对数据空间
坐标精度也有较高要求。

地图数据是地图应用的基础,需要严格控制数据质量,以更好地支撑地图应用。

室内地图数据生产需要依据专业的地图数据生产流程,遵循标准的室内地图数据生产标准和规范,历经严格的内外业处理以及质检处理,才能满足数据质量要求,满足地图应用需要。

实例:
layout/activity_main.xml

		

		

			

			

			

				

				
			

		

com/example/administrator/MainActivity.java

		package com.example.administrator;

		import android.app.Activity;
		import android.os.Bundle;
		import android.os.Handler;
		import android.util.Log;
		import com.amap.api.maps.AMap;
		import com.amap.api.maps.AMap.OnMapLoadedListener;
		import com.amap.api.maps.CameraUpdateFactory;
		import com.amap.api.maps.MapView;
		import com.amap.api.maps.model.IndoorBuildingInfo;
		import com.amap.api.maps.model.LatLng;

		public class MainActivity extends Activity{
			private MapView mapView;
			private AMap aMap;

			IndoorFloorSwitchView floorSwitchView;
			private Handler handler = new Handler();
			@Override
			protected void onCreate(Bundle savedInstanceState) {
				super.onCreate(savedInstanceState);
				setContentView(R.layout.activity_main);
				mapView = (MapView) findViewById(R.id.map);
				mapView.onCreate(savedInstanceState);// 此方法必须重写
				floorSwitchView = (IndoorFloorSwitchView) findViewById(R.id.indoor_switchview);
				init();
				// 设置楼层控制控件监听
				floorSwitchView.setOnIndoorFloorSwitchListener(new MyIndoorSwitchViewAdapter());
				// 设置室内地图回调监听
				aMap.setOnIndoorBuildingActiveListener(new AMap.OnIndoorBuildingActiveListener() {
					@Override
					public void OnIndoorBuilding(final IndoorBuildingInfo indoorBuildingInfo) {
						Log.i("amap", "indoor OnIndoorBuilding " + indoorBuildingInfo);
						if (indoorBuildingInfo != null) {
							handler.post(new Runnable() {
								@Override
								public void run() {
									floorSwitchView.setVisible(true);
									//相同室内图,不需要替换楼层总数,只需要设置选中的楼层即可
									if (mIndoorBuildingInfo == null || !mIndoorBuildingInfo.poiid.equals(indoorBuildingInfo.poiid)) {
										floorSwitchView.setItems(indoorBuildingInfo.floor_names);
										floorSwitchView.setSeletion(indoorBuildingInfo.activeFloorName);
									}


									mIndoorBuildingInfo = indoorBuildingInfo;
								}
							});
						} else {
							Log.i("amap", "indoor OnIndoorBuilding  indoor disappear");
							floorSwitchView.setVisible(false);
						}
					}
				});

				aMap.setOnMapLoadedListener(new OnMapLoadedListener() {
					@Override
					public void onMapLoaded() {
						// 室内地图默认不显示,这里把它设置成显示
						aMap.showIndoorMap(true);
						// 关闭SDK自带的室内地图控件
						aMap.getUiSettings().setIndoorSwitchEnabled(false);

						//移动到有室内地图的地方,放大级别才可以看见
						aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.91095, 116.37296), 19));

					}
				});
			}

			/**
			 * 初始化AMap对象
			 */
			private void init() {
				if (aMap == null) {
					aMap = mapView.getMap();
					aMap.getUiSettings().setScaleControlsEnabled(true);
				}
			}

			/**
			 * 方法必须重写
			 */
			@Override
			protected void onResume() {
				super.onResume();
				mapView.onResume();
			}

			/**
			 * 方法必须重写
			 */
			@Override
			protected void onPause() {
				super.onPause();
				mapView.onPause();
			}

			/**
			 * 方法必须重写
			 */
			@Override
			protected void onSaveInstanceState(Bundle outState) {
				super.onSaveInstanceState(outState);
				mapView.onSaveInstanceState(outState);
			}

			/**
			 * 方法必须重写
			 */
			@Override
			protected void onDestroy() {
				super.onDestroy();
				mapView.onDestroy();
			}

			/**
			 * 室内地图信息
			 */
			IndoorBuildingInfo mIndoorBuildingInfo = null;

			private class MyIndoorSwitchViewAdapter implements IndoorFloorSwitchView.OnIndoorFloorSwitchListener {
				@Override
				public void onSelected(final int selectedIndex) {
					Log.i("amap", "indoor onselected " + selectedIndex);
					if (mIndoorBuildingInfo != null) {
						mIndoorBuildingInfo.activeFloorIndex = mIndoorBuildingInfo.floor_indexs[selectedIndex];
						mIndoorBuildingInfo.activeFloorName = mIndoorBuildingInfo.floor_names[selectedIndex];
						aMap.setIndoorBuildingInfo(mIndoorBuildingInfo);
					}
				}

			}

		}

com/example/administrator/IndoorFloorSwitchView.java

		package com.example.administrator;

		import android.app.Activity;
		import android.content.Context;
		import android.graphics.Bitmap;
		import android.graphics.BitmapFactory;
		import android.graphics.Canvas;
		import android.graphics.Color;
		import android.graphics.ColorFilter;
		import android.graphics.Paint;
		import android.graphics.Rect;
		import android.graphics.drawable.Drawable;
		import android.text.TextPaint;
		import android.util.AttributeSet;
		import android.util.TypedValue;
		import android.view.Gravity;
		import android.view.MotionEvent;
		import android.view.View;
		import android.view.ViewGroup;
		import android.widget.LinearLayout;
		import android.widget.ScrollView;
		import android.widget.TextView;

		import java.util.ArrayList;
		import java.util.List;

		/**
		 * 楼层控制控件
		 */
		public class IndoorFloorSwitchView extends ScrollView {
			public static final String TAG = IndoorFloorSwitchView.class
					.getSimpleName();

			private Context context;

			private LinearLayout views;

			private int itemHeight = 0;
			private List items;

			private int scrollDirection = -1;
			private static final int SCROLL_DIRECTION_UP = 0;
			private static final int SCROLL_DIRECTION_DOWN = 1;

			private int viewWidth;

			private Bitmap selectBitmap = null;

			private int backGroundColor = Color.parseColor("#eeffffff");
			private int strokeColor = Color.parseColor("#44383838");
			private int strokeWidth = 4; // 边框宽度

			private int offset = 1; // 偏移量在最前面和最后面补全
			private int displayItemCount; // 每页显示的数
			int selectedIndex = 1;

			private int initialY;

			private Runnable scrollerTask;
			private int newCheck = 50;

			public IndoorFloorSwitchView(Context context) {
				super(context);
				init(context);
			}

			public IndoorFloorSwitchView(Context context, AttributeSet attrs) {
				super(context, attrs);
				init(context);
			}

			public IndoorFloorSwitchView(Context context, AttributeSet attrs,
										 int defStyle) {
				super(context, attrs, defStyle);
				init(context);
			}

			public int getOffset() {
				return offset;
			}

			/**
			 * 修改偏移量,即当第一个显示在中间是上面有几个空白
* 也会影响整体显示,如设置1,上下各偏移1,总共显3个;设置2总共显示5个; * * @param offset */ public void setOffset(int offset) { this.offset = offset; } private void init(Context context) { this.context = context; this.setVerticalScrollBarEnabled(false); selectBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.map_indoor_select); views = new LinearLayout(context); views.setOrientation(LinearLayout.VERTICAL); this.addView(views); scrollerTask = new Runnable() { public void run() { int newY = getScrollY(); if (initialY - newY == 0) { // stopped final int remainder = initialY % itemHeight; final int divided = initialY / itemHeight; if (remainder == 0) { selectedIndex = divided + offset; onSeletedCallBack(); } else { if (remainder > itemHeight / 2) { IndoorFloorSwitchView.this.post(new Runnable() { @Override public void run() { IndoorFloorSwitchView.this.smoothScrollTo( 0, initialY - remainder + itemHeight); selectedIndex = divided + offset + 1; onSeletedCallBack(); } }); } else { IndoorFloorSwitchView.this.post(new Runnable() { @Override public void run() { IndoorFloorSwitchView.this.smoothScrollTo( 0, initialY - remainder); selectedIndex = divided + offset; onSeletedCallBack(); } }); } } } else { initialY = getScrollY(); IndoorFloorSwitchView.this.postDelayed(scrollerTask, newCheck); } } }; } public void startScrollerTask() { initialY = getScrollY(); this.postDelayed(scrollerTask, newCheck); } private void initData() { if(items==null||items.size()==0){ return; } views.removeAllViews(); displayItemCount = offset * 2 + 1; for (int i=items.size()-1;i>=0;i--) { views.addView(createView(items.get(i))); } refreshItemView(0); } private TextView createView(String item) { TextView tv = new TextView(context); tv.setLayoutParams(new LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); tv.setSingleLine(true); tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); tv.setText(item); tv.setGravity(Gravity.CENTER); TextPaint tp = tv.getPaint(); tp.setFakeBoldText(true); int padding_h = dip2px(context, 8); int padding_v = dip2px(context, 6); tv.setPadding(padding_h, padding_v, padding_h, padding_v); if (0 == itemHeight) { itemHeight = getViewMeasuredHeight(tv); views.setLayoutParams(new LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, itemHeight * displayItemCount)); this.setLayoutParams(new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, itemHeight * displayItemCount)); } return tv; } private void refreshItemView(int y) { int position = y / itemHeight + offset; int remainder = y % itemHeight; int divided = y / itemHeight; if (remainder == 0) { position = divided + offset; } else { if (remainder > itemHeight / 2) { position = divided + offset + 1; } } int childSize = views.getChildCount(); for (int i = 0; i < childSize; i++) { TextView itemView = (TextView) views.getChildAt(i); if (null == itemView) { return; } if (position == i) { itemView.setTextColor(Color.parseColor("#0288ce")); } else { itemView.setTextColor(Color.parseColor("#bbbbbb")); } } } private List getItems() { return items; } /** * 设置显示的内* * * @param list */ public void setItems(List list) { if (null == items) { items = new ArrayList(); } items.clear(); items.addAll(list); // 前面和后面补 for (int i = 0; i < offset; i++) { items.add(0, ""); items.add(""); } initData(); } /** * 设置显示的内* * * @param strs */ public void setItems(String[] strs) { if (null == items) { items = new ArrayList(); } items.clear(); for (int i = 0; i < strs.length; i++) items.add(strs[i]); // 前面和后面补 for (int i = 0; i < offset; i++) { items.add(0, ""); items.add(""); } initData(); } public void setBackgroundColor(int color) { this.backGroundColor = color; } public void setStrokeColor(int color) { this.strokeColor = color; } public void setStrokeWidth(int width) { this.strokeWidth = width; } /** * 设置选中状图片 * * @param bitmap */ public void setIndoorSelectBitmap(Bitmap bitmap) { this.selectBitmap = bitmap; } public void destroy() { if (selectBitmap != null && !selectBitmap.isRecycled()) { selectBitmap.recycle(); selectBitmap = null; } } @Override public void setBackgroundDrawable(Drawable background) { if (viewWidth == 0) { viewWidth = ((Activity) context).getWindowManager() .getDefaultDisplay().getWidth(); } background = new Drawable() { @Override public void draw(Canvas canvas) { try { drawBg(canvas); drawCenterLine(canvas); drawStroke(canvas); } catch (Throwable e) { } } private void drawBg(Canvas canvas) { canvas.drawColor(backGroundColor); } /** * @param canvas */ private void drawCenterLine(Canvas canvas) { final Paint paint = new Paint(); Rect src = new Rect();// 图片 >>原矩 Rect dst = new Rect();// 屏幕 >>目标矩形 src.left = 0; src.top = 0; src.right = 0 + selectBitmap.getWidth(); src.bottom = 0 + selectBitmap.getHeight(); dst.left = 0; dst.top = obtainSelectedAreaBorder()[0]; dst.right = 0 + viewWidth; dst.bottom = obtainSelectedAreaBorder()[1]; canvas.drawBitmap(selectBitmap, src, dst, paint); } /** * @param canvas */ private void drawStroke(Canvas canvas) { final Paint mPaint = new Paint(); Rect rect = canvas.getClipBounds(); mPaint.setColor(strokeColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(strokeWidth); canvas.drawRect(rect, mPaint); } @Override public void setAlpha(int alpha) { } @Override public void setColorFilter(ColorFilter cf) { } @Override public int getOpacity() { return 0; } }; super.setBackgroundDrawable(background); } /** * 获取选中区域的边 */ private int[] obtainSelectedAreaBorder() { int[] selectedAreaBorder = null; if (null == selectedAreaBorder) { selectedAreaBorder = new int[2]; selectedAreaBorder[0] = itemHeight * offset; selectedAreaBorder[1] = itemHeight * (offset + 1); } return selectedAreaBorder; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); viewWidth = w; setBackgroundDrawable(null); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); refreshItemView(t); if (t > oldt) { scrollDirection = SCROLL_DIRECTION_DOWN; } else { scrollDirection = SCROLL_DIRECTION_UP; } } /** * 选中回调 */ private void onSeletedCallBack() { if (null != onIndoorFloorSwtichListener) { try { onIndoorFloorSwtichListener.onSelected(getSeletedIndex()); } catch (Throwable e) { } } } public void setSeletion(String selectValue) { if(items==null||items.size()==0){ return; } int position = items.indexOf(selectValue); final int p = items.size()-offset-1-position; selectedIndex = p + offset; this.post(new Runnable() { @Override public void run() { IndoorFloorSwitchView.this.smoothScrollTo(0, p * itemHeight); } }); } public String getSeletedItem() { return items.get(selectedIndex); } public int getSeletedIndex() { if(items==null||items.size()==0){ return 0; } int result = items.size()-1-selectedIndex - offset; return Math.min(items.size() - 2 * offset, Math.max(0, result)); } @Override public void fling(int velocityY) { super.fling(velocityY / 3); } @Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_UP) { startScrollerTask(); } return super.onTouchEvent(ev); } private OnIndoorFloorSwitchListener onIndoorFloorSwtichListener; public OnIndoorFloorSwitchListener getOnIndoorFloorSwitchListener() { return onIndoorFloorSwtichListener; } public void setOnIndoorFloorSwitchListener( OnIndoorFloorSwitchListener onIndoorFloorSwtichListener) { this.onIndoorFloorSwtichListener = onIndoorFloorSwtichListener; } public static abstract interface OnIndoorFloorSwitchListener { public abstract void onSelected(int selectedIndex); } // utils public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } /** * 获取控件的高度,如果获取的高度为0,则重新计算尺寸后再返回高度 * * @param view * @return */ public static int getViewMeasuredHeight(View view) { calcViewMeasure(view); return view.getMeasuredHeight(); } /** * 获取控件的宽度,如果获取的宽度为0,则重新计算尺寸后再返回宽度 * * @param view * @return */ public static int getViewMeasuredWidth(View view) { calcViewMeasure(view); return view.getMeasuredWidth(); } /** * 测量控件的尺* * * @param view */ public static void calcViewMeasure(View view) { int width = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int expandSpec = MeasureSpec.makeMeasureSpec( Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); view.measure(width, expandSpec); } public void setVisible(boolean isEnable) { if (isEnable) { if(!isVisible()) { setVisibility(VISIBLE); } } else { if(isVisible()) setVisibility(GONE); } } public boolean isVisible() { return getVisibility() == VISIBLE ? true : false; } }

你可能感兴趣的:(Android基础)