SuperMap for MapboxGL 实现自定义图标点位及多点位聚合

实现效果如图:

代码如下:

<template>
    <div class="screen-container">
        <div class="map-container">
            <div class="rlt_btn">
                <el-button class="btn" type="primary" @click="createclusterLayer('icon_1', 1)">添加点位1</el-button>
                <el-button class="btn" type="primary" @click="createclusterLayer('icon_2', 2)">添加点位2</el-button>
            </div>
            <!-- 超图及echart组件 -->
            <sm-web-map v-if="flag" @load="mapLoad" @click="mapClick" :loading="!flag" :map-options="options">
                <sm-echarts-layer :options="echartsOptions"></sm-echarts-layer>
            </sm-web-map>
            <!-- 桩位信息浮窗 -->
            <div :style="{ left: pointPosition.x + 160 + 'px', top: (pointPosition.y <= 200 ? 100 : pointPosition.y - 200) + 'px' }"
                v-if="pointVisible" class="point-info">
                <div class="pile-point-item" style="height:150px;">
                    <h2 class="pile-name">桩号:{{ pointPosition.data.stake_no }}</h2>
                    <p class="road-section">路段:{{ pointPosition.data.highway_service_name }}</p>
                    <div class="detail">
                        <p class="lnglat">X经度:{{ pointPosition.data.lng }}</p>
                        <p class="lnglat">Y纬度:{{ pointPosition.data.lat }}</p>
                    </div>
                </div>
            </div>
        </div>

    </div>
</template>
  
