vue#onMounted JavaScript Examples

The following examples show how to use vue#onMounted. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From vue-json-schema-form with Apache License 2.0 6 votes vote down vote up
globalOptions = {
    WIDGET_MAP,
    COMPONENT_MAP: {
        form: defineComponent({
            inheritAttrs: false,
            setup(props, { attrs, slots }) {
                const formRef = ref(null);
                if (attrs.setFormRef) {
                    onMounted(() => {
                        attrs.setFormRef(formRef.value);
                    });
                }

                return () => {
                    // eslint-disable-next-line no-unused-vars
                    const { setFormRef, ...otherAttrs } = attrs;

                    return h(vueUtils.resolveComponent('el-form'), {
                        ref: formRef,
                        ...otherAttrs
                    }, slots);
                };
            }
        }),
        formItem: 'el-form-item',
        button: 'el-button',
        popover: 'el-popover'
    },
    HELPERS: {
        // 是否mini显示 description
        isMiniDes(formProps) {
            return formProps && ['left', 'right'].includes(formProps.labelPosition);
        }
    }
}
Example #2
Source File: useResizeWidth.js    From ant-simple-pro with MIT License 6 votes vote down vote up
// eslint-disable-next-line
export function useResizeWidth(fn = () => {}) {
  // eslint-disable-line
  const state = reactive({
    width: getWindowtWidth(),
    height: getWindowHeight()
  })

  function onResize() {
    state.width = getWindowtWidth()
    state.height = getWindowHeight()
    fn()
  }

  const onResizeThrottled = throttle(onResize, 300)

  onMounted(() => {
    window.addEventListener('resize', onResizeThrottled)
  })

  onBeforeUnmount(() => {
    window.removeEventListener('resize', onResizeThrottled)
  })

  return {
    ...toRefs(state)
  }
}
Example #3
Source File: useChartResize.js    From ant-simple-pro with MIT License 6 votes vote down vote up
export function useChartResize(chartIns) {
  function onResize() {
    chartIns.value && chartIns.value.resize()
  }

  let timer = null

  watch(
    () => store.getters.collapsed,
    () => {
      timer = window.setTimeout(() => {
        onResize()
      }, 500)
    }
  )

  onMounted(() => {
    window.addEventListener('resize', onResize)
  })

  onBeforeUnmount(() => {
    window.removeEventListener('resize', onResize)
    timer && clearTimeout(timer)
  })
}
Example #4
Source File: useClipboard.js    From ant-simple-pro with MIT License 6 votes vote down vote up
export function useClipboard() {
  const text = ref('')

  async function onCopy() {
    text.value = await navigator.clipboard.readText()
  }

  onMounted(() => {
    window.addEventListener('copy', onCopy)
  })

  onUnmounted(() => {
    window.removeEventListener('copy', onCopy)
  })

  function write(txt) {
    text.value = txt

    return navigator.clipboard.writeText(txt)
  }

  return {
    text,
    write
  }
}
Example #5
Source File: vue3-highcharts.js    From vue3-highcharts with MIT License 5 votes vote down vote up
vueHighcharts = defineComponent({
  name: 'VueHighchart',
  props: {
    type: {
      type: String,
      default: 'chart',
    },

    options: {
      type: Object,
      required: true,
    },

    redrawOnUpdate: {
      type: Boolean,
      default: true,
    },

    oneToOneUpdate: {
      type: Boolean,
      default: false,
    },

    animateOnUpdate: {
      type: Boolean,
      default: true,
    },
  },

  setup(props, { emit }) {
    const chartRef = ref(null);
    const chart = ref(null);

    const { options } = toRefs(props);

    if (options.value && Highcharts[props.type]) {
      watch(options, (newValue) => {
        if (chart.value) {
          chart.value.update(newValue, props.redrawOnUpdate, props.oneToOneOnUpdate, props.animateOnUpdate);
          emit('updated');
        }
      }, { deep: true });

      onMounted(() => {
        chart.value = Highcharts[props.type](chartRef.value, options.value, () => {
          emit('rendered');
        });
      });

      onUnmounted(() => {
        if (chart.value) chart.value.destroy();
        emit('destroyed');
      });
    } else if (!props.options) {
      console.warn('The "options" parameter is required.');
    } else {
      console.warn(`${props.type} is not a valid highcharts type or has not been imported`);
    }

    // Rather than returning a render function here. We'll return the chart ref and highcharts
    // instance so there exposed.
    return {
      chartRef,
      chart,
    };
  },

  render() {
    return h('div', {
      class: 'vue-highcharts',
      ref: 'chartRef',
    });
  },
})
Example #6
Source File: useHotkeys.js    From ant-simple-pro with MIT License 5 votes vote down vote up
export function useHotkeys(keys, callback, options, deps) {
  if (Array.isArray(options)) {
    deps = options || []
    options = undefined
  }
  const elRef = ref()
  const {
    enableOnTags,
    filter,
    keyup,
    keydown,
    filterPreventDefault = true,
    enabled = true,
    enableOnContentEditable = false
  } = options || {}

  function keyHandler(keyboardEvent, hotkeysEvent) {
    if (filter && !filter(keyboardEvent)) {
      return !filterPreventDefault
    }

    // Check whether the hotkeys was triggered inside an input and that input is enabled or if it was triggered by a content editable tag and it is enabled.
    if (
      (isKeyboardEventTriggeredByInput(keyboardEvent) && !tagFilter(keyboardEvent, enableOnTags)) ||
      (keyboardEvent.target?.isContentEditable && !enableOnContentEditable)
    ) {
      return true
    }

    if (!elRef.value || document.activeElement === elRef.value) {
      callback(keyboardEvent, hotkeysEvent)
      return true
    }

    return false
  }

  function setHotKeys() {
    if (!enabled) {
      return
    }

    // In this case keydown is likely undefined, so we set it to false, since hotkeys needs the `keydown` key to have a value.
    if (keyup && keydown !== true) {
      options.keydown = false
    }

    hotkeys(keys, options || {}, keyHandler)
  }

  onMounted(() => {
    setHotKeys()
  })

  onUnmounted(() => {
    hotkeys.unbind(keys, keyHandler)
  })

  watch(deps ? deps.map(v => () => v) : [], () => { // eslint-disable-line
    setHotKeys()
  })

  watch([() => options, () => keys, () => enabled], () => {
    setHotKeys()
  })

  return elRef
}
Example #7
Source File: use-auto-theme.js    From konsta with MIT License 5 votes vote down vote up
useAutoTheme = (props, autoThemeDetection = true) => {
  const themeState = ref(props.theme);

  /* eslint-disable no-restricted-globals */
  const setTheme = (newTheme) => {
    if (newTheme === 'ios' || newTheme === 'material') {
      if (themeState.value !== newTheme) {
        themeState.value = newTheme;
      }
    } else if (
      autoThemeDetection &&
      themeState.value === 'parent' &&
      typeof window !== 'undefined' &&
      typeof document !== 'undefined'
    ) {
      const htmlEl = document.documentElement;
      if (htmlEl) {
        if (htmlEl.classList.contains('ios')) {
          themeState.value = 'ios';
        } else if (
          htmlEl.classList.contains('md') ||
          htmlEl.classList.contains('material')
        ) {
          themeState.value = 'material';
        }
      }
    }
  };
  /* eslint-enable no-restricted-globals */

  watch(
    () => props.theme,
    (newTheme) => {
      setTheme(newTheme);
    }
  );
  onMounted(() => {
    setTheme(props.theme);
  });

  return themeState;
}
Example #8
Source File: use-touch-ripple.js    From konsta with MIT License 5 votes vote down vote up
useTouchRipple = (elRef, props, addCondition) => {
  const context = inject('KonstaContext');
  const ripple = ref(null);
  let eventsAttached = false;

  const getEl = () => {
    if (!elRef || !elRef.value) return null;
    let el = elRef.value;
    if (el.$el) el = el.$el;
    return el;
  };

  const theme = () => {
    let value = context.value.theme || 'ios';
    if (props.ios) value = 'ios';
    if (props.material) value = 'material';
    return value;
  };
  const needsTouchRipple = () => {
    return (
      theme() === 'material' &&
      props.touchRipple &&
      (addCondition ? addCondition() : true)
    );
  };
  const removeRipple = () => {
    if (ripple.value) ripple.value.remove();
    ripple.value = null;
  };

  const onPointerDown = (e) => {
    ripple.value = new TouchRipple(getEl(), e.pageX, e.pageY);
  };
  const onPointerMove = () => {
    removeRipple();
  };
  const onPointerUp = () => {
    removeRipple();
  };

  const attachEvents = () => {
    if (!context.value.touchRipple || eventsAttached) return;
    eventsAttached = true;
    const el = getEl();
    el.addEventListener('pointerdown', onPointerDown);
    el.addEventListener('pointermove', onPointerMove);
    el.addEventListener('pointerup', onPointerUp);
  };
  const detachEvents = () => {
    eventsAttached = false;
    const el = getEl();
    el.removeEventListener('pointerdown', onPointerDown);
    el.removeEventListener('pointermove', onPointerMove);
    el.removeEventListener('pointerup', onPointerUp);
  };

  watch(
    () => needsTouchRipple(),
    (newV) => {
      if (newV) attachEvents();
      else detachEvents();
    }
  );

  onMounted(() => {
    if (!getEl() || !needsTouchRipple()) return;
    attachEvents();
  });

  onBeforeUnmount(() => {
    if (!getEl() || !needsTouchRipple()) return;
    detachEvents();
  });
}
Example #9
Source File: useDarkMode.js    From website with MIT License 5 votes vote down vote up
export default function useDarkMode() {
	const isDarkMode = ref(false);

	const updateDarkModeClass = (value = isDarkMode.value) => {
		// set `class="dark"` on `<html>` element
		const htmlEl = window?.document.querySelector('html');
		htmlEl?.classList.toggle('dark', value);

		const systemDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

		if ((value && systemDarkMode) || (!value && !systemDarkMode)) {
			localStorage.removeItem('guide-color-scheme');
		} else if (value && !systemDarkMode) {
			localStorage.setItem('guide-color-scheme', 'dark');
		} else if (!value && systemDarkMode) {
			localStorage.setItem('guide-color-scheme', 'light');
		}
	}

	const mediaQuery = ref < MediaQueryList | null > (null)
	const onMediaQueryChange = (event) => {
		isDarkMode.value = event.matches;
	};

	onMounted(() => {
		// get stored preference and `prefers-color-scheme` media query and set the initial mode
		const userMode = localStorage.getItem('guide-color-scheme');
		mediaQuery.value = window.matchMedia('(prefers-color-scheme: dark)');
		isDarkMode.value = userMode === 'dark' || (userMode !== 'light' && mediaQuery.value.matches);

		// watch changes
		mediaQuery.value.addEventListener('change', onMediaQueryChange);
		watch(isDarkMode, updateDarkModeClass, { immediate: true });
	});

	onUnmounted(() => {
		mediaQuery.value?.removeEventListener('change', onMediaQueryChange);
	});

	return {
		isDarkMode,
	};
}
Example #10
Source File: useAsync.js    From ant-simple-pro with MIT License 5 votes vote down vote up
/**
 * useAsync
 * @param  {Promise} pro 异步操作
 * @param  {Object} options 参数
 * @param  {Boolean} [options.manual=false] 是否手动调用
 * @param  {Any} options.initialData 初始化数据
 * @param  {Function} options.onSuccess 成功回调
 * @param  {Function} options.onError 失败回调
 */

