高德地图编辑多边形区域以及大地距离算法

上代码

自配送

参考门店周围

mounted () {
this.map = new AMap.Map(‘container’, {
center: this.center,
zoom: 14
});
this.adminStoreloadShippingSet()
this.setClienHeight()
window.onresize = () => {
this.setClienHeight()
}
},

methods: {
/**
* 度换成弧度
* @param {Float} d 度
* @return {[Float} 弧度
*/
rad(d) {
return d * Math.PI / 180.0;
},

/**
 * 弧度换成度
 * @param  {Float} x 弧度
 * @return {Float}   度
 */
deg(x) {
    return x*180/Math.PI;
},

// 根据一点的经纬度、方位角、距离计算另一点的经纬度
destinationVincenty(lonlat, brng, dist) {
  //lonlat 已知点的经纬度
  //brng 方位角(正北为0,顺时针为正,逆时针为负)
  // dist 距离(米)
  let ct = this.VincentyConstants;
  let a = ct.a, b = ct.b, f = ct.f;

  let lon1 = lonlat.lon;
  let lat1 = lonlat.lat;

  let s = dist;
  let alpha1 = this.rad(brng);
  let sinAlpha1 = Math.sin(alpha1);
  let cosAlpha1 = Math.cos(alpha1);

  let tanU1 = (1-f) * Math.tan(this.rad(lat1));
  let cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
  let sigma1 = Math.atan2(tanU1, cosAlpha1);
  let sinAlpha = cosU1 * sinAlpha1;
  let cosSqAlpha = 1 - sinAlpha*sinAlpha;
  let uSq = cosSqAlpha * (a*a - b*b) / (b*b);
  let A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
  let B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));

  let sigma = s / (b*A), sigmaP = 2*Math.PI;
  let sinSigma = '', cosSigma = '', cos2SigmaM = '';
  while (Math.abs(sigma-sigmaP) > 1e-12) {
      cos2SigmaM = Math.cos(2*sigma1 + sigma);
      sinSigma = Math.sin(sigma);
      cosSigma = Math.cos(sigma);
      let deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
          B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
      sigmaP = sigma;
      sigma = s / (b*A) + deltaSigma;
  }

  let tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
  let lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
      (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
  let lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
  let C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
  let L = lambda - (1-C) * f * sinAlpha *
      (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));

  let revAz = Math.atan2(sinAlpha, -tmp);  // final bearing

  return {lon2: lon1 + this.deg(L), lat2: this.deg(lat2)}
},
// 门店外卖设置信息
async adminStoreloadShippingSet () {
  let data = await this.$api.adminStoreloadShippingSet({
    id: JSON.parse(sessionStorage.getItem('userAuthInfo')).storeId
  })
  if (data !== 'error') {
    console.log('外卖信息', data)
    this.deliveryDetialData = data
    this.minDeliveryVal = data.startPrice;
    this.deliveryCost = data.deliveryFee;
    this.center = [Number(data.longitude), Number(data.latitude)]
    if (!data.polygon) {
      // 默认四点处理    
      let lonlat1 = this.destinationVincenty({lon: this.center[0], lat: this.center[1]}, 45, 2000)
      let lonlat2 = this.destinationVincenty({lon: this.center[0], lat: this.center[1]}, 135, 2000)
      let lonlat3 = this.destinationVincenty({lon: this.center[0], lat: this.center[1]}, 225, 2000)
      let lonlat4 = this.destinationVincenty({lon: this.center[0], lat: this.center[1]}, 315, 2000)
      this.path = [
        [lonlat1.lon2, lonlat1.lat2],
        [lonlat2.lon2, lonlat2.lat2],
        [lonlat3.lon2, lonlat3.lat2],
        [lonlat4.lon2, lonlat4.lat2]
      ]
    } else {
      // 有设置过配送范围

    }       
    this.initialPath = await this.DeepClone(this.path)
    this.initMap()
  }
},

// 配送费校验
deliveryCostInput () {
  if (!this.$regexp.integerOrADecimal.test(this.deliveryCost)) {
    this.deliveryCostState = true
  } else {
    this.deliveryCostState = false
  }
},

