写作背景:感觉支付宝小程序这块有很多未知的领域,于是有时间探索一下,并写文章记录一下。
遇到的问题,感觉地图这块收费很恶心。支付宝自带高德地图,应该是免费的。微信小程序自带腾讯地图是免费。地图这块很Tm恶心,收费5万。Tm的抢钱啊。于是用自带的地图。

坑爹玩意,拖动组件事件,后端也请求了,数据也更新了。就是显示不出来,奇怪了。很倒霉。晦气的很,不研究了。搞点简单的。我呸。
还是有点坑,还是没有解决。懒得解决。解决了也赚不到钱。被折腾了心情又不好。算了不写了。

第一步 小程序页面

index.axml

<view>
  <map
    id="map"
    longitude="{{longitude}}"
    latitude="{{latitude}}"
    scale="{{scale}}"
    controls="{{controls}}"
    onControlTap="controltap"
    markers="{{markers}}"
    onMarkerTap="markertap"
    polyline="{{polyline}}"
    polygon="{{polygon}}"
    circles="{{circles}}"
    panels="{{panels}}"
    onPanelTap="onPanelTap"
    onRegionChange="regionchange"
    onTap="tap"
    onCalloutTap="callouttap"
    show-location
    style="width: 100%; height: 100vh"
    include-points="{{includePoints}}"
    ground-overlays="{{ground-overlays}}">
  </map>

  <!-- <cover-view class="cover-view">
    <cover-view class="cover-view-item cover-view-item-1"></cover-view>
    <cover-view class="cover-view-item cover-view-item-2"></cover-view>
    <cover-view class="cover-view-item cover-view-item-3"></cover-view>
  </cover-view>
  <cover-image style="" src="https://gw.alipayobjects.com/mdn/rms_eb2664/afts/img/A*bFuBQZuNErMAAAAAAAAAAABkARQnAQ" /> -->

  <!-- <cover-view class="cover-right-view">
    <cover-image class="return image" src="/static/image/home/map_return.png" />
    <cover-image class="search image" src="/static/image/home/map_search.png" />
  </cover-view>
  -->

  <cover-view class="cover-view">
    <cover-image class="cover-view-item cover-view-item-1" src="/static/image/home/map_return.png" onTap="demoMoveToLocation"/>
    <cover-image class="cover-view-item cover-view-item-2" src="/static/image/home/map_search.png" />
  </cover-view>

  <!-- <cover-view class="cover-view">
    <view class="right">
      <image src="/static/image/home/map_return.png" />
      <image src="/static/image/home/map_search.png" />
    </view>
  </cover-view> -->
  
  <!-- {{ scale }}
  <button size="default" type="primary" onTap="loadData">
    查询
  </button>

  <button size="default" type="primary" onTap="demoMarkerAnimation">
    Marker
  </button>

   <view onTap="demoMoveToLocation">回到定位点</view> 
  -->
</view>

第二步:js逻辑文件

const markers = [{
  id: 0,
  latitude: 30.266786,
  longitude: 120.10675,
  width: 19,
  height: 31,
  iconPath: 'https://gw.alipayobjects.com/mdn/rms_dfc0fe/afts/img/A*x9yERpemTRsAAAAAAAAAAAAAARQnAQ',
  callout: {
    content: 'callout',
  },
}]; 

const panels = [
  {
   id: 6,
   layout:{
   src:'/layout/panel.xml'
   },
   position: {
   top: 5,
   right: 5,
   width: 200,
   height: 84
   }
}];

const animMarker = [{
  id: 1,
  latitude: 30.266786,
  longitude: 120.10675,
  width: 19,
  height: 31,

  iconPath: 'https://gw.alipayobjects.com/mdn/rms_dfc0fe/afts/img/A*x9yERpemTRsAAAAAAAAAAAAAARQnAQ',

  fixedPoint:{
    originX: 200,
    originY: 150,
  },
  markerLevel: 2
}];

const labelMarker = [{
  id: 2,
  latitude: 30.266786,
  longitude: 120.10675,
  width: 19,
  height: 31,
  iconPath: 'https://gw.alipayobjects.com/mdn/rms_dfc0fe/afts/img/A*x9yERpemTRsAAAAAAAAAAAAAARQnAQ',
  label:{
    content:"Hello Label",
    color:"#00FF00",
    fontSize:14,
    borderRadius:3,
    bgColor:"#ffffff",
    padding:10,
  },
  markerLevel: 2
}];
const customCalloutMarker = [{
  id: 3,
  latitude: 30.266786,
  longitude: 120.10675,
  width: 19,
  height: 31,
  iconPath: 'https://gw.alipayobjects.com/mdn/rms_dfc0fe/afts/img/A*x9yERpemTRsAAAAAAAAAAAAAARQnAQ',
  "customCallout":{
    "type": 2,
    "descList": [{
      "desc": "预计",
      "descColor": "#333333"
    }, {
      "desc": "5分钟",
      "descColor": "#108EE9"
    }, {
      "desc": "到达",
      "descColor": "#333333"
    }],
    "isShow": 1
  },
  markerLevel: 2
}];

