transformUtil.js 6.71 KB
Newer Older
mayongxin's avatar
mayongxin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203


// 平面坐标转换经纬度
const webMercator2LngLat = (x, y) => {
  var lng = (x / 20037508.34) * 180;
  var lat = (y / 20037508.34) * 180;
  lat =
    (180 / Math.PI) *
    (2 * Math.atan(Math.exp((lat * Math.PI) / 180)) - Math.PI / 2);
  return [lng, lat]; //[114.32894001591471, 30.58574800385281]
};
// 平面复位范围转高德坐标
const exetent2AmapPoint = extent => {
  let extents = extent.split(",");
  let midX = (parseFloat(extents[0]) + parseFloat(extents[2])) / 2;
  let midY = (parseFloat(extents[1]) + parseFloat(extents[3])) / 2;

  return webMercator2LngLat(midX, midY);
};
//平面复位范围转高德范围
const plan2AMapbound = extent => {
  let extents = extent.split(",")

  let minPoint = webMercator2LngLat(parseFloat(extents[0]), parseFloat(extents[1]))
  let maxPoint = webMercator2LngLat(parseFloat(extents[2]), parseFloat(extents[3]))
  return [minPoint, maxPoint]
}

// 将数字处理成每三个数字加一个逗号的形式,并保留n位有效小数
const dealWithNumber = (num, n = 0) => {
  return Number(num)
    .toFixed(n)
    .replace(/\d(?=(?:\d{3})+\b)/g, "$&,");
};

// 解析内容
// 以&分隔的直接解析成数组输出
// 以 | & 分隔的 通常为(图片)|标题|描述,先按这种情况进行解析
export function getDecodeDatas(data, key) {
  if (key) {
      if (data[key] && data[key].length) {
          let list = data[key].split('&')
          if (data[key].includes('|')) {
              let res = []
              list.forEach(item => {
                  res.push(item.split('|'))
              })
              return res
          } else {
              return list
          }
      } else {
          return []
      }
  } else {
      if (data.length) {
          let list = data.split('&')
          if (data.includes('|')) {
              let res = []
              list.forEach(item => {
                  res.push(item.split('|'))
              })
              return res
          } else {
              return list
          }
      } else {
          return []
      }
  }
}

// 将location中的search字符串转化成query对象
const searchToQuery = (search) => {
  if (search.length <= 1) {
    return {};
  }
  const query = {};
  // console.log(search)
  search
    .slice(1)
    .split("&")
    .forEach(item => {
      const [key, value] = item.split("=");
      query[key] = decodeURIComponent(value);
    });
  return query;
};

// 节流
const throttle = function (func, delay) {
  var timer = null;
  return function () {
    var context = this;
    var args = arguments;
    if (!timer) {
      timer = setTimeout(function () {
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  };
};

// 经纬度转墨卡托平面坐标
const lngLat2WebMercator = (lng, lat) => {
  const earthRad = 6378137.0;
  const x = ((lng * Math.PI) / 180) * earthRad;
  const a = (lat * Math.PI) / 180;
  const y =
    (earthRad / 2) * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
  return [x, y];
};


const PI = 3.14159265358979324
const delta = (lat, lon) => {
  var a = 6378245.0; //  a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
  var ee = 0.00669342162296594323; //  ee: 椭球的偏心率。
  var dLat = transformLat(lon - 105.0, lat - 35.0);
  var dLon = transformLon(lon - 105.0, lat - 35.0);
  var radLat = lat / 180.0 * PI;
  var magic = Math.sin(radLat);
  magic = 1 - ee * magic * magic;
  var sqrtMagic = Math.sqrt(magic);
  dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
  dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);
  return { 'lat': dLat, 'lon': dLon };
}
const outOfChina = (lat, lon) => {
  if (lon < 72.004 || lon > 137.8347)
    return true;
  if (lat < 0.8293 || lat > 55.8271)
    return true;
  return false;
}
const transformLat = (x, y) => {
  var 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 * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
  ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;
  ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;
  return ret;
}
const transformLon = (x, y) => {
  var 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 * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
  ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;
  ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;
  return ret;
}

const gcj_decrypt = (gcjLat, gcjLon) => {
  if (outOfChina(gcjLat, gcjLon))
    return { 'lat': gcjLat, 'lon': gcjLon };

  var d = delta(gcjLat, gcjLon);
  return { 'lat': gcjLat - d.lat, 'lon': gcjLon - d.lon };
}


/**
 * 根据坐标获取位置名称,调用高德API
 */
const getAddressByPosition = (lng, lat, callback) => {
    const geocoder = new window.AMap.Geocoder();
    geocoder.getAddress(
        new window.AMap.LngLat(lng, lat), (status, result) => {
            if(String(status) === 'complete') {
                const address = result.regeocode.formattedAddress;
                callback && typeof callback === 'function' && callback(address);
            }
    });
}

/**
 * 高德定位
 */
const positionByGaode = (callback) => {
    window.AMap.plugin('AMap.Geolocation', () => {
        const geolocation = new window.AMap.Geolocation({
          // 是否使用高精度定位,默认:true
          enableHighAccuracy: true,
          // 设置定位超时时间,默认:无穷大
          timeout: 10000,
          // 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)
          buttonOffset: new window.AMap.Pixel(10, 20),
          //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
          zoomToAccuracy: true,
          //  定位按钮的排放位置,  RB表示右下
          buttonPosition: 'RB'
        });

        geolocation.getCurrentPosition((status, data) => {
            if(status == 'complete'){
                const { position: { lng, lat  } } = data;
                typeof callback === 'function' && callback(lng, lat);
            }else{
                console.log(data)
                typeof callback === 'function' && callback('', '');
            }
        });
    });
}
mayongxin's avatar
mayongxin committed
204 205 206 207 208 209 210 211
// 生成随机
const createGuid = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      const r = Math.random() * 16 | 0,
          v = c == 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
  }).toUpperCase();
}
mayongxin's avatar
mayongxin committed
212 213 214 215 216 217 218 219 220 221 222


export {
  webMercator2LngLat,
  dealWithNumber,
  searchToQuery,
  throttle,
  exetent2AmapPoint,
  lngLat2WebMercator,
  plan2AMapbound,
  gcj_decrypt,
mayongxin's avatar
mayongxin committed
223
  createGuid
mayongxin's avatar
mayongxin committed
224
};