uni-app如何引入天地图并兼容app

uni-app引入天地图打包成app后,兼容安卓。该方式仅兼容安卓、h5,微信小程序需要用到其他方案。

安卓模拟器最终效果

image.png

uni-app提供的<map>组件,仅支持下面的服务商,想使用天地图或其他地图,需要搭配地图引擎使用。


image.png

本案例使用工具与插件

  • leaflet.js 轻量的地图引擎,获取无需魔法
  • uni-app
  • HbuilderX 3.8.3
  • MuMu模拟器12 (用于查看实时运行效果)

实现思路

  • uni-app提供的map组件中,仅支持腾讯、百度、高德三个平台的地图,想要切换成天地图需要使用另外的地图渲染引擎来实现。
  • h5端的兼容是最好做的,app与小程序端不支持dom操作,需要另想办法渲染。
  • 地图渲染引擎使用的是 leaflet,相较于其他渲染引擎,它的主体代码比较小。
  • 因为app端不支持dom的操作,使用leaflet 官方提供的渲染方式会出现不渲染情况。这时候需要配合 uni-app 中的renderjs来配合渲染。
  • renderjs 改变了uni-app的渲染模式,在逻辑层之外加上了一个视图层,二者之间互不通信,需要搭配官方提供的通信方式进行通信,同时值得注意的是,二者之间的通信只能是JSON格式的,其他的格式均不支持。

引入步骤

  • 将 leaflet.js 放在 static中,注意路径。如果跟j-leaflet路径不一致,需要改一下。
  • 将 leaflet.css 放在 static中,并引入uni.scss
  • 将 j-leaflet 文件夹放在 components
  • 放置目录结构


    image.png

引用 j-leaflet 组件demo

<template>
    <view>
        <!-- #ifndef MP-WEIXIN -->
        <!-- 除了微信均使用 -->
        <leaflet @changeView="changeView" :location="location" :data="marker"></leaflet>
        <!-- #endif -->
        <!-- #ifdef MP-WEIXIN -->
        <!-- #endif -->
    </view>
</template>
<script>
    import leaflet from '@/components/j-leaflet/j-leaflet.vue'
    export default {
        components: {
            leaflet
        },
        data() {
            var _this = this
            return {
                latitude: 39.909,
                longitude: 116.39742,
                marker:[],
                location:{}
            }
        },
        mounted() {
            setTimeout(()=>{
                this.location = {
                    latitude: 39.909,
                    longitude: 116.39742,
                }
                this.marker =[this.location]
                
            },2230)
            // this.init()
        },
        methods: {
            changeView(){ 
                console.log(12)
                let list = {
                    latitude: 39.901,
                    longitude: 116.39712,
                }
                this.marker = [this.location] 
            },
        }
    }
</script>

<style>

</style>

j-leaflet 源码

<template>
    <view :data="data" :change:data="leaflet.addMarker" :location="location" :change:location="leaflet.center"
        class="map" id="map"></view>
</template>
<script>
    export default {
        props: {
            data: Array,
            location: Object 
        },
        methods: {
            changeView(options) {
                this.$emit('changeView', options)
            },
        }
    }
</script>
<script module="leaflet" lang="renderjs">
    import L from 'static/js/leaflet.js';
    export default {
        data() {
            return {
                map: null,
                marker: {}
            };
        },
        mounted() {
            this.initMap()
        },
        methods: {
            // 鍒濆鍖栧湴鍥?
            initMap() {
                this.map = L.map('map', {
                    // crs: L.CRS.EPSG3857, 
                    center: [23.180695, 113.412674], 
                    zoom: 17, 
                    minZoom: 5,
                    maxZoom: 18, 
                    dragging: true,
                    attributionControl: false,
                    zoomControl: false
                });
                // 娣诲姞鍥惧眰
                L.tileLayer(
                    'http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=你的秘钥', {
                        zoomControl: true
                    }).addTo(this.map);
                L.tileLayer(
                    'http://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=你的秘钥', {
                        zoomControl: true
                    }).addTo(this.map);

                this.mapEvent()
            },
            mapEvent() {
                this.map.on('zoomend', (a, b) => {
                    let view = this.getBounds()
                    // 主动传递 等价于 $emit
                    UniViewJSBridge.publishHandler('onWxsInvokeCallMethod', {
                        cid: this._$id,
                        method: 'changeView',
                        args: view
                    })
                    console.log(24)
                })
                this.map.on('moveend', (a, b) => {
                    let view = this.getBounds()
                    // 主动传递 等价于 $emit
                    UniViewJSBridge.publishHandler('onWxsInvokeCallMethod', {
                        cid: this._$id,
                        method: 'changeView',
                        args: view
                    })
                    console.log(25)
                })
            },
            //可视范围 获取
            getBounds() {
                //左下
                let west = this.map.getBounds().getSouthWest()
                var leftdown = [west.lat, west.lng];
                //左上
                let northWest = this.map.getBounds().getNorthWest()
                var leftup = [northWest.lat, northWest.lng];

                //右上
                let orthEast = this.map.getBounds().getNorthEast()
                var rightup = [orthEast.lat, orthEast.lng];
                //右下
                let southEast = this.map.getBounds().getSouthEast()
                var rightdown = [southEast.lat, southEast.lng];
                return {
                    leftup,
                    leftdown,
                    rightup,
                    rightdown
                }
            },
            center(point) {
                // 添加中心点,并且移动到地图至中心点
                if (!point || !point.latitude || !point.longitude) return
                if (!this.marker.center) {
                    let m = L.marker([point.latitude, point.longitude], {
                        icon: L.divIcon({
                            className: 'div-icon'
                        })
                    }).addTo(this.map)
                    this.marker.center = m
                } else {
                    this.marker.center.setLatLng([point.latitude, point.longitude])
                }
                this.map.panTo({
                    lng: point.longitude,
                    lat: point.latitude
                });
            },
            addMarker(points) {
                // 获取到数据,进行处理,可以是添加标记,也可以是其他处理
            } 
        }
    }
</script>

<style lang="scss">
    .map {
        width: 100%;
        top: 0;
        bottom: 0;
        position: absolute;
        z-index: 0;
    }
</style>

注意事项

  • 使用leaflet插件对天地图的底图进行渲染,与uni.getLocation 中使用的三方地图的sdk互不相干,是两个独立的东西。
  • 在打不同平台的包时,需要在manifest.json配置不同的地图key。
  • 安卓包需要去对应的地图平台申请安卓使用的key。ios包申请ios使用的 key。
  • 在通信时需要注意对象深浅拷贝问题,最好都是深拷贝,浅拷贝容易发生异常。
  • 云打包每天打包都有固定次数,推荐使用模拟器查看效果。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容