地图数据可视化在PC和无线场景中的应用

1,137 阅读12分钟

地图数据可视化在PC和无线场景中的应用

一、背景
1、业务要求是什么

在零售通业务场景中,存在这样几种元素,如零售店、城市拍档、仓库及区块等。

(1)城市拍档和零售店

城市拍档代替我们零售通去跑零售店,给予店主以专业化的零售建议,提高小店的动销率和

GMV


(2)城市拍档和服务区块

每个拍档都被划分了一定的区块服务地(一般就是四级街道这个

维度

),他们会去定期拜访被划定在自己服务区块内的零售小店。如何安排区域内小店和城市拍档的配比,是悬在我们头上的一把双刃剑。如果分配得宜,则我们可以借助拍档占领零售行业的大部市场份额;反之,则我们将错过新零售这波新的行业变革。
(3)仓库

零售通目前有区域仓、城市仓和前置仓这几种类型。区域仓一般可能会跨省覆盖几个城市,城市仓一般只覆盖某个大市范围内的区域,前置仓一般是已经深入到前线的仓库(如具体到达某个街道/镇上)。仓库的选址是一个很有挑战的任务和极其慎重的选择。


2、遇到的问题

上述任意两两之间的关系,或者到三方以上之间关系都是无比复杂的。对这些元素每日具体情况掌控程度的高低直接决定了我们零售业务是否能做好做大,因为如果我们不了解前线的基本情况,那我们就是所谓的“睁眼瞎”,被别人说成是“瞎指挥”的人,就是我们了。但是,仅仅想靠人肉分析数据报表,然后得到我们想要的运营信息是远远跟不上我们的业务发展的。

我想我们零售通内部是不希望出现把优质的零售店分配给不合格或作假的拍档帮我们去运营;或者明明拍档很优秀,但却因为我们的数据分析错误而未能给他分配合理数量的服务小店;又或者因为我们未能摸清楚某个城市整体零售数据,导致将城市仓的位置没能放到更加合理的位置,以至于增加了配送成本。

通过分析我们的业务场景可以得出零售通业务带有很强的地域特性,如我们很想掌控以下这些信息:

(1)零售店

某个大区、城市、街道范围内的零售店的当日实时和历史交易信息,包括GMV、动销率、畅销品、进货频次和店均进货额等。

(2)城市拍档

拍档每天拜访小店的情况,所负责区域内走访效果的情况,以及推送品给小店的热销和难销品等情况。

(3)仓库

区域仓、城市仓和前置仓的地址分别选址在哪里是最合理的,对于公司来讲成本是最低的,对于物流配送来说效率是最高的。零售店GMV集中比较高的区域在哪里,周边区域到我仓库的配送路径最短。
3、如何做好地图数据可视化

其实在我们日常业务开发中有对零售店、拍档和仓库的行为做数据打点,换言之,我们手里是有掌控大数据的,但是我们目前大部分还停留在小二查看报表数据,分析结果的阶段。这种运营方式的效率是比较低的,也容易出现差错。那么如何把我们手上的数据生动地展示给运营小二看,这是个值得深入研究的命题。也即我们开发人员如何能够快速、精准生动地处理数据,并将这些数据以可视化的方式展现出来,这是我们需要去做的,因为可视化的数据比沉睡在表格中的数据更加直观、更加让人印象深刻!

数据可视化分很多类型,有各类静态图表、动画以及地图等。综合零售通较为普遍的业务场景,地图是零售通比较常见的数据可视化展示方式,所以本文主要介绍我们在日常需求推进过程中,对地图数据可视化场景的一些思考和沉淀。


二、思考

我们的用户操作环境分为PC端和无线端,本文中涉及的PC端用户一般是内部运营小二,无线端的用户为城市拍档。

1、赋能运营小二

内部运营小二平常会在我们的内部运营工作台中对零售店、拍档和仓库进行日常的运营工作。他们会在这些工作台对应的功能页面上进行报表数据分析、数据的增删改查操作等。
但是我们认为下面的这些地图可视化的方式能够更好地赋予小二运营的能力






如上图所示,相比于普通的报表来说,上面的这些数据可视化呈现形式要生动形象得多。并且我们也可以直接在地图上增加行动点,即在一张页面上就可以让小二完成“分析 -> 执行”的全方位操作。


2、赋能前线拍档