const iconAppendStrMarker = [{
  id: 34,
  latitude: 30.266786,
  longitude: 120.10675,
  width: 19,
  height: 31,
  iconAppendStr:"iconAppendStr",
  markerLevel: 2
}];

var myTrafficEnabled = 0;
var myCompassEnabled = 0;
var myScaleEnabled = 0;
var myGestureEnabled = 0;

const longitude = "";
const latitude = "";
const includePoints = [];

Page({
  data: {
    scale: 18,
    longitude,
    latitude,
    includePoints,
    markersData: []
  },
  onReady() {
    // 使用 my.createMapContext 获取 map 上下文
    this.mapCtx = my.createMapContext('map');
  },
  onShow() {
    // 由于跳转到系统设置页无法监听用户最终是否打开系统定位及对支付宝授权位置信息,因此请在生命周期 onShow 中调用定位授权准备方法。
    const authGuideLocation = async () => {
      const myGetSystemInfo = () => {
        return new Promise((resolve, reject) => {
          my.getSystemInfo({
            success: resolve,
            fail: reject
          });
        });
      };

      const myGetSetting = () => {
        return new Promise((resolve, reject) => {
          my.getSetting({
            success: resolve,
            fail: reject
          });
        });
      };

      const myOpenSetting = () => {
        return new Promise((resolve, reject) => {
          my.openSetting({
            success: resolve,
            fail: reject
          });
        });
      };

      const myAlert = (content) => {
        return new Promise((resolve, reject) => {
          my.alert({
            content,
            success: resolve,
            fail: reject
          });
        });
      };

      // 获取用户是否开启系统定位及授权支付宝使用定位
      const isLocationEnabled = async () => {
        const systemInfo = await myGetSystemInfo();
        return !!(systemInfo.locationEnabled && systemInfo.locationAuthorized);
      };

      // 若用户未开启系统定位或未授权支付宝使用定位,则跳转至系统设置页
      const showAuthGuideIfNeeded = async () => {
        if (!(await isLocationEnabled())) {
          my.showAuthGuide({
            authType: "LBS"
          });
          return false;
        }
        return true;
      };

      // 获取用户是否授权过当前小程序使用定位
      const isLocationMPAuthorized = async () => {
        const settingInfo = await myGetSetting();
        return settingInfo.authSetting.location === undefined || settingInfo.authSetting.location;
      };

      // 若用户未授权当前小程序使用定位,则引导用户跳转至小程序设置页开启定位权限
      const requestLocationPermission = async () => {
        await myAlert("如果用户之前拒绝授权当前小程序获取地理位置权限,将会弹出此弹窗,请根据需要替换文案。");
        const openSettingInfo = await myOpenSetting();
        return openSettingInfo.authSetting.location;
      };

      try {
        if (!(await showAuthGuideIfNeeded())) {
          return false;
        }
        if (await isLocationMPAuthorized()) {
          return true;
        }
        if (await requestLocationPermission()) {
          return true;
        }
        return false;
      } catch (error) {
        console.error(error);
        return false;
      }
    };

    const that = this
    authGuideLocation().then(res => {
      console.log(res);
      if (res === true) {
        my.getLocation({
          type: 1, // 获取经纬度和省市区县数据
          success: (res) => {
            that.setData({
              longitude: res.longitude,
              latitude: res.latitude,
              scale: res.scale
            })

            setTimeout(() => {
              that.loadData()
              that.createCenterElement()
            }, 2000)
          }, 
          fail: (error) => {
            console.error('定位失败: ', JSON.stringify(error));
          },
        });
      }
    });
  },
  createCenterElement() {
    const that = this

    setTimeout(() => {
      that.data.markersData.push({
        id: 1,
        latitude: that.data.latitude,
        longitude: that.data.longitude,
        width: 19,
        height: 31,
        iconPath: '/static/image/home/map_indicator.png',
        fixedPoint: {
          originX: (375 / 2) - (19 / 2),
          originY: (667 / 2) - (31 / 2)
        },
        markerLevel: 2
      })

      that.mapCtx.updateComponents({
        'markers': that.data.markersData
      });
      that.mapCtx.updateComponents({
        command:{
          markerAnim:[{markerId : 1, type : 0}],
        }
      });
    }, 3000)
  },
  loadData() {
    const that = this
    my.request({
      url: 'http://localhost:3000/store/list',
      method: 'GET',
      headers: {
        'content-type': 'application/json', //默认值
      },
      dataType: 'json',
      success: function (res) {
        let markers = [], includePoints = []

        includePoints.push
        ({
          latitude: that.data.latitude,
          longitude: that.data.longitude
        })

        markers.push({
          id: 99,
          latitude: that.data.latitude,
          longitude: that.data.longitude,
          width: 24,
          height: 24,
          iconPath: '/static/image/home/map_current.png',
          markerLevel: 1
        })

        res.data.data.forEach((row, index) => {
          markers.push({
            id: index,
            latitude: row.latitude,
            longitude: row.longitude,
            width: 19,
            height: 31,
            iconPath: 'https://gw.alipayobjects.com/mdn/rms_dfc0fe/afts/img/A*x9yERpemTRsAAAAAAAAAAAAAARQnAQ',
            markerLevel: 2
          })
          
          includePoints.push({
            latitude: row.latitude,
            longitude: row.longitude
          })
        })
  
        that.mapCtx.updateComponents({
          scale: 14,
          longitude,
          latitude,
          markers: markers,
          includePoints: includePoints
        })

        that.setData({
          markersData: markers
        })
        console.log(res.data.data, markers, includePoints) 
      }
    })
  },
  demoResetMap() {
    this.setData({
      scale: 14,
      longitude,
      latitude,
      includePoints,
      'ground-overlays':[],
      circles:[],
      polygon:[],
      polyline:[],
    });
    this.mapCtx.clearRoute();
  },
  demoGetCenterLocation() {
    this.mapCtx.getCenterLocation({
      success: (res) => {
        my.alert({
          content: 'longitude:' + res.longitude + '\nlatitude:' + res.latitude + '\nscale:' + res.scale,
        });

        console.log(res.longitude);
        console.log(res.latitude);
        console.log(res.scale); 
      },
    });
  },
  demoMoveToLocation() {
    this.mapCtx.moveToLocation();
  },
  demoMarkerAnimation() {
    if (!my.canIUse('createMapContext.return.updateComponents')) {
      my.alert({ 
        title: '客户端版本过低',
        content: 'this.mapCtx.updateComponents 需要 10.1.35 及以上版本'
      });
      return;
    } 
    this.mapCtx.updateComponents({
      'markers':animMarker,
    });
    this.mapCtx.updateComponents({
      command:{
        markerAnim:[{markerId:1,type:0},],
      }
    });
  },
  demoMarkerLabel() {
    if (!my.canIUse('createMapContext.return.updateComponents')) {
      my.alert({ 
        title: '客户端版本过低',
        content: 'this.mapCtx.updateComponents 需要 10.1.35 及以上版本'
      });
      return;
    } 
    this.mapCtx.updateComponents({
      scale: 14,
      longitude,
      latitude,
      includePoints,
      'markers':labelMarker,
    });
  },
  demoMarkerCustomCallout() {
    this.mapCtx.updateComponents({
      scale: 14,
      longitude,
      latitude,
      includePoints,
      'markers':customCalloutMarker,
    });
  },
  demoMarkerAppendStr() {
    this.mapCtx.updateComponents({
      scale: 14,
      longitude,
      latitude,
      includePoints,
      'markers':iconAppendStrMarker,
    });
  },
  demoTrafficOverlay() {
    if (!my.canIUse('createMapContext.return.updateComponents')) {
      my.alert({ 
        title: '客户端版本过低',
        content: 'this.mapCtx.updateComponents 需要 10.1.35 及以上版本'
      });
      return;
    } 
    myTrafficEnabled = (myTrafficEnabled+1) %2;
    this.mapCtx.updateComponents({setting:{trafficEnabled:myTrafficEnabled}});
  },
  demoShowRoute() {
    this.mapCtx.showRoute({
      startLat:30.257839, 
      startLng:120.062726,
      endLat:30.256718,
      endLng:120.059985,
      zIndex:4,
      routeColor:'#FFB90F',
      iconPath: "https://gw.alipayobjects.com/mdn/rms_dfc0fe/afts/img/A*EGCiTYQhBDkAAAAAAAAAAAAAARQnAQ",
      iconWidth:10,
      routeWidth:10
     });
  },
  demoCompass() {
    myCompassEnabled = (myCompassEnabled+1) %2;
    this.mapCtx.showsCompass({isShowsCompass:myCompassEnabled});
  },
  demoScale() {
    myScaleEnabled = (myScaleEnabled+1) %2;
    this.mapCtx.showsScale({isShowsScale:myScaleEnabled});
  },
  demoGesture() {
    myGestureEnabled = (myGestureEnabled+1) %2;
    this.mapCtx.gestureEnable({isGestureEnable:myGestureEnabled});
  },
  demoPolyline() {
    this.setData({
      scale: 16,
      longitude,
      latitude,
      polyline: [{
        points: [{// 右上
          latitude: 30.264786,
          longitude: 120.10775,
        },{// 左下
          latitude: 30.268786,
          longitude: 120.10575,
        }],
        color: '#FF0000DD',
        width: 10,
        dottedLine: false,
        iconWidth:10,
      }],
    });
  },
  demoPolygon() {
    this.setData({
      scale: 16,
      longitude,
      latitude,
      polygon: [{
        points: [{// 右上
          latitude: 30.264786,
          longitude: 120.10775,
        },{// 右下
          latitude: 30.268786,
          longitude: 120.10775,
        },{// 左下
          latitude: 30.268786,
          longitude: 120.10575,
        },{// 左上
          latitude: 30.264786,
          longitude: 120.10575,
        }],
        fillColor: '#BB0000DD',
        width: 5,
      }],
    });
    
  },
  demoCircle() {
    this.setData({
      scale: 16,
      longitude,
      latitude,
      circles: [{
        longitude,
        latitude,
        color: '#BB76FF88',
        fillColor: '#BB76FF33',
        radius: 100,
        strokeWidth:3,
    }]
    });
  },
  regionchange(e) {
    console.log('regionchange', e);
  },
  onPanelTap(e) {
    console.log('paneltap:', e);
  },
  markertap(e) {
    console.log('marker tap', e);
  },
  controltap(e) {
    console.log('control tap', e);
  },
  tap(e) {
    const that = this
    console.log(e);
    console.log('tap');

    my.request({
      url: 'http://localhost:3000/store/add',
      method: 'GET',
      data: {
        latitude: e.latitude,
        longitude: e.longitude
      },
      headers: {
        'content-type': 'application/json', //默认值
      },
      dataType: 'json',
      success: function (res) {
        // that.loadData()
      },
      fail: function (error) {
        console.error('fail: ', JSON.stringify(error));
      }
    })
  },
  callouttap(e) {
    console.log('callout tap', e);
  },
});