// 起送价非0正整数校验
minDeliveryInput () {
  if (!this.$regexp.isInterger.test(this.minDeliveryVal)) {
    this.miniDeliveryState = true
  } else {
    this.miniDeliveryState = false
  }
},

checkInput (e) {
  let key = e.key
  if (key === 'e') {
    e.returnValue = false
    return false
  }
  return true
},

setClienHeight () {
  document.getElementsByClassName('adminDeliverySettings')[0].style.height = document.documentElement.clientHeight - 125 + 'px'
},

// 保存
save () {
  this.polyEditor.close()
},

// 深复制
DeepClone (obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  let cpObj = obj instanceof Array ? [] : {}
  for (let key in obj) cpObj[key] = this.DeepClone(obj[key])
  return cpObj
},

// 退出
cancle () {
  this.path = this.DeepClone(this.initialPath);
  this.resetMap()
  if (this.checked) {
    this.setCircle();
  }
  this.handleShow = false;
},

// 编辑
edite () {
  this.polyEditor.open();
  this.handleShow = true;
},

resetMap () {
  this.map.destroy()
  this.map = new AMap.Map('container', {
    center: this.center,
    zoom: 14
  });
  this.initMap()
},

radiusInput () {
  if (this.radius > 0) {
    this.radius = this.radius && this.radius > 0 && Number.parseFloat(Number(this.radius).toFixed(2))
  }
  if (this.radius < 0) {
    this.radius = 0;
    this.resetMap();
    return
  }
  if (this.radius > 8888) {
    this.radius = 8888
  }
  if (this.radius && this.checked) {
    this.resetMap();
    this.setCircle();
  }
},

radiusBlur () {
  // console.log(this.radius)
  if (this.radius === '') {
    this.$message({
      type: 'info',
      message: '请输入数字,最多两位小数'
    })
    return
  }
},

checkChange () {
  if (this.checked) {
    this.resetMap();
    this.setCircle();
  } else {
    this.resetMap();
  }
},

// 设置参考范围
setCircle () {
  let circle = new AMap.Circle({
    center: this.center,
    radius: this.radius * 1000, //半径
    borderWeight: 3,
    strokeColor: "#FF33FF", 
    strokeOpacity: 1,
    strokeWeight: 6,
    strokeOpacity: 0.6,
    fillOpacity: 0.6,
    strokeStyle: 'dashed',
    strokeDasharray: [10, 10], 
    // 线样式还支持 'dashed'
    fillColor: 'transparent',
    zIndex: 48,
  })
  circle.setMap(this.map)
  this.map.setFitView([ this.polygon, circle ])
  let circleEditor = new AMap.CircleEditor(this.map, circle)
},

// 范围初始化
initMap() {
  this.polygon = new AMap.Polygon({
      path: this.path,
      strokeColor: "#FF33FF", 
      strokeWeight: 6,
      strokeOpacity: 0.2,
      fillOpacity: 0.4,
      fillColor: '#1791fc',
      zIndex: 50,
  })

  this.map.add(this.polygon)
  // 缩放地图到合适的视野级别
  this.map.setFitView([ this.polygon ])
  this.polyEditor = new AMap.PolyEditor(this.map, this.polygon)

  this.polyEditor.on('addnode', (event) => {
    console.log('触发事件:addnode', event)
  })

  this.polyEditor.on('adjust', (event) => {
    console.log('触发事件:adjust', event)
  })

  this.polyEditor.on('removenode', (event) => {
    console.log('触发事件:removenode', event)
  })

  this.polyEditor.on('end', async (event) => {
    console.log('触发事件: end', Array.from(event.target.w.path))
    // this.initialPath = [];
    let pathArray = Array.from(event.target.w.path);
    this.deliveryDetialData.polygon = '';
    for (let i = 0, length = pathArray.length; i < length; i++ ) {
      // await this.initialPath.push([pathArray[i].lng, pathArray[i].lat])
      this.deliveryDetialData.polygon = this.deliveryDetialData.polygon + `${pathArray[i].lng} ${pathArray[i].lat},`;
      // console.log('**********1', this.deliveryDetialData.polygon)
    }
    this.deliveryDetialData.polygon = this.deliveryDetialData.polygon.substring(0, this.deliveryDetialData.polygon.length - 1);
    // console.log('**********', this.deliveryDetialData.polygon)
    this.adminUpdateShippingSet()
    // console.log('保存的经纬度', this.initialPath, this.path)
  })
},

