管灌系统巡查员智能手机App
app/src/main/assets/js/map.js
@@ -1,14 +1,62 @@
(function () {
    // 图片路径
    const locationIMGPath = 'img/location.png';
    const markerBalckPath = 'img/marker_black.svg';
    const markerRedPath = 'img/marker_red.svg';
    const markerBluePath = 'img/marker_blue.svg';
    // 建议将这些常量移到一个配置对象中统一管理
    const CONFIG = {
        IMAGES: {
            LOCATION: 'img/location.png',
            MARKER_BLACK: 'img/marker_black.svg',
            MARKER_RED: 'img/marker_red.svg',
            MARKER_BLUE: 'img/marker_blue.svg',
            CENTER_PIN: 'img/push_pin.svg',
            DIVIDE_BLUE: 'img/divide_home_blue.svg',
            DIVIDE_RED: 'img/divide_home_red.svg'
        },
        MAP: {
            DEFAULT_ZOOM: 12,
            TIANDITU_KEY: 'd8beed89b43160a9a185e5aff431f85d'
        }
    };
    let map;
    let lastMarker = null;
    let lastClickedMarker = null;
    let lastClickedDivide = null;
    let isShowWaterIntakeDetail = false;
    let isShowDivideDetail = false;
    let zoom = 12;
    // 存储所有管网线路的数组
    let pipeLineList = [];
    let currentPipePath = [];
    // 存储所有取水口标记的数组
    let waterIntakeMarkers = [];
    // 存储所有分水房标记的数组
    let divideMarkers = [];
    // 将方法挂载到 window 上
    function mountMethodToWindow() {
        window.locationOverLay = locationOverLay;
        window.showToast = showToast;
        window.addMarker = addMarker;
        window.setCenterAndZoom = setCenterAndZoom;
        window.updateLocation = updateLocation;
        window.aginShowLocation = aginShowLocation;
        window.cleanLocationLay = cleanLocationLay;
        window.updateInspectionLocation = updateInspectionLocation;
        window.cleanLoclLay = cleanLoclLay;
        window.showPin = showPin;
        window.cancelPin = cancelPin;
        window.refreshMarker = refreshMarker;
        window.addDivide = addDivide;
        window.showAllPipeLines = showAllPipeLines;
        window.hideAllPipeLines = hideAllPipeLines;
        window.clearAllPipeLines = clearAllPipeLines;
        window.addPipeNetwork = addPipeNetwork;
        window.hideAllWaterIntakes = hideAllWaterIntakes;
        window.showAllWaterIntakes = showAllWaterIntakes;
        window.hideAllDivides = hideAllDivides;
        window.showAllDivides = showAllDivides;
    }
    document.addEventListener('DOMContentLoaded', function () {
@@ -18,18 +66,21 @@
        mountMethodToWindow();
    });
    window.onload = function () {
        //加载坐标点
        window.Android.loadMarker();
    };
    // 初始化地图
    function initMap() {
        //    影像底图
        var imageURL = "http://t0.tianditu.gov.cn/img_w/wmts?" +
            "SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
            "&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=d8beed89b43160a9a185e5aff431f85d";
        //创建自定义图层对象
        var lay = new T.TileLayer(imageURL, { minZoom: 1, maxZoom: 18 });
        var config = { layers: [lay] };
        //影像注记(地图上的地址)
        var imgURL2 = "http://t0.tianditu.gov.cn/cia_w/wmts?" + "SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
            "&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}" +
            "&tk=d8beed89b43160a9a185e5aff431f85d";
        var lay = new T.TileLayer(imageURL, { minZoom: 6, maxZoom: 18 });
        var lay2 = new T.TileLayer(imgURL2, { minZoom: 6, maxZoom: 18 });
        var config = { layers: [lay, lay2] };
        map = new T.Map("mapDiv", config);
        var scale = new T.Control.Scale();
        //添加比例尺控件
@@ -41,7 +92,7 @@
    // 地图点击后获取经纬度
    function getLngLat(lnglat) {
        console.log(lnglat.lng.toFixed(6) + "," + lnglat.lat.toFixed(6));
        addClickOverLay(lnglat);
        // addClickOverLay(lnglat);
    }
    // 点击后添加坐标点
@@ -80,47 +131,6 @@
        }
    }
    // 模拟添加取水口标注
    function buttonOverLay() {
        map.clearOverLays(); // 清理地图上的所有覆盖物
        let data_info = [
            [116.417854, 39.921988, "235取水口"],
            [116.406605, 39.921585, "237取水口"],
            [116.412222, 39.912345, "236取水口"]
        ];
        for (let i = 0; i < data_info.length; i++) {
            let icon = new T.Icon({
                iconUrl: markerBluePath,
                iconSize: new T.Point(27, 27),
                iconAnchor: new T.Point(10, 25)
            });
            let marker = new T.Marker(
                new T.LngLat(data_info[i][0], data_info[i][1]), // 创建标注
                { icon: icon }
            );
            marker.addEventListener("click", function (data) {
                addMarkerListener(data);
            });
            map.addOverLay(marker); // 将标注添加到地图中
            let label = new T.Label({
                text: data_info[i][2],
                position: marker.getLngLat(),
                offset: new T.Point(-50, 10), // 设置标注文字的位置
                opacity: 1, // 设置文本的显示不透明度(范围0-1)
            });
            label.setBorderLine(0); // 设置文本的边框线宽
            label.setBackgroundColor("transparent"); // 设置文本的背景色(透明色)
            label.setFontColor("#0000FF");
            label.setFontSize(10);
            map.addOverLay(label);
        }
    }
    // 显示标注点击后的窗口
    function openInfo(content, e) {
@@ -134,33 +144,29 @@
    // 手机获取到定位后显示定位
    function locationOverLay(lng, lag) {
        console.log("function》》》》》locationOverLay");
        map.centerAndZoom(new T.LngLat(lng, lag), 18);
        map.centerAndZoom(new T.LngLat(lng, lag), map.getZoom());
        let icon = new T.Icon({
            iconUrl: locationIMGPath,
            iconSize: new T.Point(27, 27),
            iconAnchor: new T.Point(10, 25)
            iconUrl: CONFIG.IMAGES.LOCATION,
            iconSize: new T.Point(20, 20),
            iconAnchor: new T.Point(10, 10)
        });
        let marker = new T.Marker(new T.LngLat(lng, lag), { icon: icon });
        let marker = new T.Marker(
            new T.LngLat(lng, lag),
            { icon: icon }
        );
        map.addOverLay(marker);
    }
    //设置地图中心点
    function setCenterAndZoom(lng, lat) {
    function setCenterAndZoom(lng, lat, thiszoom) {
        zoom = thiszoom;
        console.log("function》》》》》setCenterAndZoom>>>>lng:" + lng + ",lat:" + lat);
        map.centerAndZoom(new T.LngLat(lng, lat), zoom);
    }
    // 将方法挂载到 window 上
    function mountMethodToWindow() {
        window.locationOverLay = locationOverLay;
        window.showToast = showToast;
        window.addMarker = addMarker;
        window.setCenterAndZoom = setCenterAndZoom;
    }
    // 调用原生安卓方法显示取水口详情
    function showWaterIntakeDetail(data) {
@@ -170,98 +176,469 @@
    // 调用原生安卓方法隐藏取水口详情
    function closeWaterIntakeDetail(data) {
        if (lastClickedMarker !== null) {
            // 如果有点击取水口则将取水口恢复成黑色
            // 上次点击的标注改为黑色
            var defaulticon = new T.Icon({
                iconUrl: markerBluePath,
                iconSize: new T.Point(27, 27),
                iconAnchor: new T.Point(10, 25)
            });
            lastClickedMarker.setIcon(defaulticon);
        }
        if (isShowWaterIntakeDetail) {
            // 假如显示了取水口详情则隐藏取水口详情
            isShowWaterIntakeDetail = false;
            window.Android.closeWaterIntakeView();
        } else {
            // 假如没有显示取水口则添加点击的坐标
            getLngLat(data.lnglat);
        if (!isShowCenterPin) {
            if (lastClickedMarker !== null) {
                lastClickedMarker.setIcon(createIcon(CONFIG.IMAGES.MARKER_BLUE));
            }
            if(lastClickedDivide!==null)
           {
           lastClickedDivide.setIcon(createIcon(CONFIG.IMAGES.DIVIDE_BLUE));
           }
            if (isShowWaterIntakeDetail || isShowDivideDetail) {
                // 假如显示了取水口详情则隐藏取水口详情
                isShowWaterIntakeDetail = false;
                window.Android.closeWaterIntakeView();
            } else {
                // 假如没有显示取水口则添加点击的坐标
                getLngLat(data.lnglat);
            }
        }
    }
    // 点击标注的事件
    function addMarkerListener(data) {
        chageMarkerIcon(data);
        showWaterIntakeDetail("模拟数据");
    function addMarkerListener(id, data) {
        if (!isShowCenterPin) {
            chageMarkerIcon(data);
            showWaterIntakeDetail(id);
        } else {
            showToast("当前正在修改选中取水口的经纬度,完成或退出后才可选择其他!");
        }
    }
    // 修改点击标注的图标
    function chageMarkerIcon(data) {
        // 点击的标注改为红色
        var currentMarker = data.target;
        // 点击后图标
        var clickedIcon = new T.Icon({
            iconUrl: markerRedPath,
            iconSize: new T.Point(27, 27),
            iconAnchor: new T.Point(10, 25)
        });
        // 设置当前点击的 marker 为点击后图标
        currentMarker.setIcon(clickedIcon);
        // 判断点击的不是同一个坐标
        currentMarker.setIcon(createIcon(CONFIG.IMAGES.MARKER_RED));
        if (lastClickedMarker !== null) {
            if (!isEqualsLngLat(data.target.getLngLat(), lastClickedMarker.getLngLat())) {
                var defaulticon = new T.Icon({
                    iconUrl: markerBluePath,
                    iconSize: new T.Point(27, 27),
                    iconAnchor: new T.Point(10, 25)
                });
                lastClickedMarker.setIcon(defaulticon);
                lastClickedMarker.setIcon(createIcon(CONFIG.IMAGES.MARKER_BLUE));
            }
        }
        if (lastClickedDivide !== null) {
            lastClickedDivide.setIcon(createIcon(CONFIG.IMAGES.MARKER_BLUE));
        }
        lastClickedMarker = data.target;
        map.panTo(currentMarker.getLngLat());
    }
    //调安卓原生
    function showToast() {
    function showToast(data) {
        // 调用 JavaScript 接口对象的方法
        window.Android.showToast('Hello, Android!');
        window.Android.showToast(data);
    }
    // 判断两个坐标是否一致
    function isEqualsLngLat(data1, data2) {
        return data1.lat === data2.lat && data1.lng === data2.lng;
    }
    function addMarker(id, lng, lat, name) {
        addMarker(id, lng, lat, name, false)
    }
    //添加从原生传过来的坐标并显示在地图上
    function addMarker(jsonData) {
        console.log("function》》》》》addMarker");
        var array = JSON.parse(jsonData);
        var icon = new T.Icon({
            iconUrl: markerBluePath,
            iconSize: new T.Point(27, 27),
            iconAnchor: new T.Point(10, 25)
    function addMarker(id, lng, lat, name, isRed) {
        console.log("function》》》》》addMarker>>>id:" + id);
        const iconUrl = isRed ? CONFIG.IMAGES.MARKER_RED : CONFIG.IMAGES.MARKER_BLUE;
        let marker = new T.Marker(
            new T.LngLat(lng, lat),
            { icon: createIcon(iconUrl) }
        );
        //添加点击事件
        marker.addEventListener("click", (data) => {
            addMarkerListener(id, data)
        });
        array.forEach(element => {
            let marker = new T.Marker(
                new T.LngLat(element[0], element[1]) // 创建标注
                , { icon: icon });
            //添加点击事件
            marker.addEventListener("click", (data) => {
                addMarkerListener(data)
            });
            map.addOverLay(marker); // 将标注添加到地图中
            let label = new T.Label({
                text: element[2],
                position: marker.getLngLat(),
                offset: new T.Point(-35, 8), // 设置标注文字的位置
                opacity: 1, // 设置文本的显示不透明度(范围0-1)
            });
            label.setBorderLine(0); // 设置文本的边框线宽
            label.setBackgroundColor("transparent"); // 设置文本的背景色(透明色)
            label.setFontColor("#0000FF");
            label.setFontSize(10);
            map.addOverLay(label);
        let label = new T.Label({
            text: `<div style='position:absolute;left:-50%;transform: translateX(-50%);'>${name}<div>`,
            position: marker.getLngLat(),
            offset: new T.Point(0, 8),
            opacity: 1,
        });
        return "addMarker加载成功"
        label.setBorderLine(0);
        label.setBackgroundColor("transparent");
        label.setFontColor("#FFFFFF");
        label.setFontSize(10);
        marker.label = label;
        if (isRed) {
            lastClickedMarker = marker;
        }
        // 将标记和标签存储到数组中
        waterIntakeMarkers.push({
            marker: marker,
            label: label
        });
        map.addOverLay(label);
        map.addOverLay(marker);
        return "addMarker加载成功 id:" + id
    }
    //更新位坐标
    function updateLocation(log, lat) {
        if (locationMarker) {
            map.removeOverLay(locationMarker);
        }
        var newPoint = new T.LngLat(log, lat);
        let icon = new T.Icon({
            iconUrl: CONFIG.IMAGES.LOCATION,
            iconSize: new T.Point(20, 20),
            iconAnchor: new T.Point(10, 10)
        });
        locationMarker = new T.Marker(
            newPoint,
            { icon: icon }
        );
        map.addOverLay(locationMarker);
        map.panTo(newPoint);
    }
    //保存定位坐标生成轨迹
    var path = [];
    var lineLayer = new T.Polyline([], { color: '#E9900A', weight: 3, opacity: 0.8 });
    let locationMarker;
    function updateInspectionLocation(log, lat) {
        var lastLat = lat;
        var newPoint = new T.LngLat(log, lastLat);
        path.push(newPoint);
        lineLayer.setLngLats(path);
        map.addOverLay(lineLayer);
    }
    var pipePath = [];
    var pipeLineLayer = new T.Polyline([], { color: '#E9900A', weight: 3, opacity: 0.8 });
    // 管网线路管理
    const PipelineManager = {
        lines: [],  // 存储所有完成的线路
        currentLine: {
            points: [],  // 当前线路的点
            overlay: null  // 当前线路的图层对象
        },
        // 线路样式配置
        style: {
            color: '#1890FF',
            weight: 3,
            opacity: 0.8
        },
        /**
         * 添加点到管网线路
         * @param {number} lng 经度
         * @param {number} lat 纬度
         * @param {boolean} isNewLine 是否开始新的线路
         */
        addPoint(lng, lat, isNewLine) {
            if (isNewLine) {
                this.finishCurrentLine();
            }
            const point = new T.LngLat(lng, lat);
            this.currentLine.points.push(point);
            if (this.currentLine.points.length > 1) {
                this.updateCurrentLineDisplay();
            }
        },
        /**
         * 更新当前线路的显示
         */
        updateCurrentLineDisplay() {
            if (!this.currentLine.overlay) {
                // 创建新的线路图层
                this.currentLine.overlay = new T.Polyline(this.currentLine.points, this.style);
                map.addOverLay(this.currentLine.overlay);
            } else {
                // 更新现有线路的点
                this.currentLine.overlay.setLngLats(this.currentLine.points);
            }
        },
        /**
         * 完成当前线路
         */
        finishCurrentLine() {
            if (this.currentLine.points.length > 1) {
                if (this.currentLine.overlay) {
                    // 将当前线路添加到完成列表
                    this.lines.push(this.currentLine.overlay);
                }
            } else if (this.currentLine.overlay) {
                // 如果点数不足,清除图层
                map.removeOverLay(this.currentLine.overlay);
            }
            // 重置当前线路
            this.currentLine = {
                points: [],
                overlay: null
            };
        },
        /**
         * 显示所有线路
         */
        showAll() {
            this.lines.forEach(line => map.addOverLay(line));
            if (this.currentLine.overlay) {
                map.addOverLay(this.currentLine.overlay);
            }
        },
        /**
         * 隐藏所有线路
         */
        hideAll() {
            this.lines.forEach(line => map.removeOverLay(line));
            if (this.currentLine.overlay) {
                map.removeOverLay(this.currentLine.overlay);
            }
        },
        /**
         * 清除所有线路
         */
        clearAll() {
            this.hideAll();
            this.lines = [];
            this.currentLine = {
                points: [],
                overlay: null
            };
        }
    };
    /**
     * 添加管网线路点
     */
    function addPipeNetwork(lng, lat, isNewLine) {
        PipelineManager.addPoint(lng, lat, isNewLine);
    }
    /**
     * 显示所有管网线路
     */
    function showAllPipeLines() {
        PipelineManager.showAll();
    }
    /**
     * 隐藏所有管网线路
     */
    function hideAllPipeLines() {
        PipelineManager.hideAll();
    }
    /**
     * 清除所有管网线路
     */
    function clearAllPipeLines() {
        PipelineManager.clearAll();
    }
    var aginPath = [];
    var oldLineLayer = new T.Polyline([], { color: '#E9900A', weight: 3, opacity: 0.8 });
    //显示因异常关闭的巡检记录
    function aginShowLocation(lng, lat) {
        // 调用 Android 提供的接口,获取数据
        console.log("aginShowLocation>>lng:" + lng + ">>>lat:" + lat);
        var newPoint = new T.LngLat(lng, lat);
        aginPath.push(newPoint);
        oldLineLayer.setLngLats(aginPath);
        map.addOverLay(oldLineLayer);
    }
    //清除巡检记录轨迹
    function cleanLocationLay() {
        if (lineLayer) {
            map.removeOverLay(lineLayer);
            path = []
        }
        if (locationMarker) {
            map.removeOverLay(locationMarker);
        }
        if (oldLineLayer) {
            aginPath = []
            map.removeOverLay(oldLineLayer);
        }
    }
    //清除本地定位坐标位置
    function cleanLoclLay() {
        if (locationMarker) {
            map.removeOverLay(locationMarker);
        }
    }
    //是否显示了地图中心的针用来修改坐标
    var isShowCenterPin;
    //开始获取屏幕中间定位
    function showPin(lng, lat) {
        var newPoint = new T.LngLat(lng, lat);
        map.panTo(newPoint);
        isShowCenterPin = true;
        map.addEventListener("moveend", mapMoveEnd);
        window.Android.refreshCenter(map.getCenter().getLng(), map.getCenter().getLat());
        return true;
    }
    //取消修改定位
    function cancelPin() {
        isShowCenterPin = false;
    }
    //成功修改取水口经纬度后刷新取水口位置
    function refreshMarker(id, lng, lat, name) {
        map.removeOverLay(lastClickedMarker.label);
        map.removeOverLay(lastClickedMarker);
        addMarker(id, lng, lat, name, true);
    }
    function mapMoveEnd(e) {
            const center = e.target.getCenter();
            window.Android.refreshCenter(center.getLng(), center.getLat());
    }
    // 添加防抖函数
    function debounce(fn, delay) {
        let timer = null;
        return function () {
            if (timer) clearTimeout(timer);
            timer = setTimeout(() => {
                fn.apply(this, arguments);
            }, delay);
        }
    }
    // 创建marker图标的方法可以抽取出来复用
    function createIcon(iconUrl, size = 28) {
        return new T.Icon({
            iconUrl: iconUrl,
            iconSize: new T.Point(size, size),
            iconAnchor: new T.Point(size / 2, size)
        });
    }
    //添加分水房
    function addDivide(id, lng, lat, name) {
        addDivide(id, lng, lat, name, false)
    }
    //添加分水房
    function addDivide(id, lng, lat, name, isRed) {
        console.log("function》》》》》addMarker>>>id:" + id);
        const iconUrl = isRed ? CONFIG.IMAGES.DIVIDE_RED : CONFIG.IMAGES.DIVIDE_BLUE;
        let marker = new T.Marker(
            new T.LngLat(lng, lat),
            { icon: createIcon(iconUrl) }
        );
        //添加点击事件
        marker.addEventListener("click", (data) => {
            addDivideListener(id, data)
        });
        let label = new T.Label({
            text: `<div style='position:absolute;left:-50%;transform: translateX(-50%);'>${name}<div>`,
            position: marker.getLngLat(),
            offset: new T.Point(0, 8), // 设置标注文字的位置
            opacity: 1, // 设置文本的显示不透明度(范围0-1)
        });
        label.setBorderLine(0); // 设置文本的边框线宽
        label.setBackgroundColor("transparent"); // 设置文本的背景色(透明色)
        label.setFontColor("#FFFFFF");
        label.setFontSize(10);
        marker.label = label;
        if (isRed) {
            lastClickedMarker = marker;
        }
        // 将分水房标记和标签存储到数组中
        divideMarkers.push({
            marker: marker,
            label: label
        });
        map.addOverLay(label);
        map.addOverLay(marker); // 将标注添加到地图中
        return "addMarker加载成功 id:" + id
    }
    // 修改点击标注的图标
    function chageDivideIcon(data) {
        // 点击的标注改为红色
        var currentMarker = data.target;
        currentMarker.setIcon(createIcon(CONFIG.IMAGES.DIVIDE_RED));
        if (lastClickedDivide !== null) {
            if (!isEqualsLngLat(data.target.getLngLat(), lastClickedDivide.getLngLat())) {
                lastClickedDivide.setIcon(createIcon(CONFIG.IMAGES.DIVIDE_BLUE));
            }
        }
        if (lastClickedMarker !== null) {
            lastClickedMarker.setIcon(createIcon(CONFIG.IMAGES.MARKER_BLUE));
        }
        lastClickedDivide = data.target;
        map.panTo(currentMarker.getLngLat());
    }
    // 点击标注的事件
    function addDivideListener(id, data) {
        // if (!isShowCenterPin) {
        chageDivideIcon(data);
        showDivideDetail(id);
        // } else {
        //     showToast("当前正在修改选中取水口的经纬度,完成或退出后才可选择其他!");
        // }
    }
    // 调用原生安卓方法显示取水口详情
    function showDivideDetail(data) {
        isShowDivideDetail = true;
        window.Android.showDivideDetail(data);
    }
    /**
     * 隐藏所有取水口标记
     */
    function hideAllWaterIntakes() {
        waterIntakeMarkers.forEach(item => {
            map.removeOverLay(item.marker);
            map.removeOverLay(item.label);
        });
    }
    /**
     * 显示所有取水口标记
     */
    function showAllWaterIntakes() {
        waterIntakeMarkers.forEach(item => {
            map.addOverLay(item.marker);
            map.addOverLay(item.label);
        });
    }
    /**
     * 隐藏所有分水房标记
     */
    function hideAllDivides() {
        divideMarkers.forEach(item => {
            map.removeOverLay(item.marker);
            map.removeOverLay(item.label);
        });
    }
    /**
     * 显示所有分水房标记
     */
    function showAllDivides() {
        divideMarkers.forEach(item => {
            map.addOverLay(item.marker);
            map.addOverLay(item.label);
        });
    }
})();