Delivering accurate maps to Chinese Android users 为中国安卓用户提供准确的地图服务
Work at Mapbox includes: Android apps, demos, starter kits, documentation, support, syncing Android team with other departments, etc. 工作包括 : 安卓 app 演示 初学者工具包 客户服务 等 Lived in Beijing from 2011-2015 2011 到 2015, 我住在北京!
Today s talk: 简报主题 :
Today s talk: 简报主题 : 1. Design 地图设计决策
Today s talk: 简报主题 : 1. Design 地图设计决策 1. Location data 位置数据服务
Today s talk: 简报主题 : 1. Design 地图设计决策 1. Location data 位置数据服务 1. How to create an app with Mapbox 通过 Mapbox, 怎么开发一个安卓应用?
Design decisions 地图设计决策
Does the map have too much information? Too little? Wrong type of information? 太多信息? 太少?
Correct zoom level for a hotel? 酒店的位置 : 正确的缩放级别?
Right layers and information? Correct UI/UX? 你要给用户什么选择?
App user has 13 choices including the map. Right amount of options? Right type? 应用用户有十三个选择 适量选择吗? 说不定...
App user has 16 choices including the map(!) 十六个选择 (!)
Right info displayed for a bicyclist? 骑自行车的人需要看什么信息?
What's important here? Schools? Hotel prices? Subway stations? 什么是重要的? 大学的位置? 酒店的价格? 每一个地铁站?
Don t show subway lines if in driving mode? Buildings 如果开车的话, 不用看地铁线? 不用看每一个大楼?
Marker clustering 标记群集
Static image decision (markers, camera position, etc.) 静止的地图决策 ( 标记 视角位置 等 )
What s the difference? 有什么区别?
Navigation 导航 >
Daily life 日常生活 >
Asking for permissions 位置权限
Location data + context 位置数据服务
导航
位置搜索 ( 地理编码 )
智能手表
AR( 增强现实 ) 游戏
物流
社交媒体
Location data platform for developers 开发者而建的地图平台
Location data platform for developers 开发者而建的地图平台 Maps 地图
Vector tiles + video game technology (OpenGL) 矢量瓦片 + 动画游戏技术
Location data platform for developers 开发者而建的地图平台 Maps 地图 Location search 位置搜索 ( 地理编码 )
Location data platform for developers 开发者而建的地图平台 Maps 地图 Location search 位置搜索 ( 地理编码 ) Navigation (driving, walking, biking) 导航 ( 开车 走路 骑车 )
Open-source tools (700 public Github repos) 开源的安卓产品
SDKs for Android, ios, Unity, Qt (for cars), & React Native 软件开发包 : 安卓 苹果公司 Unity Qt ( 一种汽车平台 ) & React Native.
Extrusions 三维外形
Dancing buildings 三维外形 + 麦克风
AR(Core) 增强现实
AR(Core) 增强现实
In-app nav 应用里导航
Offline 离线下载
Heatmaps 热点地图
Let s build! 咱们开始!
Set up basic project
App-level build.gradle file dependencies {... compile('com.mapbox.mapboxsdk:mapbox-android-sdk:5.2.0-beta.4@aar') { transitive = true}... }
App-level build.gradle file dependencies {... compile('com.mapbox.mapboxsdk:mapbox-android-sdk:5.2.0-beta.4@aar') { transitive = true}... }
Maps SDK size 软件开发包大小 Less than 1MB 可能小于 1MB SDKs final impact is dependent on other app decisions
strings.xml file 字符串的文件 Add your key to the strings file 加你 Mapbox 的访问令牌 <resources>... <string name="access_token">mapbox_access_token</string>... </resources> Your first 50,000 mobile users are free! 你前面五万的移动用户是免费的!
XML layout file XML 布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:mapbox="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.mapbox.mapboxsdk.maps.mapview android:id="@+id/mapview" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
More XML attributes 更多 XML 属性 github.com/mapbox/mapbox-glnative/blob/master/platform/android/mapboxglandroidsdk/src/main/res/value s/attrs.xml Additional map XML attributes 更多 XML 属性 <com.mapbox.mapboxsdk.maps.mapview android:id="@+id/mapview" android:layout_width="match_parent" android:layout_height="match_parent" mapbox:mapbox_cameratargetlat="19.948045" mapbox:mapbox_cameratargetlng="-84.654463" mapbox:mapbox_camerazoom="3.371717" mapbox:mapbox_cameratilt="50" mapbox:mapbox_styleurl="@string/mapbox_style_mapbox_streets"/>
Activity file Activity 文件 public class MainActivity extends AppCompatActivity { @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); Mapbox.getInstance(this, getstring(r.string.access_token)); } setcontentview(r.layout.activity_main);
public class MainActivity extends AppCompatActivity { private MapView mapview; @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); Mapbox.getInstance(this, getstring(r.string.access_token)); setcontentview(r.layout.activity_main); mapview = (MapView) findviewbyid(r.id.runtime_mapview); mapview.oncreate(savedinstancestate); mapview.getmapasync(new OnMapReadyCallback() { @Override public void onmapready(final MapboxMap mapboxmap) { // Customize map with markers, polylines, etc. } } });
Method overrides 重写此方法 @Override public void onresume() { super.onresume(); mapview.onresume(); } @Override protected void onstart() { super.onstart(); mapview.onstart(); } @Override protected void onstop() { super.onstop(); mapview.onstop(); } @Override public void onpause() { super.onpause(); mapview.onpause(); } @Override public void onlowmemory() { super.onlowmemory(); mapview.onlowmemory(); } @Override protected void ondestroy() { super.ondestroy(); mapview.ondestroy(); } @Override protected void onsaveinstancestate(bundle outstate) { super.onsaveinstancestate(outstate); mapview.onsaveinstancestate(outstate); }
The result! 结果!
Run-time styling 运行时地图模式
mapview.oncreate(savedinstancestate); mapview.getmapasync(new OnMapReadyCallback() { @Override public void onmapready(final MapboxMap mapboxmap) { final Layer waterlayer = mapboxmap.getlayer("water"); } });
mapview.oncreate(savedinstancestate); mapview.getmapasync(new OnMapReadyCallback() { @Override public void onmapready(final MapboxMap mapboxmap) { final Layer waterlayer = mapboxmap.getlayer("water"); } findviewbyid(r.id.floatingactionbutton).setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { if (waterlayer!= null) { waterlayer.setproperties(propertyfactory.fillcolor(color.parsecolor("#023689"))); } } });
mapview.oncreate(savedinstancestate); mapview.getmapasync(new OnMapReadyCallback() { @Override public void onmapready(final MapboxMap mapboxmap) { final Layer waterlayer = mapboxmap.getlayer("water"); } findviewbyid(r.id.floatingactionbutton).setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { if (waterlayer!= null) { waterlayer.setproperties(propertyfactory.fillcolor(color.parsecolor("#023689"))); } } });
findviewbyid(r.id.floatingactionbutton).setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { if (waterlayer!= null) { waterlayer.setproperties(propertyfactory.fillcolor(color.parsecolor("#023689"))); } }); for (Layer singlemaplayer : mapboxmap.getlayers()) { if (singlemaplayer.getid().contains("marine")) { singlemaplayer.setproperties( PropertyFactory.textHaloBlur(10f), PropertyFactory.textSize(25f), PropertyFactory.textColor(Color.parseColor("#00FF08")), PropertyFactory.textOpacity(1f)); } } }
findviewbyid(r.id.floatingactionbutton).setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { if (waterlayer!= null) { waterlayer.setproperties(propertyfactory.fillcolor(color.parsecolor("#023689"))); } for (Layer singlemaplayer : mapboxmap.getlayers()) { if (singlemaplayer.getid().contains("marine")) { }); singlemaplayer.setproperties( PropertyFactory.textHaloBlur(10f), PropertyFactory.textSize(25f), PropertyFactory.textColor(Color.parseColor("#00FF08")), PropertyFactory.textOpacity(1f)); } } }
Retrieving a single map style s layer names mapview.oncreate(savedinstancestate); mapview.getmapasync(new OnMapReadyCallback() { @Override public void onmapready(final MapboxMap mapboxmap) { for (Layer singlemaplayer : mapboxmap.getlayers()) { } Log.d("MainActivity", "onmapready: layer name = "+ singlemaplayer.getid()); } });
Data-driven styling
Some current customers 现有的客户
Want to learn more? 你想了解更多吗?
Android documentation 技术资料 mapbox.com/android-docs 中文资料 : mapbox.cn/help/first-steps-android-sdk/ & mapbox.cn/android-sdk
Blog 博客 blog.mapbox.com 微信公众号 :Mapbox
Location + context 最后, 位置数据服务是最重要的