背景
當你剛上大學的時候,要想不迷失校園,除了依靠不怎麼可靠的路邊標識外,總會收到那麼一張卡通繪製的校園地圖:
這種靜態圖片可以讓我們快速地瞭解到所需的地理位置信息,但使用和思考過後,會發現以下問題:
- 地理位置信息粒度高,而同一個地點通常具有多個服務功能和別名。
- 地理位置信息變更導致地圖信息過時。一旦服務網點遷移或更名,需要重繪地圖,帶來一定的延遲和信息滯後。
- 入口較深。存儲在手機上的地圖並不是那麼好找,尤其是隨着時間的推移。
- 無法準確的定位當前所處位置,需要尋找參照物,這是靜態地圖致命的缺點。
- 缺乏更爲詳細的地點介紹,只能在有限的畫面裏堆積內容。
爲此,我設計了一款校園導覽應用,用當下流行的微信小程序結合雲開發能力,低成本高效能地解決了以上問題。此外,我還根據對市面上的同類應用進行設計上的研究,在界面和交互設計上做功夫。下面我會進行簡短的介紹。
南苑導覽
南苑導覽是一款由學生獨立開發的以地圖爲載體,提供中山大學南方學院(南苑)具體地點的位置信息、導航、校園歷史及文化介紹的小程序。旨在解決校園導航標識不到位、地圖形式低效單一、信息設計不夠好等問題,爲來南苑新人和遊客提供更加完美的出行體驗。
<div align=center>
僅需修改地圖配置文件,即可適配任意場景(校園、景區)的小程序個性化地圖定製。
技術棧:原生小程序 + TypeScript + gulp + vantUI + 雲開發能力
2019 微信小程序高校大賽 · 華南賽區二等獎
</div>
南苑導覽 · 開發
- config 配置
├─ src
├─── config
├───── index.ts // 入口
├───── cloud.ts // 雲開發相關配置
├───── info.ts // 應用介紹信息
├───── markerStyle.ts // 地圖marker樣式
├───── panorama.ts // 第三方全景地圖配置(個人類型無webview權限,默認關閉)
└───── secret.ts // 騰訊地圖key等敏感信息(可選)
- 使用雲數據庫
// markers表 數據格式
{
_id: "5ce8fe1c29c7a8581bc1e989", // id,雲數據庫錄入upsert更新用
type: "生活服務", // 場景名稱
icon: "shfw", // marker默認圖標,爲場景名稱拼音縮寫
scale: 15.0, // 場景在地圖上的縮放值,可選。已廢棄,用includePoints代替
position: 0, // 指定在各個場景中的排列順序
data: [ // 該場景下的地點markers
{
name: "孫中山銅像", // 地點名稱
short_name: "銅像", // 名稱縮寫
desc: "中山銅像...", // 描述信息
logo: "tx", // 地點logo,縮寫拼音, 如作各院系logo展示
icon: "tx@2", // 自定義marker圖標,“@”後數字爲圖標相較於默認圖標的縮放值
images: 3, // 圖片數量,作雲存儲拼接路徑用(cloud://cloudRoot/1教/n.jpg)
panorama: 0, // 全景場景id
latitude: "23.635875", // 經度
longitude: "113.678965", // 緯度
contact: { phone: "020-123456", address: "出門左轉" } // 聯繫方式
}
]
}
使用 excel 進行數據維護,通過 python pandas 進行數據清洗,使用 jsonlines 庫輸出符合雲數據庫的 JSON Lines 格式文件,以 upsert 形式導入數據庫。
數據更新流程如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9Kzq570X-1570761839095)(https://656e-enanyuan-6db383-...]
- 加載並清洗數據
使用 request 或雲數據庫進行異步數據請求時。由於 app.js 中的 onLaunch 和首頁 index 的 onLoad 的執行順序不是固定的,所以如果首頁有基於 app.js 請求的數據時要注意生命週期的問題。
// index
async loadMarkers() {
let markers;
if (app.globalData.config.debug) {
// 本地
markers = mockMarkers;
} else {
// 雲
await wx.cloud
.callFunction({
name: "loadMarkers"
})
.then((res: any) => {
markers = res.result.data;
});
}
app.globalData.markers = markers;
}
clearMarkers(markers: any[]) {
let num = 0; // 每個marker都要有一個id
for (const i of markers) {
for (const j of i.data) {
j.id = num;
num += 1;
j.iconPath = `/assets/images/markers/${j.icon ? j.icon : i.icon}.png`;
...
// 自定義氣泡樣式
j.callout = Object.assign(
{ content: j.short_name ? j.short_name : j.name },
app.globalData.config.markerStyle.calloutStyle
);
}
}
return markers;
}
- 巧用 MapContext
你不需要去手動地爲每個場景設置 scale,用 includePoints 即可讓地圖視野自動覆蓋到當前所有 POI。
你也不需要去手動地去獲取權限設置用戶位置,用 moveToLocation 即可輕鬆定位。
// index
onReady() {
this.setData!({
mapContext: wx.createMapContext("map")
});
}
includePoints(padding: number) {
this.data.mapContext.includePoints({
padding: [padding, padding, padding, padding],
points: this.data.markers
});
}
locate() {
this.data.mapContext.moveToLocation();
}
- 使用雲存儲管理圖片
添加新圖片時,直接修改 images 字段即可,文件夾目錄爲地點名稱。
<!-- 地點詳情頁 輪播圖 -->
<swiper
indicator-dots="{{imgUrls.length > 1}}"
autoplay="{{true}}"
interval="3000"
duration="1000"
>
<block wx:for="{{imgUrls}}" wx:key="{{index}}">
<swiper-item>
<image
src="{{item}}"
class="slide"
data-id="{{index}}"
bindtap="previewImage"
/>
</swiper-item>
</block>
</swiper>
for (let i = 0; i < marker.images; i++) {
imgUrls.push(
this.data.cloudRoot +
"images/" +
(marker.short_name || marker.name) +
"/" +
i +
".jpg"
);
}
南苑導覽 · 設計
如果你在微信上搜索「導覽」二字,看到的小程序大多都是一個模板,頁面層級深,界面擁擠,列表式的信息展示並不符合我們日常使用地圖 APP 的經驗。爲此,我做出了多項改良:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-j76bV81T-1570761839095)(https://656e-enanyuan-6db383-...]
- 更好的視野 - 自定義導航欄與側邊欄
因爲只有特定的頁面需要使用自定義導航欄,所以只需要設置頁面級的 config:
"navigationStyle": "custom"
接下來獲取膠囊按鈕位置信息:
bounding: wx.getMenuButtonBoundingClientRect();
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-XoDA3u2I-1570761839096)(https://656e-enanyuan-6db383-...]
動態地設置樣式:
<!-- SIDE MENU -->
<view
class="sidebar"
hidden="{{toggleRoutes}}"
style="top:{{bounding.height + bounding.top + 10}}px"
>
...
</view>
- FAB 與側邊欄設計
把最主要的定位、搜索和路線推薦功能在視覺上成爲整體,通過點擊 FAB 彈出菜單選項。側邊欄的地點場景菜單設計爲下拉滾動,注意使用半遮設計來提醒用戶滾動。同時,爲了讓界面更加精簡,側邊菜單會在點擊 FAB(Float Action Button)和母按鈕時 toggle 顯示與隱藏。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SP3GrjOr-1570761839096)(https://656e-enanyuan-6db383-...]
- 用點擊代替滾動 - scroll-into-view
在路線面板和搜索頁中,使用到了 scroll-view 組件,利用其 scroll-into-view 特性,實現點擊代替滾動的操作,同時也能起到提醒後置選項的作用。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-o18t46ea-1570761839097)(https://656e-enanyuan-6db383-...]
windowWidth: wx.getSystemInfoSync().screenWidth;
<scroll-view class="route" scroll-x scroll-into-view="{{focusPointId}}">
<view
class="points"
style="width:{{routes[routeIndex].count * 140 < windowWidth ? windowWidth : routes[routeIndex].count * 140}}rpx;"
>
...
</view>
</scroll-view>
- 更好的視角 - 全景功能
結合 web-view 和全景服務平臺,可以爲一款地圖導覽應用增色不少。
總結
雲開發讓小程序開發者無需搭建服務器,使用平臺提供的 API 即可快速地進行業務開發、上線和迭代,免費的基礎版完全可以滿足中小應用的需求。「南苑導覽」藉助騰訊雲開發能力,上線以來,幫助到了許許多多的新生和來客,實現了產品價值。最後,期望官方早日開放自定義地圖底圖能力,讓開發者能夠個性化地圖,探索出更多的應用場景!
源碼地址
https://github.com/TencentCloudBase/Good-practice-tutorial-recommended
如果你想要了解更多關於雲開發CloudBase相關的技術故事/技術實戰經驗,請掃碼關注【騰訊云云開發】公衆號~