我们的零小宝App是前线城市拍档手中的日常工具,我们希望通过不断地技术探索提升App的能力,为拍档赋予更多的能力。以拍档拜访小店为例,以前的拍档可以在家中完成“到店”签到,因为零小宝App并没有强制其必须到店的控制措施,而且也没有提供给拍档参考自己历史的拜访路线记录和明天之后的拜访路线规划。

所以通过地图可视化的方式,我们可以提示拍档当前位置和小店位置其实是有一段距离的,可以让其真实到店或者选择其他的拜访方式,这样就可以提高拜访的真实性。(功能上线后,前线的反馈也的确如我们预料的)



结合地图数据可视化,我们可以提供给拍档查询历史拜访路线的视图,图中的数字表示当天拍档拜访小店的顺序。


3、需要解决的问题
综上所述,我们想要利用地图可视化的手段为运营小二和拍档提供更加强大便捷的工具。那么现在有以下几个问题需要解决:

(1)PC端如何快速搭建数据可视化的页面,提高代码可维护性
高德地图提供的PC版开发包是JS

API

版本的,属于过程式的编程方式,每个人心中都有一个哈姆雷特,所以类似需求由不同的开发者开发的效率、性能都大相径庭。

(2)无线端如何提升性能和用户体验
之前零小宝中使用的是JS API方式的高德地图,性能较差,主要体现在画质差、速度慢、拖动时不加载等问题上。地图是拍档工作时使用的工具,我们不应该提供这样粗糙的工具。

三、方案

1、PC端
针对 上述PC端中涉及的问题,即快速搭建和提高代码可维护性,我们设计了一个PC端的地图功能包,结构图如下所示:

(1)组件化提高开发效率和代码维护性
所有地图上的基础组件、事件层和业务组件等子元素都需要被包含在Map(根组件)中,其中基础组件包括块(Polygon)、线(Line)和点标记(Marker)等。
所有业务组件都是由基础组件构件而成的,如一条轨迹组件就是由若干点标记Maker和点标记间的线段Line组成的。
组件化之后的代码可读性会得到巨大的提升,如下图所示:

(2)事件由事件层统一接收转发
所有基础组件之间的事件传递都是通过Layer层来完成的,如点击轨迹组件上的点,则属于这条轨迹的其他所有的点和线都会接收到一个点击事件。其实就相当于是这个轨迹组件整体的一个事件。
按照这种方式来处理,开发者就不需要再关心事件是如何传递的了。唯一需要关心的是当某种事件被触发后,地图上的元素应该做出哪种反映(即展示成何种样式)。如下代码片断所示,marker类型下的所有store分组的点标记都将遵循marker.store对象中的配置来显示,其中activeHover表示,点击激活且鼠标hover状态,根据不同的状态提前设置好每种元素对应不同事件的展示方式。能过这种方式,既能规范地图开发的规范,也可以提升开发效率。

{
    marker: {
      store: {  // 对应组件中的group名称
        activeHover: {
          zIndex: 10
        },
        hover: {
          zIndex: 10,
        },
        active: {
          zIndex: 9
        },
        normal: {
          zIndex: 8,
        }
      }
    },
    line: {
      road: {
        activeHover: {
          zIndex: 7,
          strokeColor: '#3e95fa',  // 线颜色
          strokeOpacity: 1,        // 线透明度
          strokeWeight: 6,         // 线宽
          strokeStyle: 'solid',    // 线样式
          strokeDasharray: [10, 5] // 补充线样式
        },
        hover: {
          zIndex: 7,
          strokeColor: '#3e95fa',  // 线颜色
          strokeOpacity: 1,        // 线透明度
          strokeWeight: 6,         // 线宽
          strokeStyle: 'solid',    // 线样式
          strokeDasharray: [10, 5] // 补充线样式
        },
        active: {
          zIndex: 6,
          strokeColor: '#3e95fa',  // 线颜色
          strokeOpacity: 1,        // 线透明度
          strokeWeight: 6,         // 线宽
          strokeStyle: 'solid',    // 线样式
          strokeDasharray: [10, 5] // 补充线样式
        },
        normal: {
          zIndex: 5,
          strokeColor: '#999',  // 线颜色
          strokeOpacity: 1,        // 线透明度
          strokeWeight: 3,         // 线宽
          strokeStyle: 'solid',    // 线样式
          strokeDasharray: [10, 5] // 补充线样式
        }
      }
    },
    polygon: {
      area: {
        activeHover: {
          zIndex: 4,
          strokeColor: '#F8E71C',
          strokeOpacity: 1,
          strokeWeight: 3,
          fillColor: '#F8E71C',
          fillOpacity: 0.25
        },
        hover: {
          zIndex: 4,
          strokeColor: '#F8E71C',
          strokeOpacity: 1,
          strokeWeight: 3,
          fillColor: '#fe6501',
          fillOpacity: 0.25
        },
        active: {
          zIndex: 3,
          strokeColor: '#F6756A',
          strokeOpacity: 1,
          strokeWeight: 3,
          fillColor: '#F6756A',
          fillOpacity: 0.25
        },
        normal: {
          zIndex: 2,
          strokeColor: '#F6756A',
          strokeOpacity: 1,
          strokeWeight: 3,
          fillColor: '#F6756A',
          fillOpacity: 0.25
        }
      }
    }
  }