export function useAsync(pro, options = {}) {
  const {
    manual = false,
    initialData,
    onSuccess = () => {}, // eslint-disable-line
    onError = console.log
  } = options

  const state = reactive({
    data: initialData || null,
    error: null,
    loading: false
  })

  const run = async () => {
    state.error = null
    state.loading = true
    try {
      const result = await pro()
      state.data = result
      onSuccess()
    } catch (err) {
      onError(err)
      state.error = err
    }
    state.loading = false
  }

  onMounted(() => {
    !manual && run()
  })

  // 从外部主动改变数据
  function mutate(data) {
    state.data = data
  }
  return {
    ...toRefs(state),
    run,
    mutate
  }
}
Example #11
Source File: index.jsx    From ant-simple-pro with MIT License 4 votes vote down vote up
QueryTemplate = defineComponent({
  emits: ['submit', 'reset'],
  props: {
    options: {
      type: Array,
      default: () => [
        {
          title: '日期',
          fieldName: 'date',
          type: 'timeRangeSelection',
          optionList: [],
          labelName: '',
          valueName: '',
          childrenName: ''
        }
      ]
    },
    name: {
      type: String,
      default: ''
    }
  },
  setup(props, { emit }) {
    const formRef = ref()
    // default form fields
    const defaultForm = {}
    const form = reactive(defaultForm)

    onMounted(() => {
      for (let i = 0; i < props.options.length; i++) {
        const item = props.options[i] // eslint-disable-line
        defaultForm[item.fieldName] = typeof item.defaultValue !== 'undefined' ? item.defaultValue : ''
      }

      const filteredOptions = props.options.filter(item => item.defaultValue) || []
      if (filteredOptions.length) {
        filteredOptions.forEach(item => {
          if (item.type === 'monthDatePicker') {
            Object.assign(form, {
              [item.fieldName]: moment(item.defaultValue, 'YYYY-MM')
            })
          }
          // else {
          //   Object.assign(form, {
          //     [item.fieldName]: moment(item.defaultValue)
          //   })
          // }
        })
      }
    })

    function onFinish(value) {
      const formData = Object.assign({}, value)
      try {
        props.options.forEach(item => {
          const rangeValue = value[item.fieldName]
          switch (item.type) {
            case 'showTimeRangePicker': {
              formData[item.fieldName] =
                rangeValue && rangeValue.length
                  ? rangeValue.map(item => {
                      if (typeof item === 'string') {
                        return item
                      }
                      return item.format('YYYY-MM-DD HH:mm:ss')
                    })
                  : []
              break
            }

            case 'timeRangeSelection': {
              formData[item.fieldName] =
                rangeValue &&
                rangeValue.length &&
                rangeValue.map(item => {
                  if (typeof item === 'string') {
                    return item
                  }
                  return item.format('YYYY-MM-DD')
                })
              break
            }

            case 'monthDatePicker': {
              formData[item.fieldName] = rangeValue && moment(rangeValue).format('YYYY-MM')
              break
            }

            case 'dayDatePicker': {
              formData[item.fieldName] = rangeValue && rangeValue.format && rangeValue.format('YYYY-MM-DD')
              break
            }

            default: {
              // ...
            }
          }
        })
      } catch (error) {
        console.log(error)
      }
      emit('submit', formData)
    }

    function onReset() {
      formRef.value?.resetFields()
      emit('reset', toRaw(form))
    }

    function disabledDate(current) {
      return current && current > moment().endOf('day')
    }

    function getTemplateByType(type, opts) {
      const templateObj = {
        input: <a-input v-model={[form[opts.fieldName], 'value']} placeholder={opts.placeholder || '请填写'}></a-input>,
        select: (
          <a-select
            v-model={[form[opts.fieldName], 'value']}
            placeholder={opts.placeholder || '请填写'}
            onChange={opts.onChange}
          >
            {opts.optionList?.map((item, index) => (
              <a-select-option key={index} value={item[opts.valueName]}>
                {item[opts.labelName]}
              </a-select-option>
            ))}
          </a-select>
        ),
        cascader: (
          <a-cascader
            v-model={[form[opts.fieldName], 'value']}
            options={opts.optionList}
            placeholder={opts.placeholder || '请填写'}
            fieldNames={{
              label: opts.labelName,
              value: opts.valueName,
              children: opts.childrenName
            }}
            changeOnSelect
          ></a-cascader>
        ),
        timeRangeSelection: (
          <TimeRangeSelection
            v-model={[form[opts.fieldName], 'value']}
            placeholder={opts.placeholder}
          ></TimeRangeSelection>
        ),
        showTimeRangePicker: (
          <a-range-picker
            v-model={[form[opts.fieldName], 'value']}
            onChange={opts.onChange}
            placeholder={opts.placeholder}
            showTime
          ></a-range-picker>
        ),
        monthDatePicker: (
          <a-month-picker
            v-model={[form[opts.fieldName], 'value']}
            onChange={opts.onChange}
            placeholder={opts.placeholder || '请填写'}
            disabledDate={disabledDate}
          ></a-month-picker>
        ),
        dayDatePicker: (
          <a-date-picker
            v-model={[form[opts.fieldName], 'value']}
            mode="date"
            onChange={opts.onChange}
            placeholder={opts.placeholder || '请填写'}
            disabledDate={disabledDate}
          ></a-date-picker>
        )
      }
      const template = templateObj[type]
      if (template) {
        return template
      }
      return (
        <a-input
          v-model={[form[opts.fieldName], 'value']}
          onChange={opts.onChange}
          placeholder={opts.placeholder || '请填写'}
        ></a-input>
      )
    }

    return () => {
      return (
        <a-form ref={formRef} model={form} onFinish={onFinish} class="search-template" name={props.name}>
          <a-row gutter={[15, 15]}>
            {props.options.map((item, index) => (
              <a-col xs={24} sm={12} md={12} lg={8} xl={props.options.length > 3 ? 6 : 8} key={index}>
                <a-form-item
                  label={item.title}
                  name={item.fieldName}
                  data-label={item.title}
                  data-name={item.fieldName}
                >
                  {getTemplateByType(item.type, item)}
                </a-form-item>
              </a-col>
            ))}
            <a-col xs={24} sm={12} md={12} lg={8} xl={props.options.length > 3 ? 6 : 8}>
              <a-form-item>
                <a-button type="primary" htmlType="submit">
                  查询
                </a-button>
                <a-button class="ml10" onClick={onReset}>
                  重置
                </a-button>
              </a-form-item>
            </a-col>
          </a-row>
        </a-form>
      )
    }
  }
})
Example #12
Source File: atropos-vue.js    From atropos with MIT License 4 votes vote down vote up
Atropos = {
  props: {
    component: { type: String, default: 'div' },
    innerClass: String,
    scaleClass: String,
    rotateClass: String,

    eventsEl: { type: [String, Object], default: undefined },
    alwaysActive: { type: Boolean, default: false },
    activeOffset: { type: Number, default: undefined },
    shadowOffset: { type: Number, default: undefined },
    shadowScale: { type: Number, default: undefined },
    duration: { type: Number, default: undefined },
    rotate: { type: Boolean, default: undefined },
    rotateTouch: { type: Boolean, default: undefined },
    rotateXMax: { type: Number, default: undefined },
    rotateYMax: { type: Number, default: undefined },
    rotateXInvert: { type: Boolean, default: undefined },
    rotateYInvert: { type: Boolean, default: undefined },
    stretchX: { type: Number, default: undefined },
    stretchY: { type: Number, default: undefined },
    stretchZ: { type: Number, default: undefined },
    commonOrigin: { type: Boolean, default: true },
    shadow: { type: Boolean, default: true },
    highlight: { type: Boolean, default: true },
  },
  emits: ['enter', 'leave', 'rotate'],
  setup(props, ctx) {
    const elRef = ref(null);
    const atroposRef = ref(null);
    const { slots, emit } = ctx;

    const init = () => {
      atroposRef.value = AtroposCore({
        el: elRef.value,
        ...props,
        onEnter() {
          emit('enter');
        },
        onLeave() {
          emit('leave');
        },
        onRotate(...args) {
          emit('rotate', ...args);
        },
      });
    };

    const destroy = () => {
      if (atroposRef.value) {
        atroposRef.value.destroy();
        atroposRef.value = null;
      }
    };

    onMounted(() => {
      init();
    });
    onBeforeUnmount(() => {
      destroy();
    });

    const cls = (...args) => {
      return args.filter((c) => !!c).join(' ');
    };

    return () =>
      h(
        props.component,
        {
          class: 'atropos',
          ref: elRef,
        },
        [
          h('span', { class: cls('atropos-scale', props.scaleClass) }, [
            h('span', { class: cls('atropos-rotate', props.rotateClass) }, [
              h('span', { class: cls('atropos-inner', props.innerClass) }, [
                slots.default && slots.default(),
                props.highlight && h('span', { class: 'atropos-highlight' }),
              ]),
              slots.rotate && slots.rotate(),
              props.shadow && h('span', { class: 'atropos-shadow' }),
            ]),
            slots.scale && slots.scale(),
          ]),
          slots.root && slots.root(),
        ],
      );
  },
}
Example #13
Source File: index.js    From vue-json-schema-form with Apache License 2.0 4 votes vote down vote up
globalOptions = {
    WIDGET_MAP,
    COMPONENT_MAP: {
        form: defineComponent({
            inheritAttrs: false,
            setup(props, { attrs, slots }) {
                // 处理 labelPosition 参数和 label-placement 之间的关系
                const labelPositionMap = {
                    top: {
                        labelAlign: 'left',
                        labelPlacement: 'top',
                    },
                    left: {
                        labelAlign: 'left',
                        labelPlacement: 'left',
                    },
                    right: {
                        labelAlign: 'right',
                        labelPlacement: 'left',
                    }
                };

                const formRef = ref(null);
                if (attrs.setFormRef) {
                    onMounted(() => {
                        // form组件实例上重置一个 validate 方法
                        formRef.value.$$validate = (callBack) => {
                            formRef.value.validate((errors) => {
                                if (errors) {
                                    return callBack(false, errors);
                                }

                                return callBack(true);
                            });
                        };

                        attrs.setFormRef(formRef.value);
                    });
                }

                return () => {
                    const {
                        // eslint-disable-next-line no-unused-vars
                        setFormRef, labelPosition, model, ...otherAttrs
                    } = attrs;

                    return h(vueUtils.resolveComponent('n-form'), {
                        ref: formRef,
                        model: model.value, // 不会自动解包
                        ...labelPositionMap[labelPosition || 'top'],
                        ...otherAttrs
                    }, slots);
                };
            }
        }),
        formItem: defineComponent({
            inheritAttrs: false,
            setup(props, { attrs, slots }) {
                return () => {
                    const { prop, rules, ...originAttrs } = attrs;
                    const childAttrs = {
                        ...originAttrs,
                        path: prop,
                        rule: (rules || []).map(validateRule => ({
                            trigger: validateRule.trigger,
                            asyncValidator(rule, value, callback) {
                                return validateRule.validator(rule, value, callback);
                            }
                        })),
                    };
                    return h(vueUtils.resolveComponent('n-form-item'), childAttrs, slots);
                };
            }
        }),
        button: 'n-button',
        // popover: ,
        popover: defineComponent({
            setup(props, { attrs, slots }) {
                return () => h(vueUtils.resolveComponent('n-popover'), attrs, {
                    trigger: slots.reference,
                    default: slots.default,
                });
            }
        }),
    },
    HELPERS: {
        // 是否mini显示 description
        isMiniDes(formProps) {
            return formProps && ['left', 'right'].includes(formProps.labelPosition);
        }
    }
}
Example #14
Source File: index.js    From vue-json-schema-form with Apache License 2.0 4 votes vote down vote up
globalOptions = {
    WIDGET_MAP,
    COMPONENT_MAP: {
        form: defineComponent({
            inheritAttrs: false,
            setup(props, { attrs, slots }) {
                // 处理 labelPosition 参数和layout之间转换
                const labelPositionMap = {
                    top: {
                        layout: 'vertical'
                    },
                    left: {
                        layout: 'horizontal',
                        labelAlign: 'left'
                    },
                    right: {
                        layout: 'horizontal',
                        labelAlign: 'right'
                    }
                };

                // 返回当前的 form ref
                const formRef = ref(null);
                if (attrs.setFormRef) {
                    onMounted(() => {
                        // form组件实例上附加一个 validate 方法
                        formRef.value.$$validate = (callBack) => {
                            formRef.value.validate().then((res) => {
                                callBack(true, res);
                            }).catch((err) => {
                                callBack(false, err.errorFields);
                            });
                        };
                        attrs.setFormRef(formRef.value);
                    });
                }

                return () => {
                    const {
                        // eslint-disable-next-line no-unused-vars
                        setFormRef, labelPosition, labelWidth, model, ...otherAttrs
                    } = attrs;

                    if (otherAttrs.inline) {
                        Object.assign(otherAttrs, {
                            layout: 'inline',
                            // labelCol: undefined,
                            // wrapperCol: undefined
                        });
                    }

                    return h(vueUtils.resolveComponent('a-form'), {
                        ref: formRef,
                        model: model.value,
                        ...labelPositionMap[labelPosition || 'top'],
                        ...otherAttrs,
                        colon: false
                    }, slots);
                };
            }
        }),
        formItem: defineComponent({
            inheritAttrs: false,
            setup(props, { attrs, slots }) {
                const formItemRef = ref(null);
                return () => {
                    const { prop, rules, ...originAttrs } = attrs;

                    return h(vueUtils.resolveComponent('a-form-item'), {
                        ...originAttrs,
                        ref: formItemRef,

                        // 去掉callback 使用promise 模式
                        rules: (rules || []).map(validateRule => ({
                            ...validateRule,
                            validator(rule, value) {
                                return validateRule.validator.apply(this, [rule, value]);
                            }
                        })),
                        name: prop ? prop.split('.') : prop
                    }, {
                        ...slots,
                        default: function proxySlotDefault() {
                            // 解决 a-form-item 只对第一个子元素进行劫持,并监听 blur 和 change 事件,如果存在第一个元素description无法校验
                            // @blur="() => {$refs.name.onFieldBlur()}"
                            // @change="() => {$refs.name.onFieldChange()}"
                            return slots.default.call(this, {
                                onBlur: () => {
                                    if (formItemRef.value.$el.querySelector('.genFromWidget_des')) {
                                        // 存在 description,需要手动触发校验事件
                                        formItemRef.value.onFieldBlur();
                                    }
                                },
                                onChange: () => {
                                    if (formItemRef.value.$el.querySelector('.genFromWidget_des')) {
                                        // 存在 description,需要手动触发校验事件
                                        formItemRef.value.onFieldChange();
                                    }
                                }
                            });
                        }
                    });
                };
            }
        }),
        button: 'a-button',
        popover: defineComponent({
            setup(props, { attrs, slots }) {
                return () => h(vueUtils.resolveComponent('a-popover'), attrs, {
                    default: slots.reference,
                    content: slots.default,
                });
            }
        }),
    },
    HELPERS: {
        // 是否mini显示 description
        isMiniDes(formProps) {
            return formProps && (
                ['left', 'right'].includes(formProps.labelPosition)
                || formProps.layout === 'horizontal' || formProps.inline === true
            );
        }
    }
}
Example #15
Source File: split-screen.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
//简单局部状态管理