第三步:css文件

.cover-view {
  position: absolute;
  bottom: 64rpx;
  right: 24rpx;
  display:flex;
  flex-direction:row;
  background-color: rgba(0, 0, 0, 0);
  flex-direction: column;
}

.cover-view-item{
  width: 102rpx;
  height: 102rpx;
}

第四步:express

const express = require('express')
require('express-async-errors')

const app = express()
const port = 3000

const conn = require('./config/mysql')

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.get('/store/list', (req, res) => {
  conn.query('select * from store ORDER BY store_id', function (err, rows, fields) {
    res.send({"result": "ok", "data": rows})
  })
})

app.get('/store/add', (req, res) => {
  const query = req.query
  conn.query(`INSERT INTO store (latitude, longitude) VALUES ('${query.latitude}', '${query.longitude}')`, function (err, rows, fields) {
    console.log(err)
    res.send({"result": "ok"})
  })
  res.send({"result": "ok", 'data': req.query})
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

第五步:数据库文件

CREATE TABLE `store` (
    `store_id` INT(11) NOT NULL AUTO_INCREMENT,
    `store_name` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
    `store_image` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
    `create_time` INT(11) NULL DEFAULT NULL,
    `update_time` INT(11) NULL DEFAULT NULL,
    `latitude` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
    `longitude` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
    PRIMARY KEY (`store_id`) USING BTREE,
    UNIQUE INDEX `latitude` (`latitude`) USING BTREE,
    UNIQUE INDEX `longitude` (`longitude`) USING BTREE
)
COLLATE='utf8_unicode_ci'
ENGINE=MyISAM
AUTO_INCREMENT=69
;

第六步:数据库连接

const mysql = require('mysql')

const conn = mysql.createConnection({
    host: '127.0.0.1',
    user: 'root',
    password: 'root',
    database: 'mini',
    port: 3306
})

try {
    conn.connect(function(err){
        if(err) {console.log("连接失败!")};
        console.log("连接成功,当前连接线程ID:"+conn.threadId);
    })
} catch(e) {}

module.exports = conn

ThinkPHP
4 声望3 粉丝

引用和评论

0 条评论