Copy


2、无线端
我们的无线App零小宝中目前新的需求都采用RAX来开发,而以前的地图相关需求都是通过JS API的高德地图来开发的,但是高德也是提供了Native的地图

SDK

包的。所以我们就想是否可以开发一个地图的RAX组件来优先使用Native的地图功能,如果页面被降级成h5,那就使用JS API的高德地图。
经过调研,我们发现公司内的前人大牛们已经做过这个方向的研究了,从

ATA

上我们检索到了一个名为weex-amap的weex模块,这个模块可以提供Native地图的能力,且兼容安卓和IOS。所以无线端的方案就大概明了了,使用weex-amap模块作为weex环境下的地图解决方案,使用JS API作为h5降级环境下的解决方案。两套环境下的地图解决方案合起来就是我们需要的RAX地图功能组件。
weex-amap模块的官方文档地址:github.com/weex-plugin…,其他内外网上找到的文档都不是很完善,经与作者确认,以github上的这版为准(但还不不排除有一些问题,具体使用过程中遇到问题可以咨询我们)。
A

TA

上的参考文档地址(注意以上个文档为准):www.atatech.org/articles/76…

四、成果

组件层面原本打算是只出一个组件,实现PC端和无线端共用的。但是一方面我们PC端和无线端的构建体系不同,另一方面PC和无线的地图使用的确有差异,所以从长远的角度来看,还是按照两端各自实现一个,这样可以更精更专。两端组件由于是新开发的,文档还没有补充,近期会在组件的README中写完。

1、PC端
PC端这边沉淀了一个通用组件,@alife/bird-amap

2、无线端
无线端这边沉淀了一个RAX组件,@ali/rax-amap



3、Native端接入weex-amap爬坑参考文档
(1)安卓(作者少瑾)
amap接入: www.atatech.org/articles/95…
weex jsBridge: www.atatech.org/articles/96…
首页容器: www.atatech.org/articles/96…

(2)IOS(作者希运)
iOS 集成 weex-amap 插件经验总结: www.atatech.org/articles/98…



五、展望

1、PC端
(1)组件的扩展
@alife/bird-amap组件目前接入了最基本的Polygon、Line和Marker三种基本组件,一个负责事件层的Layer组件,以及地图容器组件Map。后面我们会再扩展如Circle和Rectangle等基础组件,以及海量点和轨迹展示等UI组件接入。

(2)批量操作
地图上一个重要功能就是批量操作,比如每家小店是一个点,如果每个点操作一次成本太大,接口请求也过于频繁。所以需要研究一种合理的批量操作的方式,一般考虑为鼠标矩形批量选中及多次点击批量选中,这两种操作模式。


2、无线端
(1)组件扩展及完善
接入weex-amap模块是个艰难爬坑的过程,目前仅支持了Map、Marker、PolyLine、Polygon、Circle和InfoWindow的接入,但是线上正在使用的只有Map和Marker是经过测试验证了的。在我们本次的需求中原本想要接入Polyline,但是发现这个组件存在绘制后无法清除的问题,所以还是需要Native端支持排查一下这个问题。因此,后面需要对上述未经测试通过的组件进行功能完善。

(2)接入@weex-module/amap
该模块能够提供获取当前位置,计算两点间距离及判断点是否在合围区域内。这些功能的接入可以极大地丰富我们的产品功能,可以让我们做更复杂的地图交互,提升用户的体验。