function splitScreen(props) {

    // 设置默认值数据
    let state = reactive({
        multiViewport: "NONE", //
        selectedViewport: '0', //
        TreeDatas: [],
    })
    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }
    // 初始化数据
    let layers, imgLayers, terrainLayers, mvtLayers;
    let tree = ref(null);
    //记录视口的选中状态
    let KeysViewports = {
        KeysViewport1: [],
        KeysViewport2: [],
        KeysViewport3: [],
        KeysViewport4: []
    };

    onMounted(() => {
        setTimeout(() => {
            initLayers()
        }, 500)
    });

    //监听图层加载完成
    watch(() => storeState.changeLayers, val => {
        initLayers()
    });

    //初始化图层
    function initLayers() {
        layers = viewer.scene.layers.layerQueue;
        imgLayers = viewer.imageryLayers._layers;
        mvtLayers = viewer.scene._vectorTileMaps._layerQueue;
        terrainLayers = viewer.terrainProvider;
        state.TreeDatas.length = 0;
        updataS3MLayer();
        updataImgLayers();
        updataMvtLayers();
        setTimeout(() => {
            tree.value.setCheckedNodes(state.TreeDatas);
            let keys = tree.value.getCheckedKeys(true);
            KeysViewports.KeysViewport1 = [...keys];
            KeysViewports.KeysViewport2 = [...keys];
            KeysViewports.KeysViewport3 = [...keys];
            KeysViewports.KeysViewport4 = [...keys];
        }, 500)
    }


    // 分析

    // updatS3M图层
    function updataS3MLayer() {
        if (layers.length == 0) {
            return;
        }
        let S3MLayersObj = {
            id: 's3m',
            label: "S3M图层",
            children: []
        };
        layers.forEach((layer, index) => {
            let S3Mlayer = {
                id: 's3m-' + index,
                label: layer._name,
            };
            S3MLayersObj.children.push(S3Mlayer);
        });
        state.TreeDatas[0] = S3MLayersObj;

    }

    //updatImg
    function updataImgLayers() {
        if (imgLayers.length == 1) {
            return;
        }
        let imgLayersObj = {
            id: 'img',
            label: "IMG图层",
            children: []
        };
        imgLayers.forEach((layer, index) => {
            let isMvt = layer._imageryProvider instanceof Cesium.MvtProviderGL;
            if (index === 0 || isMvt) return true;
            let IMGlayer = {
                id: 'img-' + index,
                label: resource.BaseMapImg,
            };
            if (layer._imageryProvider.tablename) {
                IMGlayer.label = layer._imageryProvider.tablename;
            }
            imgLayersObj.children.unshift(IMGlayer);
        });
        if (imgLayersObj.children.length > 0) state.TreeDatas[1] = imgLayersObj;
    }

    //updatMVT
    function updataMvtLayers() {
        console.log(mvtLayers)
        if (mvtLayers.length == 0) {
            return;
        }
        let mvtLayersObj = {
            id: 'mvt',
            label: "MVT图层",
            children: []
        };
        mvtLayers.forEach((layer, index) => {
            let IMGlayer = {
                id: 'mvt-' + index,
                label: layer.name,
            };
            mvtLayersObj.children.unshift(IMGlayer);
        });
        state.TreeDatas[2] = mvtLayersObj;
    }

    //updatTerrain
    function updataTerrainLayers() {
        if (!terrainLayers.tablename) {
            return;
        }
        let terrainLayersObj = {
            id: 'terrain',
            label: "地形图层",
            children: []
        };
        let TerrainLayer = {
            id: 'terrain-0',
            label: terrainLayers.tablename,
        };
        terrainLayersObj.children.push(TerrainLayer);
        state.TreeDatas[4] = terrainLayersObj;

    }

    //勾选节点函数
    function checkNode(data) {
        let node = tree.value.getNode(data)
        let ids = data.id.split('-');
        setVisibleInViewport(ids, node.checked)
    }

    //设置图层视口显隐
    function setVisibleInViewport(ids, checked) {
        let type = ids[0];
        let index = ids[1];
        switch (type) {
            case 's3m':
                if (!index) {
                    for (let i = 0; i < layers.length; i++) {
                        layers[i].setVisibleInViewport(Number(state.selectedViewport), checked);
                    }
                    return;
                }
                layers[index].setVisibleInViewport(Number(state.selectedViewport), checked)
                break;
            case 'img':
                if (!index) {
                    for (let i = 0; i < imgLayers.length; i++) {
                        imgLayers[i].setVisibleInViewport(Number(state.selectedViewport), checked)
                    }
                    return;
                }
                imgLayers[index].setVisibleInViewport(Number(state.selectedViewport), checked)
                break;
            case 'mvt':
                if (!index) {
                    for (let i = 0; i < mvtLayers.length; i++) {
                        mvtLayers[i].setVisibleInViewport(Number(state.selectedViewport), checked)
                    }
                    return;
                }
                mvtLayers[index].setVisibleInViewport(Number(state.selectedViewport), checked)
                break;
            default: null
        }
    }


    //监听
    watch(() => state.multiViewport, val => {
        viewer.scene.multiViewportMode = Cesium.MultiViewportMode[val];
    });

    watch(() => state.selectedViewport, (val, oldval) => {
        let keys = tree.value.getCheckedKeys(true);
        KeysViewports['KeysViewport' + oldval] = keys;
        tree.value.setCheckedKeys(KeysViewports['KeysViewport' + val], true);
    });


    // 销毁
    onBeforeUnmount(() => {
        layers = null;
        imgLayers = null;
        terrainLayers = null;
        mvtLayers = null;
        KeysViewports = null;
    })

    return {
        ...toRefs(state),
        tree,
        checkNode,
    };
}
Example #16
Source File: roller.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
//简单局部状态管理