<script>
import { HomeApi } from '@/services/Home'
import '@supermap/iclient-mapboxgl';
import { DatasourceService, GetFeaturesByGeometryParameters } from '@supermap/iclient-mapboxgl';
import { gantry, blockList } from '@/assets/json/gantry'
import * as turf from '@turf/turf'
import icon_1 from '@/assets/ali.png'
const icon_2 = 'https://cdn.bootcdn.net/ajax/libs/leaflet/1.0.0/images/marker-icon.png'
export default {
    data() {
        return {
            options: {
            },
            echartsOptions: {
            },
            flag: false,
            visible: false,
            // 超图实例
            supermapInstance: {},
            prefix: 'http://localhost:8090/',
            nearestList: [],
            symbolSize: 8,
            pointVisible: false,
            // 点位位置信息
            pointPosition: {
                x: 0,
                y: 0,
                data: {}
            },
            pos: {
                x: 0,
                y: 0
            },
            // echart实例
            echartInstance: {},
            heatMapLayer: {},
            clusterLayer: null,//聚合图层
        };
    },
    watch: {

    },
    props: {

    },
    computed: {

    },
    created() {

    },
    async mounted() {
        await this.render()

    },
    methods: {
        // 创建聚合图层
        createclusterLayer(iconName, index) {
            let e = this.supermapInstance;
            if (e.map.getSource(`poidata-${index}`)) {
                this.removeclusterLayer(index)
            }
            let iconMap = {
                'icon_1': icon_1,
                'icon_2': icon_2
            }
            const icon = iconMap[iconName]
            var geojson = {
                "type": "FeatureCollection",
                "features": []
            };
            // 后端接口返回点坐标数据
            geojson.features = [{
                type: 'Feature',
                geometry: {
                    type: 'Point',
                    coordinates: [120.02225397864616 + index * 0.1, 30.2407888431817 + index * 0.1]
                },
                properties: {
                    title: '点一',
                    id: 1,
                }
            },
            {
                type: 'Feature',
                geometry: {
                    type: 'Point',
                    coordinates: [119.978604 + index * 0.1, 30.23495 + index * 0.1]
                },
            },
            {
                type: 'Feature',
                geometry: {
                    type: 'Point',
                    coordinates: [119.94344968972486 + index * 0.1, 30.253317832596277 + index * 0.1]
                },
            },
            {
                type: 'Feature',
                geometry: {
                    type: 'Point',
                    coordinates: [119.91344968972486 + index * 0.1, 30.273317832596277 + index * 0.1]
                },
            }
            ]
            // 创建聚合图层
            e.map.addSource(`poidata-${index}`, {
                type: 'geojson',
                data: geojson,
                cluster: true,
                //最大的聚合级别,超过级别不进行聚合
                clusterMaxZoom: 12,
                //聚合的半径,单位是像素 
                clusterRadius: 80,
                //最小聚合的点数量
                clusterMinPoints: 2

            });
            e.map.loadImage(icon, function (error, image) {
                if (error) throw error;
                e.map.addImage(`custom-icon-${index}`, image);
                e.map.addLayer({
                    id: `clusters-${index}`,
                    type: "circle",// 第一个图层为circle类型,无需显示图标,目的是根据点位大小创建圆形图层,以供点击聚合点位缩放事件
                    source: `poidata-${index}`,
                    filter: ["has", "point_count"],
                    paint: {
                        "circle-color": [
                            "step",
                            ["get", "point_count"],
                            "rgba(0,0,0,0)",
                            100,
                            "rgba(0,0,0,0)",
                            750,
                            "rgba(0,0,0,0)",
                        ],
                        "circle-radius": [
                            "step",
                            ["get", "point_count"],
                            20,
                            100,
                            30,
                            750,
                            40
                        ]
                    }
                });
                e.map.addLayer({
                    id: `cluster-count-${index}`,
                    type: "symbol",
                    source: `poidata-${index}`,
                    filter: ["has", "point_count"],
                    layout: {
                        "text-field": "{point_count_abbreviated}",
                        "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
                        "text-size": 16,
                        // "text-offset": [2, 2], 
                        'icon-image': `custom-icon-${index}`,
                        'icon-size': 0.8,
                    },
                    paint: {
                        "text-color": "#fff",
                        "text-translate": [16, -16],
                        "text-halo-color": "#1753aa", // 文本的光晕颜色(可选,默认值为 rgba(0,0,0,0))
                        "text-halo-width": 16, // 文本的光晕宽度(可选,值 >= 0,默认值为 0,单位:像素)
                        // "text-halo-blur": 0, // 文本的光晕模糊宽度(可选,值 >= 0,默认值为 0,单位:像素)
                    }
                });
                e.map.addLayer({
                    id: `unclustered-point-${index}`,
                    type: "symbol",
                    source: `poidata-${index}`,
                    filter: ["!", ["has", "point_count"]],
                    layout: {
                        'icon-image': `custom-icon-${index}`,
                        'icon-size': 0.8,
                    }
                });
                // 监听聚合图层点击事件
                // 聚合点点击事件
                e.map.on('click', `clusters-${index}`, function (el) {
                    console.log(el)
                    var features = e.map.queryRenderedFeatures(el.point, {
                        layers: [`clusters-${index}`]
                    });
                    var clusterId = features[0].properties.cluster_id;
                    e.map.getSource(`poidata-${index}`).getClusterExpansionZoom(clusterId, function (
                        err, zoom) {
                        if (err)
                            return;
                        e.map.flyTo({
                            center: features[0].geometry.coordinates,
                            zoom: zoom
                        });
                    });
                });
                // 散点点击事件
                e.map.on('click', `unclustered-point-${index}`, function (el) {
                    var features = e.map.queryRenderedFeatures(el.point, {
                        layers: [`unclustered-point-${index}`]
                    });
                    console.log(features, '散点点击事件')
                });
                e.map.on('mouseenter', `clusters-${index}`, function () {
                    e.map.getCanvas().style.cursor = 'pointer';
                });
                e.map.on('mouseleave', `clusters-${index}`, function () {
                    e.map.getCanvas().style.cursor = '';
                });
            });


        },
        // 清除聚合图层
        removeclusterLayer(index) {
            let e = this.supermapInstance;
            if (e.map.getSource(`poidata-${index}`)) {
                e.map.removeImage(`custom-icon-${index}`)
                e.map.removeLayer(`clusters-${index}`)
                e.map.removeLayer(`cluster-count-${index}`)
                e.map.removeLayer(`unclustered-point-${index}`)
                e.map.removeSource(`poidata-${index}`)
            }
        },
        mapClick(e) {
            this.render()
        },
        render() {
            this.flag = false
            this.echartsOptions = {
                GLMap: {
                    roam: true
                },
                coordinateSystem: 'GLMap',
                animation: false,
                series: []
            }
            let baseUrl = this.prefix + '/iserver/services/map-hhymap0822/rest/maps/hhy@hhymap'
            this.options = {
                container: 'map', // 地图容器 id
                style: {
                    'version': 8,
                    // glyphs为字体文件地址,必填,不然聚合缩放时聚合点位数量字体无法显示
                    "glyphs": "https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China/tileFeature/sdffonts/{fontstack}/{range}.pbf",
                    'sources': {
                        'raster-tiles': {
                            'type': 'raster',
                            'tiles': [
                                `${baseUrl}/zxyTileImage.gif?z={z}&x={x}&y={y}&transparent=true`

                            ],
                            'tileSize': 256
                        },
                        baseLayer_img: {
                            type: 'raster',
                            tiles: [
                                // process.env.BASE_IMG_API
                                `${baseUrl}/zxyTileImage.gif?z={z}&x={x}&y={y}&transparent=true`
                            ],
                            tileSize: 256
                        },
                        baseLayer_vec: {
                            type: 'raster',
                            tiles: [
                                // process.env.BASE_VEC_API
                                `${baseUrl}/zxyTileImage.gif?z={z}&x={x}&y={y}&transparent=true`
                            ],
                            tileSize: 256
                        },
                        labelLayer_img: {
                            type: 'raster',
                            tiles: [
                                // process.env.LABEL_IMG_API
                                `${baseUrl}/zxyTileImage.gif?z={z}&x={x}&y={y}&transparent=true`
                            ],
                            tileSize: 256
                        },
                        labelLayer_vec: {
                            type: 'raster',
                            tiles: [
                                // process.env.LABEL_VEC_API
                                `${baseUrl}/zxyTileImage.gif?z={z}&x={x}&y={y}&transparent=true`
                            ],
                            tileSize: 256
                        }
                    },
                    'layers': [
                        {
                            id: 'baseLayer_img',
                            type: 'raster',
                            source: 'baseLayer_img',
                            minzoom: 0,
                            maxzoom: 12
                        },
                        {
                            id: 'baseLayer_vec',
                            type: 'raster',
                            source: 'baseLayer_vec',
                            minzoom: 12,
                            maxzoom: 18
                        },
                        {
                            id: 'labelLayer_img',
                            type: 'raster',
                            source: 'labelLayer_img',
                            minzoom: 0,
                            maxzoom: 12
                        },
                        {
                            id: 'labelLayer_vec',
                            type: 'raster',
                            source: 'labelLayer_vec',
                            minzoom: 12,
                            maxzoom: 18
                        }
                    ]
                },
                center: [120.02225397864616, 30.2407888431817], // 地图中心点
                zoom: 10, // 地图初始缩放级别

                minZoom: 8,
                echartsOptions: this.echartsOptions

            }
            this.flag = true
        },
        getData() {

        }
    },

};
</script>
  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Mapbox GL支持编辑功能,可以让用户在地图上编辑的位置和样式。实现编辑需要以下步骤: 1. 创建一个Mapbox GL地图,并添加一个图层。 2. 使用Mapbox GL编辑库(mapbox-gl-draw)来创建一个编辑控制器。 3. 将编辑控制器添加到地图上,并配置它的行为和样式。 4. 处理编辑事件,以便在编辑时更新的位置和样式。 下面是一个简单的示例代码,演示如何实现编辑: ```javascript // 创建地图 var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v11', center: [-73.935242, 40.730610], zoom: 12 }); // 添加图层 map.on('load', function() { map.addSource('points', { type: 'geojson', data: { type: 'FeatureCollection', features: [{ type: 'Feature', geometry: { type: 'Point', coordinates: [-73.935242, 40.730610] }, properties: { name: 'Some point' } }] } }); map.addLayer({ id: 'points-layer', type: 'circle', source: 'points', paint: { 'circle-radius': 10, 'circle-color': '#3388ff' } }); }); // 创建编辑控制器 var drawControl = new MapboxDraw({ displayControlsDefault: false, controls: { point: true, trash: true } }); // 添加编辑控制器 map.addControl(drawControl); // 处理编辑事件 map.on('draw.update', function(e) { var features = e.features; // 更新的位置和样式 map.getSource('points').setData({ type: 'FeatureCollection', features: features }); }); ``` 在这个示例中,我们创建了一个地图,添加了一个图层,并在图层上显示一个。然后,我们创建了一个编辑控制器,并将它添加到地图上。最后,我们处理了编辑事件,并在编辑时更新了的位置和样式。 你可以根据自己的需求进一步定制编辑的行为和样式。更多关于Mapbox GL编辑功能的详细信息可以在Mapbox GL的官方文档中找到。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阁下何不同风起?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值