uniapp中利用renderjs引入leaflet

由于uniapp中要使用地图,虽然uni-app有地图组件map,但是很难用,而且性能很差。在app中是不能操作dom,所以直接用leaflet是不可能的。最终发现了renderjs,官网提出,在app-vue环境下,视图层由webview渲染,而renderjs运行在视图层,自然可以操作dom和window。

官网renderjs的说明链接

使用注意事项:

:prop 传值 :change:prop 监听prop改变

调用改变的方法内有四个参数

newValue:跟新后的数据

oldValue:原先的数据

ownerInstance:通过该函数可以调用内部函数,可以传输数据

instance:当前service层实例

通过 this.$ownerInstance.$vm 获取当前组件的 ComponentDescriptor 实例

完整示例代码:

<template>
  <view class="leafletMap">
    <view
      class="mapBox"
      id="mapId"
      :prop="psArr"
      :change:prop="leaflet.updatePsArr"
    ></view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      psArr: [], //企业数组
    };
  },
  onLoad() {
    this.$nextTick(() => {
      this.queryPsGis();
    });
  },
  methods: {
    //请求企业gis数据
    async queryPsGis() {
      this.psArr = []; //重置企业的站点信息
      const { data = {} } = await this.$http(
        '/smoke/smokeData/getPsRealityDataGis',
        'get'
      );
      if (data.code !== 200) {
        return uni.showToast({
          title: '请求数据异常',
          icon: 'error',
          mask: true,
        });
      }
      if (data.result.length > 0) {
        this.psArr = data.result.filter(
          (item) =>
            item.pscode !== null &&
            item.pscode !== undefined &&
            item.pscode !== ''
        ); //排除第一个无意义内容
      }
    },
    //renderjs 传递给视图层
    getMessage(option) {
      uni.showToast({
        title: option.text,
        icon: 'success',
        mask: true,
      });
    },
  },
};
</script>
<script module="leaflet" lang="renderjs">
export default {
    data() {
        return {
            map: null, //地图容器
            centerpoint: [37.6211, 114.9304676], //默认中心位置
            zoomlevel: 14, //初始化放大倍数
            baseLayer: null, //矢量底图
            markers:null,
            ownerInstance:null,//接收视图层dom
        }
    },
    mounted() {
        // 动态引入较大类库避免影响页面展示
        const link = document.createElement('link');
        link.rel = "stylesheet"
        link.href = "https://unpkg.com/leaflet@1.9.3/dist/leaflet.css";
        document.head.appendChild(link)
        const script = document.createElement('script')
        script.src = "https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
        script.type = "text/javascript"
        script.onload = this.initMap.bind(this)
        document.head.appendChild(script)
    },
    methods: {
        initMap() {
            this.map = L.map('mapId', {
                minZoom: 5,
                maxZoom: 18,
                crs: L.CRS.EPSG3857,
                center: this.centerpoint,
                zoom: this.zoomlevel,
                fullscreenControl: false,
                zoomControl: false,
                attributionControl: false,
            })
            //添加基础图层
            this.baseLayer = L.tileLayer(
                'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}', {
                    minZoom: 5,
                    maxZoom: 18,
                    pane: 'overlayPane',
                }
            )
            this.map.addLayer(this.baseLayer)
        },
        //属性psArr变化监控
        updatePsArr(newValue, oldValue, ownerInstance, instance) {
          if(newValue.length>0){
            this.ownerInstance = ownerInstance
            if(this.markers){
              this.map.removeLayer(this.markers)
              this.markers = null
            }
            this.addMarkerCluster(newValue)
          }
        },
        //处理整合geoJSON所需要的marker数据
        handlePsGeoJson(arr) {
            let coorsField = {
                type: 'FeatureCollection',
                features: [],
            }
            arr.forEach((item) => {
                let lon = item.lon
                let lat = item.lat
                if (lon && lat) {
                    coorsField.features.push({
                        type: 'Feature',
                        properties: {},
                        geometry: {
                            type: 'Point', // 配合 pointToLayer 一起使用
                            coordinates: [lon, lat],
                        },
                    })
                }
            })
            return coorsField
        },
        //添加marker标记
        addMarkerCluster(arr) {
            // 添加站点marker标记
            this.markers = L.geoJSON(this.handlePsGeoJson(arr), {
                pointToLayer: (feature, latlng) => {
                    return L.marker(latlng, {
                        icon: this.getMarkerIcon(),
                        zIndexOffset: 1000
                    }) // 添加标记
                },
            })
      this.map.fitBounds(this.markers.getBounds())
      this.markers.addTo(this.map)
      //renderjs传递给视图层
      // this.ownerInstance.callMethod('getMessage', {
            //     text: '成功'
            // })
        },
        getMarkerIcon() {
            let htmlContent = '<div style="width:24px;height:24px;border-radius:50%;background-color:#5ed323"></div>'
            let icon = L.divIcon({
                html: htmlContent,
                className: 'ss',
                iconAnchor: [13, 4],
            })
            return icon

        }

    }
}
</script>

<style lang="scss" scoped>
.leafletMap {
  width: 100%;
  height: 100%;

  .mapBox {
    box-sizing: border-box;
    width: 100%;
    height: 100vh;
    background-color: #042046;
    overflow: hidden;
  }
}
</style>

 

posted @ 2022-12-16 17:05  JackGIS  阅读(2048)  评论(0编辑  收藏  举报