function roller(props) {

    // 设置默认值数据
    let state = reactive({
        useRoller: false,  //使用卷帘
        rollerMode: "lrRoller",   //卷帘模式
        lrRoller: "1",  //左右卷帘时默认屏蔽左边
        tbRoller: "4",  //上下卷帘时默认屏蔽上面
        TreeDatas: [],   //图层树
    })
    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }
    // 初始化数据
    let layers, imgLayers, terrainLayers, mvtLayers;
    let dom = document.getElementById('cesiumContainer');
    let wide = document.body.clientWidth - dom.clientWidth;  //定位矫正
    let heide = document.body.clientHeight- dom.clientHeight;
    let width = dom.clientWidth; // 界面宽度
    let height = dom.clientHeight; // 界面高度
    let tree = ref(null);
    let verticalSliderLeft = ref(null);
    let verticalSliderRight = ref(null);
    let horizontalSliderTop = ref(null);
    let horizontalSliderBottom = ref(null);
    let scratchSwipeRegion = new Cesium.BoundingRectangle();
    // 卷帘配置参数,以对象方式实现地址传递
    let rollerShutterConfig = {
        startX: 0.33,  //x方向左卷帘条比例
        startY: 0.33,  //y方向上卷帘条比例
        endX: 0.66,  //x方向右卷帘条比例
        endY: 0.66,  //y方向下卷帘条比例
        index: 1,  //当前控制卷帘条
        mode: 1,  //卷帘模式
    };

    
    //监听图层加载完成
    watch(() => storeState.changeLayers, val => {
        initLayers()
    });

    onMounted(() => {
        bindSliderEvt();  //绑定事件
        setTimeout(() => {
            initLayers()
        }, 500)
    });

    //初始化图层
    function initLayers() {
        layers = viewer.scene.layers.layerQueue;
        imgLayers = viewer.imageryLayers._layers;
        mvtLayers = viewer.scene._vectorTileMaps._layerQueue;
        terrainLayers = viewer.terrainProvider;
        state.TreeDatas.length = 0;
        updataS3MLayer();
        updataImgLayers();
        updataMvtLayers();
        updataTerrainLayers();
        setTimeout(() => {
            tree.value.setCheckedNodes(state.TreeDatas); //默认全部勾选参与卷帘
        }, 500)
    };

    // 分析

    // updatS3M图层
    function updataS3MLayer() {
        if (layers.length == 0) {
            return;
        }
        let S3MLayersObj = {
            id: 's3m',
            label: "S3M图层",
            children: []
        };
        layers.forEach((layer, index) => {
            let S3Mlayer = {
                id: 's3m-' + index,
                label: layer._name,
            };
            S3MLayersObj.children.push(S3Mlayer);
        });
        state.TreeDatas[0] = S3MLayersObj;

    };

    //updatImg
    function updataImgLayers() {
        if (imgLayers.length == 1) {
            return;
        }
        let imgLayersObj = {
            id: 'img',
            label: "IMG图层",
            children: []
        };
        imgLayers.forEach((layer, index) => {
            if (index === 0) return true;
            let isMvt = layer._imageryProvider instanceof Cesium.MvtProviderGL;
            if (isMvt) return true;
            let IMGlayer = {
                id: 'img-' + index,
                label: resource.BaseMapImg,
            };
            if (layer._imageryProvider.tablename) {
                IMGlayer.label = layer._imageryProvider.tablename;
            }
            imgLayersObj.children.unshift(IMGlayer);
        });
        if (imgLayersObj.children.length > 0) state.TreeDatas[1] = imgLayersObj;
    };

    //updatMVT
    function updataMvtLayers() {
        if (mvtLayers.length == 0) {
            return;
        }
        let mvtLayersObj = {
            id: 'mvt',
            label: "MVT图层",
            children: []
        };
        mvtLayers.forEach((layer, index) => {
            let IMGlayer = {
                id: 'mvt-' + index,
                label: layer.name,
            };
            mvtLayersObj.children.unshift(IMGlayer);
        });
        state.TreeDatas[2] = mvtLayersObj;
    };

    //updatTerrain(地表)
    function updataTerrainLayers() {
        // if (!terrainLayers.tablename) {
        //     return;
        // }
        let terrainLayersObj = {
            id: 'globe',
            label: "地球",
            children: []
        };
        let TerrainLayer = {
            id: 'globe-0',
            label: '地表',
        };
        terrainLayersObj.children.push(TerrainLayer);
        state.TreeDatas[4] = terrainLayersObj;
    };

    //勾选节点函数
    function checkNode(data) {
        let node = tree.value.getNode(data)
        let ids = data.id.split('-');
        setLayersRoller(ids, node.checked)
    };


    /**
         * 设置卷帘的分割方向及分割条的位置。
         *
    */
    function setRollerShutterSplit() {
        let startX = rollerShutterConfig.startX;
        let startY = rollerShutterConfig.startY;
        let endX = rollerShutterConfig.endX;
        let endY = rollerShutterConfig.endY;
        let mode = rollerShutterConfig.mode;
        // 左右卷帘使用left slider滑动,上下卷帘使用top slider滑动
        switch (mode) {
            case 1:
                Cesium.BoundingRectangle.unpack([startX, 0, 1, 1], 0, scratchSwipeRegion);
                break;
            case 2:
                Cesium.BoundingRectangle.unpack([0, 0, startX, 1], 0, scratchSwipeRegion);
                break;
            case 4:
                Cesium.BoundingRectangle.unpack([0, startY, 1, 1], 0, scratchSwipeRegion);
                break;
            case 8:
                Cesium.BoundingRectangle.unpack([0, 0, 1, startY], 0, scratchSwipeRegion);
                break;
            case 15:
                Cesium.BoundingRectangle.unpack([startX, startY, endX - startX, endY - startY], 0, scratchSwipeRegion);
                break;
            default:
                Cesium.BoundingRectangle.unpack([0, 0, 1, 1], 0, scratchSwipeRegion);
                break;
        }

        let checkedKeys = tree.value.getCheckedKeys(true);
        checkedKeys.forEach((key) => {
            let ids = key.split('-');
            setLayersRoller(ids, true);
        })
    };

    //设置各类图层的卷帘
    function setLayersRoller(ids, checked) {
        let type = ids[0];
        let index = ids[1];
        switch (type) {
            case 's3m':
                if (!index) {
                    for (let i = 0; i < layers.length; i++) {
                        layers[i].swipeEnabled = checked;
                        layers[i].swipeRegion = scratchSwipeRegion;
                    }
                    return;
                }
                layers[index].swipeEnabled = checked;
                layers[index].swipeRegion = scratchSwipeRegion;
                break;
            case 'img':
                if (!index) {
                    for (let i = 1; i < imgLayers.length; i++) {
                        imgLayers[i].swipeEnabled = checked;
                        imgLayers[i].swipeRegion = scratchSwipeRegion;
                    }
                    return;
                }
                imgLayers[index].swipeEnabled = checked;
                imgLayers[index].swipeRegion = scratchSwipeRegion;
                break;
            case 'mvt':
                if (!index) {
                    for (let i = 0; i < mvtLayers.length; i++) {
                        mvtLayers[i].swipeEnabled = checked;
                        mvtLayers[i].swipeRegion = scratchSwipeRegion;
                    }
                    return;
                }
                mvtLayers[index].swipeEnabled = checked;
                mvtLayers[index].swipeRegion = scratchSwipeRegion;
                break;
            case 'globe':
                viewer.scene.globe.swipeEnabled = checked;
                viewer.scene.globe.swipeRegion = scratchSwipeRegion;
                break;
            default: null
        }
    };

    // 取消所有图层的卷帘
    function cancelLayersRoller() {
        setLayersRoller(['s3m'], false);
        setLayersRoller(['img'], false);
        setLayersRoller(['mvt'], false);
        setLayersRoller(['globe'], false);
    }

    //设置卷帘条显隐
    function enableSlider(index) {
        verticalSliderLeft.value.style.display = 'none';
        verticalSliderRight.value.style.display = 'none';
        horizontalSliderTop.value.style.display = 'none';
        horizontalSliderBottom.value.style.display = 'none';
        if (index & 1) {
            verticalSliderLeft.value.style.display = 'block';
        }
        if (index & 2) {
            verticalSliderRight.value.style.display = 'block';
        }
        if (index & 4) {
            horizontalSliderTop.value.style.display = 'block';
        }
        if (index & 8) {
            horizontalSliderBottom.value.style.display = 'block';
        }
    }


    /**
     * 注册卷帘分割条的拖拽事件。
     */
    function bindSliderEvt() {
        verticalSliderLeft.value.addEventListener('mousedown', function (e) {
            mouseDown(e, 1);
        }, false);
        verticalSliderRight.value.onmousedown = function (e) {
            mouseDown(e, 3);
        };
        horizontalSliderTop.value.onmousedown = function (e) {
            mouseDown(e, 2);
        };
        horizontalSliderBottom.value.onmousedown = function (e) {
            mouseDown(e, 4);
        };
        window.addEventListener('resize', function () {
            width = document.body.clientWidth - wide; // 窗口宽度
            height = document.body.clientHeight - heide; // 窗口高度
        });

        document.addEventListener('mouseup', mouseUp, false);
        function mouseUp(e) {
            document.removeEventListener('mousemove', sliderMove, false);
        }

        function mouseDown(e, index) {
            rollerShutterConfig.index = index;
            document.addEventListener('mousemove', sliderMove, false);
        }

        function sliderMove(e) {
            if (e.preventDefault) {
                e.preventDefault();
            } else {
                e.returnValue = false;
            }

            switch (rollerShutterConfig.index) {
                case 1:
                    verticalSliderLeft.value.style.left = e.clientX - wide + 'px';
                    rollerShutterConfig.startX = (e.clientX - wide) / width;
                    break;
                case 2:
                    horizontalSliderTop.value.style.top = e.clientY - heide+ 'px';
                    rollerShutterConfig.startY = (e.clientY- heide) / height;
                    break;
                case 3:
                    verticalSliderRight.value.style.left = e.clientX- wide + 'px';
                    rollerShutterConfig.endX = (e.clientX- wide) / width;
                    break;
                case 4:
                    horizontalSliderBottom.value.style.top = e.clientY- heide + 'px';
                    rollerShutterConfig.endY = (e.clientY- heide) / height;
                    break;
            }
            setRollerShutterSplit();
        }

    }

    //监听
    watch(() => state.multiViewport, val => {
        viewer.scene.multiViewportMode = Cesium.MultiViewportMode[val];
    });

    watch(() => state.selectedViewport, (val, oldval) => {
        let keys = tree.value.getCheckedKeys(true);
        state['KeysViewport' + oldval] = keys;
        tree.value.setCheckedKeys(state['KeysViewport' + val], true);
    });

    watch(() => state.useRoller, val => {
        if (val) {
            if (rollerShutterConfig.mode == 1 || rollerShutterConfig.mode == 2)
                enableSlider(1);
            if (rollerShutterConfig.mode == 4 || rollerShutterConfig.mode == 8)
                enableSlider(4);
            if (rollerShutterConfig.mode == 15)
                enableSlider(15);
            setRollerShutterSplit();
        } else {
            enableSlider(0);
            cancelLayersRoller()
        }
    });

    watch(() => state.rollerMode, val => {
        switch (val) {
            case "lrRoller":
                if (state.useRoller) enableSlider(1);
                rollerShutterConfig.mode = Number(state.lrRoller);
                break;
            case "tbRoller":
                if (state.useRoller) enableSlider(4);
                rollerShutterConfig.mode = Number(state.tbRoller);
                break;
            case "customRoller":
                if (state.useRoller) enableSlider(15);
                rollerShutterConfig.mode = 15;
                break;
            default:
                break;
        }
        if (!state.useRoller) return;
        setRollerShutterSplit();
    });
    watch(() => state.lrRoller, val => {
        if (!state.useRoller) return;
        rollerShutterConfig.mode = Number(val);
        setRollerShutterSplit();
    });
    watch(() => state.tbRoller, val => {
        if (!state.useRoller) return;
        rollerShutterConfig.mode = Number(val);
        setRollerShutterSplit();
    });

    // 销毁
    onBeforeUnmount(() => {
        layers = undefined;
        imgLayers = undefined;
        terrainLayers = undefined;
        mvtLayers = undefined;
    })

    return {
        ...toRefs(state),
        tree,
        checkNode,
        verticalSliderLeft,
        verticalSliderRight,
        horizontalSliderTop,
        horizontalSliderBottom
    };
}
Example #17
Source File: projection-image.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
function projectionImage(props) {
    // 设置默认值数据
    let state = reactive({
        viewlongitude: "",
        viewlatitude: "",
        viewheight: "",
        direction: "",
        pitch: "",
        horizontal: 20,
        vertical: 10,
        distance: 200,
        hintLineColor: "rgba(251,250,248,1)",
        clipMode: "clip-inside",
        visibleLine: true,
        fileText: "",
        fromInfo: null,
    })

    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let layers, scene;
    let currentProject;
    let vedioFile_dom = ref(null)
    let modelIdProjectPairs = new Map(); // 模型id和视频投放对象对象的键值对
    let s3mInstanceColc, modelEditor;
    let modelUrl = 'public/data/s3m/projector.s3m';
    let isActive = false;
    let currentSelectedSymbol = null;
    let reader = new FileReader();
    let currntVideoDom, isClip = false;
    if (storeState.isViewer) {
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
        scene = viewer.scene;
        layers = viewer.scene.layers.layerQueue;
        s3mInstanceColc = new Cesium.S3MInstanceCollection(scene._context);
        viewer.scene.primitives.add(s3mInstanceColc);
        viewer.eventManager.addEventListener("CLICK", click_set_target, true);
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
            scene = viewer.scene;
            layers = viewer.scene.layers.layerQueue;
            s3mInstanceColc = new Cesium.S3MInstanceCollection(scene._context);
            viewer.scene.primitives.add(s3mInstanceColc);
        }
    });

    //监听图层加载完成
    watch(() => storeState.changeLayers, val => {
        for (let i = 0; i < layers.length; i++) {
            layers[i].selectEnabled = false;
        }
    });
    onMounted(() => {
        fileChange();
        currntVideoDom = document.getElementById("trailer-0");
    })

    // 点击选择文件函数
    function chooseFile() {
        vedioFile_dom.value.click();
    }

    //文件夹改变文件触发
    function fileChange() {
        vedioFile_dom.value.addEventListener("change", evt => {
            let file = evt.target.files[0];
            if (!file) return;
            state.fileText = vedioFile_dom.value.value;
            const aBlob = new Blob([file], { type: 'video/mp4' })
            reader.readAsDataURL(aBlob)
            reader.onload = function (e) {
                let vedio = e.target.result;
                let index = document.querySelectorAll('#videoContain>video').length;
                creatVideo_dom(vedio, index).then((res) => {
                    currntVideoDom = document.getElementById("trailer-" + index)
                });
            };
        });
    }

    function creatVideo_dom(src, index) {
        return new Promise((resolve, reject) => {
            let videoContain = document.getElementById("videoContain");
            let video = document.createElement("video");
            let source = document.createElement("source");
            source.src = src;
            video.appendChild(source);
            video.id = "trailer-" + index;
            video.classList.add("videoBox");
            video.setAttribute("autoplay", "autoplay");
            video.setAttribute("loop", "loop");
            video.setAttribute("crossorigin", "crossorigin");
            video.setAttribute("controls", "controls");
            video.setAttribute("muted", "muted");
            videoContain.appendChild(video);
            setTimeout(() => {
                resolve(video);
            }, 500);
        });
    };


    function startProjection() {
        viewer.enableCursorStyle = false;
        viewer._element.style.cursor = "";
        document.body.classList.add("measureCur");
        let viewPosition = viewer.scene.camera.position;
        currntVideoDom.play();
        currentProject = new Cesium.ProjectionImage(scene);
        currentProject.setImage({ video: currntVideoDom });
        currentProject.distance = Number(state.distance);
        currentProject.horizontalFov = Number(state.horizontal);
        currentProject.verticalFov = Number(state.vertical);
        currentProject.viewPosition = tool.CartesiantoDegrees(viewPosition);
        currentProject.build();
        isActive = true;
        window.tooltip.showAt(' <p>选中投放模型进行编辑和清除</p>', '400px');
        viewer.eventManager.addEventListener("MOUSE_MOVE", move_set_target);
        viewer.eventManager.addEventListener("CLICK", click_set_target, true);

    }

    function click_set_target(e) {
        if (isClip) return;
        if (isActive) {
            viewer.enableCursorStyle = true;
            document.body.classList.remove("measureCur");
            let Cartesian3 = Cesium.Cartesian3.fromDegrees(currentProject.viewPosition[0], currentProject.viewPosition[1], currentProject.viewPosition[2]);
            let viewPosition = JSON.parse(JSON.stringify(Cartesian3));
            viewer.eventManager.removeEventListener("MOUSE_MOVE", move_set_target);
            addModel(viewPosition);
            isActive = false;
            return;
        }
        let symbol = viewer.scene.pick(e.message.position) || viewer.selectedEntity;
        if (symbol && symbol.id && typeof (symbol.id) === 'string' && symbol.id.indexOf("projector-") != -1) {
            // if (currentSelectedSymbol && currentSelectedSymbol.id === symbol.id) return;
            if (modelEditor) modelEditor.destroy();
            currentSelectedSymbol = symbol;
            currentProject = modelIdProjectPairs.get(symbol.id);
            if (currentProject) {
                state.horizontal = currentProject.horizontalFov;
                state.vertical = currentProject.verticalFov;
                state.distance = currentProject.distance;
            }
            // modelEditor = new Cesium.ModelEditor({
            //     model: symbol.primitive,
            //     scene: viewer.scene,
            //     // offset: new Cesium.Cartesian3(0, 0, 2)
            // });
            // modelEditor.activate();
            // console.log(modelEditor)
            return;
        }
        // if (modelEditor) modelEditor.destroy();
        // modelEditor = null;
        currentSelectedSymbol = null;
        currentProject = null;
    }

    function move_set_target(e) {
        let distance = 0;
        let viewPosition = viewer.scene.camera.position;
        let targetPosition = scene.pickPosition(e.message.endPosition);
        if (targetPosition)
            distance = Cesium.Cartesian3.distance(viewPosition, targetPosition);
        if (distance > 0 && distance < 1000)
            currentProject.setDistDirByPoint(tool.CartesiantoDegrees(targetPosition));
    }

    function addModel(position, position2) {
        let id = 'projector-' + new Date().getTime();
        let direction = currentProject.direction;
        let pitch = currentProject.pitch;
        let radians = Cesium.Math.toRadians(direction);
        let heading = radians >= Cesium.Math.PI ? radians - Cesium.Math.PI : radians + Cesium.Math.PI;
        let pitch2 = -Cesium.Math.toRadians(pitch)
        s3mInstanceColc.add(modelUrl, {
            id: id,
            position: position,
            hpr: {
                heading: heading,
                pitch: 0,
                roll: pitch2,
            },
            // scale: new Cesium.Cartesian3(2, 2, 2),
            // offset: new Cesium.Cartesian3(0, 0, 0.1)
        });
        currentSelectedSymbol = s3mInstanceColc.getInstance(modelUrl, id);
        modelIdProjectPairs.set(id, currentProject);
    }

    // 裁剪
    function clipProjectImg() {
        isClip = true;
        tooltip.setVisible(false);
        window.tooltip.showAt(' <p>点击鼠标左键绘制裁剪区域</p><p>点击鼠标右键结束绘制</p><p>注:只能裁剪当前选中投放对象</p>', '400px');
        if (!window.handlerPolygon) {
            initHandler("Polygon");
        }
        handlerDrawing("Polygon").then(
            res => {
                isClip = false;
                let handlerPolygon = window.handlerPolygon;
                updateClipImg(res.positions)
                handlerPolygon.polygon.show = false;
                handlerPolygon.polyline.show = false;
                window.polylineTransparent.show = false; //半透线隐藏
                handlerPolygon.deactivate();
            },
            err => {
                console.log(err);
            }
        );
        window.handlerPolygon.activate();
    }

    function updateClipImg(position) {
        if (!currentProject) return;
        currentProject.addClipRegion({
            name: "clip-Projector" + new Date().getTime(),
            position: position,
        });
    }

    function clear() {
        viewer.eventManager.removeEventListener("MOUSE_MOVE", move_set_target);
        if (currentSelectedSymbol) {
            modelIdProjectPairs.delete(currentSelectedSymbol.id);
            s3mInstanceColc.removeInstance(modelUrl, currentSelectedSymbol.id);
            currentSelectedSymbol = null;
        }
        if (currentProject) {
            currentProject.removeAllClipRegion()
            currentProject.destroy();}
        if (modelIdProjectPairs.size === 0)
            viewer.eventManager.removeEventListener("CLICK", click_set_target);
        if (modelEditor) modelEditor.destroy();
        modelEditor = null;
        currentProject = null;
        window.tooltip.setVisible(false);
        clearHandlerDrawing();
        viewer.enableCursorStyle = true;
        document.body.classList.remove("measureCur");
    }


    watch(() => state.fileText, val => {
        if (val.indexOf("http") === -1) return;
        let index = document.querySelectorAll('#videoContain>video').length;
        creatVideo_dom(val, index).then((res) => {
            currntVideoDom = document.getElementById("trailer-" + index)
        });
    })
    watch(() => state.horizontal, val => {
        if (val == "" || !currentProject) return;
        currentProject.horizontalFov = Number(val);
    })
    watch(() => state.vertical, val => {
        if (val == "" || !currentProject) return;
        currentProject.verticalFov = Number(val);
    })
    watch(() => state.distance, val => {
        if (val == "" || !currentProject) return;
        currentProject.distance = Number(val);
    })

    watch(() => state.visibleLine, val => {
        if (!currentProject) return;
        // currentProject.hintLineVisible = val;
        s3mInstanceColc.visible = val; //隐藏所有模型
        modelIdProjectPairs.forEach((projector) => { //隐藏所有投放线
            projector.hintLineVisible = val
        })
    })
    watch(() => state.hintLineColor, val => {
        if (!currentProject) return;
        currentProject.hintLineColor = Cesium.Color.fromCssColorString(val);
    })
    watch(() => state.clipMode, val => {
        if (!currentProject) return;
        let clipMode =
            val === "clip-outside"
                ? Cesium.ModifyRegionMode.CLIP_INSIDE
                : Cesium.ModifyRegionMode.CLIP_OUTSIDE;
        currentProject.setClipMode(clipMode);
    })

    watch(() => state.viewlongitude, val => {
        if (!currentProject || val == "") return;
        currentProject.viewPosition[0] = val;
    })
    watch(() => state.viewlatitude, val => {
        if (!currentProject || val == "") return;
        currentProject.viewPosition[1] = val;
    })
    watch(() => state.viewheight, val => {
        if (!currentProject || val == "") return;
        currentProject.viewPosition[2] = val;
    })
    watch(() => state.direction, val => {
        if (!currentProject || val == "") return;
        currentProject.direction = Number(val);
    })
    watch(() => state.pitch, val => {
        if (!currentProject || val == "") return;
        currentProject.pitch = Number(val);
    });
    watch(() => state.fromInfo, val => {
        if (!val || val == "") return;
        Cesium.ProjectionImage.fromInfo(scene, state.fromInfo.infoUrl, state.fromInfo.baseUrl)
    })

    // 销毁
    onBeforeUnmount(() => {
        for (let i = 0; i < layers.length; i++) {
            layers[i].selectEnabled = true;
        }
    });


    return {
        ...toRefs(state),
        chooseFile,
        vedioFile_dom,
        startProjection,
        clear,
        clipProjectImg
    };
}
Example #18
Source File: layer-manage.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
//简单局部状态管理

