You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Survey123:修改JavaScript实现经纬度从本地JSON获取线段Label

求助:Survey123中调用本地JSON文件获取最近线段Label字段的脚本问题

问题描述

我需要编写一个脚本,根据给定的地理点经纬度(或Survey123打开时设备的自身经纬度),通过邻近性计算返回最近线段的Label字段值。我基于Esri的Ismael提供的代码进行修改,但自身JavaScript能力有限,修改后在Survey123中出现问题。原代码通过调用Web服务获取最近记录,而我的需求是调用media文件夹下的scat_segment.json文件,并且仅返回Label字段值。以下是原代码和我修改后的代码,寻求解决帮助。

原代码

function getNearestRecord(featureLayer, location, searchWithinMeters,fields,where,token,debugmode){
    
    if (featureLayer=== "" || featureLayer===undefined){
        featureLayer = "https://services.arcgis.com/P3ePLMYs2RVChkJx/ArcGIS/rest/services/USA_Major_Cities/FeatureServer/0";
    }

    if (location=== "" || location===undefined){
        return (debugmode? "Location Object is empty":"");
    }

    if (fields=== "" || fields===undefined){
        fields="*";
    }

    if (where=== "" || where===undefined){
        where="1=1";
    }

    var coordsArray = location.split(" ");
    var coords = coordsArray[1] + "," + coordsArray[0]

    var xmlhttp = new XMLHttpRequest();
    var url = featureLayer + "/query?geometry=" + coords +  "&where=" + where + "&geometryType=esriGeometryPoint&inSR=4326&distance=" + searchWithinMeters + "&units=esriSRUnit_Meter&outFields=" + fields + "&returnGeometry=true&outSR=4326&f=json"

    if (token){
        url = url + "&token=" + token;
    }

    xmlhttp.open("GET",url,false);
        xmlhttp.send();

    if (xmlhttp.status!==200){
        return (debugmode? xmlhttp.status:"");
    } else {
        var responseJSON=JSON.parse(xmlhttp.responseText)
        if (responseJSON.error){
            return (debugmode? JSON.stringify(responseJSON.error):"");
        } else {
            var count = responseJSON.features.length;
            if (count===0){
                return (debugmode? "No Features Found":"");
            }
            else if (count===1){
                return JSON.stringify(responseJSON.features[0]);
            }
            else if (count>1){
                var nearestIndex = findNearestIndex (location, responseJSON.features);
                return JSON.stringify(responseJSON.features[nearestIndex]);
            }
        }
    }
}

function findNearestIndex(location, features){
    var nearestIndex = 0;
    var minDistance = 999999999999;

    var coordsArray = location.split(" ");
    var lat1 = coordsArray[0];
    var lon1 = coordsArray[1];

    for (let i = 0; i < features.length; i++) {
      var dist = getDistanceKM(lat1,lon1,features[i].geometry.y,features[i].geometry.x);
      if (dist < minDistance){
        minDistance = dist;
        nearestIndex = i;
      }
    } 

    return nearestIndex;
}

function getDistanceKM(lat1, lon1, lat2, lon2) {
    if ((lat1 == lat2) && (lon1 == lon2)) {
        return 0;
    }
    else {
        var radlat1 = Math.PI * lat1/180;
        var radlat2 = Math.PI * lat2/180;
        var theta = lon1-lon2;
        var radtheta = Math.PI * theta/180;
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        if (dist > 1) {
            dist = 1;
        }
        dist = Math.acos(dist);
        dist = dist * 180/Math.PI;
        dist = dist * 60 * 1.1515;
        return dist * 1.609344;
    }
}

我修改后的代码

function getNearestLabel(filePath, segmentPoint, debugmode) {
    if (!filePath || filePath === undefined) {
        return (debugmode ? "File path is not provided" : "");
    }

    if (!segmentPoint || segmentPoint === undefined) {
        return (debugmode ? "Segment point is not provided" : "");
    }

    var coordsArray = segmentPoint.split(" ");
    var pointLat = parseFloat(coordsArray[0]);
    var pointLon = parseFloat(coordsArray[1]);

    // 读取本地JSON文件
    var xmlhttp = new XMLHttpRequest();
    var url = "media/scat_segment.json"; // 修正后的文件路径
    xmlhttp.open("GET", url, false);
    xmlhttp.send();

    if (xmlhttp.status !== 200) {
        return (debugmode ? "Failed to fetch data from JSON file" : "");
    } else {
        var responseJSON = JSON.parse(xmlhttp.responseText);
        var nearestIndex = findNearestLineIndex(pointLat, pointLon, responseJSON.features);
        var nearestLabel = responseJSON.features[nearestIndex].attributes.Label;
        return nearestLabel.toString(); // 返回前转为字符串
    }
}

function findNearestLineIndex(pointLat, pointLon, features) {
    var nearestIndex = 0;
    var minDistance = Number.MAX_VALUE;

    for (var i = 0; i < features.length; i++) {
        var coords = features[i].geometry.coordinates;
        var dist = getDistanceToPoint(pointLat, pointLon, coords);
        if (dist < minDistance) {
            minDistance = dist;
            nearestIndex = i;
        }
    }

    return nearestIndex;
}

function getDistanceToPoint(pointLat, pointLon, lineCoords) {
    var minDistance = Number.MAX_VALUE;

    for (var i = 0; i < lineCoords.length - 1; i++) {
        var dist = distanceToSegment(pointLat, pointLon, lineCoords[i][1], lineCoords[i][0], lineCoords[i + 1][1], lineCoords[i + 1][0]);
        minDistance = Math.min(minDistance, dist);
    }

    return minDistance;
}

// 计算点到线段的距离
function distanceToSegment(pointLat, pointLon, lat1, lon1, lat2, lon2) {
    var x0 = pointLon;
    var y0 = pointLat;
    var x1 = lon1;
    var y1 = lat1;
    var x2 = lon2;
    var y2 = lat2;

    var dx = x2 - x1;
    var dy = y2 - y1;
    var along = ((x0 - x1) * dx + (y0 - y1) * dy) / (dx * dx + dy * dy);

    var x, y;
    if (along <= 0) {
        x = x1;
        y = y1;
    } else if (along >= 1) {
        x = x2;
        y = y2;
    } else {
        x = x1 + along * dx;
        y = y1 + along * dy;
    }

    return Math.sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0));
}

内容的提问来源于stack exchange,提问作者Brewster101

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 10:42:09