// 更新门店外卖设置
async adminUpdateShippingSet () {
  // console.log(this.minDeliveryVal, this.deliveryCost)
  if (!this.minDeliveryVal && this.minDeliveryVal !== 0) {
    this.$message({
      type: 'info',
      message: '起送价格不能为空!'
    })
    return;
  }
  if (!this.deliveryCost && this.deliveryCost !== 0) {
    this.$message({
      type: 'info',
      message: '配送费不能为空!'
    })
    return;
  }
  if (this.miniDeliveryState) {
    this.$message({
      type: 'info',
      message: '起送价格式不正确!'
    })
    return;
  }
  if (this.deliveryCostState) {
    this.$message({
      type: 'info',
      message: '配送费格式不正确!'
    })
    return;
  }
  this.deliveryDetialData.shippingType = Number(this.radio)
  this.deliveryDetialData.startPrice = this.minDeliveryVal
  this.deliveryDetialData.deliveryFee = this.deliveryCost
  // console.log(this.deliveryDetialData)
  let data = await this.$api.adminUpdateShippingSet(this.deliveryDetialData);
  if (data !== 'error') {
    console.log(data)
  }
}

}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#define geo_max(a,b) (((a) > (b)) ? (a) : (b)) #define geo_min(a,b) (((a) < (b)) ? (a) : (b)) GEO_EXPORT mappoint geo_trangeo2map(georect* grt, geopoint* pt, maprect* mrt); GEO_EXPORT geopoint geo_tranmap2geo(maprect* mrt, mappoint* mpt, georect* grt); /* *判断点在不在矩形里.在返回0 * 不在返回-1 */ GEO_EXPORT int geo_gptingrt(geopoint* gpt, georect* grt); GEO_EXPORT int geo_mptinmrt(mappoint* mpt, maprect* mrt); GEO_EXPORT geobool geo_gptingpolygon(geopoint* gpt, geopoints *gpts); /* *返回单位为:米 */ GEO_EXPORT double geo_distance(geopoint* gptfrom, geopoint* gptto); GEO_EXPORT double geo_distance_pt2polyline(geopoint* gpt, geopoints* gpts, geopoint* rnearestpt); GEO_EXPORT double geo_distance_pt2polygon(geopoint* gpt, geopoints* gpts, geopoint* rnearestpt); /* *返回单位为:平方米 */ //GEO_EXPORT double geo_area(geopoints* gpts); /* *返回单位为:度 *正北为0度,顺时针为正 */ GEO_EXPORT double geo_direction(geopoint* gptfrom, geopoint* gptto); /* * 矩形与矩形的关系 * a 在 b 里面, 返回 0 * a 部份在 b 里面,返回 1 * a 没和 b 相交, 返回 -1 * /\ y * | * | * | * |------------> x * o */ int geo_grtingrt(georect* rta, georect* rtb); /* * 矩形与矩形的关系 * a 在 b 里面, 返回 0 * a 部份在 b 里面,返回 1 * a 没和 b 相交, 返回 -1 * * o * |------------> x * | * | * | * | * \/ y */ int geo_mrtinmrt(maprect* rta, maprect* rtb); //判断线段是否相关 //相交返回GEO_TRUE //不相交返回GEO_FALSE geobool geo_linecrossline(geopoint* lafrom, geopoint* lato, geopoint* lbfrom, geopoint* lbto); /* * 多边形多边形的关系 * a 在 b 里面, 返回 0 * a 和 b 相交,返回 1 * a 没和 b 相交, 返回 -1 * b 在 a 里面, 返回 -2 * * /\ y * | * | * | * |------------> x * o */ int geo_gpolygoningpolygon(geopoints* gptsa, geopoints* gptsb);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值