收藏
回答

MapContext.addGroundOverlay贴的图在地图上为什么图片和原图不一样?

使用该api时,得到的贴图和原图不一样,导致贴图在地图上有偏差,看起来像是原图被挤压了,是不是我算的坐标的代码不对?

成果图:

为了看的更明显,改成了黑色背景,可以明显看到直角不再是直角:

原图:http://dl.dpgrid.com/wxapp/dom/zcl-wuhan.jpg

整体代码:

<template>
    <view>
        <map id="myMap" :latitude="markers[0].latitude" :longitude="markers[0].longitude" scale="16" :markers="markers"
            :ground-overlays="groundOverlays" @markertap="onMarkerTap" enable-satellite :min-scale="16"
            :max-scale="18"></map>
        <view v-if="showImage" class="image-container">
            <movable-area class="movable-area">
                <movable-view class="movable-view" scale scale-min="1" scale-max="4" direction="all">
                    <image :src="imageUrl" mode="aspectFit"></image>
                </movable-view>
            </movable-area>
            <view class="close-btn" @click="hideImage">×</view>
        </view>
    </view>
</template>


<script>
export default {
    data() {
        return {
            markers: [
                {
                    id: 1,
                    latitude: 30.4701,
                    longitude: 114.4301,
                    iconPath: '/static/alarmLocation.png',
                    width: 50,
                    height: 70
                }
            ],
            imageUrl: '',
            iconSrc: '/static/alarmLocation.png',
            showImage: false,
            mapContext: null,
            groundOverlayOptions: {
                area1: {
                    id: 1,
                    src: 'https://dl.dpgrid.com/wxapp/dom/zcl-wuhan.jpg',
                    pixelScale: 0.00000496465716626,
                    width: 1916,
                    height: 1832,
                    topLeftLng: 114.33830699979174,
                    topLeftLat: 30.75189899769226,
                },
                area2: {
                    id: 2,
                    src: '',
                    pixelScale: 0,
                    width: 0,
                    height: 0,
                    topLeftLng: 0,
                    topLeftLat: 0,
                }
            },
        };
    },
    onLoad(options) {
        try {
            this.mapContext = wx.createMapContext('myMap', this);
            if (!this.validateOptions(options)) {
                throw new Error('无效的参数');
            }


            const imageUrl = `https://dl.dpgrid.com/${options.img}`;
            this.imageUrl = imageUrl;
            this.updateMarkerPosition(options);
            // this.addGroundOverlay(options.type);
            this.addGroundOverlay('area1');
        } catch (error) {
            console.error('初始化失败:', error.message);
        }
    },
    methods: {
        validateOptions(options) {
            return options?.latitude
                && options?.longitude
                && options?.img
            // && options?.type;
        },
        updateMarkerPosition(options) {
            // 不进行WGS84到GCJ02的转换
            // const gcj02Coords = this.wgs84ToGcj02(Number(options.longitude), Number(options.latitude));
            // 进行WGS84到GCJ02的转换
            const gcj02Coords = this.wgs84ToGcj02(Number(options.longitude), Number(options.latitude));


            const newMarkers = [{
                id: 1,
                // latitude: Number(options.latitude),
                // longitude: Number(options.longitude),
                latitude: gcj02Coords.lat,
                longitude: gcj02Coords.lng,
                iconPath: this.iconSrc,
                width: 50,
                height: 70
            }];
            this.replaceMarkers(newMarkers);
        },
        replaceMarkers(newMarkers) {
            // console.log('替换为新marker', newMarkers);
            this.markers = newMarkers
        },
        onMarkerTap() {
            this.showImage = true;
        },
        hideImage() {
            this.showImage = false;
        },
        addGroundOverlay(type) {
            const overlayOption = this.groundOverlayOptions[type];
            if (!overlayOption) {
                console.log('未找到对应的覆盖物配置');
                return;
            }


            const bounds = this.calculateBoundsFromTfw(
                overlayOption.pixelScale,
                overlayOption.width,
                overlayOption.height,
                overlayOption.topLeftLng,
                overlayOption.topLeftLat
            );
            // console.log('计算的边界值:', bounds);


            this.mapContext.addGroundOverlay({
                id: overlayOption.id,
                src: overlayOption.src,
                bounds: bounds,
                success: (res) => {
                    console.log('添加覆盖物成功', res);
                },
                fail: (err) => {
                    console.log('添加覆盖物失败', err);
                }
            });
        },
        calculateBoundsFromTfw(pixelScale, width, height, topLeftLng, topLeftLat) {
            const wgs84NE = {
                lng: topLeftLng + (pixelScale * width),
                lat: topLeftLat
            };
            const wgs84SW = {
                lng: topLeftLng,
                lat: topLeftLat + (-pixelScale * height)
            };


            const wgs84NW = {
                lng: topLeftLng,
                lat: topLeftLat
            };
            const wgs84SE = {
                lng: topLeftLng + (pixelScale * width),
                lat: topLeftLat + (-pixelScale * height)
            };


            // 输出四个角的GCJ02坐标
            console.log('贴图四个角的GCJ02坐标:');
            console.log('西北角:', wgs84NW.lat, wgs84NW.lng);
            console.log('东北角:', wgs84NE.lat, wgs84NE.lng);
            console.log('西南角:', wgs84SW.lat, wgs84SW.lng);
            console.log('东南角:', wgs84SE.lat, wgs84SE.lng);
            const gcj02NE = this.wgs84ToGcj02(wgs84NE.lng, wgs84NE.lat);
            const gcj02SW = this.wgs84ToGcj02(wgs84SW.lng, wgs84SW.lat);
            return {
                northeast: {
                    latitude: gcj02NE.lat,
                    longitude: gcj02NE.lng
                },
                southwest: {
                    latitude: gcj02SW.lat,
                    longitude: gcj02SW.lng
                }
            };
        },
        wgs84ToGcj02(lng, lat) {
            const PI = 3.14159265358979324;
            const a = 6378245.0;
            const ee = 0.00669342162296594323;


            if (this.outOfChina(lat, lng)) {
                return { lng, lat };
            }


            let dLat = this.transformLat(lng - 105.0, lat - 35.0);
            let dLng = this.transformLng(lng - 105.0, lat - 35.0);


            const radLat = lat / 180.0 * PI;
            let magic = Math.sin(radLat);
            magic = 1 - ee * magic * magic;


            const sqrtMagic = Math.sqrt(magic);
            dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
            dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);


            return {
                lat: lat + dLat,
                lng: lng + dLng
            };
        },
        outOfChina(lat, lng) {
            if (lng < 72.004 || lng > 137.8347) {
                return true;
            }
            if (lat < 0.8293 || lat > 55.8271) {
                return true;
            }
            return false;
        },
        transformLat(x, y) {
            let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
            ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0;
            ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0;
            return ret;
        },
        transformLng(x, y) {
            let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
            ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0;
            ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0;
            return ret;
        }
    }
};
</script>


