1330 lines
39 KiB
HTML
1330 lines
39 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="divport" content="width=device-width, initial-scale=1">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||
<title>浇灌</title>
|
||
<link rel="stylesheet" href="res/fonts/iconfont.css" />
|
||
<!-- 引入Leaflet CSS -->
|
||
<link rel="stylesheet" href="res/leaflet.css" />
|
||
</head>
|
||
<body style="margin: 0;">
|
||
<div class="main">
|
||
<div id="map">
|
||
<!-- 搜索 -->
|
||
<div class="search-box" onclick="event.stopPropagation();PageHandle.openMapSearch(true)">
|
||
<div class="search">
|
||
<i class="iconfont icon-sousuo"></i>
|
||
<span>查找地点</span>
|
||
<div class="text">搜索</div>
|
||
</div>
|
||
</div>
|
||
<!-- 图层 -->
|
||
<div class="above">
|
||
<div onclick="event.stopPropagation();PageHandle.openSwitchLayer(true)">
|
||
<i class="iconfont icon-tuceng">
|
||
<span>图层</span>
|
||
</i>
|
||
</div>
|
||
</div>
|
||
<!-- 工具 -->
|
||
<div class="below">
|
||
<div onclick="event.stopPropagation();PageHandle.toCenterPoint()">
|
||
<i class="iconfont icon-dingwei"></i>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.navigation() ">
|
||
<svg class="icon" aria-hidden="true">
|
||
<use xlink:href="#icon-luxian"></use>
|
||
</svg>
|
||
<span>路线</span>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerTool(this)">
|
||
<span>圆形</span>
|
||
<div class="markerTool paddle hide" name="circle">
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,1)">
|
||
<div class="btn">开始</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,2)">
|
||
<div class="btn">删除</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this)">
|
||
<div class="btn">结束</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerTool(this)">
|
||
<span>矩形</span>
|
||
<div class="markerTool paddle hide" name="rectangle">
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,1)">
|
||
<div class="btn">开始</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,2)">
|
||
<div class="btn">删除</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this)">
|
||
<div class="btn">结束</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerTool(this)">
|
||
<span>多边形</span>
|
||
<div class="markerTool paddle hide" name="polygon">
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,1)">
|
||
<div class="btn">开始</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,2)">
|
||
<div class="btn">删除</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this)">
|
||
<div class="btn">结束</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerTool(this)">
|
||
<span>线</span>
|
||
<div class="markerTool paddle hide" name="polyline">
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,1)">
|
||
<div class="btn">开始</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,2)">
|
||
<div class="btn">删除</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this)">
|
||
<div class="btn">结束</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerTool(this)">
|
||
<span>测距</span>
|
||
<div class="markerTool paddle hide" name="ranging">
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,1)">
|
||
<div class="btn">开始</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this,2)">
|
||
<div class="btn">删除</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.markerToolHandle(this)">
|
||
<div class="btn">结束</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div onclick="event.stopPropagation();PageHandle.deleteDrawing(this)" name="delete">
|
||
<span>删除</span>
|
||
</div>
|
||
</div>
|
||
<!-- 搜索弹出 -->
|
||
<div class="pop-up hide" id="mapsearch">
|
||
<div class="search">
|
||
<i class="iconfont icon-xiazai6"
|
||
onclick="event.stopPropagation();PageHandle.openMapSearch(false)"></i>
|
||
<input id="search-input" class="input" type="text" placeholder="查找地点" />
|
||
<div class="text" onclick="PageHandle.mapSearch()">搜索</div>
|
||
</div>
|
||
<div class="list">
|
||
<ul>
|
||
<li>
|
||
<i class="iconfont icon-address"></i>
|
||
<span>西安市</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<!-- 图层弹出 -->
|
||
<div class="switchLayer LAYER hide">
|
||
<div class="title">
|
||
<span>图层</span>
|
||
<div onclick="event.stopPropagation();PageHandle.openSwitchLayer(false)">
|
||
<i class="iconfont icon-guanbi"></i>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="layer-item" name="vec_w"
|
||
onclick="event.stopPropagation();PageHandle.switchLayer(this)">
|
||
<div class="img"><img src="../html/res/images/dt.jpg" /></div>
|
||
标准地图
|
||
</div>
|
||
<div class="layer-item" name="ter_w"
|
||
onclick="event.stopPropagation();PageHandle.switchLayer(this)">
|
||
<div class="img"><img src="../html/res/images/dx.jpg" /></div>
|
||
地形图
|
||
</div>
|
||
<div class="layer-item" name="img_w"
|
||
onclick="event.stopPropagation();PageHandle.switchLayer(this)">
|
||
<div class="img"><img src="../html/res/images/wx.jpg" /></div>
|
||
卫星图
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- uni 的 SDK -->
|
||
<!-- <script type="text/javascript" src="https://gitcode.net/dcloud/uni-app/-/raw/dev/dist/uni.webview.1.5.6.js"></script> -->
|
||
<script type="text/javascript" src="res/index.js"></script>
|
||
<!-- 引入Leaflet JS -->
|
||
<!-- <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
|
||
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" crossorigin=""></script> -->
|
||
<script type="text/javascript" src="res/leaflet.js"></script>
|
||
<!-- 其他 的 SDK -->
|
||
<script type="text/javascript" src="res/jquery.min.js"></script>
|
||
<script type="text/javascript" src="res/axios.min.js"></script>
|
||
<script src="res/fonts/iconfont.js"></script>
|
||
|
||
<script type="text/javascript">
|
||
let appType = null;
|
||
//等待uniapp js加载完成
|
||
document.addEventListener('UniAppJSBridgeReady', function() {
|
||
uni.webView.getEnv(function(res) {
|
||
console.log('当前环境:' + JSON.stringify(res));
|
||
if (res["h5"]) {
|
||
$(".search-box").css('bottom', '1px')
|
||
}
|
||
postToastToApp("测试提示消息");
|
||
postMessageToApp('onLoad');
|
||
});
|
||
});
|
||
|
||
/********************************** 向App发送消息 **********************************/
|
||
//向App发送消息
|
||
function postMessageToApp(action, data = null) {
|
||
uni.postMessage({
|
||
data: {
|
||
action: action,
|
||
data: data
|
||
}
|
||
});
|
||
}
|
||
//向App发送toast
|
||
function postToastToApp(msg) {
|
||
postMessageToApp('uni-toast', msg);
|
||
}
|
||
//向App发送确认提示框
|
||
function postModelToApp(content, title = '提示', data = null) {
|
||
postMessageToApp('uni-modal', {
|
||
title: title,
|
||
content: content,
|
||
data: data,
|
||
});
|
||
}
|
||
|
||
/********************************** 接受App发送消息 **********************************/
|
||
//监听uniapp请求WebView的方法
|
||
window.VUEPageMsg = function(res) {
|
||
postMessage(res);
|
||
}
|
||
//页面接受参数处理
|
||
function postMessage(res) {
|
||
// console.error("webview收到的消息:", res);
|
||
// console.error("webview收到的消息:", JSON.stringify(res));
|
||
|
||
switch (res.action) {
|
||
case "loadMap":
|
||
MapUtil.initMap(res.data.key, res.data.centerPoint);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/********************************** 页面操作 **********************************/
|
||
var PageHandle = {
|
||
openMapSearch(type) { //显示搜索界面
|
||
MapUtil.closeAllPainting();
|
||
$("#search-input").val("");
|
||
$("#search-input").off('blur')
|
||
if (type) {
|
||
$("#mapsearch").removeClass("hide").addClass("show");
|
||
$("#search-input").focus();
|
||
$("#search-input").on('blur',function(){
|
||
PageHandle.mapSearch();
|
||
});
|
||
} else {
|
||
$("#mapsearch").removeClass("show").addClass("hide");
|
||
}
|
||
$("#mapsearch").find('.list').empty();
|
||
},
|
||
mapSearch(item) { //搜索
|
||
const value = $("#search-input").val();
|
||
if (value == null || value == '') {
|
||
return;
|
||
}
|
||
const that = this;
|
||
if (item && item.address && item.lonlat) {
|
||
that.openMapSearch(false);
|
||
const [lat, lng] = item.lonlat.split(",").map(Number);
|
||
MapUtil.toCenterPoint(lng, lat);
|
||
MapUtil.setCenterPoint(lng, lat);
|
||
return;
|
||
}
|
||
let params = {
|
||
keyWord: value, //搜索的关键字
|
||
mapBound: "47.95898437500239,7.759699085623154,162.04101562500443,56.875842480765385",
|
||
// mapBound: "73.37,21.13,135.25,53.65", //查询的地图范围
|
||
level: 3, //目前查询的级别 String 必填 1-18级
|
||
queryType: 1, //搜索类型 String 必填 1:普通搜索(含地铁公交) 7:地名搜索
|
||
start: 0, //返回结果起始位(用于分页和缓存)默认0
|
||
count: 10, //返回的结果数量(用于分页和缓存)
|
||
};
|
||
if (item && item.value) {
|
||
params.specify = item.value;
|
||
}
|
||
const searchUrl = `https://api.tianditu.gov.cn/v2/search?` +
|
||
`postStr=${encodeURIComponent(JSON.stringify(params))}` +
|
||
`&type=query` +
|
||
`&tk=${MapUtil.key}`;
|
||
axios.get(searchUrl).then(function(response) {
|
||
if (response.status === 200) {
|
||
that.handleSearchResponse(response.data);
|
||
}
|
||
}).catch(function(error) {
|
||
postToastToApp('搜索出错:', error.response ? error.response.data : error.message);
|
||
});
|
||
},
|
||
handleSearchResponse(res) { //搜索结果处理
|
||
if (res.resultType !== 1 && res.resultType !== 2 && res.resultType !== 3) {
|
||
$("#mapsearch").find('.list').remove();
|
||
return;
|
||
}
|
||
let cityOptions = [];
|
||
switch (res.resultType) {
|
||
case 1:
|
||
cityOptions = res.pois.map(v => ({
|
||
label: v.name,
|
||
value: v.nid,
|
||
address: v.address,
|
||
lonlat: v.lonlat,
|
||
type: 1
|
||
}));
|
||
break;
|
||
case 2:
|
||
cityOptions = res.statistics.allAdmins.map(v => ({
|
||
label: v.adminName,
|
||
value: v.adminCode,
|
||
count: v.count,
|
||
lonlat: v.lonlat,
|
||
type: 2,
|
||
isleaf: v.isleaf
|
||
}));
|
||
break;
|
||
case 3:
|
||
this.openMapSearch(false);
|
||
const [lat, lng] = res.area.lonlat.split(",").map(Number);
|
||
MapUtil.toCenterPoint(lng, lat);
|
||
MapUtil.setCenterPoint(lng, lat);
|
||
break;
|
||
}
|
||
if (cityOptions.length > 0) {
|
||
const that = this;
|
||
let $html = $("<ul></ul>")
|
||
cityOptions.forEach(item => {
|
||
var $li = $(`<li><i class="iconfont icon-address"></i><span>${item.label}</span></li>`);
|
||
$li.click(function() {
|
||
that.mapSearch(item);
|
||
})
|
||
$html.append($li);
|
||
});
|
||
$("#mapsearch").find('.list').empty();
|
||
$("#mapsearch").find('.list').append($html);
|
||
}
|
||
},
|
||
openSwitchLayer(type) { //打开图层选择
|
||
if (type) {
|
||
$(".switchLayer").removeClass("hide").addClass("show");
|
||
$(".layer-item").each((index, item) => {
|
||
if ($(item).attr("name") == MapUtil.selectMapType) {
|
||
$(item).addClass('click')
|
||
} else {
|
||
$(item).removeClass('click')
|
||
}
|
||
});
|
||
} else {
|
||
$(".switchLayer").removeClass("show").addClass("hide");
|
||
}
|
||
},
|
||
switchLayer(dom) { //选择图层
|
||
const key = $(dom).attr("name");
|
||
$(".layer-item").each((index, item) => {
|
||
if ($(item).attr("name") == key) {
|
||
$(item).addClass('click')
|
||
} else {
|
||
$(item).removeClass('click')
|
||
}
|
||
});
|
||
MapUtil.switchLayer(key);
|
||
this.openSwitchLayer(false);
|
||
},
|
||
toCenterPoint(lng = null, lat = null) { //中心点
|
||
if (lng && lat) {
|
||
MapUtil.toCenterPoint(lng, lat);
|
||
} else {
|
||
MapUtil.toCenterPoint();
|
||
}
|
||
},
|
||
navigation() { //导航
|
||
postMessageToApp('map-navigation', JSON.stringify(MapUtil.centerPoint));
|
||
},
|
||
markerTool(dom) { //绘图工具
|
||
// 阻止事件冒泡
|
||
if ($(dom).find(".paddle").hasClass('show')) {
|
||
$(dom).find(".paddle").removeClass('show').addClass('hide');
|
||
$(dom).parent().removeClass('show').addClass('hide');
|
||
} else {
|
||
$(".markerTool").removeClass('show').addClass('hide');
|
||
$(dom).find(".paddle").removeClass('hide').addClass('show');
|
||
}
|
||
},
|
||
markerToolHandle(dom, type) { //绘制工具操作类型
|
||
$(dom).parent().removeClass('show').addClass('hide');
|
||
const key = $(dom).parent().attr("name");
|
||
MapUtil.closeAllPainting(key);
|
||
switch (key) {
|
||
case "circle": //圆形工具
|
||
MapUtil.circle(type);
|
||
break;
|
||
case "rectangle": //矩形工具
|
||
MapUtil.rectangle(type);
|
||
break;
|
||
case "polygon": //多边形工具
|
||
MapUtil.polygon(type);
|
||
break;
|
||
case "polyline": //线工具
|
||
MapUtil.polyline(type);
|
||
break;
|
||
case "ranging": //测距
|
||
MapUtil.ranging(type);
|
||
break;
|
||
}
|
||
},
|
||
deleteDrawing(dom) { //删除状态
|
||
MapUtil.closeAllPainting();
|
||
if ($(dom).attr('name') == 'delete') {
|
||
//删除模式
|
||
$(dom).attr('name', "view")
|
||
$(dom).css('background', "red");
|
||
MapUtil.deleteDrawing = true;
|
||
} else {
|
||
//查看模式
|
||
$(dom).attr('name', "delete")
|
||
$(dom).css('background', "#fff");
|
||
MapUtil.deleteDrawing = false;
|
||
}
|
||
},
|
||
}
|
||
|
||
|
||
/********************************** 地图操作 **********************************/
|
||
var MapUtil = {
|
||
key: null, //天地图密钥
|
||
map: null, //地图对象
|
||
mapType: {
|
||
vec_w: null, //矢量地图
|
||
img_w: null, //影像地图
|
||
ter_w: null, //地形图
|
||
labelLayer: null, //矢量地名标注
|
||
}, //地图类型
|
||
selectMapType: "img_w",
|
||
centerPoint: null, //中心点
|
||
centerPointMarker: null, //中心点
|
||
deleteDrawing: false, //删除模式
|
||
drawing: { //是否在绘制覆盖物
|
||
circle: null, //圆形
|
||
rectangle: null, //矩形
|
||
polygon: null, //多边形
|
||
polyline: null, //线
|
||
ranging: null, //测距
|
||
},
|
||
layers: { //layers对象
|
||
circle: [], //圆形
|
||
rectangle: [], //矩形
|
||
polygon: [], //多边形
|
||
polyline: [], //线
|
||
ranging: [], //测距
|
||
},
|
||
initMap(key, centerPoint) { //初始化地图
|
||
const that = this;
|
||
that.key = key;
|
||
that.centerPoint = {
|
||
lat: centerPoint[0],
|
||
lng: centerPoint[1],
|
||
};
|
||
that.mapType = {
|
||
vec_w: new L.tileLayer(
|
||
`http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${key}`, {
|
||
attribution: '矢量地图'
|
||
}),
|
||
img_w: new L.tileLayer(
|
||
`http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=${key}`, {
|
||
attribution: '影像地图'
|
||
}),
|
||
ter_w: new L.tileLayer(
|
||
`http://t0.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=${key}`, {
|
||
attribution: '地形图'
|
||
}),
|
||
labelLayer: new L.tileLayer(
|
||
`http://t0.tianditu.gov.cn/cva_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cva&tileMatrixSet=w&TileMatrix={z}&TileRow={y}&TileCol={x}&style=default&format=tiles&tk=${key}`, {
|
||
attribution: '矢量地名标注'
|
||
}),
|
||
};
|
||
var normal = L.layerGroup([that.mapType[that.selectMapType], that.mapType.labelLayer])
|
||
|
||
const map = L.map('map', {
|
||
// crs: L.CRS.EPSG3857,
|
||
// center: [34.07148, 108.84076], //中心点
|
||
center: [that.centerPoint.lng, that.centerPoint.lat], //中心点
|
||
layers: normal,
|
||
zoom: 5, //默认层级
|
||
minZoom: 2, //最小层级
|
||
maxZoom: 18, //最大层级
|
||
zoomControl: true, //是否将 zoom 缩放控件添加到地图中。
|
||
doubleClickZoom: false, //图是否可以通过双击来放大
|
||
dragging: true, //地图是否可以通过 mouse/touch 进行拖动。
|
||
attributionControl: false, //是否将 attribution 版权控件添加到地图中。
|
||
tap: true // 确保此选项为 true 或者不指定,因为默认值是 true
|
||
});
|
||
|
||
// 如果需要监听缩放过程中的变化,可以使用 'zoom' 事件
|
||
map.on('zoom', function() {
|
||
that.onZoomend();
|
||
});
|
||
|
||
that.map = map;
|
||
that.setCenterPoint(that.centerPoint.lng, that.centerPoint.lat);
|
||
},
|
||
onZoomend() { //缩放监听
|
||
var currentZoomLevel = this.map.getZoom();
|
||
console.log("正在缩放,当前缩放级别: " + currentZoomLevel);
|
||
},
|
||
setZoom(type) { //设置层级
|
||
if (type > 0) {
|
||
this.map.zoomIn(); //放大
|
||
} else {
|
||
this.map.zoomOut(); //缩小
|
||
}
|
||
},
|
||
setDragging(dragging = true) {
|
||
if (dragging) {
|
||
this.map.dragging.enable() //启用拖拽
|
||
} else {
|
||
this.map.dragging.disable(); //禁用拖拽
|
||
}
|
||
// postToastToApp(dragging ? "启用拖拽" : "禁用拖拽");
|
||
},
|
||
switchLayer(key) { //切换地图
|
||
const that = this;
|
||
|
||
// 移除当前所有图层
|
||
that.map.eachLayer(function(layer) {
|
||
if (layer instanceof L.TileLayer) {
|
||
that.map.removeLayer(layer);
|
||
}
|
||
});
|
||
// 添加新的图层
|
||
that.mapType[key].addTo(that.map);
|
||
that.mapType["labelLayer"].addTo(that.map);
|
||
that.selectMapType = key;
|
||
},
|
||
setCenterPoint(lng, lat) {
|
||
// 生成标记点
|
||
if (this.centerPointMarker) {
|
||
this.centerPointMarker.setLatLng([lng, lat]);
|
||
} else {
|
||
// 定义图标属性
|
||
let markerIcon = L.icon({
|
||
iconUrl: "https://unpkg.com/leaflet@1.9.2/dist/images/marker-icon-2x.png",
|
||
iconSize: [20, 34], //图标图像的尺寸,单位是像素。
|
||
iconAnchor: [7,
|
||
9
|
||
], //图标 "tip" 的坐标(相对于其左上角)。图标将被对齐,使该点位于标记的地理位置。如果指定了尺寸,默认为居中,也可以在CSS中设置负的边距。
|
||
popupAnchor: [-3, -3], //弹出窗口(popup)的坐标,相对于图标锚点而言,将从该点打开。
|
||
});
|
||
this.centerPointMarker = L.marker([lng, lat], {
|
||
icon: markerIcon,
|
||
}).addTo(this.map).bindTooltip("中心点").openTooltip();
|
||
}
|
||
},
|
||
toCenterPoint(lng = null, lat = null) { //中心点
|
||
this.removeEditLayer();
|
||
if (!lng && !lat) {
|
||
lng = this.centerPoint.lng;
|
||
lat = this.centerPoint.lat;
|
||
}
|
||
var currentZoomLevel = this.map.getZoom();
|
||
if (currentZoomLevel > 10) {
|
||
this.map.setView([lng, lat], currentZoomLevel);
|
||
|
||
// this.map.panTo([lng, lat]);
|
||
// this.map.setZoom(18);
|
||
// this.map.flyTo([lng, lat], currentZoomLevel);
|
||
} else {
|
||
this.map.setZoomAround([lng, lat], 18);
|
||
this.map.flyTo([lng, lat], 18);
|
||
}
|
||
},
|
||
openPopup() { //弹窗
|
||
var popup = L.popup()
|
||
.setLatLng([this.centerPoint.lng, this.centerPoint.lat])
|
||
.setContent('<p>弹窗<br />这是中心点</p>')
|
||
.openOn(this.map);
|
||
},
|
||
removeEditLayer() {
|
||
this.map.off('click');
|
||
this.map.off('mousedown touchstart');
|
||
this.map.off('mouseup touchmove');
|
||
this.map.off('mousemove touchend');
|
||
this.setDragging(true);
|
||
for (let key in this.drawing) {
|
||
this.drawing[key] = null;
|
||
}
|
||
},
|
||
closeAllPainting(key) { //关闭所有绘制工具
|
||
for (let _key in this.drawing) {
|
||
if (key != _key) {
|
||
switch (_key) {
|
||
case "circle": //圆形工具
|
||
this.circle();
|
||
break;
|
||
case "rectangle": //矩形工具
|
||
this.rectangle();
|
||
break;
|
||
case "polygon": //多边形工具
|
||
this.polygon();
|
||
break;
|
||
case "polyline": //线工具
|
||
this.polyline();
|
||
break;
|
||
case "ranging": //测距
|
||
this.ranging();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
circle(type) { //圆形
|
||
const that = this;
|
||
if (type == 1) { //开始
|
||
that.setDragging(false);
|
||
that.drawing.circle = {
|
||
slatlng: null,
|
||
pop: null,
|
||
item: null,
|
||
}
|
||
|
||
that.map.off('click');
|
||
that.map.on('click', (e) => {
|
||
if (that.drawing.circle.slatlng) {
|
||
//计算半径
|
||
const radius = L.latLng(that.drawing.circle.slatlng).distanceTo(e.latlng);
|
||
if (that.drawing.circle.item) {
|
||
that.drawing.circle.item.setRadius(radius);
|
||
// 存储起来方便删除
|
||
that.layers.circle[that.layers.circle.length - 1] = that.drawing.circle.item;
|
||
} else {
|
||
// that.drawing.circle.item = L.circle()
|
||
// .setLatLng(that.drawing.circle.slatlng)
|
||
// .setRadius(radius);
|
||
that.drawing.circle.item = L.circle(that.drawing.circle.slatlng, {
|
||
radius: radius,
|
||
color: 'red',
|
||
fillColor: '#f03'
|
||
});
|
||
// 添加点击事件监听器
|
||
that.drawing.circle.item.on('click', function(e) {
|
||
if (that.deleteDrawing) {
|
||
that.map.removeLayer(e.target);
|
||
|
||
let index = that.layers.circle.findIndex(x => x
|
||
._leaflet_id === e.target._leaflet_id);
|
||
if (index !== -1) {
|
||
that.layers.circle.splice(index, 1); // 移除一个元素
|
||
}
|
||
}
|
||
});
|
||
that.map.addLayer(that.drawing.circle.item);
|
||
// 存储起来方便删除
|
||
that.layers.circle.push(that.drawing.circle.item);
|
||
}
|
||
//删除中心popup
|
||
if (that.drawing.circle.pop) {
|
||
that.map.removeLayer(that.drawing.circle.pop);
|
||
that.drawing.circle.pop = null;
|
||
}
|
||
} else {
|
||
//创建中心popup
|
||
that.drawing.circle.pop = L.popup()
|
||
.setLatLng(e.latlng)
|
||
.setContent('<p>请确定半径</p>');
|
||
that.map.addLayer(that.drawing.circle.pop);
|
||
//记录中心点
|
||
that.drawing.circle.slatlng = e.latlng;
|
||
}
|
||
});
|
||
} else if (type == 2) { //删除
|
||
that.drawing.circle.slatlng = null;
|
||
if (that.drawing.circle.pop) {
|
||
that.map.removeLayer(that.drawing.circle.pop);
|
||
that.drawing.circle.pop = null;
|
||
} else {
|
||
if (that.layers.circle.length) {
|
||
let layer = that.layers.circle.pop(); // 移除并返回最后一项
|
||
that.map.removeLayer(layer);
|
||
}
|
||
}
|
||
} else { //结束
|
||
if (!that.drawing.circle) {
|
||
return;
|
||
}
|
||
that.drawing.circle.slatlng = null;
|
||
if (that.drawing.circle.pop) {
|
||
that.map.removeLayer(that.drawing.circle.pop);
|
||
that.drawing.circle.pop = null;
|
||
}
|
||
that.drawing.circle.item = null;
|
||
that.setDragging(true);
|
||
that.map.off('click');
|
||
}
|
||
},
|
||
rectangle(type) { //矩形
|
||
const that = this;
|
||
if (type == 1) { //开始
|
||
that.setDragging(false);
|
||
that.drawing.rectangle = {
|
||
bounds: [],
|
||
pop: null,
|
||
item: null,
|
||
}
|
||
|
||
that.map.off('click');
|
||
that.map.on('click', (e) => {
|
||
//记录坐标
|
||
that.drawing.rectangle.bounds.push(e.latlng);
|
||
if (that.drawing.rectangle.bounds.length == 1) {
|
||
//创建popup
|
||
that.drawing.rectangle.pop = L.popup()
|
||
.setLatLng(e.latlng)
|
||
.setContent('<p>起点</p>');
|
||
that.map.addLayer(that.drawing.rectangle.pop);
|
||
} else if (that.drawing.rectangle.bounds.length == 2) {
|
||
that.drawing.rectangle.item = L.rectangle(that.drawing.rectangle.bounds, {
|
||
color: "#ff7800",
|
||
weight: 1
|
||
});
|
||
// 添加点击事件监听器
|
||
that.drawing.rectangle.item.on('click', function(e) {
|
||
if (that.deleteDrawing) {
|
||
that.map.removeLayer(e.target);
|
||
|
||
let index = that.layers.rectangle.findIndex(x => x
|
||
._leaflet_id === e.target._leaflet_id);
|
||
if (index !== -1) {
|
||
that.layers.rectangle.splice(index, 1); // 移除一个元素
|
||
}
|
||
}
|
||
});
|
||
that.map.addLayer(that.drawing.rectangle.item);
|
||
// 存储起来方便删除
|
||
that.layers.rectangle.push(that.drawing.rectangle.item);
|
||
//删除popup
|
||
that.map.removeLayer(that.drawing.rectangle.pop);
|
||
that.drawing.rectangle.pop = null;
|
||
} else {
|
||
that.drawing.rectangle.item.setBounds(that.drawing.rectangle.bounds);
|
||
let index = that.layers.rectangle.length - 1;
|
||
that.layers.rectangle[index] = that.drawing.rectangle.item
|
||
}
|
||
});
|
||
} else if (type == 2) { //删除
|
||
that.drawing.rectangle.bounds = [];
|
||
if (that.drawing.rectangle.pop) {
|
||
that.map.removeLayer(that.drawing.rectangle.pop);
|
||
that.drawing.rectangle.pop = null;
|
||
} else {
|
||
if (that.layers.rectangle.length) {
|
||
let layer = that.layers.rectangle.pop(); // 移除并返回最后一项
|
||
that.map.removeLayer(layer);
|
||
}
|
||
}
|
||
} else { //结束
|
||
if (!that.drawing.rectangle) {
|
||
return;
|
||
}
|
||
that.drawing.rectangle.bounds = [];
|
||
if (that.drawing.rectangle.pop) {
|
||
that.map.removeLayer(that.drawing.rectangle.pop);
|
||
that.drawing.rectangle.pop = null;
|
||
}
|
||
that.drawing.rectangle.item = null;
|
||
that.setDragging(true);
|
||
that.map.off('click');
|
||
}
|
||
},
|
||
polygon(type) { //多边形
|
||
const that = this;
|
||
if (type == 1) { //开始
|
||
that.setDragging(false);
|
||
that.drawing.polygon = {
|
||
latlngs: [],
|
||
pop: null,
|
||
item: null,
|
||
}
|
||
|
||
that.map.off('click');
|
||
that.map.on('click', (e) => {
|
||
//记录坐标
|
||
that.drawing.polygon.latlngs.push(e.latlng);
|
||
if (that.drawing.polygon.latlngs.length == 1) {
|
||
//创建popup
|
||
that.drawing.polygon.pop = L.popup()
|
||
.setLatLng(e.latlng)
|
||
.setContent('<p>起点</p>');
|
||
that.map.addLayer(that.drawing.polygon.pop);
|
||
} else if (that.drawing.polygon.latlngs.length == 2) {
|
||
that.drawing.polygon.item = L.polygon(that.drawing.polygon.latlngs, {
|
||
color: "red"
|
||
});
|
||
// 添加点击事件监听器
|
||
that.drawing.polygon.item.on('click', function(e) {
|
||
if (that.deleteDrawing) {
|
||
that.map.removeLayer(e.target);
|
||
|
||
let index = that.layers.polygon.findIndex(x => x
|
||
._leaflet_id === e.target._leaflet_id);
|
||
if (index !== -1) {
|
||
that.layers.polygon.splice(index, 1); // 移除一个元素
|
||
}
|
||
}
|
||
});
|
||
that.map.addLayer(that.drawing.polygon.item);
|
||
// 存储起来方便删除
|
||
that.layers.polygon.push(that.drawing.polygon.item);
|
||
//删除popup
|
||
that.map.removeLayer(that.drawing.polygon.pop);
|
||
that.drawing.polygon.pop = null;
|
||
} else {
|
||
that.drawing.polygon.item.setLatLngs(that.drawing.polygon.latlngs);
|
||
let index = that.layers.polygon.length - 1;
|
||
that.layers.polygon[index] = that.drawing.polygon.item
|
||
}
|
||
});
|
||
} else if (type == 2) { //删除
|
||
that.drawing.polygon.latlngs = [];
|
||
if (that.drawing.polygon.pop) {
|
||
that.map.removeLayer(that.drawing.polygon.pop);
|
||
that.drawing.polygon.pop = null;
|
||
} else {
|
||
if (that.layers.polygon.length) {
|
||
let layer = that.layers.polygon.pop(); // 移除并返回最后一项
|
||
that.map.removeLayer(layer);
|
||
}
|
||
}
|
||
} else { //结束
|
||
if (!that.drawing.polygon) {
|
||
return;
|
||
}
|
||
that.drawing.polygon.latlngs = [];
|
||
if (that.drawing.polygon.pop) {
|
||
that.map.removeLayer(that.drawing.polygon.pop);
|
||
that.drawing.polygon.pop = null;
|
||
}
|
||
that.drawing.polygon.item = null;
|
||
that.setDragging(true);
|
||
that.map.off('click');
|
||
}
|
||
},
|
||
polyline(type) { //折线
|
||
const that = this;
|
||
if (type == 1) { //开始
|
||
that.setDragging(false);
|
||
that.drawing.polyline = {
|
||
latlngs: [],
|
||
pop: null,
|
||
item: null,
|
||
}
|
||
|
||
that.map.off('click');
|
||
that.map.on('click', (e) => {
|
||
//记录坐标
|
||
that.drawing.polyline.latlngs.push(e.latlng);
|
||
if (that.drawing.polyline.latlngs.length == 1) {
|
||
//创建popup
|
||
that.drawing.polyline.pop = L.popup()
|
||
.setLatLng(e.latlng)
|
||
.setContent('<p>起点</p>');
|
||
that.map.addLayer(that.drawing.polyline.pop);
|
||
} else if (that.drawing.polyline.latlngs.length == 2) {
|
||
that.drawing.polyline.item = L.polyline(that.drawing.polyline.latlngs, {
|
||
color: "red"
|
||
});
|
||
// 添加点击事件监听器
|
||
that.drawing.polyline.item.on('click', function(e) {
|
||
if (that.deleteDrawing) {
|
||
that.map.removeLayer(e.target);
|
||
|
||
let index = that.layers.polyline.findIndex(x => x
|
||
._leaflet_id === e.target._leaflet_id);
|
||
if (index !== -1) {
|
||
that.layers.polyline.splice(index, 1); // 移除一个元素
|
||
}
|
||
}
|
||
});
|
||
that.map.addLayer(that.drawing.polyline.item);
|
||
// 存储起来方便删除
|
||
that.layers.polyline.push(that.drawing.polyline.item);
|
||
//删除popup
|
||
that.map.removeLayer(that.drawing.polyline.pop);
|
||
that.drawing.polyline.pop = null;
|
||
} else {
|
||
that.drawing.polyline.item.setLatLngs(that.drawing.polyline.latlngs);
|
||
let index = that.layers.polyline.length - 1;
|
||
that.layers.polyline[index] = that.drawing.polyline.item
|
||
}
|
||
});
|
||
} else if (type == 2) { //删除
|
||
that.drawing.polyline.latlngs = [];
|
||
if (that.drawing.polyline.pop) {
|
||
that.map.removeLayer(that.drawing.polyline.pop);
|
||
that.drawing.polyline.pop = null;
|
||
} else {
|
||
if (that.layers.polyline.length) {
|
||
let layer = that.layers.polyline.pop(); // 移除并返回最后一项
|
||
that.map.removeLayer(layer);
|
||
}
|
||
}
|
||
} else { //结束
|
||
if (!that.drawing.polyline) {
|
||
return;
|
||
}
|
||
that.drawing.polyline.latlngs = [];
|
||
if (that.drawing.polyline.pop) {
|
||
that.map.removeLayer(that.drawing.polyline.pop);
|
||
that.drawing.polyline.pop = null;
|
||
}
|
||
that.drawing.polyline.item = null;
|
||
that.setDragging(true);
|
||
that.map.off('click');
|
||
}
|
||
},
|
||
ranging(type) { //测距
|
||
const that = this;
|
||
if (type == 1) { //开始
|
||
that.setDragging(false);
|
||
that.drawing.ranging = {
|
||
latlngs: [],
|
||
gap: [],
|
||
pop: [],
|
||
item: null,
|
||
}
|
||
|
||
that.map.off('click');
|
||
that.map.on('click', (e) => {
|
||
//记录坐标
|
||
that.drawing.ranging.latlngs.push(e.latlng);
|
||
if (that.drawing.ranging.latlngs.length > 1) {
|
||
if (that.drawing.ranging.item) {
|
||
that.drawing.ranging.item.setLatLngs(that.drawing.ranging.latlngs);
|
||
} else {
|
||
that.drawing.ranging.item = L.polyline(that.drawing.ranging.latlngs, {
|
||
color: "red"
|
||
});
|
||
that.map.addLayer(that.drawing.ranging.item);
|
||
}
|
||
//计算距离
|
||
const prev = that.drawing.ranging.latlngs[that.drawing.ranging.latlngs.length - 2];
|
||
const gap = L.latLng(prev).distanceTo(e.latlng);
|
||
that.drawing.ranging.gap.push(gap);
|
||
let sumgap = that.drawing.ranging.gap.reduce((acc, curr) => acc + curr, 0);
|
||
|
||
if (sumgap > 1000) {
|
||
sumgap = (sumgap / 1000).toFixed(2);
|
||
let marker = L.marker(e.latlng, {
|
||
icon: L.divIcon({
|
||
html: `<span>${sumgap}公里</span>`,
|
||
className: 'my-div-icon'
|
||
})
|
||
}).addTo(that.map);
|
||
that.drawing.ranging.pop.push(marker);
|
||
} else {
|
||
let marker = L.marker(e.latlng, {
|
||
icon: L.divIcon({
|
||
html: `<span>${Math.round(sumgap)}m</span>`,
|
||
className: 'my-div-icon'
|
||
})
|
||
}).addTo(that.map);
|
||
that.drawing.ranging.pop.push(marker);
|
||
}
|
||
} else {
|
||
//创建marker
|
||
let marker = L.marker(e.latlng, {
|
||
icon: L.divIcon({
|
||
html: '<span>起点</span>',
|
||
className: 'my-div-icon'
|
||
})
|
||
}).addTo(that.map);
|
||
that.drawing.ranging.pop.push(marker);
|
||
}
|
||
});
|
||
} else if (type == 2) { //删除
|
||
if (that.drawing.ranging.latlngs.length) {
|
||
that.drawing.ranging.latlngs.pop();
|
||
}
|
||
if (that.drawing.ranging.pop.length) {
|
||
let pop = that.drawing.ranging.pop.pop();
|
||
that.map.removeLayer(pop);
|
||
}
|
||
if (that.drawing.ranging.item) {
|
||
that.drawing.ranging.item.setLatLngs(that.drawing.ranging.latlngs);
|
||
// if (that.drawing.ranging.latlngs.length > 1) {
|
||
// //计算距离
|
||
// let start = that.drawing.ranging.latlngs[0];
|
||
// let end = that.drawing.ranging.latlngs[that.drawing.ranging.latlngs.length - 1];
|
||
// const gap = L.latLng(start).distanceTo(end);
|
||
// }
|
||
}
|
||
} else { //结束
|
||
if (!that.drawing.ranging) {
|
||
return;
|
||
}
|
||
that.drawing.ranging.latlngs = null;
|
||
if (that.drawing.ranging.pop && that.drawing.ranging.pop.length) {
|
||
that.drawing.ranging.pop.forEach(x => {
|
||
that.map.removeLayer(x);
|
||
});
|
||
}
|
||
that.drawing.ranging.pop = null;
|
||
if (that.drawing.ranging.item) {
|
||
that.map.removeLayer(that.drawing.ranging.item);
|
||
}
|
||
that.drawing.ranging.item = null;
|
||
that.setDragging(true);
|
||
that.map.off('click');
|
||
}
|
||
},
|
||
};
|
||
</script>
|
||
</body>
|
||
<style>
|
||
* {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
html,
|
||
body,
|
||
div,
|
||
ul,
|
||
li,
|
||
h1,
|
||
h2,
|
||
h3,
|
||
h4,
|
||
h5,
|
||
h6,
|
||
b,
|
||
p,
|
||
dl,
|
||
dt,
|
||
dd,
|
||
ol,
|
||
form,
|
||
input,
|
||
textarea,
|
||
th,
|
||
td,
|
||
select {
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
ul,
|
||
li,
|
||
dl,
|
||
dt,
|
||
dd,
|
||
ol {
|
||
list-style: none;
|
||
}
|
||
|
||
.icon {
|
||
width: 16px;
|
||
height: 16px;
|
||
fill: currentColor;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.main {
|
||
width: 100%;
|
||
height: 100vh;
|
||
}
|
||
|
||
#map {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.search-box {
|
||
position: absolute;
|
||
z-index: 1100;
|
||
padding: 0 10px;
|
||
bottom: 10%;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 100%;
|
||
height: 45px;
|
||
background: linear-gradient(to top, #eff0f5 50%, transparent);
|
||
}
|
||
|
||
.search {
|
||
background-color: #fff;
|
||
border-radius: 5px;
|
||
padding: 0 10px;
|
||
height: 35px;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.search .text {
|
||
color: #1a8def;
|
||
margin-left: 10px;
|
||
}
|
||
|
||
|
||
.search .input,
|
||
.search span {
|
||
margin-left: 10px;
|
||
flex: 1 1 0%;
|
||
height: 25px;
|
||
line-height: 25px;
|
||
border: none;
|
||
}
|
||
|
||
/* 聚焦状态 */
|
||
.input:focus {
|
||
border-color: none;
|
||
outline: none;
|
||
/* 移除默认的浏览器焦点轮廓 */
|
||
}
|
||
|
||
.iconfont {
|
||
line-height: 1;
|
||
font-size: 20px;
|
||
color: #333;
|
||
}
|
||
|
||
.above {
|
||
background-color: #fff;
|
||
border-radius: 5px;
|
||
position: absolute;
|
||
z-index: 1100;
|
||
width: 35px;
|
||
min-height: 35px;
|
||
top: 50%;
|
||
right: 10px;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.above>div {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-direction: column;
|
||
height: 35px;
|
||
}
|
||
|
||
.above>div i {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.above>div i span,
|
||
.below>div span {
|
||
font-size: 9px;
|
||
}
|
||
|
||
.above {
|
||
top: 15%;
|
||
}
|
||
|
||
.below {
|
||
position: absolute;
|
||
z-index: 1100;
|
||
bottom: 20%;
|
||
right: 10px;
|
||
}
|
||
|
||
.below>div {
|
||
margin-bottom: 5px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-direction: column;
|
||
width: 35px;
|
||
height: 35px;
|
||
background-color: #fff;
|
||
border-radius: 10px;
|
||
}
|
||
|
||
/* 地图放大缩小 */
|
||
.leaflet-control-container {
|
||
position: absolute;
|
||
right: 55px;
|
||
top: 20%;
|
||
}
|
||
|
||
/* 图层弹出 */
|
||
.LAYER {
|
||
padding: 10px;
|
||
position: absolute;
|
||
z-index: 1200;
|
||
background-color: #eff0f5;
|
||
width: 100%;
|
||
border-radius: 10px 10px 0 0;
|
||
transition: bottom 0.5s ease-out;
|
||
}
|
||
|
||
.LAYER.show {
|
||
bottom: 10%;
|
||
}
|
||
|
||
.LAYER.hide {
|
||
bottom: -20%;
|
||
}
|
||
|
||
.LAYER .title {
|
||
padding: 0 10px 10px 10px;
|
||
font-size: 16px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.LAYER .title div {
|
||
width: 30px;
|
||
}
|
||
|
||
.LAYER .title i {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.LAYER .card {
|
||
background-color: #fff;
|
||
border-radius: 5px;
|
||
display: flex;
|
||
justify-content: space-around;
|
||
}
|
||
|
||
.LAYER .card>div {
|
||
width: 74px;
|
||
height: auto;
|
||
margin: 15px 0;
|
||
text-align: center;
|
||
}
|
||
|
||
.LAYER .card>div .img {
|
||
width: 74px;
|
||
height: 50px;
|
||
overflow: hidden;
|
||
margin-bottom: 5px;
|
||
border-radius: 5px;
|
||
}
|
||
|
||
.LAYER .card>div .img img {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.LAYER .card .click {
|
||
color: #1a8def;
|
||
}
|
||
|
||
.LAYER .card .click .img {
|
||
border: 1px solid #1a8def;
|
||
}
|
||
|
||
/* 搜索弹出 */
|
||
.pop-up {
|
||
padding: 0 10px;
|
||
position: absolute;
|
||
z-index: 1200;
|
||
background: linear-gradient(to top, #eff0f5 96%, transparent);
|
||
width: 100%;
|
||
transition: bottom 0.5s ease-out;
|
||
height: 88vh;
|
||
}
|
||
|
||
.pop-up.show {
|
||
bottom: 10%;
|
||
}
|
||
|
||
.pop-up.hide {
|
||
bottom: -100%;
|
||
}
|
||
|
||
.pop-up .search {
|
||
background-color: #fff;
|
||
border-radius: 5px;
|
||
padding: 0 10px;
|
||
}
|
||
|
||
.pop-up .list {
|
||
margin-top: 10px;
|
||
background-color: #fff;
|
||
border-radius: 10px;
|
||
}
|
||
|
||
.pop-up .list li {
|
||
padding: 0 10px;
|
||
border-bottom: 1px solid #eee;
|
||
line-height: 35px;
|
||
}
|
||
|
||
.pop-up .list li i {
|
||
font-size: 16px;
|
||
vertical-align: sub;
|
||
}
|
||
|
||
/* 侧滑 */
|
||
.paddle {
|
||
position: absolute;
|
||
z-index: -1;
|
||
border-radius: 10px 0 0 10px;
|
||
right: 10px;
|
||
padding: 0 35px 0 5px;
|
||
height: 35px;
|
||
background-color: #fff;
|
||
transition: width 0.5s ease-out, opacity 0s ease-out;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.paddle.show {
|
||
width: auto;
|
||
opacity: 1;
|
||
}
|
||
|
||
.paddle.hide {
|
||
width: 0;
|
||
opacity: 0;
|
||
}
|
||
|
||
.paddle>div {
|
||
margin: 0 5px;
|
||
font-size: 9px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.paddle>div .btn {
|
||
background-color: #1a8def;
|
||
color: #fff;
|
||
padding: 3px 8px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* 测距 */
|
||
.my-div-icon {
|
||
background-color: transparent;
|
||
}
|
||
|
||
.my-div-icon span {
|
||
white-space: nowrap;
|
||
display: block;
|
||
border-radius: 4px;
|
||
background-color: #fff;
|
||
width: fit-content;
|
||
padding: 2px 5px;
|
||
}
|
||
</style>
|
||
</html> |