addDataSet.html 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <link rel="stylesheet" href="./ol.css" type="text/css">
  5. <link rel="stylesheet" href="./style.css" type="text/css">
  6. <script src="./ol.js"></script>
  7. <style>
  8. [v-cloak] {
  9. display: none;
  10. }
  11. #editor {
  12. height: 200px;
  13. }
  14. </style>
  15. <!-- <script src="./ol.js"></script> -->
  16. <title>控制点定位</title>
  17. </head>
  18. <body>
  19. <div id="app" v-cloak>
  20. <div class="content">
  21. <div id="plane">
  22. <div class="scrollBox">
  23. <!-- <button id="location1">定位1</button>
  24. <button id="location2">定位2</button> -->
  25. <p class="title">数据集位置</p>
  26. <p class="desc">输入拍摄时记录的坐标,将数据集放置在真实世界地图中</p>
  27. <form>
  28. <div class="tag">
  29. <P class="formTitle">锚点1</P>
  30. <div class="localIcon" @click="location(1)"></div>
  31. </div>
  32. <div class="formItem">
  33. <p class="itemTitle">本地坐标:</p>
  34. <div class="inputItem">
  35. <div class="name"> X</div>
  36. <div class="ipt">
  37. <input type="text" v-model="ax" name="ax" id="ax" />
  38. </div>
  39. <span class="unit">m</span>
  40. </div>
  41. <div class="inputItem">
  42. <div class="name"> Y</div>
  43. <div class="ipt">
  44. <input type="text" v-model="ay" name="ay" id="ay" />
  45. </div>
  46. <span class="unit">m</span>
  47. </div>
  48. <div class="inputItem">
  49. <div class="name"> Z</div>
  50. <div class="ipt">
  51. <input type="text" v-model="az" name="az" id="az" />
  52. </div>
  53. <span class="unit">m</span>
  54. </div>
  55. </div>
  56. <div class="formItem">
  57. <p class="itemTitle">地理坐标:</p>
  58. <div class="inputItem">
  59. <div class="name">经度</div>
  60. <div class="ipt">
  61. <input type="text" v-model="alon" name="alon" id="alon" value="120" />
  62. </div>
  63. </div>
  64. <div class="inputItem">
  65. <div class="name">纬度</div>
  66. <div class="ipt">
  67. <input type="text" v-model="alat" name="alat" id="alat" value="22" />
  68. </div>
  69. </div>
  70. <div class="inputItem">
  71. <div class="name">高程</div>
  72. <div class="ipt">
  73. <input type="text" v-model="aalt" name="aalt" id="aalt" value="0" />
  74. </div>
  75. </div>
  76. </div>
  77. <div class="tag">
  78. <P class="formTitle">锚点2</P>
  79. <div class="localIcon" @click="location(2)"></div>
  80. </div>
  81. <div class="formItem">
  82. <p class="itemTitle">本地坐标:</p>
  83. <div class="inputItem">
  84. <div class="name"> X</div>
  85. <div class="ipt">
  86. <input type="text" v-model="bx" name="bx" id="bx" />
  87. </div>
  88. <span class="unit">m</span>
  89. </div>
  90. <div class="inputItem">
  91. <div class="name"> Y</div>
  92. <div class="ipt">
  93. <input type="text" v-model="by" name="by" id="by" />
  94. </div>
  95. <span class="unit">m</span>
  96. </div>
  97. <div class="inputItem">
  98. <div class="name"> Z</div>
  99. <div class="ipt">
  100. <input type="text" v-model="bz" name="bz" id="bz" />
  101. </div>
  102. <span class="unit">m</span>
  103. </div>
  104. </div>
  105. <div class="formItem">
  106. <p class="itemTitle">地理坐标:</p>
  107. <div class="inputItem">
  108. <div class="name">经度</div>
  109. <div class="ipt">
  110. <input type="text" v-model="blon" name="blon" id="blon" value="123" />
  111. </div>
  112. </div>
  113. <div class="inputItem">
  114. <div class="name">纬度</div>
  115. <div class="ipt">
  116. <input type="text" v-model="blat" name="blat" id="blat" value="22" />
  117. </div>
  118. </div>
  119. <div class="inputItem">
  120. <div class="name">高程</div>
  121. <div class="ipt">
  122. <input type="text" v-model="balt" name="balt" id="balt" value="0" />
  123. </div>
  124. </div>
  125. </div>
  126. <p class="itemTitle">EPSG 坐标系 4326</p>
  127. <div class="formItem">
  128. <div class="allIpt">
  129. <input type="text" v-model="EPSG" name="EPSG" id="EPSG" value="EPSG:4326" />
  130. </div>
  131. </div>
  132. </form>
  133. </div>
  134. <div class="bottom">
  135. <div class="style"></div>
  136. <!-- <input type="submit" class="submitBtn" value="提交" />
  137. <button id="clear">取消</button> -->
  138. <div id="clear" @click="clearMap">取消</div>
  139. <div class="submitBtn" @click="commit()">
  140. 提交
  141. </div>
  142. </div>
  143. </div>
  144. <div class="rightBox">
  145. <div id="map" class="map">
  146. <div class="plane1">
  147. <!-- 文件路径:<input type="text" id="filePath" value="./img/gangwan256.png" /><button
  148. id="upload">上传</button><br> -->
  149. 上传地图:<input type="file" id="file" name="file" multiple="multiple" @change="handleFileChange">
  150. <br>
  151. 位置(左上角):<br>
  152. 经度:<input type="text" id="lon" v-model="uploadData.lon" /><br>
  153. 纬度:<input type="text" id="lat" v-model="uploadData.lat" /><br>
  154. 朝向(顺时针为正):<input type="text" id="direction" v-model="uploadData.direction" /><br>
  155. 大小:<input type="text" id="size" v-model="uploadData.size" /><br>
  156. <!-- <button id="ok" @click="getImage">确定</button> -->
  157. <button id="drug" @click="onDrawImage">
  158. <span v-if="!isDraw">开启拖拽</span>
  159. <span v-if="isDraw">关闭拖拽</span>
  160. </button>
  161. <button id="rotate" @click="onRotate">
  162. <span v-if="!isRotate">开启旋转</span>
  163. <span v-if="isRotate">关闭旋转</span>
  164. </button>
  165. <button id="save" @click="onSave">保存</button>
  166. </div>
  167. </div>
  168. </div>
  169. </div>
  170. </div>
  171. <script src="./js/vue.js"></script>
  172. <script src="./js/axios.min.js"></script>
  173. <script type="text/javascript">
  174. //输入经纬度就可以定位
  175. </script>
  176. <script>
  177. new Vue({
  178. el: '#app',
  179. data() {
  180. return {
  181. pointLayerArray: [],
  182. map: {},
  183. gaodeMapLayer: {},
  184. ax: '',
  185. ay: '',
  186. az: '',
  187. alon: '120',
  188. alat: '22',
  189. aalt: '0',
  190. bx: '',
  191. by: '',
  192. bz: '',
  193. blon: '123',
  194. blat: '22',
  195. balt: '0',
  196. EPSG: 'EPSG:4326',
  197. ageControlLocation1: [],
  198. ageControlLocation2: [],
  199. gpsControlCoordinate1: [],
  200. gpsControlCoordinate2: [],
  201. sceneNum: '',
  202. canvas: null,
  203. ctx: null,
  204. imageCanvas: null,
  205. imageCanvasLayer: null,
  206. img: null,
  207. drugObj: null,
  208. rotateObj: null,
  209. imgSrc: null,
  210. file: null,
  211. isRotate: false,
  212. isDraw: false,
  213. size: 512,
  214. limitSize: 512,
  215. uploadData: {
  216. file: null,
  217. lon: '113.59963069739054',
  218. lat: '22.364821730960752',
  219. direction: '0',
  220. size: '256'
  221. }
  222. }
  223. },
  224. created() {
  225. },
  226. mounted() {
  227. this.sceneNum = window.location.pathname.split('/')[2]
  228. this.map = this.initMap('map');
  229. },
  230. methods: {
  231. initMap(divid) {
  232. this.pointLayerArray = [];
  233. this.gaodeMapLayer = new ol.layer.Tile({
  234. source: new ol.source.XYZ({
  235. url: 'http://wprd03.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}' //高德地图切片访问路径
  236. })
  237. });
  238. return new ol.Map({
  239. layers: [this.gaodeMapLayer],
  240. target: divid,
  241. view: new ol.View({
  242. center: ol.proj.fromLonLat([113.59569403794666,
  243. 22.36656052911783
  244. ]), //最初定位的位置
  245. zoom: 4 //地图层级
  246. })
  247. });
  248. },
  249. clearMap() {
  250. this.pointLayerArray.map(each => {
  251. if (each.type == "con_point") {
  252. this.map.removeLayer(each)
  253. }
  254. });
  255. this.pointLayerArray = [];
  256. },
  257. addPoint(lon, lat, text) {
  258. let vector = new ol.source.Vector();
  259. let vLayer = new ol.layer.Vector({
  260. source: vector
  261. })
  262. vLayer.type = "con_point";
  263. this.map.addLayer(vLayer)
  264. this.pointLayerArray.push(vLayer);
  265. let labelCoords = ol.proj.transform([lon, lat], "EPSG:4326", "EPSG:3857");
  266. let feature = new ol.Feature({
  267. geometry: new ol.geom.Point(labelCoords)
  268. });
  269. vector.addFeature(feature);
  270. vLayer.setStyle(new ol.style.Style({
  271. image: new ol.style.Circle({ //点样式
  272. radius: 7,
  273. fill: new ol.style.Fill({
  274. color: '#00c033'
  275. })
  276. }),
  277. text: new ol.style.Text({
  278. text: text,
  279. font: '15px sans-serif',
  280. offsetX: 5,
  281. offsetY: -10,
  282. fill: new ol.style.Fill({
  283. color: "#b9391f"
  284. }),
  285. stroke: new ol.style.Stroke({
  286. color: "#b9391f"
  287. })
  288. })
  289. }))
  290. this.map.getView().setCenter(labelCoords)
  291. },
  292. location(type) {
  293. let alon
  294. let alat
  295. let str = ''
  296. if (type == 1) {
  297. alon = this.alon;
  298. alat = this.alat;
  299. str = '锚点1'
  300. } else {
  301. alon = this.blon;
  302. alat = this.blat;
  303. str = '锚点2'
  304. }
  305. this.addPoint(+alon, +alat, str)
  306. },
  307. handleData() {
  308. this.ageControlLocation1.push(this.ax - 0)
  309. this.ageControlLocation1.push(this.ay - 0)
  310. this.ageControlLocation1.push(this.az - 0)
  311. this.gpsControlCoordinate1.push(this.alon - 0)
  312. this.gpsControlCoordinate1.push(this.alat - 0)
  313. this.gpsControlCoordinate1.push(this.aalt - 0)
  314. this.ageControlLocation2.push(this.bx - 0)
  315. this.ageControlLocation2.push(this.by - 0)
  316. this.ageControlLocation2.push(this.bz - 0)
  317. this.gpsControlCoordinate2.push(this.blon - 0)
  318. this.gpsControlCoordinate2.push(this.blat - 0)
  319. this.gpsControlCoordinate2.push(this.balt - 0)
  320. },
  321. commit() {
  322. this.handleData()
  323. axios.post('/indoor/test3/api/controlPoint/save', {
  324. ageControlLocation1: this.ageControlLocation1,
  325. ageControlLocation2: this.ageControlLocation2,
  326. gpsControlCoordinate1: this.gpsControlCoordinate1,
  327. gpsControlCoordinate2: this.gpsControlCoordinate2,
  328. sceneNum: this.sceneNum,
  329. // id: 1
  330. })
  331. .then(function (response) {
  332. alert('成功')
  333. })
  334. .catch(function (error) {
  335. alert('失败')
  336. });
  337. },
  338. handleFileChange(e) {
  339. const input = e.target;
  340. const files = e.target.files;
  341. if (files && files[0]) {
  342. const file = files[0];
  343. // onload 里面不能用this
  344. this.imgSrc = window.URL.createObjectURL(file);
  345. let img = new Image();
  346. img.src = this.imgSrc;
  347. let self = this;
  348. img.onload = function () {
  349. console.log(img.width, img.height)
  350. if (img.width < self.limitSize || img.height < self.limitSize) {
  351. alert('图片宽高需要大于512')
  352. input.value = '';
  353. return false;
  354. } else if (img.width != img.height) {
  355. alert('图片比例必须为1:1')
  356. input.value = '';
  357. return false;
  358. } else {
  359. self.file = file
  360. self.uploadData.size =img.width
  361. self.getImage()
  362. }
  363. };
  364. }
  365. },
  366. getImage() {
  367. let lon = document.getElementById("lon").value;
  368. let lat = document.getElementById("lat").value;
  369. let direction = document.getElementById("direction").value;
  370. // let url = document.getElementById("filePath").value;
  371. let url = this.imgSrc;
  372. this.showSmallMap(+lon, +lat, +direction, url)
  373. },
  374. onDrawImage() {
  375. let self = this
  376. this.isRotate = false
  377. this.rotateObj && this.rotateObj.close();
  378. this.isDraw = !this.isDraw
  379. if (this.isDraw) {
  380. this.drugObj = new Drug(canvas, ctx, img);
  381. this.drugObj.open();
  382. } else {
  383. this.drugObj.close();
  384. }
  385. /**
  386. * canvas 原生拖拽
  387. **/
  388. function Drug(canvas, ctx, img) {
  389. //这里禁用底图拖拽
  390. self.setMapDragPan(false)
  391. let oldX, oldY, allMoveX = 0,
  392. allMoveY = 0;
  393. canvas.draggable = false; //禁用原生拖拽
  394. let onmousedown = function (evt) {
  395. oldX = evt.x;
  396. oldY = evt.y;
  397. document.addEventListener("mousemove", onmousemove);
  398. }
  399. let onmousemove = function (evt) {
  400. if (!isNaN(oldX - evt.x)) {
  401. ctx.clearRect(0, 0, canvas.width, canvas.height);
  402. allMoveX = allMoveX + evt.x - oldX;
  403. allMoveY = allMoveY + evt.y - oldY;
  404. ctx.translate(evt.x - oldX, evt.y - oldY);
  405. self.drawImage(canvas, ctx, img);
  406. oldX = evt.x;
  407. oldY = evt.y;
  408. imageCanvas.refresh();
  409. }
  410. }
  411. let onmouseup = function (evt) {
  412. document.removeEventListener("mousemove", onmousemove);
  413. }
  414. this.open = function () {
  415. document.addEventListener("mousedown", onmousedown);
  416. document.addEventListener("mousemove", onmousemove);
  417. document.addEventListener("mouseup", onmouseup);
  418. }
  419. this.close = function () {
  420. document.removeEventListener("mousedown", onmousedown);
  421. document.removeEventListener("mousemove", onmousemove);
  422. document.removeEventListener("mouseup", onmouseup);
  423. self.setMapDragPan(true) //打开底图拖拽
  424. }
  425. this.getMoveXY = function () {
  426. this.moveX = allMoveX;
  427. this.moveY = allMoveY;
  428. return [this.moveX, this.moveY]
  429. }
  430. return this;
  431. }
  432. },
  433. onRotate() {
  434. let self = this
  435. this.isDraw = false
  436. this.drugObj && this.drugObj.close();
  437. this.isRotate = !this.isRotate
  438. if (this.isRotate) {
  439. this.rotateObj = new Rotate(canvas, ctx, img);
  440. this.rotateObj.open();
  441. } else {
  442. this.rotateObj.close();
  443. }
  444. /**
  445. * canvas 原生旋转
  446. **/
  447. function Rotate(canvas, ctx, img) {
  448. //这里禁用底图拖拽
  449. self.setMapDragPan(false)
  450. let oldX, oldY, angle = 0,
  451. angleAll = 0;
  452. canvas.draggable = false; //禁用原生拖拽
  453. let onmousedown = function (evt) {
  454. oldX = evt.x;
  455. oldY = evt.y;
  456. document.addEventListener("mousemove", onmousemove);
  457. }
  458. let onmousemove = function (evt) {
  459. if (!isNaN(oldX - evt.x)) {
  460. ctx.clearRect(0, 0, canvas.width, canvas.height);
  461. let tana = (oldY - evt.y) / (evt.x - oldX);
  462. angle = 0.02 * Math.atan(tana);
  463. angleAll = angleAll + angle;
  464. ctx.translate(128, 128);
  465. ctx.rotate(angle);
  466. ctx.translate(-128, -128);
  467. self.drawImage(canvas, ctx, img)
  468. imageCanvas.refresh();
  469. }
  470. }
  471. let onmouseup = function (evt) {
  472. document.removeEventListener("mousemove", onmousemove);
  473. }
  474. this.open = function () {
  475. document.addEventListener("mousedown", onmousedown);
  476. document.addEventListener("mousemove", onmousemove);
  477. document.addEventListener("mouseup", onmouseup);
  478. }
  479. this.close = function () {
  480. document.removeEventListener("mousedown", onmousedown);
  481. document.removeEventListener("mousemove", onmousemove);
  482. document.removeEventListener("mouseup", onmouseup);
  483. self.setMapDragPan(true) //打开底图拖拽
  484. }
  485. this.getAngle = function () {
  486. this.angle = angleAll
  487. return this.angle;
  488. }
  489. return this;
  490. }
  491. },
  492. onSave() {
  493. let lon = document.getElementById("lon").value;
  494. let lat = document.getElementById("lat").value;
  495. let direction = document.getElementById("direction").value;
  496. let size = document.getElementById("size").value;
  497. this.save(+lon, +lat, +direction, +size, this.drugObj, this.rotateObj)
  498. },
  499. showSmallMap(lon, lat, direction, imageUrl) {
  500. let canvasOption = {};
  501. let isFirst = true;
  502. canvasOption.canvasFunction = (extent, resolution, pixelRatio, size, projection) => {
  503. if (isFirst) {
  504. isFirst = false;
  505. canvas = document.createElement('canvas');
  506. canvas.width = size[0];
  507. canvas.height = size[1];
  508. //Canvas四至范围不同于当前地图四至范围,计算出南北方向与东西方向的偏移
  509. let mapExtent = this.map.getView().calculateExtent(this.map
  510. .getSize()); //当前底图视图范围的投影坐标
  511. let canvasOrigin = this.map.getPixelFromCoordinate([extent[0], extent[
  512. 3]]); //添加到地图上的canvas图像的左上角
  513. let mapOrigin = this.map.getPixelFromCoordinate([mapExtent[0], mapExtent[3]]);
  514. let delta = [mapOrigin[0] - canvasOrigin[0], mapOrigin[1] - canvasOrigin[1]];
  515. let leftTop = this.map.getPixelFromCoordinate(ol.proj.fromLonLat([lon, lat]));
  516. //canvas原生加载图片
  517. ctx = canvas.getContext('2d');
  518. img = new Image();
  519. img.src = imageUrl;
  520. img.onload = () => {
  521. ctx.translate(leftTop[0] + delta[0], leftTop[1] + delta[1])
  522. ctx.translate(128, 128)
  523. ctx.rotate(direction * (Math.PI / 180))
  524. ctx.translate(-128, -128)
  525. this.drawImage(canvas, ctx, img)
  526. }
  527. return canvas;
  528. }
  529. }
  530. imageCanvas = new ol.source.ImageCanvas(canvasOption);
  531. imageCanvasLayer = new ol.layer.Image({
  532. source: imageCanvas
  533. });
  534. this.map.addLayer(imageCanvasLayer);
  535. this.map.getView().setCenter(ol.proj.fromLonLat([lon, lat]));
  536. this.map.getView().setZoom(19)
  537. },
  538. save(lon, lat, direction, size, drugObj, rotateObj) {
  539. let saveLonLat, saveAngle;
  540. if (drugObj) {
  541. let moveXY = drugObj.getMoveXY();
  542. let leftTop = this.map.getPixelFromCoordinate(ol.proj.fromLonLat([lon, lat]));
  543. let pixelX = moveXY[0] + leftTop[0];
  544. let pixelY = moveXY[1] + leftTop[1];
  545. saveLonLat = this.map.getCoordinateFromPixel([pixelX, pixelY]);
  546. saveLonLat = ol.proj.toLonLat(saveLonLat);
  547. } else {
  548. saveLonLat = [lon, lat]
  549. }
  550. if (rotateObj) {
  551. saveAngle = rotateObj.getAngle() * 180 / Math.PI + Number(direction);
  552. } else {
  553. saveAngle = direction
  554. }
  555. let save = {
  556. lonlat: saveLonLat,
  557. angle: saveAngle,
  558. size: size
  559. }
  560. console.log(save) //保存到数据库去
  561. let location = saveLonLat;
  562. if (location.length == 2) {
  563. location.push(0)
  564. }
  565. let formData = new FormData()
  566. formData.append('file', this.file)
  567. formData.append('location', location)
  568. formData.append('orientation', saveAngle)
  569. // formData.append('sceneCode', this.sceneNum)
  570. // formData.append('sceneCode', 't810')
  571. axios.post('indoor/' + this.sceneNum + '/api/map/upload', formData)
  572. // axios.post('http://192.168.0.135:9294/indoor/t810/api/map/upload', formData)
  573. .then(function (response) {
  574. alert('成功')
  575. })
  576. .catch(function (error) {
  577. alert('失败')
  578. });
  579. },
  580. drawImage(canvas, ctx, img) {
  581. ctx.clearRect(0, 0, canvas.width, canvas.height);
  582. ctx.drawImage(img, 0, 0); //canvas 从左上角开始绘制
  583. },
  584. setMapDragPan(bool) {
  585. this.map.getInteractions().forEach(function (element, index, array) {
  586. if (element instanceof ol.interaction.DragPan)
  587. element.setActive(bool);
  588. });
  589. }
  590. }
  591. })
  592. </script>
  593. </body>
  594. </html>