function layerManage(props) {

    // 设置默认值数据
    let state = reactive({
        TreeDatas: [],
        expandedKeys: []
    })

    // 初始化数据
    let layers, imgLayers, terrainLayers, mvtLayers, terrainProvider;
    let tree = ref(null), domContextmenu = ref(null);
    let node_rightClick; //保存右键选中的节点
    let deleteCallback = () => { }; //右键删除图层的回调函数初始化
    let dom = document.getElementById('cesiumContainer');
    let wide = document.body.clientWidth - dom.clientWidth;  //定位矫正
    let heide = document.body.clientHeight- dom.clientHeight;
    if (props && props.deleteCallback) { deleteCallback = props.deleteCallback }

    //监听图层加载完成
    watch(() => storeState.changeLayers, val => {
        initLayers()
    });
    onMounted(() => {
        setTimeout(() => {
            initLayers()
        }, 500)
    });

    //初始化图层
    function initLayers() {
        layers = viewer.scene.layers.layerQueue;
        imgLayers = viewer.imageryLayers._layers;
        mvtLayers = viewer.scene._vectorTileMaps._layerQueue;
        terrainLayers = viewer.terrainProvider;
        state.TreeDatas.length = 0;
        updataS3MLayer();
        updataImgLayers();
        updataMvtLayers();
        updataTerrainLayers();
        setTimeout(() => {
            tree.value.setCheckedNodes(state.TreeDatas);
        }, 500)
        console.log(mvtLayers)
    }


    // 分析

    // updatS3M图层
    function updataS3MLayer() {
        if (layers.length == 0) {
            if (state.TreeDatas[0]) tree.value.remove(state.TreeDatas[0]);
            return;
        }
        let S3MLayersObj = {
            id: 's3m',
            label: "S3M图层",
            children: []
        };
        layers.forEach((layer, index) => {
            let S3Mlayer = {
                id: 's3m-' + index,
                label: layer._name,
            };
            S3MLayersObj.children.push(S3Mlayer);
        });
        state.TreeDatas[0] = S3MLayersObj;

    }

    //updatImg
    function updataImgLayers() {
        if (imgLayers.length == 1) {
            if (state.TreeDatas[1]) tree.value.remove(state.TreeDatas[1]);
            return;
        }
        let imgLayersObj = {
            id: 'img',
            label: "IMG图层",
            children: []
        };
        imgLayers.forEach((layer, index) => {
            let isMvt = layer._imageryProvider instanceof Cesium.MvtProviderGL;
            if (index === 0 || isMvt) return true;
            let IMGlayer = {
                id: 'img-' + index,
                label: resource.BaseMapImg,
            };
            if (layer._imageryProvider.tablename) {
                IMGlayer.label = layer._imageryProvider.tablename;
            }
            imgLayersObj.children.unshift(IMGlayer);
        });
        if (imgLayersObj.children.length > 0) state.TreeDatas[1] = imgLayersObj;
    }

    //updatMVT
    function updataMvtLayers() {
        if (mvtLayers.length == 0) {
            if (state.TreeDatas[2]) tree.value.remove(state.TreeDatas[2]);
            return;
        }
        let mvtLayersObj = {
            id: 'mvt',
            label: "MVT图层",
            children: []
        };
        mvtLayers.forEach((layer, index) => {
            let IMGlayer = {
                id: 'mvt-' + index,
                label: layer.name,
            };
            mvtLayersObj.children.unshift(IMGlayer);
        });
        state.TreeDatas[2] = mvtLayersObj;
    }

    //updatTerrain
    function updataTerrainLayers() {
        if (!terrainLayers.tablename) {
            return;
        }
        let terrainLayersObj = {
            id: 'terrain',
            label: "地形图层",
            children: []
        };
        let TerrainLayer = {
            id: 'terrain-0',
            label: terrainLayers.tablename,
        };
        terrainLayersObj.children.push(TerrainLayer);
        state.TreeDatas[3] = terrainLayersObj;

    }

    //勾选节点函数
    function checkNode(data) {
        let node = tree.value.getNode(data)
        let ids = data.id.split('-');
        setVisible(ids, node.checked)
    }

    //设置图层显隐
    function setVisible(ids, checked) {
        let type = ids[0];
        let index = ids[1];
        switch (type) {
            case 's3m':
                if (!index) {
                    for (let i = 0; i < layers.length; i++) {
                        layers[i].visible = checked;
                    }
                    return;
                }
                layers[index].visible = checked;
                break;
            case 'img':
                if (!index) {
                    for (let i = 1; i < imgLayers.length; i++) {
                        imgLayers[i].show = checked
                    }
                    return;
                }
                imgLayers[index].show = checked;
                break;
            case 'mvt':
                if (!index) {
                    for (let i = 0; i < mvtLayers.length; i++) {
                        mvtLayers[i].show = checked
                    }
                    return;
                }
                mvtLayers[index].show = checked
                break;
            case 'terrain':
                if (!checked) {
                    terrainProvider = viewer.terrainProvider;
                    viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider();
                } else {
                    viewer.terrainProvider = terrainProvider;
                }
                break;
            default: null
        }
    };

    //点击节点函数
    function nodeClick(data) {
        let ids = data.id.split('-');
        flytoLayer(ids)
    }
    //定位飞向指定图层
    function flytoLayer(ids) {
        let type = ids[0];
        let index = ids[1];
        let layer;
        switch (type) {
            case 's3m':
                if (index) layer = layers[index];
                break;
            case 'img':
                if (index) layer = imgLayers[index];
                break;
            case 'mvt':
                if (index) layer = mvtLayers[index];
                break;
            case 'terrain':
                break;
            default: null
        }
        if (layer) viewer.flyTo(layer);
    };

    // 节点右键事件
    function nodeContextmenu(event, data) {
        let ids = data.id.split('-');
        if (!ids[1]) return;
        node_rightClick = data;
        domContextmenu.value.style.left = (event.clientX + 30-wide) + 'px';
        if (event.clientX >= 1810) domContextmenu.value.style.left = (event.clientX - 80-wide) + 'px';
        domContextmenu.value.style.top = event.clientY - heide + 'px';
        domContextmenu.value.style.display = 'block';

    }

    // 点击任意隐藏右键弹出的操作框
    document.onclick = function (e) {
        e.stopPropagation();
        domContextmenu.value.style.display = 'none';
    }

    // 删除图层函数
    function deleteLayer() {
        domContextmenu.value.style.display = 'none';
        let ids = node_rightClick.id.split('-');
        let type = ids[0];
        let index = ids[1];
        switch (type) {
            case 's3m':
                if (index) {
                    // layers[index].destroy();
                    viewer.scene.layers.remove(layers[index]._name);
                    updataS3MLayer();
                    setTimeout(() => {
                        state.expandedKeys = ['s3m']
                        tree.value.setCheckedNodes(state.TreeDatas);
                    }, 50)
                };
                break;
            case 'img':
                if (index) {
                    // imgLayers[index].destroy();
                    viewer.imageryLayers.remove(imgLayers[index]);
                    updataImgLayers();
                    setTimeout(() => {
                        tree.value.setCheckedNodes(state.TreeDatas);
                    }, 50)
                };
                break;
            case 'mvt':
                if (index) {
                    // mvtLayers[index].destroy();
                    viewer.scene.removeVectorTilesMap(mvtLayers[index].name);
                    updataMvtLayers();
                    setTimeout(() => {
                        tree.value.setCheckedNodes(state.TreeDatas);
                    }, 100)
                };
                break;
            case 'terrain':
                viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider();
                terrainProvider = null;
                let node = tree.value.getNode(type)
                tree.value.remove(node)
                break;
            default: null
        };
        actions.setChangeLayers();
        deleteCallback(node_rightClick) //删除图层回调,用于外部在图层删除后的操作
    }


    // 销毁
    onBeforeUnmount(() => {
        document.onclick = () => { };
    })

    return {
        ...toRefs(state),
        tree,
        domContextmenu,
        checkNode,
        nodeContextmenu,
        nodeClick,
        deleteLayer
    };
}
Example #19
Source File: fly-route.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
function compass(props) {

    // 设置默认值数据
    let state = reactive({
        routeType: "designatedRoute",  //自定义还得指定路线类型
        fileSrc: "",  //文件地址,不能同时使用fpfUrl
        fpfUrl: null, //指定fpf路径
        selectedStopIndex: 0,  //选中当前站点
        showRoute: false,  //显示路线
        showStop: false,   //显示站点
        currentStopNames: [],   //当前路线的站点名称集合
        //自定义
        customRouteNames: [],  //保存自定义路线名称
        customRouteSelectedIndex: null,  //自定义选中路线索引
        routeStops: [],  //自定义当前路线的站点集合
        selectedAddedStopIndex: null,    //自定义已加站点选中索引
        //站点
        setStopName: 'Stop-1',  //设置当前站点名称
        setStopSpeed: 0,   // 设置当前站点速度
        stopPlayMode: 'StopPause',  //设置站点模式:默认停留
        waitTime: 0,  //停留时间
        surroundDuration: 1,  //环绕模式时间
        //飞行路线设置
        isAlongline: false,  //获取或者设置该飞行路线是否是沿线飞行。
        routeSpeed: 200,  //飞行路线速度
    });


    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let flyManager, routeCollection; //创建飞行路线集合对象类
    let flyFile_dom = ref(null);
    let currentStops //当前路线所有站点集合
    let reader = new FileReader();
    let createXml, flyLineXmls = []; //创建和保存xml飞行路线文件

    if (storeState.isViewer) {
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
        initFlyManager()
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
            initFlyManager()
        }
    });

    onMounted(() => {
        fileChange();
    })


    /**
    * 指定路线分析
    */
    //初始化飞行管理
    function initFlyManager() {
        routeCollection = new Cesium.RouteCollection(viewer.entities);
        flyManager = new Cesium.FlyManager({
            scene: viewer.scene,
            routes: routeCollection
        });
        createXml = new createFlyLine_xml();
        if (state.fpfUrl) {
            fpfUrlChange()
        }
    }
    // 点击选择文件函数
    function chooseFile() {
        flyFile_dom.value.click();
    }

    // 改变默认fpf文件路径触发
    function fpfUrlChange() {
        flyManager.stop();
        routeCollection.fromFile(state.fpfUrl);
        flyManager.readyPromise.then(function () {
            let route = flyManager.currentRoute;
            route.isLineVisible = state.showRoute;
            route.isStopVisible = state.showStop;
            updateCurrentStops();
        })
    }
    //文件夹改变文件触发
    function fileChange() {
        flyFile_dom.value.addEventListener("change", evt => {
            flyManager.stop();
            let route = flyManager.currentRoute;
            if (route) route.clear(); //清除之前的
            routeCollection = new Cesium.RouteCollection(viewer.entities);  //飞行路线底层默认第一条路线,所以重新new
            let file = evt.target.files[0];
            if (!file) return;
            state.fileSrc = flyFile_dom.value.value;
            reader.onload = function (e) {
                // 读取操作完成时出发
                let XMLContent = e.target.result;
                routeCollection.fromXML(XMLContent);
            };
            reader.readAsBinaryString(file);
            readyPromise();
        });
    }
    // 异步飞行管理准备就绪函数
    function readyPromise() {
        routeCollection.readyPromise.then(() => {
            flyManager.routes = routeCollection;
            let route = flyManager.currentRoute;
            route.isLineVisible = state.showRoute;
            route.isStopVisible = state.showStop;
            updateCurrentStops();
        })
    }

    // 更新当前路线站点
    function updateCurrentStops() {
        state.currentStopNames.length = 0;
        currentStops = flyManager.getAllRouteStops();
        for (let i = 0, j = currentStops.length; i < j; i++) {
            let stopName = currentStops[i].stopName || 'Stop' + (i + 1);
            state.currentStopNames.push(stopName)
        }
    }
    // 更新当前飞行管理的所有路线(暂不支持路线选择,所有未开放)
    function updateAllRoutes() {
        state.allRoutes.length = 0;
        let allRoutes = routeCollection.routes;
        for (let i = 0, j = allRoutes.length; i < j; i++) {
            let route = '飞行路线' + (i + 1);
            state.allRoutes.push(route)
        }
    }

    function flyStart() {
        flyManager.readyPromise.then(() => {
            flyManager.play();
        })
    };
    function flyPause() {
        flyManager && flyManager.pause();
    };
    function flyStop() {
        flyManager && flyManager.stop();
    };

    /**
   * 自定义路线分析
   */
    // 添加站点
    function addStop() {
        flyManager.stop();
        let point = viewer.camera.position;
        let position = tool.CartesiantoDegrees(point);
        let stop = {
            stopName: state.setStopName,
            point: position,
            heading: viewer.camera.heading,
            tilt: viewer.camera.pitch,
            speed: state.setStopSpeed,
            stopPlayMode: state.stopPlayMode,
            surroundDuration: state.surroundDuration,
            waitTime: state.waitTime
        }
        state.routeStops.push(stop);
        if (state.routeStops.length > 0) {
            let len = state.routeStops.length;
            let lastStopName = state.routeStops[len - 1].stopName;
            let index = lastStopName.split('-')[1] || 1;
            let name = 'Stop-' + (Number(index) + 1);
            state.setStopName = name;
        }
        state.selectedAddedStopIndex = state.routeStops.length - 1;
    }

    // 保存站点
    function saveStop() {
        if (state.routeStops.length < 2) {
            tool.Message.warnMsg('节点小于2')
            return;
        }

        // 飞行路线配置
        let index = flyLineXmls.length + 1;
        let route = {
            routeName: '飞行路线_' + index,
            speed: state.routeSpeed,
            isAlongLine: "False",
            routeStops: state.routeStops
        }
        let xml = createXml.createXMLflyLine(route);
        flyLineXmls.push(xml);
        state.customRouteNames.push(route.routeName);
        // restStops();
        if (state.customRouteSelectedIndex === null)
            state.customRouteSelectedIndex = 0;
    }

    // 重置当前路线
    function restStops() {
        state.routeStops.length = 0;
        state.setStopName = 'Stop-1';
        state.setStopSpeed = 0;
        state.stopPlayMode = 'StopPause';
        state.waitTime = 0;
        state.surroundDuration = 1;
    }

    // 下载选择的飞行路线fpf文件
    function downLoad() {
        let data = flyLineXmls[state.customRouteSelectedIndex];
        if (!data) return;
        let blob = new Blob([data]);//将返回的数据包装成blob(方法的具体使用参考mdn)
        let alink = document.createElement("a");
        alink.download = 'fly-route.fpf';//文件名,大部分浏览器兼容,IE10及以下不兼容
        alink.href = URL.createObjectURL(blob);//根据blob 创建 url
        alink.click(); //自动点击
    }
    // 清除选中飞行路线
    function clearRoute() {
        flyManager.stop();
        if (flyLineXmls.length < 1) return;
        flyLineXmls.splice(state.customRouteSelectedIndex, 1);
        state.customRouteNames.splice(state.customRouteSelectedIndex, 1);
        if (flyLineXmls.length > 0) {
            state.customRouteSelectedIndex = 0;
            return;
        }
        state.customRouteSelectedIndex = null;
        state.currentStopNames.length = 0;
        let route = flyManager.currentRoute;
        if (route) route.clear(); //清除之前的

    }

    // 清除选中站点
    function clearStop() {
        state.routeStops.splice(state.selectedAddedStopIndex, 1);
        if (state.routeStops.length > 0) {
            state.selectedAddedStopIndex = state.routeStops.length - 1;
            return;
        }
        state.selectedAddedStopIndex = null;
        state.setStopName = 'Stop-1';
    }


    // 监听
    watch(() => state.selectedStopIndex, val => {
        flyManager && flyManager.stop();
        let index = Number(val);
        let stop = currentStops[index];
        flyManager.viewToStop(stop);
    });
    watch(() => state.showRoute, val => {
        let route = flyManager.currentRoute;
        if (route) route.isLineVisible = val
    });
    watch(() => state.showStop, val => {
        let route = flyManager.currentRoute;
        if (route) route.isStopVisible = val
    });
    watch(() => state.fpfUrl, val => {
        fpfUrlChange()
    });

    watch(() => state.customRouteSelectedIndex, val => {
        if (val === null) return;
        flyManager && flyManager.stop();
        let route = flyManager.currentRoute;
        if (route) route.clear(); //清除之前的
        routeCollection = new Cesium.RouteCollection(viewer.entities);  //飞行路线底层默认第一条路线,所以重新new
        routeCollection.fromXML(flyLineXmls[val]);
        readyPromise()
    });

    watch(() => state.selectedAddedStopIndex, val => {
        let stop = state.routeStops[val];
        if (!stop) return;
        viewer.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(stop.point[0], stop.point[1], stop.point[2]),
            orientation: {
                heading: stop.heading,
                pitch: stop.tilt,
                roll: 0
            }
        });
    });

    watch(() => state.routeType, val => {
        if(val === 'customRoute'){
            window.tooltip.showAt(' <p>调整当前相机位置和视角</p><p>以当前相机位置和视角设置站点</p><p>点击添加保存此站点</p>', '50%');
            setTimeout(()=>{
                window.tooltip.setVisible(false);
            },5000)
        }else{
            window.tooltip.setVisible(false);
        }
    });


    // 销毁
    onBeforeUnmount(() => {
        state = null;
        flyManager = routeCollection = null;
        currentStops = null;
        createXml = flyLineXmls = null;
    });


    return {
        ...toRefs(state),
        flyFile_dom,
        chooseFile,
        flyStart,
        flyPause,
        flyStop,
        addStop,
        saveStop,
        restStops,
        downLoad,
        clearRoute,
        clearStop
    };
}
Example #20
Source File: sky-line.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
//公共handler.js

