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

什么是室内地图

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

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

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

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

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

实例:
layout/activity_main.xml

     <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.amap.api.maps.MapViewandroid:id="@+id/map"android:layout_width="match_parent"android:layout_height="match_parent"></com.amap.api.maps.MapView><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="200dp"><com.example.administrator.IndoorFloorSwitchViewandroid:id="@+id/indoor_switchview"android:layout_width="wrap_content"android:layout_height="200dp"></com.example.administrator.IndoorFloorSwitchView></LinearLayout></RelativeLayout>

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();@Overrideprotected 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() {@Overridepublic void OnIndoorBuilding(final IndoorBuildingInfo indoorBuildingInfo) {Log.i("amap", "indoor OnIndoorBuilding " + indoorBuildingInfo);if (indoorBuildingInfo != null) {handler.post(new Runnable() {@Overridepublic 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() {@Overridepublic 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);}}/*** 方法必须重写*/@Overrideprotected void onResume() {super.onResume();mapView.onResume();}/*** 方法必须重写*/@Overrideprotected void onPause() {super.onPause();mapView.onPause();}/*** 方法必须重写*/@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);mapView.onSaveInstanceState(outState);}/*** 方法必须重写*/@Overrideprotected void onDestroy() {super.onDestroy();mapView.onDestroy();}/*** 室内地图信息*/IndoorBuildingInfo mIndoorBuildingInfo = null;private class MyIndoorSwitchViewAdapter implements IndoorFloorSwitchView.OnIndoorFloorSwitchListener {@Overridepublic 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<String> 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;}/*** 修改偏移量,即当第一个显示在中间是上面有几个空白<br>* 也会影响整体显示,如设置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) { // stoppedfinal 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() {@Overridepublic void run() {IndoorFloorSwitchView.this.smoothScrollTo(0, initialY - remainder+ itemHeight);selectedIndex = divided + offset + 1;onSeletedCallBack();}});} else {IndoorFloorSwitchView.this.post(new Runnable() {@Overridepublic 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<String> getItems() {return items;}/*** 设置显示的内*** @param list*/public void setItems(List<String> list) {if (null == items) {items = new ArrayList<String>();}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<String>();}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;}}@Overridepublic void setBackgroundDrawable(Drawable background) {if (viewWidth == 0) {viewWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();}background = new Drawable() {@Overridepublic 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);}@Overridepublic void setAlpha(int alpha) {}@Overridepublic void setColorFilter(ColorFilter cf) {}@Overridepublic 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;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);viewWidth = w;setBackgroundDrawable(null);}@Overrideprotected 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() {@Overridepublic 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));}@Overridepublic void fling(int velocityY) {super.fling(velocityY / 3);}@Overridepublic 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);}// utilspublic 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;}}

