将lat/lng坐标转换为给定地图上的像素(使用JavaScript)

mat*_*sko 3 javascript maps latitude-longitude

我已经将MaxMind的城市数据库放在一起,它包含了数据库中每个城市的lat/lng值.我还整理了一张North/America地图,我希望在地图的x/y坐标上出现一个图标,该图标来自城市数据库记录的lat/lng坐标.

根据我的理解,我需要首先找到地图的左/上界(lat/lng - > x/y),然后将其用作任何北美城市x/y坐标之间线性关系的差异.最后,根据地图的大小,只需要几个简单的除法和减法操作来确定放置点的位置.

但是,我似乎无法弄清楚如何以下内容:

  1. 我不确定lat/lng映射系统是什么.我怎么找到这个?
  2. 使用JavaScript库,如何将lat/lng转换为0,0 coord和每个城市坐标的像素.我尝试过Proj4js,但是它们要求你指定你的坐标图类型等等.这是另一个问类似问题的问题. 将long/lat转换为给定图片上的像素x/y

有任何想法吗?

- 编辑 -

输出图(北美)是一个连续圆柱:"米勒圆柱投影".http://en.wikipedia.org/wiki/Miller_cylindrical_projection

小智 7

纬度和经度是在地球上绘制的虚线,以便您可以准确地确定世界上的任何位置.简单地说它们是飞机的X和Y坐标.纬度是一条从北向南延伸的垂直线,北极为90度,南极为-90度.

另一方面,经度是一条从东到南的水平线,西面为-180度,东面为180度.

您可以将latLng转换为像素坐标,因为假设html容器的宽度是世界的宽度,同样适用于高度.

公式 - 经度 - 像素

(givenLng*widthOfContainerElement)/360
Run Code Online (Sandbox Code Playgroud)

其中360是以度为单位的总经度

Formula -Latitude - 像素化

(givenLat*heightOfContainerElement)/180
Run Code Online (Sandbox Code Playgroud)

其中360是度数的总经度

//Height is calculated from the bottom
Run Code Online (Sandbox Code Playgroud)

如果您仍需要任何澄清,请与我们联系.

  • 经度是垂直线,而纬度是水平线。请更正您的答案 (2认同)

ow3*_*w3n 5

下面是墨卡托投影的 Javascript 实现,它仅返回正值(屏幕的笛卡尔坐标系)并考虑球体 > 平面转换:

// get x   
var x = (lng + 180) * (mapWidth / 360);
// convert from degrees to radians
var latRad = lat * Math.PI / 180;
// get y value
var mercN = Math.log(Math.tan((Math.PI / 4) + (latRad / 2)));
var y = (mapHeight / 2) - (mapWidth * mercN / (2 * Math.PI));
Run Code Online (Sandbox Code Playgroud)


Web*_*rer 5

这是一个非常古老的问题,但接受的答案有一些......细微差别......

通常,这是针对卫星/航空图像完成的,通常伴有“缩放级别”。

这个缩放级别粗略地(我的意思是粗略地)转换为“地面样本距离”或 GSD,当提供时,它表示图像中每个像素的厘米。

您经常会看到缩放级别为 18、19、20 或 21。

需要注意的问题之一是地球既不是平坦的,也不是完美的球形,因此,有许多不同的“投影”方法可用于将地球表面的三维坐标转换为屏幕上的二维图像。这些投影方法中最流行且使用最广泛的是墨卡托投影。

Google 提供了一种使用墨卡托投影来提供x和的像素坐标的方法y

然后我们可以使用“缩放级别”来缩放坐标以适合我们的图像。

interface LatLngLiteral {
    lat: number;
    lng: number;
}

interface Coordinate {
    x: number;
    y: number;
}

const project = (latLng: LatLngLiteral): Coordinate => {
    const TILE_SIZE: number = 256;
    let siny: number = Math.sin((latLng.lat * Math.PI) / 180);

    // Truncating to 0.9999 effectively limits latitude to 89.189. This is
    // about a third of a tile past the edge of the world tile.
    siny = Math.min(Math.max(siny, -0.9999), 0.9999);

    return {
        x: TILE_SIZE * (0.5 + latLng.lng / 360),
        y: TILE_SIZE * (0.5 - Math.log((1 + siny) / (1 - siny)) / (4 * Math.PI))
    };
};
export function formatToPoint(latLng: LatLngLiteral, zoom: number): Coordinate {
    // Get the world coordinates in pixels
    const worldCoordinate: Coordinate = project(latLng);
    // Scale to fit our image
    const scale: number = Math.pow(2, zoom);

    // Apply scale to world coordinates to get image coordinates
    return {
        x: Math.floor(worldCoordinate.x * scale),
        y: Math.floor(worldCoordinate.y * scale)
    }
}
Run Code Online (Sandbox Code Playgroud)