mirror of
https://github.com/eatfishfish/openpilot-server.git
synced 2026-08-22 04:42:32 +00:00
Compare commits
12 Commits
OPS
..
videoonline
| Author | SHA1 | Date | |
|---|---|---|---|
| c155fb43a5 | |||
| 9efaf98d38 | |||
| 33cf4d0dc5 | |||
| c1f4be2af9 | |||
| bed7911298 | |||
| 1914d64fe8 | |||
| dea36727f2 | |||
| 2395dda013 | |||
| 5d4d33b620 | |||
| 7d07631514 | |||
| b35bffa85b | |||
| 57781a3bcb |
@@ -6,6 +6,8 @@
|
|||||||
<http_bind> 是绑定http server 的ip和端口。
|
<http_bind> 是绑定http server 的ip和端口。
|
||||||
<athena_host> 是该服务端公网的域名。
|
<athena_host> 是该服务端公网的域名。
|
||||||
<upload_url> 是该服务端公网的域名。
|
<upload_url> 是该服务端公网的域名。
|
||||||
|
<amap_key> 高德API KEY 。https://console.amap.com/dev/index 这里注册。选择绑定“Web服务”。
|
||||||
|
<ffmpeg_path>ffmpeg程序路径。 ffmpeg 从https://ffmpeg.org/download.html下载。
|
||||||
(2) 启动
|
(2) 启动
|
||||||
在服务器上启动opserver.exe。
|
在服务器上启动opserver.exe。
|
||||||
|
|
||||||
@@ -14,12 +16,14 @@
|
|||||||
(2) 在/data/continue.sh export 添加 <athena_host> 和 <upload_url>。
|
(2) 在/data/continue.sh export 添加 <athena_host> 和 <upload_url>。
|
||||||
export ATHENA_HOST='ws://laolang.duckdns.org:7899'
|
export ATHENA_HOST='ws://laolang.duckdns.org:7899'
|
||||||
export API_HOST='http://laolang.duckdns.org:7898'
|
export API_HOST='http://laolang.duckdns.org:7898'
|
||||||
|
export MAPBOX_TOKEN='<自己注册>'
|
||||||
像这样:
|
像这样:
|
||||||
/-----/data/continue.sh file-----------------
|
/-----/data/continue.sh file-----------------
|
||||||
#!/usr/bin/bash
|
#!/usr/bin/bash
|
||||||
|
|
||||||
export ATHENA_HOST='ws://laolang.duckdns.org:7899'
|
export ATHENA_HOST='ws://laolang.duckdns.org:7899'
|
||||||
export API_HOST='http://laolang.duckdns.org:7898'
|
export API_HOST='http://laolang.duckdns.org:7898'
|
||||||
|
export MAPBOX_TOKEN='pk.eyJ1Ijoiam5ld2IiLCJhIjoiY2xxNW8zZXprMGw1ZzJwbzZneHd2NHljbSJ9.gV7VPRfbXFetD-1OVF0XZg'
|
||||||
|
|
||||||
cd /data/openpilot
|
cd /data/openpilot
|
||||||
exec ./launch_openpilot.sh
|
exec ./launch_openpilot.sh
|
||||||
@@ -29,9 +33,13 @@ exec ./launch_openpilot.sh
|
|||||||
(3) rm -rf /data/params/d/DongleId
|
(3) rm -rf /data/params/d/DongleId
|
||||||
sudo reboot #重启你的c3/c3x
|
sudo reboot #重启你的c3/c3x
|
||||||
|
|
||||||
#### 3. 下载文件
|
#### 3. 下载文件和设置导航
|
||||||
(1) 浏览器中打开 http://laolang.duckdns.org:7898/op/DongleId
|
(1) 浏览器中打开 http://<your_domain_name> 例如 [http://laolang.duckdns.org:7898](http://laolang.duckdns.org:7898/static/index.html)
|
||||||
DongleId替换成你的ID。 DongleId可以在你的c3/c3x设备上查看。
|
输入测试Dongle ID : e7a8b8c1cb559c9d
|
||||||
|
|
||||||
|
(2) 进入设置导航地址。(仅支持IPhone地图和高德地图)
|
||||||
|
|
||||||
|
#### 4.Star me. Thank you.如果觉得很复杂,可以直接看第二步,使用我的服务器。
|
||||||
|
|
||||||
# openpilot-server for english
|
# openpilot-server for english
|
||||||
|
|
||||||
@@ -40,7 +48,7 @@ exec ./launch_openpilot.sh
|
|||||||
<ws_bind> IP and port of the websocket server.
|
<ws_bind> IP and port of the websocket server.
|
||||||
<http_bind> IP and port of the http server.
|
<http_bind> IP and port of the http server.
|
||||||
<athena_host> The domain name of the server.
|
<athena_host> The domain name of the server.
|
||||||
<upload_url> The the domain name of the server.
|
<upload_url> The domain name of the server.
|
||||||
(2) Launch
|
(2) Launch
|
||||||
Launch opserver.exe on your windows server.
|
Launch opserver.exe on your windows server.
|
||||||
|
|
||||||
@@ -49,12 +57,14 @@ Launch opserver.exe on your windows server.
|
|||||||
(2) In "/data/continue.sh" file, export <athena_host> and <upload_url>.
|
(2) In "/data/continue.sh" file, export <athena_host> and <upload_url>.
|
||||||
export ATHENA_HOST='ws://laolang.duckdns.org:7899'
|
export ATHENA_HOST='ws://laolang.duckdns.org:7899'
|
||||||
export API_HOST=' http://laolang.duckdns.org:7898 '
|
export API_HOST=' http://laolang.duckdns.org:7898 '
|
||||||
|
export MAPBOX_TOKEN='<register_on_mapbox_website.>'
|
||||||
like this:
|
like this:
|
||||||
/-----/data/continue.sh file-----------------
|
/-----/data/continue.sh file-----------------
|
||||||
#!/usr/bin/bash
|
#!/usr/bin/bash
|
||||||
|
|
||||||
export ATHENA_HOST='ws://laolang.duckdns.org:7899'
|
export ATHENA_HOST='ws://laolang.duckdns.org:7899'
|
||||||
export API_HOST='http://laolang.duckdns.org:7898'
|
export API_HOST='http://laolang.duckdns.org:7898'
|
||||||
|
export MAPBOX_TOKEN='<register_on_mapbox_website.>'
|
||||||
|
|
||||||
cd /data/openpilot
|
cd /data/openpilot
|
||||||
exec ./launch_openpilot.sh
|
exec ./launch_openpilot.sh
|
||||||
@@ -64,6 +74,10 @@ exec ./launch_openpilot.sh
|
|||||||
(3) rm -rf /data/params/d/DongleId
|
(3) rm -rf /data/params/d/DongleId
|
||||||
sudo reboot #Restart your c3/c3x
|
sudo reboot #Restart your c3/c3x
|
||||||
|
|
||||||
#### 3. Download the file
|
#### 3. Download and navigation
|
||||||
(1) Open http://laolang.duckdns.org:7898/op/DongleId in your browser
|
(1) Open http://<your_domain_name> (for example [http://laolang.duckdns.org:7898](http://laolang.duckdns.org:7898/static/index.html)) in your browser
|
||||||
and replace DongleId with your ID. DongleId can be viewed on your c3/c3x device.
|
Input test Dongle ID : e7a8b8c1cb559c9d
|
||||||
|
|
||||||
|
(2) In the web page configure the navigation.(Only support IPhone map and AMap)
|
||||||
|
|
||||||
|
#### 4.Star me. Thank you
|
||||||
|
|||||||
@@ -2,3 +2,5 @@ ws_bind=0.0.0.0:7899
|
|||||||
http_bind=0.0.0.0:7898
|
http_bind=0.0.0.0:7898
|
||||||
athena_host=ws://laolang.duckdns.org:7899
|
athena_host=ws://laolang.duckdns.org:7899
|
||||||
upload_url=http://laolang.duckdns.org:7898
|
upload_url=http://laolang.duckdns.org:7898
|
||||||
|
amap_key=23428738744447ba93dda0d6473ff026e
|
||||||
|
ffmpeg_path=D:\\software\\ffmpeg.exe
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,430 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||||
|
<title>eatfishfish/opserver</title>
|
||||||
|
<script type="text/javascript" src="https://cache.amap.com/lbs/static/addToolbar.js"></script>
|
||||||
|
<script type="text/javascript" src='https://cdn.sheetjs.com/xlsx-0.19.2/package/dist/xlsx.full.min.js'></script>
|
||||||
|
</head>
|
||||||
|
<style type="text/css">
|
||||||
|
html,body{
|
||||||
|
font-size: 12px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
.map{
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*数据卡片*/
|
||||||
|
.input-card{
|
||||||
|
padding: 5px;
|
||||||
|
max-height: 360px;
|
||||||
|
width: 360px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
min-width: 0;
|
||||||
|
word-wrap: break-word;
|
||||||
|
background-color: #fff;
|
||||||
|
background-clip: border-box;
|
||||||
|
border-radius: .25rem;
|
||||||
|
border-width: 0;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
|
||||||
|
position: fixed;
|
||||||
|
/*bottom: 1rem;*/
|
||||||
|
right: 1.25rem;
|
||||||
|
-ms-flex: 1 1 auto;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
padding: 0.75rem 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*图标*/
|
||||||
|
.pot-out {
|
||||||
|
background-color:#F0FFF0;
|
||||||
|
width:18px;height:18px;
|
||||||
|
border:solid 1px #00BFFF;
|
||||||
|
border-radius:16px 16px 16px 0;
|
||||||
|
-webkit-transform:rotate(-45deg);
|
||||||
|
-moz-transform: ratate(-45deg);
|
||||||
|
transform:rotate(-45deg);
|
||||||
|
}
|
||||||
|
.pot-in {
|
||||||
|
line-height: 18px;
|
||||||
|
text-align: center;
|
||||||
|
width:18px;height:18px;
|
||||||
|
-webkit-transform:rotate(45deg);
|
||||||
|
-moz-transform: ratate(45deg);
|
||||||
|
transform:rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*表格*/
|
||||||
|
table {
|
||||||
|
text-align: center;
|
||||||
|
width:350px;
|
||||||
|
/* table-layout:fixed;*//* 只有定义了表格的布局算法为fixed,下面td的定义才能起作用。 */
|
||||||
|
border-color: white;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
table thead tr {
|
||||||
|
background-color: #C0EEF2;
|
||||||
|
}
|
||||||
|
table tr {
|
||||||
|
background-color: #E9F8F9;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td{
|
||||||
|
/*width:20px;*/
|
||||||
|
word-break:keep-all;/* 不换行 */
|
||||||
|
white-space:nowrap;/* 不换行 */
|
||||||
|
overflow:hidden;/* 内容超出宽度时隐藏超出部分的内容 */
|
||||||
|
text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用*/
|
||||||
|
}
|
||||||
|
.btn2{
|
||||||
|
border: none;
|
||||||
|
background-color: #E3F6FF;
|
||||||
|
}
|
||||||
|
.btns-box{
|
||||||
|
display: flex;
|
||||||
|
display: -webkit-flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 330px;
|
||||||
|
}
|
||||||
|
.btns{
|
||||||
|
border: none;
|
||||||
|
flex-basis: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: solid 1px white;
|
||||||
|
background-color: #E3E6FA;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div id="container" class="map"></div>
|
||||||
|
|
||||||
|
<div class="input-card">
|
||||||
|
<div class="btns-box">
|
||||||
|
<button id="hide-obj3d-btn" onclick="setRoadNetLayer()" class="btns">街景</button>
|
||||||
|
<button id="show-obj3d-btn" onclick="setSatelliteLayer()" class="btns">卫星</button>
|
||||||
|
<button id="show-obj3d-btn" onclick="setMixLayer()" class="btns">混合</button>
|
||||||
|
<button class="btns" style="display: none;" onclick="noDomExportExcel() ">导出Excel</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table border="1" style="display: none;">
|
||||||
|
<input id="tipinput"/>
|
||||||
|
<button name="search" onclick="onSearch()">Search</button>
|
||||||
|
</table>
|
||||||
|
<table border="1" >
|
||||||
|
<thead>
|
||||||
|
<th >Id</th>
|
||||||
|
<th style="display: none;">经度</th>
|
||||||
|
<th style="display: none;">纬度</th>
|
||||||
|
<th>地址</th>
|
||||||
|
<th style="display: none;">删除</th>
|
||||||
|
<th>发送OP</th>
|
||||||
|
<th style="display: none;">定位</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://webapi.amap.com/maps?v=1.4.15&key=b8de4cd1c32ebd939282e7fb176429b3&plugin=AMap.Autocomplete"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var num = 0;
|
||||||
|
// 数组
|
||||||
|
let data = [];
|
||||||
|
|
||||||
|
dongleid = "0e6a9a3cdf6a1092";
|
||||||
|
|
||||||
|
function onSearch()
|
||||||
|
{
|
||||||
|
num=0;
|
||||||
|
data = [];
|
||||||
|
|
||||||
|
input_text = document.getElementById("tipinput").value
|
||||||
|
if (input_text == ""){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dongleid = localStorage.getItem("dongleId");
|
||||||
|
console.log(dongleid);
|
||||||
|
|
||||||
|
uri = '/amap/' + dongleid + "/"+input_text
|
||||||
|
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', uri, true);
|
||||||
|
xhr.onload = function() {
|
||||||
|
|
||||||
|
if (this.status === 200) {
|
||||||
|
//console.log(this.responseText);
|
||||||
|
let arr = this.responseText.split(';');
|
||||||
|
|
||||||
|
for (i=0; i < arr.length-1; i++) {
|
||||||
|
console.log(arr[i]);
|
||||||
|
let ll = arr[i].split(',');
|
||||||
|
data.push({
|
||||||
|
id:num,
|
||||||
|
lng:Number(ll[0]),
|
||||||
|
lat:Number(ll[1]),
|
||||||
|
remark:ll[2]
|
||||||
|
});
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
initdata();
|
||||||
|
|
||||||
|
if (num > 0){
|
||||||
|
map.setCenter([data[0].lng, data[0].lat]); //设置地图中心点
|
||||||
|
map.setZoom(17); //设置缩放等级
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
numSearch = num;
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
let inputElement = document.getElementById("tipinput");
|
||||||
|
|
||||||
|
// 监听输入框的 keydown 事件
|
||||||
|
inputElement.addEventListener("keydown", function(event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
onSearch()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//发送到op
|
||||||
|
function sends(e){
|
||||||
|
var i=e.target.getAttribute("index");
|
||||||
|
map.setCenter([data[i].lng, data[i].lat]); //设置地图中心点
|
||||||
|
var httpRequest = new XMLHttpRequest();//第一步:创建需要的对象
|
||||||
|
uri = "/v1/navigation/"+dongleid+"/"+"set_destination"
|
||||||
|
httpRequest.open('POST', uri, true); //第二步:打开连接/***发送json格式文件必须设置请求头 ;如下 - */
|
||||||
|
httpRequest.setRequestHeader("Content-type","application/json");//设置请求头 注:post方式必须设置请求头(在建立连接后设置请求头)var obj = { name: 'zhansgan', age: 18 };
|
||||||
|
httpRequest.setRequestHeader("Authorization","jwt-from-amap-web");
|
||||||
|
|
||||||
|
var placeName = data[i].remark;
|
||||||
|
var placeDetail = data[i].remark;
|
||||||
|
if (placeName == ""){
|
||||||
|
placeName = document.getElementById("tipinput").value;
|
||||||
|
}
|
||||||
|
var obj = { place_name: placeName, place_details:placeDetail,longitude:data[i].lng, latitude:data[i].lat};
|
||||||
|
httpRequest.send(JSON.stringify(obj));//发送请求 将json写入send中
|
||||||
|
/**
|
||||||
|
* 获取数据后的处理程序
|
||||||
|
*/
|
||||||
|
httpRequest.onreadystatechange = function () {//请求后的回调接口,可将请求成功后要执行的程序写在其中
|
||||||
|
if (httpRequest.readyState == 4 && httpRequest.status == 200) {//验证请求是否发送成功
|
||||||
|
var json = httpRequest.responseText;//获取到服务端返回的数据
|
||||||
|
console.log(json);
|
||||||
|
if (json == "ok")
|
||||||
|
{
|
||||||
|
alert("发送成功")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var save=false;
|
||||||
|
|
||||||
|
|
||||||
|
//标记
|
||||||
|
var markers = [];
|
||||||
|
//高德地图
|
||||||
|
var map = new AMap.Map("container", {
|
||||||
|
resizeEnable: true,
|
||||||
|
expandZoomRange:true,
|
||||||
|
zoom:20, //设置初始化级别
|
||||||
|
zooms:[3,20] //设置缩放级别范围 3-20 级
|
||||||
|
});
|
||||||
|
|
||||||
|
// 构造官方卫星、路网图层
|
||||||
|
var satelliteLayer = new AMap.TileLayer.Satellite();
|
||||||
|
var roadNetLayer = new AMap.TileLayer.RoadNet();
|
||||||
|
|
||||||
|
//设置鼠标样式
|
||||||
|
// map.setDefaultCursor("crosshair");
|
||||||
|
|
||||||
|
//为地图注册click事件获取鼠标点击出的经纬度坐标
|
||||||
|
map.on('click', function(e) {
|
||||||
|
var find = false;
|
||||||
|
for (i=0; i < data.length; i++) {
|
||||||
|
if (data[i].remark == "")
|
||||||
|
{
|
||||||
|
data[i].lng = e.lnglat.R;
|
||||||
|
data[i].lat = e.lnglat.Q;
|
||||||
|
data[i].remark = "";
|
||||||
|
find = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!find) {
|
||||||
|
data.push({
|
||||||
|
id:num,
|
||||||
|
lng:e.lnglat.R,
|
||||||
|
lat:e.lnglat.Q,
|
||||||
|
remark:""
|
||||||
|
});
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
initdata();
|
||||||
|
//num++;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//初始化数据
|
||||||
|
function initdata(){
|
||||||
|
//1、清除所有图标
|
||||||
|
markers=[];
|
||||||
|
map.clearMap();
|
||||||
|
//2、渲染图标
|
||||||
|
for(let i=0;i<data.length;i++){
|
||||||
|
//console.log(typeof data[i].lng);
|
||||||
|
//添加图标
|
||||||
|
var marker = new AMap.Marker({
|
||||||
|
// 将 html 传给 content
|
||||||
|
content: '<div class="pot-out"><div class="pot-in">'+data[i].id+'</div></div>',
|
||||||
|
position:[data[i].lng,data[i].lat],
|
||||||
|
offset:new AMap.Pixel(-9,-18), //中心点
|
||||||
|
draggable: true, // 设置是否可以拖拽
|
||||||
|
cursor: 'move', //拖动时的鼠标样式
|
||||||
|
raiseOnDrag: true, //托拽效果
|
||||||
|
extData:i //自定义数据
|
||||||
|
});
|
||||||
|
//鼠标移动
|
||||||
|
marker.on('mouseup',function (e3) {
|
||||||
|
var index=e3.target.De.extData;
|
||||||
|
data[index].lng=e3.lnglat.R;
|
||||||
|
data[index].lat=e3.lnglat.Q;
|
||||||
|
initdata();
|
||||||
|
});
|
||||||
|
markers.push(marker); //保存到标识列表中
|
||||||
|
}
|
||||||
|
map.add(markers); //添加标识到地图中
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 渲染表格
|
||||||
|
*/
|
||||||
|
let tbodyinner = document.getElementsByTagName("tbody")[0]
|
||||||
|
let html = ''
|
||||||
|
for(let i=0;i<data.length;i++){
|
||||||
|
html+=`
|
||||||
|
<tr>
|
||||||
|
<td >${data[i].id}</td>
|
||||||
|
<td style="display: none;" name="latlng" title='${data[i].lng}'>${data[i].lng}</td>
|
||||||
|
<td style="display: none;" name="latlng" title='${data[i].lng}'>${data[i].lat}</td>
|
||||||
|
|
||||||
|
<td> <button name="locate" class="btn2" index="${i}">${data[i].remark}</button> </td>
|
||||||
|
<td style="display: none;"> <button name="del" class="btn2" index="${i}">删除</button> </td>
|
||||||
|
<td> <button name="send" class="btn2" index="${i}">op导航</button> </td>
|
||||||
|
</tr>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
// tbody.innerHTML="..."往tbody中添加内容
|
||||||
|
tbodyinner.innerHTML = html
|
||||||
|
addEvents()
|
||||||
|
save=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格添加监听click事件
|
||||||
|
function addEvents(){
|
||||||
|
let subject = document.getElementsByName("grade")
|
||||||
|
for(let i=0;i<subject.length;i++){
|
||||||
|
subject[i].addEventListener('click',function(e){
|
||||||
|
edit(this,e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let delbut = document.getElementsByName("del")
|
||||||
|
for(let i=0;i<delbut.length;i++){
|
||||||
|
delbut[i].addEventListener('click',function(e){
|
||||||
|
deletes(e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let locate = document.getElementsByName("locate")
|
||||||
|
for(let i=0;i<delbut.length;i++){
|
||||||
|
locate[i].addEventListener('click',function(e){
|
||||||
|
locates(e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let send = document.getElementsByName("send")
|
||||||
|
for(let i=0;i<delbut.length;i++){
|
||||||
|
send[i].addEventListener('click',function(e){
|
||||||
|
sends(e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//表格编辑
|
||||||
|
function edit(i,e){
|
||||||
|
let oldvalue = i.innerHTML;
|
||||||
|
// 设置该标签为空
|
||||||
|
i.innerHTML = ''
|
||||||
|
// 添加input对象
|
||||||
|
let inp = document.createElement("input")
|
||||||
|
inp.value = oldvalue
|
||||||
|
inp.classList.add("inputClass")
|
||||||
|
// 添加子节点
|
||||||
|
i.appendChild(inp)
|
||||||
|
// 获取文本中的内容
|
||||||
|
inp.select()
|
||||||
|
// 失去焦点事件
|
||||||
|
inp.onblur = function(){
|
||||||
|
i.innerHTML = inp.value;
|
||||||
|
var index=e.target.getAttribute("index");
|
||||||
|
data[index].remark=inp.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除表格行数据
|
||||||
|
function deletes(e){
|
||||||
|
//var r=confirm("确定删除?");
|
||||||
|
var r=true
|
||||||
|
if (r==true){
|
||||||
|
var index=e.target.getAttribute("index");
|
||||||
|
//表格数据移除
|
||||||
|
data.splice(index, 1);
|
||||||
|
//地图上移除标记
|
||||||
|
map.remove([markers[index]]);
|
||||||
|
//列表中移除标记
|
||||||
|
markers.splice(index, 1);
|
||||||
|
initdata();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log("取消");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除表格行数据
|
||||||
|
function locates(e){
|
||||||
|
var i=e.target.getAttribute("index");
|
||||||
|
map.setCenter([data[i].lng, data[i].lat]); //设置地图中心点
|
||||||
|
map.setZoom(18); //设置缩放等级
|
||||||
|
}
|
||||||
|
|
||||||
|
//街道图层
|
||||||
|
function setRoadNetLayer() {
|
||||||
|
map.remove(satelliteLayer);
|
||||||
|
map.add(roadNetLayer);
|
||||||
|
}
|
||||||
|
//卫星图层
|
||||||
|
function setSatelliteLayer() {
|
||||||
|
map.remove(roadNetLayer);
|
||||||
|
map.add(satelliteLayer);
|
||||||
|
}
|
||||||
|
//混合图层
|
||||||
|
function setMixLayer() {
|
||||||
|
map.add(roadNetLayer);
|
||||||
|
map.add(satelliteLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Vendored
+1
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
@@ -0,0 +1,198 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<title>openpilot</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.onload = function() {
|
||||||
|
input_text = localStorage.getItem("dongleId");
|
||||||
|
document.forms["formDongleId"]["input_text"].value = input_text;
|
||||||
|
|
||||||
|
strSec = localStorage.getItem("operationTime")
|
||||||
|
now = Math.floor(Date.now() / 1000)
|
||||||
|
if (now - Number(strSec) < 180)
|
||||||
|
{
|
||||||
|
document.forms["formDongleId"].style.display="none";
|
||||||
|
document.getElementById('btnlist').style.display="";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="css/form.min.css"/>
|
||||||
|
<style>
|
||||||
|
.button {
|
||||||
|
background-color: #4CAF50; /* Green */
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
padding: 25px 40px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 4px 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-transition-duration: 0.4s; /* Safari */
|
||||||
|
transition-duration: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button1 {
|
||||||
|
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button2:hover {
|
||||||
|
box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="subjects">
|
||||||
|
<div class="form_ctrl page_head" id="1" title="openpilot">
|
||||||
|
<h2>openpilot online</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form name="formDongleId" action="/nav/" onsubmit="return login()" method="post">
|
||||||
|
<div class="form_ctrl page_text" id="2" title="">
|
||||||
|
<p>openpilot is an open source advanced driver assistance system that works on 250+ car models of Toyota, Hyundai, Honda, and many other brands.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div name="div_input_text" class="form_ctrl input_text" id="dongleid" title="dongleid">
|
||||||
|
<label class="ctrl_title">Dongle ID</label>
|
||||||
|
<input type="text" id="dongleid_value" name="input_text" value="" placeholder="Please input dongle ID.Check your c3 device.">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form_ctrl form_submit" id="12" title="Login private openpilot server.">
|
||||||
|
<label class="ctrl_title">Login private openpilot server.</label>
|
||||||
|
<input type="submit" value="Submit" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="logo">
|
||||||
|
<div style="margin-bottom: 5px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function login() {
|
||||||
|
var input_text = document.forms["formDongleId"]["input_text"].value;
|
||||||
|
uri = '/check/'+input_text
|
||||||
|
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', uri, true);
|
||||||
|
xhr.onload = function() {
|
||||||
|
console.log(this.status);
|
||||||
|
if (this.status === 200) {
|
||||||
|
console.log(this.responseText);
|
||||||
|
if (this.responseText==="true")
|
||||||
|
{
|
||||||
|
localStorage.setItem("dongleId", input_text);
|
||||||
|
document.forms["formDongleId"].style.display="none";
|
||||||
|
document.getElementById('btnlist').style.display="";
|
||||||
|
}else {
|
||||||
|
alert("Dongle Id error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showNavigation() {
|
||||||
|
dongleId = localStorage.getItem("dongleId");
|
||||||
|
document.getElementById('nav_home').style.display="";
|
||||||
|
document.getElementById('nav_home').action = "/nav/"+ dongleId + "/"
|
||||||
|
document.getElementById('nav_work').style.display="";
|
||||||
|
document.getElementById('nav_work').action = "/nav/"+ dongleId + "/"
|
||||||
|
document.getElementById('set_destination').style.display="";
|
||||||
|
document.getElementById('set_destination').action = "/nav/"+ dongleId + "/"
|
||||||
|
//document.getElementById('btnlist').style.display="none";
|
||||||
|
recordOperationTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showlog() {
|
||||||
|
dongleId = localStorage.getItem("dongleId");
|
||||||
|
document.getElementById('nav_home').style.display="none";
|
||||||
|
document.getElementById('nav_work').style.display="none";
|
||||||
|
document.getElementById('set_destination').style.display="none";
|
||||||
|
|
||||||
|
url = "/op/"+ dongleId + "/"
|
||||||
|
window.location = url;
|
||||||
|
//document.getElementById('btnlist').style.display="none";
|
||||||
|
recordOperationTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAmap(){
|
||||||
|
url = "/static/amap.html"
|
||||||
|
window.location = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showVOD(){
|
||||||
|
url = "/static/vod.html"
|
||||||
|
window.location = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function recordOperationTime(){
|
||||||
|
strSec = Math.floor(Date.now() / 1000)
|
||||||
|
localStorage.setItem("operationTime", strSec)
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form id="nav_home" action="/nav/" method="post" style="display: none;">
|
||||||
|
<div class="form_ctrl input_text">
|
||||||
|
<label class="ctrl_title">Home Address</label>
|
||||||
|
<input type="text" name="nav_home" placeholder="Please input home address."/>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div class="form_ctrl form_submit" id="12" title="Input your home address.">
|
||||||
|
<input type="submit" value="submit" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form id="nav_work" action="/nav/" method="post" style="display: none;">
|
||||||
|
<div class="form_ctrl input_text">
|
||||||
|
<label class="ctrl_title">Work Address</label>
|
||||||
|
<input type="text" name="nav_work" placeholder="Please input work address." />
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div class="form_ctrl form_submit" title="Input your work address.">
|
||||||
|
<input type="submit" value="submit" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form id="set_destination" action="/nav/" method="post" style="display: none;">
|
||||||
|
<div class="form_ctrl input_text">
|
||||||
|
<label class="ctrl_title">Set Destination</label>
|
||||||
|
<input type="text" name="set_destination" placeholder="Please input destination."/>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div class="form_ctrl form_submit">
|
||||||
|
<input type="submit" value="submit" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="btnlist" style="display: none;text-align:center" title="" >
|
||||||
|
</br></br></br></br>
|
||||||
|
<input type="button" value="Vod" class="button button1" onclick = "showVOD();" />
|
||||||
|
</br></br>
|
||||||
|
<input type="button" value="Log" class="button button1" onclick = "showlog();" />
|
||||||
|
|
||||||
|
<input type="button" value="AMap" class="button button1" onclick = "showAmap();" />
|
||||||
|
|
||||||
|
<input type="button" value="Nav" class="button button1" onclick = "showNavigation();" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</br></br></br></br>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
+212
@@ -0,0 +1,212 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<!--Happy children's day 2024-05-30-->
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://vjs.zencdn.net/7.14.3/video-js.css" rel="stylesheet">
|
||||||
|
<script src="https://vjs.zencdn.net/7.14.3/video.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls-container {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
max-width: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#m3u8Input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 12px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 12px 20px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0 5px 5px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<title>openpilot-online</title>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function isWeChat(){
|
||||||
|
//window.navigator.userAgent属性包含了浏览器类型、版本、操作系统类型、浏览器引擎类型等信息,这个属性可以用来判断浏览器类型
|
||||||
|
var ua = window.navigator.userAgent.toLowerCase();
|
||||||
|
//通过正则表达式匹配ua中是否含有MicroMessenger字符串
|
||||||
|
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
console.log(window.navigator.platform);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="video-frame" class="video-container"></div>
|
||||||
|
<div>
|
||||||
|
<input type='button' style="width:100px; height:50px;" onclick='playVideo(lastUrl);' value='Play'>
|
||||||
|
<input type='button' style="width:100px; height:50px;" onclick='window.location="/static/index.html";' value='Return'>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
init = false;
|
||||||
|
lastUrl = "";
|
||||||
|
var arr_url;
|
||||||
|
|
||||||
|
dongleid = localStorage.getItem("dongleId");
|
||||||
|
uri = "/vod/"+dongleid
|
||||||
|
|
||||||
|
getVodUrl();
|
||||||
|
var int=self.setInterval("clock()",10000);
|
||||||
|
function clock()
|
||||||
|
{
|
||||||
|
getVodUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVodUrl() {
|
||||||
|
console.log("getVodUrl");
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', uri, true);
|
||||||
|
xhr.onload = function() {
|
||||||
|
if (this.status === 200) {
|
||||||
|
let arr = this.responseText.split(',');
|
||||||
|
console.log(arr)
|
||||||
|
if (arr.length == 0){
|
||||||
|
alert("No video.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
arr_url = arr;
|
||||||
|
|
||||||
|
if (!init) {
|
||||||
|
vodUrl = findUrl();
|
||||||
|
if (vodUrl != "") {
|
||||||
|
content = '<video onended="videoEnded()" id="m3u8Player" class="video-js vjs-default-skin" controls width="360" height="640">\
|
||||||
|
<source id="src_m3u8" src="'+vodUrl+ '" type="application/x-mpegURL">\
|
||||||
|
</video>'
|
||||||
|
console.log(content);
|
||||||
|
document.getElementById('video-frame').innerHTML = content;
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function findUrl() {
|
||||||
|
var arr = arr_url;
|
||||||
|
idx = 99;
|
||||||
|
for (i=0; i < arr.length; i++) {
|
||||||
|
if (lastUrl == arr[i]) {
|
||||||
|
idx = i;
|
||||||
|
console.log(arr[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx != 0){
|
||||||
|
if (idx==99) {
|
||||||
|
idx = arr.length - 1;
|
||||||
|
} else {
|
||||||
|
idx = idx -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastUrl = arr[idx];
|
||||||
|
return lastUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function videoEnded(){
|
||||||
|
console.log("The End.")
|
||||||
|
|
||||||
|
vodUrl = findUrl();
|
||||||
|
if (vodUrl == "") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(vodUrl);
|
||||||
|
|
||||||
|
src = vodUrl;
|
||||||
|
newSource = {
|
||||||
|
src: vodUrl,
|
||||||
|
type: 'application/x-mpegURL'
|
||||||
|
};
|
||||||
|
|
||||||
|
const videoPlayer = videojs('m3u8Player');
|
||||||
|
videoPlayer.src(newSource);
|
||||||
|
videoPlayer.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
function playVideo(src) {
|
||||||
|
console.log(src);
|
||||||
|
input = document.getElementById('src_m3u8').src
|
||||||
|
document.getElementById('video-frame').style.display="";
|
||||||
|
const videoPlayer = videojs('m3u8Player');
|
||||||
|
|
||||||
|
newSource = {
|
||||||
|
src: src,
|
||||||
|
type: 'application/x-mpegURL'
|
||||||
|
};
|
||||||
|
|
||||||
|
videoPlayer.src(newSource);
|
||||||
|
|
||||||
|
videoPlayer.ready(function(){
|
||||||
|
videoPlayer.on('loadedmetadata', function(){
|
||||||
|
console.log("videoPlayer duration:",videoPlayer.duration());
|
||||||
|
videoPlayer.error(null);
|
||||||
|
})});
|
||||||
|
|
||||||
|
videoPlayer.play();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user