| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338 |
- <template>
- <div class="g-map-wrapper">
- <!-- 地图区域 -->
- <div id="g-container" :style="{ width: '100%', height: '100%' }" />
- <!-- 绘制面板 -->
- <div class="g-action-panel">
- <div :class="state.currentType === 'pin' ? 'g-action-item selection' : 'g-action-item'"
- @click="draw('pin', true)">
- <a><a-image :src="pin" :preview="false" /></a>
- </div>
- <div :class="state.currentType === 'polyline' ? 'g-action-item selection' : 'g-action-item'"
- @click="draw('polyline', true)">
- <a>
- <LineOutlined :rotate="135" class="fz20" />
- </a>
- </div>
- <div :class="state.currentType === 'polygon' && !state.isFlightArea ? 'g-action-item selection' : 'g-action-item'"
- @click="draw('polygon', true)">
- <a>
- <BorderOutlined class="fz18" />
- </a>
- </div>
- <!-- <FlightAreaActionIcon class="g-action-item mt10" :class="{'selection': mouseMode && state.isFlightArea}" @select-action="selectFlightAreaAction" @click="selectFlightAreaAction"/> -->
- <div v-if="mouseMode" class="g-action-item" @click="draw('off', false)">
- <a style="color: red;">
- <CloseOutlined />
- </a>
- </div>
- </div>
- <!-- 地图类型切换控件 -->
- <div class="g-mapType">
- <img :src="planeSrc" v-if="state.mapType === 0" @click="onClickSwitchMapType" />
- <img :src="satelliteSrc" v-else @click="onClickSwitchMapType" />
- </div>
- <!-- 最下方信息区域 -->
- <div class="g-info">
- <AimOutlined style="margin-right: 10px;" />
- <div>
- WGS 84
- </div>
- </div>
- <!-- 飞机OSD -->
- <div v-if="osdVisible.visible && !osdVisible.is_dock" v-drag-window class="osd-panel fz12">
- <div class="pl5 pr5 flex-align-center flex-row flex-justify-between"
- style="border-bottom: 1px solid #515151; height: 18%;">
- <div class="drag-title">
- <span>{{ osdVisible.callsign }}</span>
- </div>
- <a class="fz16" style="color: white;" @click="() => osdVisible.visible = false">
- <CloseOutlined />
- </a>
- </div>
- <div style="height: 82%;">
- <div class="osd">
- <a-row>
- <a-col span="4">
- <a-tooltip :title="osdVisible.model">
- <div style="width: 90%;" class="flex-column flex-align-center flex-justify-center">
- <span><a-image :src="M30" :preview="false" /></span>
- <span>{{ osdVisible.model }}</span>
- </div>
- </a-tooltip>
- </a-col>
- <a-col span="20">
- <span>
- 飞行状态:
- </span>
- <span>
- {{ getTextByModeCode(deviceInfo.device.mode_code) }}
- </span>
- <div class="openLiveButton" @click="state.deviceLiveStatus = true" v-if="!state.deviceLiveStatus">
- 开启直播
- </div>
- <div class="openLiveButton" @click="state.deviceLiveStatus = false" v-else>
- 关闭直播
- </div>
- </a-col>
- </a-row>
- <DeviceLive :sn="osdVisible.sn" v-if="state.deviceLiveStatus" />
- <a-row>
- <a-col span="6">
- <a-tooltip title="GPS卫星数">
- <span>
- GPS
- <WifiOutlined />
- </span>
- <span class="ml10">{{ deviceInfo.device.position_state.gps_number }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="RTK">
- <span>
- RTK
- </span>
- <span class="ml10">{{ deviceInfo.device.position_state.rtk_number }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="电量">
- <span>电量</span>
- <span class="ml10">
- {{ deviceInfo.device.battery.capacity_percent + '%' }}
- </span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="风向速度">
- <span>W.S</span>
- <span class="ml10">{{ deviceInfo.device.wind_speed === str ? str : (deviceInfo.device.wind_speed /
- 10).toFixed(2) + ' m/s' }}</span>
- </a-tooltip>
- </a-col>
- </a-row>
- <a-row>
- <a-col span="6">
- <a-tooltip title="海拔高度">
- <span>ASL</span>
- <span class="ml10">
- {{ deviceInfo.device.height === str ? str : deviceInfo.device.height.toFixed(2) + ' m' }}
- </span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="离地高度">
- <span>ALT</span>
- <span class="ml10">
- {{ deviceInfo.device.elevation === str ? str : deviceInfo.device.elevation.toFixed(2) + ' m' }}
- </span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="水平速度">
- <span>H.S</span>
- <span class="ml10">
- {{ deviceInfo.device.horizontal_speed === str ? str :
- deviceInfo.device.horizontal_speed.toFixed(2) + ' m/s' }}
- </span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="当前高度">
- <span>H</span>
- <span class="ml10">
- {{ deviceInfo.device.home_distance === str ? str : deviceInfo.device.home_distance.toFixed(2) + ' m'
- }}
- </span>
- </a-tooltip>
- </a-col>
- </a-row>
- </div>
- </div>
- <div class="battery-slide" v-if="deviceInfo.device.battery.remain_flight_time !== 0">
- <div style="background: #535759;" class="width-100"></div>
- <div class="capacity-percent" :style="{ width: deviceInfo.device.battery.capacity_percent + '%' }"></div>
- <div class="return-home" :style="{ width: deviceInfo.device.battery.return_home_power + '%' }"></div>
- <div class="landing" :style="{ width: deviceInfo.device.battery.landing_power + '%' }"></div>
- <div class="white-point" :style="{ left: deviceInfo.device.battery.landing_power + '%' }"></div>
- <div class="battery" :style="{ left: deviceInfo.device.battery.capacity_percent + '%' }">
- {{ Math.floor(deviceInfo.device.battery.remain_flight_time / 60) }}:
- {{ 10 > (deviceInfo.device.battery.remain_flight_time % 60) ? '0' :
- '' }}{{ deviceInfo.device.battery.remain_flight_time % 60 }}
- </div>
- </div>
- </div>
- <!-- 机场OSD -->
- <div v-if="osdVisible.visible && osdVisible.is_dock" v-drag-window class="osd-panel fz12">
- <div class="drag-title fz16 pl5 pr5 flex-align-center flex-row flex-justify-between"
- style="border-bottom: 1px solid #515151; height: 10%;">
- <span>{{ osdVisible.gateway_callsign }}</span>
- </div>
- <span><a style="color: white; position: absolute; top: 5px; right: 5px;"
- @click="() => osdVisible.visible = false">
- <CloseOutlined />
- </a></span>
- <!-- 机场 -->
- <div class="flex-display" style="border-bottom: 1px solid #515151;">
- <div class="flex-column flex-align-stretch flex-justify-center" style="width: 60px; background: #2d2d2d;">
- <a-tooltip :title="osdVisible.model">
- <div class="flex-column flex-align-center flex-justify-center" style="width: 90%;">
- <span>
- <RobotFilled style="font-size: 48px;" />
- </span>
- <span class="mt10">Dock</span>
- </div>
- </a-tooltip>
- </div>
- <div class="osd flex-1" style="flex: 1">
- <a-row>
- <a-col span="16"
- :style="deviceInfo.dock.basic_osd?.mode_code === EDockModeCode.Disconnected ? 'color: red; font-weight: 700;' : 'color: rgb(25,190,107)'">
- {{ EDockModeCode[deviceInfo.dock.basic_osd?.mode_code] }}</a-col>
- </a-row>
- <a-row>
- <a-col span="12">
- <a-tooltip title="Accumulated Running Time">
- <span>
- <HistoryOutlined />
- </span>
- <span class="ml10">
- <span v-if="deviceInfo.dock.work_osd?.acc_time >= 2592000"> {{
- Math.floor(deviceInfo.dock.work_osd?.acc_time / 2592000) }}m </span>
- <span v-if="(deviceInfo.dock.work_osd?.acc_time % 2592000) >= 86400"> {{
- Math.floor((deviceInfo.dock.work_osd?.acc_time % 2592000) / 86400) }}d </span>
- <span v-if="(deviceInfo.dock.work_osd?.acc_time % 2592000 % 86400) >= 3600"> {{
- Math.floor((deviceInfo.dock.work_osd?.acc_time % 2592000 % 86400) / 3600) }}h </span>
- <span v-if="(deviceInfo.dock.work_osd?.acc_time % 2592000 % 86400 % 3600) >= 60"> {{
- Math.floor((deviceInfo.dock.work_osd?.acc_time % 2592000 % 86400 % 3600) / 60) }}min </span>
- <span>{{ Math.floor(deviceInfo.dock.work_osd?.acc_time % 2592000 % 86400 % 3600 % 60) }} s</span>
- </span>
- </a-tooltip>
- </a-col>
- <a-col span="12">
- <a-tooltip title="Activation time">
- <span>
- <FieldTimeOutlined />
- </span>
- <span class="ml10">{{ new Date((deviceInfo.dock.work_osd?.activation_time ?? 0) * 1000).toLocaleString()
- }}
- </span>
- </a-tooltip>
- </a-col>
- </a-row>
- <a-row>
- <a-col span="6">
- <a-tooltip title="Network State">
- <span :style="qualityStyle">
- <span v-if="deviceInfo.dock.basic_osd?.network_state?.type === NetworkStateTypeEnum.FOUR_G">
- <SignalFilled />
- </span>
- <span v-else>
- <GlobalOutlined />
- </span>
- </span>
- <span class="ml10">{{ deviceInfo.dock.basic_osd?.network_state?.rate }} kb/s</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="The total number of times the dock has performed missions.">
- <span>
- <CarryOutOutlined />
- </span>
- <span class="ml10">{{ deviceInfo.dock.work_osd?.job_number }} </span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Media File Remain Upload">
- <span>
- <CloudUploadOutlined class="fz14" />
- </span>
- <span class="ml10">{{ deviceInfo.dock.link_osd?.media_file_detail?.remain_upload }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip>
- <template #title>
- <p>total: {{ deviceInfo.dock.basic_osd?.storage?.total }}</p>
- <p>used: {{ deviceInfo.dock.basic_osd?.storage?.used }}</p>
- </template>
- <span>
- <FolderOpenOutlined />
- </span>
- <span class="ml10" v-if="deviceInfo.dock.basic_osd?.storage?.total > 0">
- <a-progress type="circle" :width="20"
- :percent="deviceInfo.dock.basic_osd?.storage?.used * 100 / deviceInfo.dock.basic_osd?.storage?.total"
- :strokeWidth="20" :showInfo="false"
- :strokeColor="deviceInfo.dock.basic_osd?.storage?.used * 100 / deviceInfo.dock.basic_osd?.storage?.total > 80 ? 'red' : '#00ee8b'" />
- </span>
- </a-tooltip>
- </a-col>
- </a-row>
- <a-row>
- <a-col span="6">
- <a-tooltip title="Wind Speed">
- <span>W.S</span>
- <span class="ml10">{{ (deviceInfo.dock.basic_osd?.wind_speed ?? str) + ' m/s' }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Rainfall">
- <span>🌧</span>
- <span class="ml10">{{ RainfallEnum[deviceInfo.dock.basic_osd?.rainfall] }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Environment Temperature">
- <span>°C</span>
- <span class="ml10">{{ deviceInfo.dock.basic_osd?.environment_temperature }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Dock Temperature">
- <span>°C</span>
- <span class="ml10">{{ deviceInfo.dock.basic_osd?.temperature }}</span>
- </a-tooltip>
- </a-col>
- </a-row>
- <a-row>
- <a-col span="6">
- <a-tooltip title="Dock Humidity">
- <span>💦</span>
- <span class="ml10">{{ deviceInfo.dock.basic_osd?.humidity }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Working Voltage">
- <span
- style="border: 1px solid; border-radius: 50%; width: 18px; height: 18px; line-height: 16px; text-align: center; float: left;">V</span>
- <span class="ml10">{{ (deviceInfo.dock.work_osd?.working_voltage ?? str) + ' mV' }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Working Current">
- <span
- style="border: 1px solid; border-radius: 50%; width: 18px; height: 18px; line-height: 15px; text-align: center; float: left;">A</span>
- <span class="ml10">{{ (deviceInfo.dock.work_osd?.working_current ?? str) + ' mA' }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Drone in dock">
- <span>
- <RocketOutlined />
- </span>
- <span class="ml10">{{ deviceInfo.dock.basic_osd?.drone_in_dock }}</span>
- </a-tooltip>
- </a-col>
- </a-row>
- <a-row class="p5">
- <a-col span="24">
- <a-button type="primary" :disabled="dockControlPanelVisible" size="small"
- @click="setDockControlPanelVisible(true)">
- Actions
- </a-button>
- </a-col>
- </a-row>
- <!-- 机场控制面板 -->
- <DockControlPanel v-if="dockControlPanelVisible" :sn="osdVisible.gateway_sn" :deviceInfo="deviceInfo"
- @close-control-panel="onCloseControlPanel">
- </DockControlPanel>
- </div>
- </div>
- <!-- 飞机-->
- <div class="flex-display">
- <div class="flex-column flex-align-stretch flex-justify-center" style="width: 60px; background: #2d2d2d;">
- <a-tooltip :title="osdVisible.model">
- <div style="width: 90%;" class="flex-column flex-align-center flex-justify-center">
- <span><a-image :src="M30" :preview="false" /></span>
- <span>M30</span>
- </div>
- </a-tooltip>
- </div>
- <div class="osd flex-1">
- <a-row>
- <a-col span="16"
- :style="!deviceInfo.device || deviceInfo.device?.mode_code === EModeCode.Disconnected ? 'color: red; font-weight: 700;' : 'color: rgb(25,190,107)'">
- {{ !deviceInfo.device ? EModeCode[EModeCode.Disconnected] : EModeCode[deviceInfo.device?.mode_code] }}
- </a-col>
- </a-row>
- <a-row>
- <a-col span="6">
- <a-tooltip title="Upward Quality">
- <span>
- <SignalFilled />
- <ArrowUpOutlined style="font-size: 9px; vertical-align: top;" />
- </span>
- <span class="ml10">{{ deviceInfo.dock.link_osd?.sdr?.up_quality }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Downward Quality">
- <span>
- <SignalFilled />
- <ArrowDownOutlined style="font-size: 9px; vertical-align: top;" />
- </span>
- <span class="ml10">{{ deviceInfo.dock.link_osd?.sdr?.down_quality }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Drone Battery Level">
- <span>
- <ThunderboltOutlined class="fz14" />
- </span>
- <span class="ml10">{{ deviceInfo.device && deviceInfo.device.battery.capacity_percent !== str ?
- deviceInfo.device?.battery.capacity_percent + ' %' : str }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip>
- <template #title>
- <p>total: {{ deviceInfo.device?.storage?.total }}</p>
- <p>used: {{ deviceInfo.device?.storage?.used }}</p>
- </template>
- <span>
- <FolderOpenOutlined />
- </span>
- <span class="ml10" v-if="deviceInfo.device?.storage?.total > 0">
- <a-progress type="circle" :width="20"
- :percent="deviceInfo.device?.storage?.used * 100 / deviceInfo.device?.storage?.total"
- :strokeWidth="20" :showInfo="false"
- :strokeColor="deviceInfo.device?.storage?.used * 100 / deviceInfo.device?.storage?.total > 80 ? 'red' : '#00ee8b'" />
- </span>
- </a-tooltip>
- </a-col>
- </a-row>
- <a-row>
- <a-tooltip title="RTK Fixed">
- <a-col span="6" class="flex-row flex-align-center flex-justify-start">
- <span>Fixed</span>
- <span class="ml10 circle"
- :style="deviceInfo.device?.position_state.is_fixed === 1 ? 'backgroud: rgb(25,190,107);' : ' background: red;'"></span>
- </a-col>
- </a-tooltip>
- <a-col span="6">
- <a-tooltip title="GPS">
- <span>GPS</span>
- <span class="ml10">{{ deviceInfo.device ? deviceInfo.device.position_state.gps_number : str }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="RTK">
- <span>
- <TrademarkOutlined class="fz14" />
- </span>
- <span class="ml10">{{ deviceInfo.device ? deviceInfo.device.position_state.rtk_number : str }}</span>
- </a-tooltip>
- </a-col>
- </a-row>
- <a-row>
- <a-col span="6">
- <a-tooltip title="Flight Mode">
- <span>
- <ControlOutlined class="fz16" />
- </span>
- <span class="ml10">{{ deviceInfo.device ? EGear[deviceInfo.device?.gear] : str }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Altitude above sea level">
- <span>ASL</span>
- <span class="ml10">{{ !deviceInfo.device || deviceInfo.device.height === str ? str :
- deviceInfo.device?.height.toFixed(2) + ' m' }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Altitude above takeoff level">
- <span>ALT</span>
- <span class="ml10">{{ !deviceInfo.device || deviceInfo.device.elevation === str ? str :
- deviceInfo.device?.elevation.toFixed(2) + ' m' }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Distance to Home Point">
- <span
- style="border: 1px solid; border-radius: 50%; width: 18px; height: 18px; line-height: 15px; text-align: center; display: block; float: left;">H</span>
- <span class="ml10">{{ !deviceInfo.device || deviceInfo.device.home_distance === str ? str :
- deviceInfo.device?.home_distance.toFixed(2) + ' m' }}</span>
- </a-tooltip>
- </a-col>
- </a-row>
- <a-row>
- <a-col span="6">
- <a-tooltip title="Horizontal Speed">
- <span>H.S</span>
- <span class="ml10">{{ !deviceInfo.device || deviceInfo.device?.horizontal_speed === str ? str :
- deviceInfo.device?.horizontal_speed.toFixed(2) + ' m/s' }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Vertical Speed">
- <span>V.S</span>
- <span class="ml10">{{ !deviceInfo.device || deviceInfo.device.vertical_speed === str ? str :
- deviceInfo.device?.vertical_speed.toFixed(2) + ' m/s' }}</span>
- </a-tooltip>
- </a-col>
- <a-col span="6">
- <a-tooltip title="Wind Speed">
- <span>W.S</span>
- <span class="ml10">{{ !deviceInfo.device || deviceInfo.device.wind_speed === str ? str :
- (deviceInfo.device?.wind_speed / 10).toFixed(2) + ' m/s' }}</span>
- </a-tooltip>
- </a-col>
- </a-row>
- </div>
- </div>
- <div class="battery-slide" v-if="deviceInfo.device && deviceInfo.device.battery.remain_flight_time !== 0"
- style="border: 1px solid red">
- <div style="background: #535759;" class="width-100"></div>
- <div class="capacity-percent" :style="{ width: deviceInfo.device.battery.capacity_percent + '%' }"></div>
- <div class="return-home" :style="{ width: deviceInfo.device.battery.return_home_power + '%' }"></div>
- <div class="landing" :style="{ width: deviceInfo.device.battery.landing_power + '%' }"></div>
- <div class="white-point" :style="{ left: deviceInfo.device.battery.landing_power + '%' }"></div>
- <div class="battery" :style="{ left: deviceInfo.device.battery.capacity_percent + '%' }">
- {{ Math.floor(deviceInfo.device.battery.remain_flight_time / 60) }}:
- {{ 10 > (deviceInfo.device.battery.remain_flight_time % 60) ? '0' :
- '' }}{{ deviceInfo.device.battery.remain_flight_time % 60 }}
- </div>
- </div>
- <!-- 飞行指令 -->
- <DroneControlPanel :sn="osdVisible.gateway_sn" :deviceInfo="deviceInfo" :payloads="osdVisible.payloads">
- </DroneControlPanel>
- </div>
- <!-- liveview -->
- <div class="liveview" v-if="livestreamOthersVisible" v-drag-window>
- <div style="height: 40px; width: 100%" class="drag-title"></div>
- <a style="position: absolute; right: 10px; top: 10px; font-size: 16px; color: white;"
- @click="closeLivestreamOthers">
- <CloseOutlined />
- </a>
- <LivestreamOthers />
- </div>
- <div class="liveview" v-if="livestreamAgoraVisible" v-drag-window>
- <div style="height: 40px; width: 100%" class="drag-title"></div>
- <a style="position: absolute; right: 10px; top: 10px; font-size: 16px; color: white;"
- @click="closeLivestreamAgora">
- <CloseOutlined />
- </a>
- <LivestreamAgora />
- </div>
- </div>
- </template>
- <script lang="ts">
- import { computed, defineComponent, onMounted, reactive, ref, watch, onUnmounted } from 'vue'
- import {
- generateLineContent,
- generatePointContent,
- generatePolyContent
- } from '../utils/map-layer-utils'
- import { postElementsReq } from '/@/api/layer'
- import { MapDoodleType, MapElementEnum } from '/@/constants/map'
- import { useGMapManage } from '/@/hooks/use-g-map'
- import { useGMapCover } from '/@/hooks/use-g-map-cover'
- import { useMouseTool } from '/@/hooks/use-mouse-tool'
- import { useGMapTrajectory } from '/@/hooks/use-g-map-trajectory'
- import { getApp, getRoot } from '/@/root'
- import { useMyStore } from '/@/store'
- import { GeojsonCoordinate } from '/@/types/map'
- import { MapDoodleEnum } from '/@/types/map-enum'
- import { PostElementsBody } from '/@/types/mapLayer'
- import { uuidv4 } from '/@/utils/uuid'
- import { gcj02towgs84, wgs84togcj02 } from '/@/vendors/coordtransform'
- import { deviceTsaUpdate } from '/@/hooks/use-g-map-tsa'
- import {
- DeviceOsd, DeviceStatus, DockOsd, EGear, EModeCode, GatewayOsd, EDockModeCode,
- NetworkStateQualityEnum, NetworkStateTypeEnum, RainfallEnum, DroneInDockEnum
- } from '/@/types/device'
- import pin from '/@/assets/icons/pin-2d8cf0.svg'
- import M30 from '/@/assets/icons/m30.png'
- import planeSrc from '/@/assets/icons/plane.png'
- import satelliteSrc from '/@/assets/icons/satellite.png'
- import {
- BorderOutlined, LineOutlined, CloseOutlined, AimOutlined, ControlOutlined, TrademarkOutlined, ArrowDownOutlined,
- ThunderboltOutlined, SignalFilled, GlobalOutlined, HistoryOutlined, CloudUploadOutlined, RocketOutlined,
- FieldTimeOutlined, CloudOutlined, CloudFilled, FolderOpenOutlined, RobotFilled, ArrowUpOutlined, CarryOutOutlined
- } from '@ant-design/icons-vue'
- import { EDeviceTypeName, ELocalStorageKey } from '../types'
- import DockControlPanel from './g-map/DockControlPanel.vue'
- import DeviceLive from './deviceLive/index.vue'
- import { useDockControl } from './g-map/use-dock-control'
- import DroneControlPanel from './g-map/DroneControlPanel.vue'
- import { useConnectMqtt } from './g-map/use-connect-mqtt'
- import LivestreamOthers from './livestream-others.vue'
- import FlightAreaActionIcon from './flight-area/FlightAreaActionIcon.vue'
- import { EFlightAreaType } from '../types/flight-area'
- import { useFlightArea } from './flight-area/use-flight-area'
- import { useFlightAreaDroneLocationEvent } from './flight-area/use-flight-area-drone-location-event'
- import { getTextByModeCode } from '/@/utils/index'
- export default defineComponent({
- components: {
- BorderOutlined,
- LineOutlined,
- CloseOutlined,
- AimOutlined,
- ControlOutlined,
- TrademarkOutlined,
- ThunderboltOutlined,
- SignalFilled,
- GlobalOutlined,
- HistoryOutlined,
- CloudUploadOutlined,
- FieldTimeOutlined,
- CloudOutlined,
- CloudFilled,
- FolderOpenOutlined,
- RobotFilled,
- ArrowUpOutlined,
- ArrowDownOutlined,
- DockControlPanel,
- DroneControlPanel,
- DeviceLive,
- CarryOutOutlined,
- RocketOutlined,
- LivestreamOthers,
- FlightAreaActionIcon,
- },
- name: 'GMap',
- props: {},
- setup() {
- const useMouseToolHook = useMouseTool()
- const useGMapManageHook = useGMapManage()
- const deviceTsaUpdateHook = deviceTsaUpdate()
- const root = getRoot()
- const mouseMode = ref(false)
- const store = useMyStore()
- const state = reactive({
- mapType: 0,// 地图类型 0-普通 1-卫星
- currentType: '',
- coverIndex: 0,
- isFlightArea: false,
- deviceLiveStatus: false,// 设备直播状态
- })
- // 点击切换地图类型
- const onClickSwitchMapType = () => {
- const mapType = state.mapType === 0 ? 1 : 0;
- state.mapType = mapType;
- useMouseToolHook.onChangeMapType(mapType);
- }
- const str: string = '--'
- const deviceInfo: any = reactive({
- gateway: {
- capacity_percent: str,
- transmission_signal_quality: str,
- } as GatewayOsd,
- dock: {
- } as DockOsd,
- device: {
- gear: -1,
- mode_code: EModeCode.Disconnected,
- height: str,
- home_distance: str,
- horizontal_speed: str,
- vertical_speed: str,
- wind_speed: str,
- wind_direction: str,
- elevation: str,
- position_state: {
- gps_number: str,
- is_fixed: 0,
- rtk_number: str
- },
- battery: {
- capacity_percent: str,
- landing_power: str,
- remain_flight_time: 0,
- return_home_power: str,
- },
- latitude: 0,
- longitude: 0,
- } as DeviceOsd
- })
- const shareId = computed(() => {
- return store.state.layerBaseInfo.share
- })
- const livestreamOthersVisible = computed(() => {
- return store.state.livestreamOthersVisible
- })
- const livestreamAgoraVisible = computed(() => {
- return store.state.livestreamAgoraVisible
- })
- const osdVisible = computed(() => {
- return store.state.osdVisible
- })
- const qualityStyle = computed(() => {
- if (deviceInfo.dock.basic_osd?.network_state?.type === NetworkStateTypeEnum.ETHERNET ||
- (deviceInfo.dock.basic_osd?.network_state?.quality || 0) > NetworkStateQualityEnum.FAIR) {
- return 'color: #00ee8b'
- }
- if ((deviceInfo.dock.basic_osd?.network_state?.quality || 0) === NetworkStateQualityEnum.FAIR) {
- return 'color: yellow'
- }
- return 'color: red'
- })
- watch(() => store.state.trajectoryList, (list: any) => {
- setTimeout(() => {
- if (list.length >= 2) {// 至少要有起点终点两个坐标才可以绘制轨迹
- const trajectoryHook = useGMapTrajectory()
- trajectoryHook.drawTrajectory(list);
- }
- }, 1000)
- }, { deep: true })
- watch(() => store.state.deviceStatusEvent, (data: any) => {
- if (Object.keys(data.deviceOnline).length !== 0) {
- deviceTsaUpdateHook.initMarker(data.deviceOnline.domain, data.deviceOnline.device_callsign, data.deviceOnline.sn)
- store.state.deviceStatusEvent.deviceOnline = {} as DeviceStatus
- }
- if (Object.keys(data.deviceOffline).length !== 0) {
- deviceTsaUpdateHook.removeMarker(data.deviceOffline.sn)
- if ((data.deviceOffline.sn === osdVisible.value.sn) || (osdVisible.value.is_dock && data.deviceOffline.sn === osdVisible.value.gateway_sn)) {
- osdVisible.value.visible = false
- store.commit('SET_OSD_VISIBLE_INFO', osdVisible)
- }
- store.state.deviceStatusEvent.deviceOffline = {}
- }
- }, { deep: true })
- watch(() => store.state.deviceState, data => {
- if (data.currentType === EDeviceTypeName.Gateway && data.gatewayInfo[data.currentSn]) {
- const coordinate = wgs84togcj02(data.gatewayInfo[data.currentSn].longitude, data.gatewayInfo[data.currentSn].latitude)
- deviceTsaUpdateHook.moveTo(data.currentSn, coordinate[0], coordinate[1])
- if (osdVisible.value.visible && osdVisible.value.gateway_sn !== '') {
- deviceInfo.gateway = data.gatewayInfo[osdVisible.value.gateway_sn]
- }
- }
- if (data.currentType === EDeviceTypeName.Aircraft && data.deviceInfo[data.currentSn]) {
- const coordinate = wgs84togcj02(data.deviceInfo[data.currentSn].longitude, data.deviceInfo[data.currentSn].latitude)
- deviceTsaUpdateHook.moveTo(data.currentSn, coordinate[0], coordinate[1])
- if (osdVisible.value.visible && osdVisible.value.sn !== '') {
- deviceInfo.device = data.deviceInfo[osdVisible.value.sn]
- }
- }
- if (data.currentType === EDeviceTypeName.Dock && data.dockInfo[data.currentSn]) {
- const coordinate = wgs84togcj02(data.dockInfo[data.currentSn].basic_osd?.longitude, data.dockInfo[data.currentSn].basic_osd?.latitude)
- deviceTsaUpdateHook.initMarker(EDeviceTypeName.Dock, EDeviceTypeName[EDeviceTypeName.Dock], data.currentSn, coordinate[0], coordinate[1])
- if (osdVisible.value.visible && osdVisible.value.is_dock && osdVisible.value.gateway_sn !== '') {
- deviceInfo.dock = data.dockInfo[osdVisible.value.gateway_sn]
- deviceInfo.device = data.deviceInfo[deviceInfo.dock.basic_osd.sub_device?.device_sn ?? osdVisible.value.sn]
- }
- }
- }, {
- deep: true
- })
- watch(() => store.state.wsEvent, newData => {
- const useGMapCoverHook = useGMapCover()
- const event = newData
- let exist = false
- if (Object.keys(event.mapElementCreat).length !== 0) {
- const ele: any = event.mapElementCreat
- store.state.Layers.forEach((layer: any) => {
- layer.elements.forEach((e: any) => {
- if (e.id === ele.id) {
- exist = true
- }
- })
- })
- if (exist === false) {
- setLayers({
- id: ele.id,
- name: ele.name,
- resource: ele.resource
- })
- updateCoordinates('wgs84-gcj02', ele)
- const data = { id: ele.id, name: ele.name }
- if (MapElementEnum.PIN === ele.resource?.type) {
- useGMapCoverHook.init2DPin(
- ele.name,
- ele.resource.content.geometry.coordinates,
- ele.resource.content.properties.color,
- data
- )
- } else if (MapElementEnum.LINE === ele.resource?.type) {
- useGMapCoverHook.initPolyline(
- ele.name,
- ele.resource.content.geometry.coordinates,
- ele.resource.content.properties.color,
- data
- )
- } else if (MapElementEnum.POLY === ele.resource?.type) {
- useGMapCoverHook.initPolygon(
- ele.name,
- ele.resource.content.geometry.coordinates,
- ele.resource.content.properties.color,
- data
- )
- }
- }
- store.state.wsEvent.mapElementCreat = {}
- }
- if (Object.keys(event.mapElementUpdate).length !== 0) {
- console.log(event.mapElementUpdate)
- console.log('该功能还未实现,请开发商自己增加')
- store.state.wsEvent.mapElementUpdate = {}
- }
- if (Object.keys(event.mapElementDelete).length !== 0) {
- console.log(event.mapElementDelete)
- console.log('该功能还未实现,请开发商自己增加')
- store.state.wsEvent.mapElementDelete = {}
- }
- }, { deep: true })
- function draw(type: MapDoodleType, bool: boolean, flightAreaType?: EFlightAreaType) {
- state.currentType = type
- mouseMode.value = bool
- state.isFlightArea = !!flightAreaType
- useMouseToolHook.mouseTool(type, getDrawCallback, flightAreaType)
- }
- // dock 控制面板
- const {
- dockControlPanelVisible,
- setDockControlPanelVisible,
- onCloseControlPanel,
- } = useDockControl()
- // 连接或断开drc
- useConnectMqtt()
- onMounted(() => {
- const app = getApp()
- useGMapManageHook.globalPropertiesConfig(app)
- })
- onUnmounted(() => {
- const gatewayInfo = store.state.deviceState.gatewayInfo;
- for (const key in gatewayInfo) {
- deviceTsaUpdateHook.removeDeviceMarker(key)
- }
- root.$map.destroy()
- })
- const { getDrawFlightAreaCallback, onFlightAreaDroneLocationWs } = useFlightArea()
- useFlightAreaDroneLocationEvent(onFlightAreaDroneLocationWs)
- function selectFlightAreaAction({ type, isCircle }: { type: EFlightAreaType, isCircle: boolean }) {
- draw(isCircle ? MapDoodleEnum.CIRCLE : MapDoodleEnum.POLYGON, true, type)
- }
- function getDrawCallback({ obj }: { obj: any }) {
- if (state.isFlightArea) {
- getDrawFlightAreaCallback(obj)
- return
- }
- switch (state.currentType) {
- case MapDoodleEnum.PIN:
- postPinPositionResource(obj)
- break
- case MapDoodleEnum.POLYLINE:
- postPolylineResource(obj)
- break
- case MapDoodleEnum.POLYGON:
- postPolygonResource(obj)
- break
- default:
- break
- }
- draw('off', false)
- }
- async function postPinPositionResource(obj: any) {
- const req: any = getPinPositionResource(obj)
- const userName = localStorage.getItem(ELocalStorageKey.Username) || ''
- req.element_from = 1
- req.resource.user_name = userName
- setLayers(req)
- const coordinates = req.resource.content.geometry.coordinates
- updateCoordinates('gcj02-wgs84', req);
- await postElementsReq(shareId.value, req)
- obj.setExtData({ id: req.id, name: req.name })
- const title = coordinates.map((item: any, index: number) => {
- if (index < 2) {
- return item.toFixed(4)
- }
- });
- obj.setTitle(title)
- store.state.coverMap[req.id] = [obj]
- const map = root.$map
- const AMap = root.$aMap
- const text = new AMap.Text({
- position: new AMap.LngLat(coordinates[0], coordinates[1]),
- offset: new AMap.Pixel(20, -2),
- text: req.name,
- style: {
- backgroundColor: 'transparent',
- borderColor: 'transparent',
- }
- })
- const other = [text]
- map.add(other);
- store.state.coverMap[req.id + '_other'] = other
- obj.on('click', function () {
- store.commit('SET_MAP_CLICK_ELEMENT', {
- id: req.id,
- type: 'DEFAULT',
- });
- });
- }
- async function postPolylineResource(obj: any) {
- const req: any = getPolylineResource(obj)
- const userName = localStorage.getItem(ELocalStorageKey.Username) || ''
- req.element_from = 1
- req.resource.user_name = userName
- setLayers(req)
- updateCoordinates('gcj02-wgs84', req)
- await postElementsReq(shareId.value, req)
- obj.setExtData({ id: req.id, name: req.name })
- store.state.coverMap[req.id] = [obj]
- const map = root.$map
- const AMap = root.$aMap
- const coordinatesList = req.resource.content.geometry.coordinates.map((item: any) => wgs84togcj02(item[0], item[1]))
- if (coordinatesList.length < 2) {
- return
- }
- const color = req.resource.content.properties.color
- const circles = coordinatesList.map((item: any) => {
- return new AMap.Circle({
- center: new AMap.LngLat(item[0], item[1]),
- radius: 8, // 半径
- strokeColor: color,
- fillColor: color,
- fillOpacity: 1,
- strokeWeight: 8,
- });
- })
- const coordinates = coordinatesList[0];
- const text = new AMap.Text({
- position: new AMap.LngLat(coordinates[0], coordinates[1]),
- offset: new AMap.Pixel(-30, -30),
- text: req.name,
- style: {
- backgroundColor: 'transparent',
- borderColor: 'transparent',
- }
- })
- const distances = [];
- const paths = [...coordinatesList]
- // 计算并显示每段线的距离
- for (let i = 0; i < paths.length - 1; i++) {
- const distance = AMap.GeometryUtil.distance(new AMap.LngLat(paths[i][0], paths[i][1]), new AMap.LngLat(paths[i + 1][0], paths[i + 1][1]));
- // 计算两个点之间的中点坐标
- const midLng = (paths[i][0] + paths[i + 1][0]) / 2;
- const midLat = (paths[i][1] + paths[i + 1][1]) / 2;
- const midPoint = new AMap.LngLat(midLng, midLat);
- // 在中点位置放置文本以显示距离
- const distanceText = new AMap.Text({
- position: midPoint,
- offset: new AMap.Pixel(-16, 10),
- text: `${distance.toFixed(1)} m`,// 距离
- style: {
- fontSize: '10px',
- color: '#FFFFFF',
- backgroundColor: 'rgba(0, 0, 0, 0.75)',
- borderColor: 'transparent',
- },
- });
- distances.push(distanceText);
- }
- const other = [...circles, text, ...distances]
- map.add(other);
- store.state.coverMap[req.id + '_other'] = other;
- obj.on('click', function () {
- store.commit('SET_MAP_CLICK_ELEMENT', {
- id: req.id,
- type: 'DEFAULT',
- });
- });
- }
- async function postPolygonResource(obj: any) {
- const req: any = getPoygonResource(obj)
- const userName = localStorage.getItem(ELocalStorageKey.Username) || ''
- req.element_from = 1
- req.resource.user_name = userName
- setLayers(req)
- updateCoordinates('gcj02-wgs84', req)
- await postElementsReq(shareId.value, req)
- obj.setExtData({ id: req.id, name: req.name })
- store.state.coverMap[req.id] = [obj]
- const map = root.$map
- const AMap = root.$aMap
- const coordinatesList = req.resource.content.geometry.coordinates[0].map((item: any) => wgs84togcj02(item[0], item[1]))
- if (coordinatesList.length < 3) {
- return
- }
- const color = req.resource.content.properties.color
- const circles = coordinatesList.map((item: any) => {
- return new AMap.Circle({
- center: new AMap.LngLat(item[0], item[1]),
- radius: 8, // 半径
- strokeColor: color,
- fillColor: color,
- fillOpacity: 1,
- strokeWeight: 8,
- });
- })
- const coordinates = coordinatesList[0];
- const text = new AMap.Text({
- position: new AMap.LngLat(coordinates[0], coordinates[1]),
- offset: new AMap.Pixel(0, -30),
- text: req.name,
- style: {
- backgroundColor: 'transparent',
- borderColor: 'transparent',
- }
- })
- const distances = [];
- // 确保首尾相连
- const paths = [...coordinatesList, coordinatesList[0]]
- // 计算并显示每段线的距离
- for (let i = 0; i < paths.length - 1; i++) {
- const distance = AMap.GeometryUtil.distance(new AMap.LngLat(paths[i][0], paths[i][1]), new AMap.LngLat(paths[i + 1][0], paths[i + 1][1]));
- // 计算两个点之间的中点坐标
- const midLng = (paths[i][0] + paths[i + 1][0]) / 2;
- const midLat = (paths[i][1] + paths[i + 1][1]) / 2;
- const midPoint = new AMap.LngLat(midLng, midLat);
- // 在中点位置放置文本以显示距离
- const distanceText = new AMap.Text({
- position: midPoint,
- offset: new AMap.Pixel(-16, 10),
- text: `${distance.toFixed(1)} m`,// 距离
- style: {
- fontSize: '10px',
- color: '#FFFFFF',
- backgroundColor: 'rgba(0, 0, 0, 0.75)',
- borderColor: 'transparent',
- },
- });
- distances.push(distanceText);
- }
- const other = [...circles, text, ...distances]
- map.add(other);
- store.state.coverMap[req.id + '_other'] = other;
- obj.on('click', function () {
- store.commit('SET_MAP_CLICK_ELEMENT', {
- id: req.id,
- type: 'DEFAULT',
- });
- });
- }
- function getPinPositionResource(obj: any) {
- const position = obj.getPosition()
- const resource = generatePointContent(position)
- const name = obj._originOpts.title
- const id = uuidv4()
- return {
- id,
- name,
- resource
- }
- }
- function getPolylineResource(obj: any) {
- const path = obj.getPath()
- const resource = generateLineContent(path)
- const { name, id } = getBaseInfo(obj._opts)
- return {
- id,
- name,
- resource
- }
- }
- function getPoygonResource(obj: any) {
- const path = obj.getPath()
- const resource = generatePolyContent(path)
- const { name, id } = getBaseInfo(obj._opts)
- return {
- id,
- name,
- resource
- }
- }
- function getBaseInfo(obj: any) {
- const name = obj.title
- const id = uuidv4()
- return { name, id }
- }
- function setLayers(resource: PostElementsBody) {
- const layers = store.state.Layers
- const layer: any = layers.find((item: any) => item.id.includes(shareId.value))
- if (layer?.elements) {
- (layer?.elements as any[]).push(resource)
- }
- store.commit('SET_LAYER_INFO', layers)
- }
- function closeLivestreamOthers() {
- store.commit('SET_LIVESTREAM_OTHERS_VISIBLE', false)
- }
- function closeLivestreamAgora() {
- store.commit('SET_LIVESTREAM_AGORA_VISIBLE', false)
- }
- function updateCoordinates(transformType: string, element: any) {
- const type = element.resource?.type as number
- if (element.resource) {
- if (MapElementEnum.PIN === type) {
- const coordinates = element.resource?.content.geometry
- .coordinates as GeojsonCoordinate
- if (transformType === 'wgs84-gcj02') {
- const transResult = wgs84togcj02(
- coordinates[0],
- coordinates[1]
- ) as GeojsonCoordinate
- element.resource.content.geometry.coordinates = transResult
- } else if (transformType === 'gcj02-wgs84') {
- const transResult = gcj02towgs84(
- coordinates[0],
- coordinates[1]
- ) as GeojsonCoordinate
- element.resource.content.geometry.coordinates = transResult
- }
- } else if (MapElementEnum.LINE === type) {
- const coordinates = element.resource?.content.geometry
- .coordinates as GeojsonCoordinate[]
- if (transformType === 'wgs84-gcj02') {
- coordinates.forEach((coordinate, i, arr) => {
- arr[i] = wgs84togcj02(
- coordinate[0],
- coordinate[1]
- ) as GeojsonCoordinate
- })
- } else if (transformType === 'gcj02-wgs84') {
- coordinates.forEach((coordinate, i, arr) => {
- arr[i] = gcj02towgs84(
- coordinate[0],
- coordinate[1]
- ) as GeojsonCoordinate
- })
- }
- element.resource.content.geometry.coordinates = coordinates
- } else if (MapElementEnum.POLY === type) {
- const coordinates = element.resource?.content.geometry
- .coordinates[0] as GeojsonCoordinate[]
- if (transformType === 'wgs84-gcj02') {
- coordinates.forEach((coordinate, i, arr) => {
- arr[i] = wgs84togcj02(
- coordinate[0],
- coordinate[1]
- ) as GeojsonCoordinate
- })
- } else if (transformType === 'gcj02-wgs84') {
- coordinates.forEach((coordinate, i, arr) => {
- arr[i] = gcj02towgs84(
- coordinate[0],
- coordinate[1]
- ) as GeojsonCoordinate
- })
- }
- element.resource.content.geometry.coordinates = [coordinates]
- }
- }
- }
- return {
- draw,
- mouseMode,
- livestreamOthersVisible,
- livestreamAgoraVisible,
- osdVisible,
- pin,
- state,
- M30,
- planeSrc,
- satelliteSrc,
- deviceInfo,
- onClickSwitchMapType,
- EGear,
- EModeCode,
- str,
- EDockModeCode,
- dockControlPanelVisible,
- setDockControlPanelVisible,
- onCloseControlPanel,
- NetworkStateTypeEnum,
- NetworkStateQualityEnum,
- RainfallEnum,
- DroneInDockEnum,
- closeLivestreamOthers,
- closeLivestreamAgora,
- qualityStyle,
- selectFlightAreaAction,
- getTextByModeCode,
- }
- }
- })
- </script>
- <style lang="scss" scoped>
- .g-map-wrapper {
- height: 100%;
- width: 100%;
- .g-action-panel {
- position: absolute;
- top: 16px;
- right: 16px;
- .g-action-item {
- width: 28px;
- height: 28px;
- background: white;
- color: $primary;
- border-radius: 2px;
- line-height: 28px;
- text-align: center;
- margin-bottom: 2px;
- }
- .g-action-item:hover {
- border: 1px solid $primary;
- border-radius: 2px;
- }
- }
- .selection {
- border: 1px solid $primary;
- border-radius: 2px;
- }
- // antd button 光晕
- &:deep(.ant-btn) {
- &::after {
- display: none;
- }
- }
- }
- .g-mapType {
- width: 28px;
- height: 28px;
- background: white;
- border-radius: 2px;
- line-height: 28px;
- text-align: center;
- position: absolute;
- bottom: 50px;
- right: 16px;
- cursor: pointer;
- img {
- width: 18px;
- height: 18px;
- }
- }
- .g-info {
- width: 100%;
- height: 26px;
- padding: 0 16px;
- background: rgba(255, 255, 255, 0.7);
- border-radius: 2px;
- line-height: 28px;
- text-align: center;
- position: absolute;
- bottom: 0;
- right: 0;
- display: flex;
- justify-content: flex-end;
- align-items: center;
- }
- .osd-panel {
- position: absolute;
- margin-left: 10px;
- left: 0;
- top: 10px;
- width: 480px;
- background: #000;
- color: #fff;
- border-radius: 2px;
- background-color: rgba(0, 0, 0, 0.8);
- }
- .openLiveButton {
- padding: 5px;
- border: 1px solid #5c5c5c;
- cursor: pointer;
- }
- .osd>div:not(.dock-control-panel) {
- margin-top: 5px;
- padding: 5px;
- }
- .circle {
- border-radius: 50%;
- width: 10px;
- height: 10px;
- }
- .battery-slide {
- .capacity-percent {
- background: #00ee8b;
- }
- .return-home {
- background: #ff9f0a;
- }
- .landing {
- background: #f5222d;
- }
- .white-point {
- width: 4px;
- height: 4px;
- border-radius: 50%;
- background: white;
- bottom: -0.5px;
- }
- .battery {
- background: #141414;
- color: #00ee8b;
- margin-top: -10px;
- height: 20px;
- width: auto;
- border-left: 1px solid #00ee8b;
- padding: 0 5px;
- }
- }
- .battery-slide>div {
- position: absolute;
- min-height: 2px;
- border-radius: 2px;
- }
- .liveview {
- position: absolute;
- color: #fff;
- z-index: 1;
- left: 0;
- margin-left: 10px;
- top: 10px;
- text-align: center;
- width: 800px;
- height: 660px;
- background: #232323;
- }
- </style>
- <style lang="scss">
- .amap-logo {
- display: none !important;
- }
- .amap-copyright {
- display: none !important;
- }
- </style>
|