<style>
map {
    width: 100%;
    height: 100vh;
}


.image-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 100;
    background-color: rgba(0, 0, 0, 0.5);
}


.movable-area {
    width: 100%;
    height: 100%;
}


.movable-view {
    width: 100%;
    height: 100%;
}


image {
    width: 100%;
    height: 100%;
}


.close-btn {
    position: fixed;
    top: 30px;
    right: 30px;
    width: 40px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    background-color: rgba(0, 0, 0, 0.5);
    color: #fff;
    border-radius: 50%;
    font-size: 24px;
    z-index: 101;
    cursor: pointer;
}
</style>

回答关注问题邀请回答
收藏

1 个回答

  • 小黎
    小黎
    02-24

    就是经纬度问题

    试试这个经纬度     southwest: {

              longitude: "114.343909",

              latitude: '30.741349'

            },

            northeast: {

              longitude: "114.353878",

              latitude: '30.749573'

            }


    02-24
    有用 1
    回复 1
    • yeah~
      yeah~
      02-24
      感谢你拿到回答!大佬,您这个坐标确实没有偏差,但是我还是不确定问题在哪,是area1的坐标不对吗。
      这个坐标是我在同事给我的pgw文件里拿到的:
      0.00000496465716626
      0
      0
      -0.00000496465716626
      114.33830699979174
      30.75189899769226
      02-24
      回复
登录 后发表内容