jsy-app/static/html/tianditu.html
2024-12-13 14:24:58 +08:00

1330 lines
39 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>