function skyLine(props) {

    // 设置默认值数据
    let state = reactive({
        skylineRadius: 10000,  //分析半径
        lineWidth: 3,   //天际线宽度
        skylineColor: "rgb(200, 0, 0)",   //天际线颜色
        skyBodyColor: "rgba(44,149,197,0.6)",   //天际体颜色
        barrierColor: "rgba(255, 186, 1, 1)",   //障碍物颜色
        skylineMode: 0,   //分析模式
        highlightBarrier: false,   //是否显示高亮障碍物
        getSkyline2d: true,    //是否显示二维分析结果
        skylineSpatialAnalysisUrl: null,   //分析服务地址 'http://www.supermapol.com/realspace/services/spatialAnalysis-data_all/restjsr/spatialanalyst/geometry/3d/skylinesectorbody.json'
        observerInformation: null,  //观察者信息
        ignoreGlobe: true,  // 地球表面不参与分析
    });

    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let myChart, s3mInstance, skyline, scene, tipFlag = true;
    const echarts_box = ref(null);
    onMounted(() => {
        initMyChart();
    });

    if (storeState.isViewer) {
        scene = viewer.scene;
        skyline = new Cesium.Skyline(scene);
        skyline.ignoreGlobe = state.ignoreGlobe;  //地球表面不参与分析
        skyline.build();
        s3mInstance = new Cesium.S3MInstanceCollection(scene._context);
        scene.primitives.add(s3mInstance);
        //初始化观察者信息(后面有需要可以添加监听)
        if (state.observerInformation) {
            skyLineUpdate(state.observerInformation);
        }
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            scene = viewer.scene;
            skyline = new Cesium.Skyline(viewer.scene);
            skyline.ignoreGlobe = state.ignoreGlobe;
            skyline.build();
            s3mInstance = new Cesium.S3MInstanceCollection(viewer.scene._context);
            viewer.scene.primitives.add(s3mInstance);
            if (state.observerInformation) {
                skyLineUpdate(state.observerInformation);
            }
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
        }
    });

    //初始化echarts
    function initMyChart() {
        if (window.echarts) {
            if (!myChart) {
                myChart = window.echarts.init(echarts_box.value);  //初始化echarts
                window.onresize = function () {
                    myChart.resize()  //自适应屏幕
                };
            }
        } else {
            tool.Message.warnMsg(resource.EchartsErr);
            return;
        }
        myChart.setOption({
            title: {
                text: "二维天际线",
                textStyle: {
                    fontSize: 14
                }
            },
            grid: {
                left: 30,
                right: 0,
                top: 30,
                bottom: 8
            },
            tooltip: {},
            xAxis: {
                show: false
            },
            yAxis: {
                show: false
            },
            series: [
                {
                    type: "bar",
                    data: [],
                },
            ],
        });
    };

    /*
     ***分析模块***
    */

    //分析
    function skyLineAnalysis() {
        clear(); // 清除上一次分析结果
        // 天际线分析的视口位置设置成当前相机位置
        let cartographic = viewer.scene.camera.positionCartographic;
        let observerObj = {
            longitude: Cesium.Math.toDegrees(cartographic.longitude),
            latitude: Cesium.Math.toDegrees(cartographic.latitude),
            height: cartographic.height,
            pitch: Cesium.Math.toDegrees(scene.camera.pitch),
            direction: Cesium.Math.toDegrees(scene.camera.heading)
        };
        skyLineUpdate(observerObj);
    };

    // 设置限高体
    function setLimitBody() {
        if (!window.handlerPolygon) {
            initHandler("Polygon");
        }
        tooltip.setVisible(false);
        if (tipFlag) {   //只提示一次
            window.tooltip.showAt(' <p>点击鼠标左键绘制区域</p><p>点击鼠标右键结束绘制</p>', '450px');
            tipFlag = false
        }
        handlerDrawing("Polygon").then(
            res => {
                skyline.removeLimitbody("limitBody");
                let handlerPolygon = window.handlerPolygon;
                let pos = res.result.object.positions;
                let positions = [];
                // 遍历多边形,取出所有点
                for (let i = 0, len = pos.length; i < len; i++) {
                    //转化为经纬度,并加入至临时数组
                    let cartographic = Cesium.Cartographic.fromCartesian(pos[i]);
                    let longitude = Cesium.Math.toDegrees(cartographic.longitude);
                    let latitude = Cesium.Math.toDegrees(cartographic.latitude);
                    positions.push([longitude, latitude]);
                }
                //去除重复点
                let p = tool.unique(positions);
                let posArr = [];
                //再次遍历转化为接口所需的数组格式
                for (let i = 0, len = p.length; i < len; i++) {
                    posArr.push(positions[i][0]);
                    posArr.push(positions[i][1]);
                }
                //添加限高体对象
                skyline.addLimitbody({
                    position: posArr,
                    name: "limitBody"
                });
                handlerPolygon.polygon.show = false;
                handlerPolygon.polyline.show = false;
                //   window.polylineTransparent.show = false; //半透线隐藏
                handlerPolygon.deactivate();
            },
            err => {
                console.log(err);
            }
        );
        window.handlerPolygon.activate();
    };

    // 更新天际线
    function skyLineUpdate(observerObj) {
        skyline.viewPosition = [observerObj.longitude, observerObj.latitude, observerObj.height];
        //设置俯仰和方向
        skyline.pitch = observerObj.pitch
        skyline.direction = observerObj.direction
        skyline.radius = Number(state.skylineRadius);
        skyline.lineWidth = Number(state.lineWidth);
        skyline.color = Cesium.Color.fromCssColorString(state.skylineColor);
        skyline.displayStyle = Number(state.skylineMode > 1 ? 0 : state.skylineMode);

        setTimeout(() => {
            if (state.highlightBarrier) { // 显示障碍物
                let BarrierColor = Cesium.Color.fromCssColorString(
                    state.barrierColor
                );
                changeBarrierColor(BarrierColor);
            }
            if (state.skylineMode == 2) {   // 是否切换天际体
                if (state.skylineSpatialAnalysisUrl) {
                    setSkyLineBody(observerObj)
                } else {
                    setSkyLineBody2(observerObj)
                    // setSkyLineBody(observerObj)
                }
            }
            let object = skyline.getSkyline2D();
            setOptions(object)  // 设置二维天际线
        }, 300);
        state.observerInformation = observerObj
    }

    // 改变障碍物颜色
    function changeBarrierColor(BarrierColor) {
        let ObjectIds = skyline.getObjectIds();
        console.log(ObjectIds)

        let layers = viewer.scene.layers._layerQueue;
        for (let index in ObjectIds) {
            layers.forEach(layer => {
                if (layer._id === Number(index)) {
                    layer.setObjsColor(ObjectIds[index], BarrierColor);
                }
            });
        }
    };

    // 设置二维天际线
    function setOptions(object) {
        if (state.observerInformation && myChart) {
            let option = {
                tooltip: {
                    trigger: 'axis',
                    // formatter: 'X: {b}<br/>Y : {c}'
                    formatter: (param) => {
                        let datax = Number(param[0].axisValue);
                        let datay = param[0].data;
                        return [
                            "X: " +
                            datax.toFixed(6) +
                            "<br/>",
                            "Y: " +
                            datay.toFixed(6)
                        ].join("");
                    },
                },
                grid: {
                    left: 40,
                    right: 0,
                    top: 35,
                    bottom: 8,
                    borderColor: '#333333'
                },
                // backgroundColor: "rgba(73,139,156,0.0)",
                color: 'red',
                xAxis: [
                    {
                        type: "category",
                        boundaryGap: false,
                        data: object.x,
                        show: false
                    }
                ],
                yAxis: {
                    min: function (value) {
                        return (value.min - 0.05).toFixed(2);
                    },
                    show: true,
                    axisLine: {
                        show: true,

                    }
                },
                dataZoom: [
                    {
                        type: "inside",
                        xAxisIndex: 0,
                        filterMode: "filter",
                        start: 0,
                        end: 100,
                    },
                ],
                series: [
                    {
                        symbolSize: 8,
                        symbol: 'circle',
                        smooth: true,
                        // name: "天际线分析",
                        // symbol: "none",
                        type: "line",
                        data: object.y,
                        lineStyle: {
                            width: 2,
                            shadowColor: 'rgba(145, 146, 148,0.7)',
                            shadowBlur: 10,
                            shadowOffsetY: 8
                        },
                    }
                ]
            };
            myChart.setOption(option);
        }
    };

    // 天际线体走数据服务
    function setSkyLineBody() {
        let param = skyline.getSkylineSectorParameter();
        let geometrySkylineSectorBodyPostParameter = {
            viewerPoint: param.viewPos,
            line3D: param.geoLine3D,
            height: 0,
            lonlat: true
        };

        let url = state.skylineSpatialAnalysisUrl;
        let queryData = JSON.stringify(geometrySkylineSectorBodyPostParameter);
        axios
            .post(url, queryData)
            .then(response => {
                //再发送一次GET请求  获取到运算结果
                axios
                    .get(response.data.newResourceLocation + ".json")
                    .then(response => {
                        let data = response.data;
                        if (data.geometry === null) {
                            return;
                        }
                        let uint8Array = new Uint8Array(data.geometry.model);
                        let buffer = uint8Array.buffer;
                        s3mInstance.add(
                            "SkyLineBody",
                            {
                                id: 1,
                                position: Cesium.Cartesian3.fromDegrees(
                                    data.geometry.position.x,
                                    data.geometry.position.y,
                                    data.geometry.position.z
                                ),
                                hpr: new Cesium.HeadingPitchRoll(0, 0, 0),
                                color: Cesium.Color.fromCssColorString(state.skyBodyColor)
                            },
                            buffer, false
                        );
                        data.geometry.model = [4, 0, 0, 0].concat(data.geometry.model);
                        // // 传到store可以做gpu查询
                        data.geometry["name"] = resource.SkyLineBody;
                        storeDate.geometrys["SkyLineBody"] = data.geometry;
                        actions.setGeometrys();
                    })
                    .catch(function (error) {
                        console.log(error);
                        tool.Message.errorMsg("获取天际线体数据失败", error);
                    });
            })
            .catch(function (error) {
                console.log(error);
                tool.Message.errorMsg("获取天际线体数据失败", error);
            });
    };

    // 天际线体走entity
    function setSkyLineBody2(observerObj) {
        let points = skyline.getSkyline3D();
        let pointArr = new Array();
        let cameraPoint = Cesium.Cartesian3.fromDegrees(observerObj.longitude, observerObj.latitude, observerObj.height);
        pointArr.push(cameraPoint);
        for (let i = 0; i < points.x.length; i++) {
            let point = Cesium.Cartesian3.fromDegrees(points.x[i], points.y[i], points.z[i]);
            pointArr.push(point);
        }
        viewer.entities.add({
            id: 'SkyLineBody',
            polygon: {
                extrudedHeight: 10,
                hierarchy: pointArr,
                perPositionHeight: true,
                material: Cesium.Color.fromCssColorString(state.skyBodyColor)
            }
        })
    }

    // 清除
    function clear() {
        clearHandlerDrawing();
        tooltip.setVisible(false);
        if (!state.observerInformation) return;
        // viewer.entities.removeAll();
        viewer.entities.removeById('SkyLineBody')
        if (skyline) {
            skyline.clear();
        }
        for (let i = 0; i < scene.layers._layerQueue.length; i++) {
            let layer = scene.layers.findByIndex(i);
            layer.removeAllObjsColor();
        }
        state.observerInformation = null;
        myChart.clear();
        initMyChart()
        s3mInstance.removeCollection("SkyLineBody");
        if (storeDate.geometrys.SkyLineBody) {
            delete storeDate.geometrys.SkyLineBody;
            actions.setGeometrys();
        }

    };

    // 监听

    watch(() => state.skylineRadius, val => {
        if (state.observerInformation) {
            skyline.radius = parseFloat(val);
            skyline.pitch = parseFloat(state.observerInformation.pitch);
        }
    });
    watch(() => state.lineWidth, val => {
        skyline.lineWidth = Number(val);
        if (state.observerInformation) {
            skyline.pitch = parseFloat(state.observerInformation.pitch); //加上才能实时改变线宽,可能是缺陷
        }
    });
    watch(() => state.skylineColor, newValue => {
        if (state.observerInformation && newValue != "") {
            let color = Cesium.Color.fromCssColorString(newValue);
            skyline.color = color;
            skyline.pitch = parseFloat(state.observerInformation.pitch);
        }
    });
    watch(() => state.barrierColor, newValue => {
        if (state.observerInformation || !state.highlightBarrier) {
            let BarrierColor = Cesium.Color.fromCssColorString(newValue);
            changeBarrierColor(BarrierColor);
        }
    });
    watch(() => state.ignoreGlobe, newValue => {
        if (skyline) skyline.ignoreGlobe = newValue;
    });


    watch(() => state.highlightBarrier, newValue => {
        if (newValue && state.observerInformation) {
            let BarrierColor = Cesium.Color.fromCssColorString(
                state.barrierColor
            );
            changeBarrierColor(BarrierColor);
        } else {
            for (let i = 0; i < scene.layers._layerQueue.length; i++) {
                let layer = scene.layers.findByIndex(i);
                layer.removeAllObjsColor();
            }
        }
    });
    watch(() => state.skyBodyColor, newValue => {
        if (state.observerInformation && newValue != "") {
            let color = Cesium.Color.fromCssColorString(newValue);
            if (state.skylineSpatialAnalysisUrl) {
                s3mInstance.getInstance("SkyLineBody", 1).updateColor(color);
            } else {
                viewer.entities.getById('SkyLineBody').polygon.material = color //不走服务用这个
            }
        }
    });
    watch(() => state.getSkyline2d, newValue => {
        if (!newValue || !myChart) {
            state.getSkyline2d = false;
            return;
        }
        setTimeout(() => {
            myChart.resize()  //自适应屏幕
        }, 200)

    });
    watch(() => state.skylineMode, newValue => {
        if (newValue == 0) {
            skyline.displayStyle = 0;
            viewer.entities.removeById('SkyLineBody')
            s3mInstance.removeCollection("SkyLineBody");
            if (storeDate.geometrys.SkyLineBody) {
                delete storeDate.geometrys.SkyLineBody;
                actions.setGeometrys();
            }
        } else if (newValue == 1) {
            skyline.displayStyle = 1;
            viewer.entities.removeById('SkyLineBody')
            s3mInstance.removeCollection("SkyLineBody");
            if (storeDate.geometrys.SkyLineBody) {
                delete storeDate.geometrys.SkyLineBody;
                actions.setGeometrys();
            }
        } else if (newValue == 2) {
            // 需要iServer910支持=
            skyline.displayStyle = 0;
            if (state.observerInformation) {
                if (state.skylineSpatialAnalysisUrl) {
                    setSkyLineBody(state.observerInformation)
                } else {
                    setSkyLineBody2(state.observerInformation)
                    // setSkyLineBody(state.observerInformation)
                }
            }
        }
    });

    // 销毁
    onBeforeUnmount(() => {
        clear();
        if (s3mInstance) {
            // s3mInstance.destroy();
        }
        skyline = undefined;
        myChart = undefined;
        s3mInstance = undefined;
    })

    return {
        ...toRefs(state),
        skyLineAnalysis,
        setLimitBody,
        echarts_box,
        clear
    };
}
Example #21
Source File: profile.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
function profile(props) {

    // 设置默认值数据
    let state = reactive({
        profile2d: false, //显示剖面分析结果
        polylineColor: "rgb(250, 213, 6)", //贴线颜色
        polylineWidth: 5,   //贴线宽度
        initEchartsOption:null,  //初始化自定义echarts配置对象
        updateEchartsOption:null , //自定义更新echarts配置对象
    });

    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let myChart, count, //插值点个数
        Entypositions; //当前图标的位置
    let tipFlag = true;  //提示操作提醒一次
    let LatAndLons = []; //所有点的经纬度
    let Cartesians = [];  //所有点的笛卡尔
    let EditPositions= null; //编辑时保存之前位置

    const echarts_box = ref(null);
    onMounted(() => {
        initMyChart();
    });
    if (storeState.isViewer) {
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
        }
    });

    //初始化echarts
    function initMyChart() {
        if (window.echarts) {
            if (!myChart) {
                myChart = window.echarts.init(echarts_box.value);  //初始化echarts
                window.onresize = function () {
                    myChart.resize()  //自适应屏幕
                };
            }
        } else {
            tool.Message.warnMsg(resource.EchartsErr);
            return;
        }
        if(state.initEchartsOption){
            myChart.setOption(state.initEchartsOption);
            return;
        }
        myChart.setOption({
            title: {
                text: "剖面分析",
                textStyle: {
                    fontSize: 14
                }
            },
            grid: {
                left: 30,
                right: 0,
                top: 30,
                bottom: 8
            },
            tooltip: {},
            xAxis: {
                data: [],
            },
            yAxis: {
                data: [],
            },
            series: [
                {
                    type: "bar",
                    data: [],
                },
            ],
        });
    };
    /*
     ***分析模块***
    */

    //分析
    function analysis() {
        if (tipFlag) {   //只提示一次
            tooltip.showAt(' <p>点击鼠标左键开始绘制</p> <p>单击右键结束分析</p><p>选中可进行编辑</p>', '250px');
            tipFlag = false
        }
        if (!window.handlerPolyline) {
            initHandler("Polyline");
        }
        handlerDrawing("Polyline").then(
            res => {
                myChart.showLoading();
                EditPositions = res.positions;
                DrawPolylineUpdate(res.positions); //划线效果
                let handlerPolyline = window.handlerPolyline;
                handlerPolyline.polyline.show = false;
                window.polylineTransparent.show = false; //半透线隐藏
                handlerPolyline.deactivate();
                updataProfile3D('', res.result.object); //更新剖面
                Edit(EditPositions, false, updataProfile3D); //编辑功能
                tooltip.setVisible(false);
            },
            (err) => {
                console.log(err);
            }
        );
        window.handlerPolyline.activate();
    };

    // 绘制剖面分析的线
    function DrawPolylineUpdate(position) {
        viewer.entities.removeById('polyline-profile');
        viewer.entities.removeById('location4');
        let fullLineColor = Cesium.Color.fromCssColorString(state.polylineColor);
        viewer.entities.add({
            id: "polyline-profile",
            polyline: {
                positions: Cesium.Cartesian3.fromDegreesArrayHeights(position),
                width: state.polylineWidth,
                material: fullLineColor,
                clampToGround: true, //线贴地
                // classificationType: Cesium.ClassificationType.S3M_TILE, //线面贴对象
            },
        });
        entityUpdate();
    };

    // 更新剖面分析二维图
    function updataProfile3D(position, line) {
        state.profile2d = true; //打开echarts
        myChart.clear()
        myChart.showLoading();
        //position参数不起作用,是为了edit函数不冲突
        LatAndLons.length = 0; //清空之前的点数据
        Cartesians.length = 0; //清空之前的点数据
        let positions = [];
        //折线实现
        for (let i = 1, j = line._positions.length; i < j; i++) {
            let startPoint = line._positions[i - 1];
            let endPoint = line._positions[i];
            let d = Cesium.Cartesian3.distance(startPoint, endPoint)
            getCount(parseInt(d));
            for (let i = 1, j = count; i <= j; i++) {
                positions.push(
                    Cesium.Cartesian3.lerp(
                        startPoint,
                        endPoint,
                        i / count,
                        new Cesium.Cartesian3()
                    )
                );
            }
        }
        viewer.scene
            .clampToHeightMostDetailed(positions)
            .then((clampedCartesians) => {
                Cartesians = clampedCartesians;  //记录所有点的笛卡尔坐标
                LatAndLons = tool.CartesiantoDegreesObjs(Cartesians);  //记录所有点的经纬度坐标
                echartsOption();  //更新echarts
            });
    };

    //精度计算count插值
    function getCount(distance) {
        if (distance / 10000 > 1) {
            count = parseInt(distance / 100)    //  (>10000)  100m
        } else if (distance / 1000 > 5) {
            count = parseInt(distance / 10)    // (5000-10000)  10m
        } else if (distance / 1000 > 2) {
            count = parseInt(distance / 5)     // (2000-5000)  5m
        } else if (distance / 1000 > 1) {
            count = parseInt(distance / 2)     // (1000-2000)  2m
        } else if (distance / 100 > 5) {
            count = parseInt(distance / 1.5)   //  (500-1000) 1.5m
        } else if (distance / 100 > 2) {
            count = distance                  // (200-500) 1m 
        } else {
            count = distance * 2              //   (<200) 0.5m
        }
    }

    // 更新交互图标
    function entityUpdate() {
        if (viewer.entities.getById("location4")) {
            return;
        }
        viewer.entities.add({
            id: "location4",
            position: new Cesium.CallbackProperty(() => {
                return Entypositions;
            }, false),
            billboard: {
                image: "src/style/images/location4.png",
                width: 30,
                height: 40,
                scaleByDistance: new Cesium.NearFarScalar(10, 1.0, 2000, 0.6),
                eyeOffset :new Cesium.Cartesian3(0, 1, -5)
                // heightReference :Cesium.HeightReference.RELATIVE_TO_GROUND
                // disableDepthTestDistance :5000,
                // pixelOffset : new Cesium.Cartesian2(0.0, 1.0),
                // pixelOffsetScaleByDistance : new Cesium.NearFarScalar(1.5e2, 0.0, 8.0e6, 10.0)
            },
        });
    };

    // 更新图表数据
    function echartsOption() {
        myChart.hideLoading();
        myChart.clear();
        if(state.updateEchartsOption){
            myChart.setOption(state.updateEchartsOption);
            return;
        }
        let option = {
            title: {
                text: "剖面信息",
                textStyle: {
                    fontSize: 14
                }
            },
            // 定位
            grid: {
                left: 50,
                right: 8,
                top: 40,
                bottom: 20,
            },
            // backgroundColor: "rgba(73,139,156,0.0)",
            tooltip: {
                trigger: "axis",
                backgroundColor: "#ffffff",
                textStyle: {
                    color: "#000",
                },
                formatter: (param) => {
                    let dataIndex = param[0].dataIndex;
                    Entypositions = Cartesians[dataIndex];
                    return [
                        "当前位置: " + '<hr size=1 style="margin: 3px 0">',
                        "经度: " +
                        LatAndLons[dataIndex].longitude.toFixed(6) +
                        "<br/>",
                        "纬度: " +
                        LatAndLons[dataIndex].latitude.toFixed(6) +
                        "<br/>",
                        "海拔: " +
                        LatAndLons[dataIndex].height.toFixed(2) +
                        "米" +
                        "<br/>",
                    ].join("");
                },
            },
            xAxis: {
                data: LatAndLons.map(function (item, index) {
                    return index;
                }),
                show: false,
            },
            yAxis: {
                min: function (value) {
                    return value.min < 20 ? 0 : Math.floor(value.min);
                },
                axisLabel: {
                    interval: "auto",
                    formatter: function (value, index) {
                        return value > 999
                            ? (value / 1000).toFixed(2) + "km"
                            : value + "m";
                    },
                },
                splitLine: {
                    show: true,
                },
            },
            toolbox: {
                left: "right",
                feature: {
                    dataZoom: {
                        yAxisIndex: "none",
                    },
                    restore: {},
                    saveAsImage: {},
                },
            },
            dataZoom: [
                {
                    type: "inside",
                    xAxisIndex: 0,
                    filterMode: "filter",
                    start: 0,
                    end: 100,
                },
            ],
            series: {
                name: "height",
                type: "line",
                data: LatAndLons.map(function (item) {
                    return item.height;
                }),
                areaStyle: {},
            },
        };
        myChart.setOption(option);
    };

    // 清除
    function clear() {
        state.profile2d = false;
        viewer.entities.removeById('location4');
        viewer.entities.removeById('polyline-profile');
        myChart.clear();
        LatAndLons.length = 0; //清空之前的点数据
        Cartesians.length = 0; //清空之前的点数据
        clearHandlerDrawing("Polyline");
        clearEditHandler();
        initMyChart();
        tooltip.setVisible(false);
    };

    // 监听
    watch(() => state.profile2d, newValue => {
        if (!newValue || !myChart) {
            state.getSkyline2d = false;
            return;
        }
        setTimeout(() => {
            myChart.resize()  //自适应屏幕
        }, 200)
    });

    // 销毁
    onBeforeUnmount(() => {
        clear();
        myChart.clear();
        LatAndLons.length = 0; //清空之前的点数据
        Cartesians.length = 0; //清空之前的点数据
    })

    return {
        ...toRefs(state),
        echarts_box,
        myChart,
        Entypositions,
        LatAndLons,  //所有点的经纬度
        Cartesians,  //所有点的笛卡尔
        analysis,
        clear
    };
}