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

智能手表轨迹绘制:经纬度转像素轨迹变形问题求助

Fixing Distorted GPS Track Rendering on Smart Watch Apps

Let's break down why your current transformToPixels function is causing distorted tracks, and how to fix it while keeping your shape-preserving requirement (no need for meter-perfect accuracy):

The Root Cause of Distortion

Your current code uses a linear 1:1 mapping of latitude/longitude degrees directly to screen pixels. This works fine near the equator, but as you move north or south:

  • Longitude degrees represent a shorter physical distance (e.g., 1° longitude at 60° latitude is only ~55km, vs ~111km at the equator)
  • Your linear scaling stretches/shrinks the track horizontally based on latitude, leading to squashed or offset paths.

You don't need survey-grade accuracy, but you need a projection that preserves shape—enter the simplified Mercator projection, which keeps angles and shapes intact (critical for track rendering) and is lightweight enough for smart watch hardware.

Improved Transform Function

Here's a revised version of your function that uses Mercator projection for latitude, then maps both coordinates to your screen bounds. This eliminates the need for trial-and-error offset values too:

function transformToPixels(lat, lon) {
    // Extract bounding box values (convert to degrees once, outside the function for efficiency!)
    const westLon = boundingBox[1].toDegrees()[1];
    const eastLon = boundingBox[0].toDegrees()[1];
    const northLat = boundingBox[1].toDegrees()[0];
    const southLat = boundingBox[0].toDegrees()[0];

    // Step 1: Apply simplified Mercator projection to latitude
    // This adjusts for the shrinking longitude distance at higher latitudes
    function mercatorLat(lat) {
        return Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360));
    }

    // Project bounding box latitudes
    const northMerc = mercatorLat(northLat);
    const southMerc = mercatorLat(southLat);

    // Step 2: Normalize coordinates to 0-1 range relative to bounding box
    const xNorm = (lon - westLon) / (eastLon - westLon);
    const yNorm = (northMerc - mercatorLat(lat)) / (northMerc - southMerc); // Flip y because screen y increases downward

    // Step 3: Map to screen pixels
    const xPixel = xNorm * DISPLAY_WIDTH;
    const yPixel = yNorm * DISPLAY_HEIGHT;

    return [yPixel, xPixel]; // Match your original result order [y, x]
}

Key Improvements Explained

  • Mercator Latitude Adjustment: The mercatorLat function converts latitude to a value that accounts for the curvature of the Earth, ensuring horizontal scale matches vertical scale relative to the track's location.
  • No Trial-and-Error Offsets: By normalizing first to a 0-1 range, we eliminate the need for manual +25 or -3 adjustments—your track will fit perfectly within the display bounds if your bounding box is correctly calculated to contain all track points.
  • Efficiency: Calculate the projected bounding box values once outside the function (e.g., when loading the GeoJSON) instead of every time you convert a point—this saves CPU cycles on a smart watch.

Quick Validation Tip

For the distorted track data you mentioned, test this function and you'll see the track shape matches what you see on your phone (since most mobile mapping apps use Mercator under the hood).

Remember: If your bounding box is too large (e.g., includes areas far outside your track), you might still get some empty space, but the track shape itself will remain true to the original GPS path.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:23:41