高德地图五:室内地图功能相关推荐

  1. android高德地图上加自定义菜单,高德地图Android室内地图如何自定义覆盖物

    高德地图Android室内地图如何自定义覆盖物 亲,小德看到亲已经在开坛创建工单咨询了呢,建议亲耐心等待回复哦,会有开发大神给亲回复哦~ gao de di tu a n d r o i d shi ...

  2. android室内地图,概述-Android 室内地图SDK | 高德地图API

    Android 室内地图 SDK 简介 说明: 室内地图数据对新用户暂停开放,建议您使用 Android地图SDK 可实现室内外一体化效果. 高德地图 Android 室内地图SDK 是一套室内地图开 ...

  3. android 地图选房效果,概述-Android 室内地图SDK | 高德地图API

    Android 室内地图 SDK 简介 说明: 室内地图数据对新用户暂停开放,建议您使用 Android地图SDK 可实现室内外一体化效果. 高德地图 Android 室内地图SDK 是一套室内地图开 ...

  4. 高德离线地图开发 java_使用离线地图-创建地图-开发指南-Android 地图SDK | 高德地图API...

    高德3D 地图 SDK支持离线地图功能.(2D 地图 SDK 不支持离线地图功能) 离线地图可满足在无网络环境下查看地图信息的需求,在设备本地有离线地图数据的情况下,SDK 会优先加载离线地图. 离线 ...

  5. 高德离线数据api_使用离线地图-创建地图-开发指南-iOS 地图SDK | 高德地图API

    高德3D 地图 SDK支持离线地图功能.(2D 地图 SDK 不支持离线地图功能) 离线地图可满足在无网络环境下查看地图信息的需求,在设备本地有离线地图数据的情况下,SDK 会优先加载离线地图. 离线 ...

  6. 设置电子围栏 高德地图_简直监视他人行踪的神器!高德地图重磅更新体验

    [PConline 应用]高德地图更新了!这一次的更新给用户带来了一个非常实用的功能,让许多用户点赞,不过也遭到了一些用户的声讨,具体是怎么一回事呢?咱赶紧来看看. 高德地图变身儿童手表? 此次高德地 ...

  7. 高德地图PC版国内首发室内地图

    近日,高德地图PC版上线了室内地图功能,以往商场.交通枢纽等在地图上仅显示轮廓的地点,现在也能显示详细的室内信息了.使用此功能,用户不仅能够清晰地看到商场内的平面地图,快速找到各商铺或候车室.登机口的 ...

  8. vue移动端高德地图的使用及实现最简单的地图功能

    目录 一.创建应用获取key 1.进入开放平台,按步骤注册成为开发者 2. 登录之后,点击头像,进入「应用管理」 页面「创建新应用」 3. 为应用添加 Key 二.配置 1.在public下的inde ...

  9. 【高德地图API】从零开始学高德JS API(一)地图展现——仙剑地图,麻点图,街景,室内图...

    原文:[高德地图API]从零开始学高德JS API(一)地图展现--仙剑地图,麻点图,街景,室内图 摘要:关于地图的显示,我想大家最关心的就是麻点图,自定义底图的解决方案了吧.在过去,marker大于 ...

最新文章

  1. 2D-2D:对极约束
  2. Java中的ReentrantLock和synchronized两种锁定机制的对比
  3. (0086)iOS开发之iPhone 屏幕尺寸、分辨率、ppi以及@2x@3x图
  4. web开发入门到深入-html5(2)
  5. 借助Fiddle使用不同版本的UI5库文件进行测试
  6. 一种User Mode下访问物理内存及Kernel Space的简单实现
  7. $.post把表单对象传递过去_FormData对象
  8. ARP防火墙 (防如网络执法官、网络剪刀手、局域网终结者限制本机网速)
  9. HDFView打开.h5文件时报错Failed to open file
  10. HDU 6437 最小费用最大流
  11. 【KD】2022 计算机学报 深度学习中知识蒸馏研究综述
  12. 数据增强-亮度-对比度-色彩饱和度-色调-锐度 不改变图像大小 --增加ssd目标框xml文件的同步处理方法。
  13. 关于 SQL Server Reporting Services 2012 匿名登录
  14. 计蒜客 A1596.蒜头君王国 概率计算(dp)
  15. 网络测速一原理及实例
  16. 利用photoshop去掉图片中文字
  17. 微软云强劲增长的背后,是全新的人工智能黑科技
  18. 深度学习中常见卷积(普通卷积、1×1卷积、转置卷积、可分离卷积、膨胀(空洞)卷积、3D卷积)
  19. 详解HBase架构原理
  20. OUC2021秋-Web安全技术-期末(回忆版)

热门文章

  1. 电脑爱好者GHOSTWIN7纯净版V3.0
  2. 一生一世一双人!爱她就给她最美的H5婚礼请柬~
  3. linux命令面试题
  4. 矩形面积和矩形周长并的模板——来自notonlysuccess
  5. Ubuntu 16.04.6 LTS (Xenial Xerus) - Download (下载)
  6. webshell批量寄生虫
  7. SSM Chapter 05 Spring 核心概念
  8. 2019南开软院保研夏令营(优营)
  9. KMSAuto Net工具的正确使用方法
  10. 计算机常用螺丝刀,拆机必备工具──南旗螺丝刀