mapRang.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <div class="rang">
  3. <div class="mapRang" :id="_id" :style="{height:attrs.height?attrs.height+'px':'300px'}"></div>
  4. <el-button type="primary" class="clear" @click="clearValue">清除</el-button>
  5. </div>
  6. </template>
  7. <script setup>
  8. import { computed,getCurrentInstance,nextTick, ref } from "vue";
  9. const { proxy } = getCurrentInstance();
  10. import $bus from '@/benyun/utils/bus.js'
  11. const value = ref('')
  12. const config = ref({})
  13. const lnglat = ref([])
  14. // const lng = ref(null) // 经度
  15. // const lat = ref(null) //纬度
  16. const map = ref(null) //地图
  17. const zoom = ref(13) //地图层级
  18. const emit = defineEmits();
  19. const geocoder = ref('');
  20. const area = ref('') //区域值
  21. const address = ref('') //详情值
  22. const _id = ref('')
  23. const handler = ref(null)
  24. const props = defineProps({
  25. propConfig:{},
  26. propValue:{},
  27. parentValue:{}
  28. })
  29. const attrs = computed({
  30. get() {
  31. return config.value.attr ? config.value.attr : {};
  32. }
  33. })
  34. const onChange = () => {
  35. emit('onChange',getValue());
  36. }
  37. //设置配置
  38. const setConfig = c => {
  39. if(c){
  40. config.value = c;
  41. }
  42. }
  43. //获取配置
  44. const getConfig = () => {
  45. return lodash.cloneDeep(config.value)
  46. }
  47. const getValue = () => {
  48. let obj = proxy.lodash(lnglat.value);
  49. // if(obj.length > 2){
  50. // if(obj[obj.length - 1].lat === obj[obj.length - 2].lat && obj[obj.length - 1].lng === obj[obj.length - 2].lng){
  51. // obj.splice(obj.length - 1,1)
  52. // }
  53. // }
  54. return JSON.stringify(obj)
  55. }
  56. const getUuid = () => {
  57. return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  58. }
  59. const clearValue = () => {
  60. lnglat.value = []
  61. map.value.clearOverLays();
  62. openHandler()
  63. onChange()
  64. }
  65. const openHandler = () => {
  66. handler.value = new T.PolygonTool(map.value);
  67. handler.value.open();
  68. handler.value.on("draw",getLngLat);
  69. }
  70. //初始化地图
  71. const initMap = callb => {
  72. if(map.value) return
  73. map.value = new T.Map(_id.value);
  74. map.value.centerAndZoom(new T.LngLat(109.411030,24.328160), zoom.value);
  75. geocoder.value = new T.Geocoder();
  76. openHandler()
  77. if(callb) {
  78. callb()
  79. }
  80. }
  81. const getLngLat = e => {
  82. lnglat.value=e.currentLnglats
  83. onChange()
  84. }
  85. const setValue = v => {
  86. nextTick(() => {
  87. if(v) {
  88. try{
  89. lnglat.value = JSON.parse(v)
  90. zoom.value = 17
  91. if(!map.value){
  92. initMap(() => {
  93. initPoint()
  94. })
  95. }else{
  96. initPoint()
  97. }
  98. }catch(e) {}
  99. } else {
  100. let pointArea = () => {
  101. let address = ''
  102. if(props.parentValue.addrCodeInfo){
  103. address = props.parentValue.addrCodeInfo
  104. }
  105. if(props.parentValue.addrInfo){
  106. address = address + props.parentValue.addrInfo
  107. }
  108. if(address){
  109. zoom.value = 17;
  110. geocoder.value.getPoint(address, searchResult);
  111. }
  112. }
  113. if(!map.value){
  114. initMap(() => {
  115. pointArea()
  116. })
  117. }else{
  118. pointArea()
  119. }
  120. }
  121. })
  122. }
  123. const initPoint = () => {
  124. let points = [];
  125. let totalLng = 0;
  126. let totalLat = 0;
  127. if(lnglat.value.length == 0) return
  128. for(const item of lnglat.value){
  129. if(Number(item.lng)){
  130. totalLng = totalLng + Number(item.lng)
  131. }
  132. if(Number(item.lat)){
  133. totalLat = totalLat + Number(item.lat)
  134. }
  135. points.push(new T.LngLat(item.lng, item.lat));
  136. }
  137. //创建面对象
  138. let polygon = new T.Polygon(points);
  139. //向地图上添加面
  140. map.value.addOverLay(polygon);
  141. handler.value.close()
  142. map.value.centerAndZoom(new T.LngLat(totalLng/lnglat.value.length,totalLat/lnglat.value.length), zoom.value);
  143. }
  144. const searchResult = result => {
  145. if(result.getStatus() == 0){
  146. map.value.panTo(result.getLocationPoint(), zoom.value);
  147. }
  148. }
  149. // 接收数据
  150. onMounted(()=>{
  151. $bus.on('areaEvent',(data)=>{
  152. let areaValue = data.area ? data.area : '';
  153. if(area){
  154. area.value = areaValue.replaceAll('/','');
  155. if(geocoder.value){
  156. if(address.value){
  157. zoom.value = 17;
  158. }else if(props.parentValue.addrInfo) {
  159. address.value = props.parentValue.addrInfo
  160. zoom.value = 17;
  161. }
  162. geocoder.value.getPoint(area.value + address.value, searchResult);
  163. }
  164. }
  165. })
  166. $bus.on('addressEvent',data => {
  167. address.value = data;
  168. if(address.value && geocoder.value){
  169. if(!area.value && props.parentValue.addrCodeInfo) {
  170. area.value = props.parentValue.addrCodeInfo.replaceAll('/','');
  171. }
  172. zoom.value = 17;
  173. geocoder.value.getPoint(area.value + address.value, searchResult);
  174. }
  175. })
  176. })
  177. defineExpose({
  178. getValue,getConfig,setConfig,clearValue,setValue
  179. })
  180. _id.value = getUuid()
  181. if(props.propConfig){
  182. setConfig(props.propConfig)
  183. }
  184. if(props.propValue){
  185. setValue(props.propValue)
  186. }
  187. nextTick(() => {
  188. initMap()
  189. })
  190. </script>
  191. <style lang="scss" scoped>
  192. .rang{
  193. width: 100%;
  194. position: relative;
  195. }
  196. .mapRang{
  197. width: 100%;
  198. height: 300px;
  199. }
  200. .clear{
  201. position: absolute;
  202. bottom: 0;
  203. right: 0;
  204. z-index: 999;
  205. }
  206. </style>