在静态Mapbox img上计算纬度

问题描述 投票:-1回答:2

我有一个只有中心点经/纬度的静态图像(例如https://api.mapbox.com/styles/v1/mapbox/light-v9/static/-78.4649,42.5128,5,0,0/300x200),我想在画布的帮助下在地图上放置一些标记(经度.long)。但是我需要以某种方式计算这些标记的xy坐标。因此,我知道了地图的中心(纬度/经度)和纬度/经度标记坐标。有什么方法可以将lat / long转换为xy,仅知道缩放级别和中心?

或者如果我知道中心纬度/经度(始终等于150px * 100px)和缩放级别的xy,我可以计算其他标记的xy吗?

我有很多标记(> 200,并且它们都是自定义的svg生成的,依此类推),以将其放置在此地图上。由于标记的限制等原因,我无法使用mapbox mapbox静态地图。

mapbox geospatial mapbox-gl
2个回答
1
投票

如果要进行线性插值,则需要知道2点的经/纬度和x / y。除非您还有像素转换指标(即),否则仅靠中心点是不可能的。 50个像素为0.1纬度/经度。

如果您有两个点的纬度/经度和x / y,则可以将比率创建为y1- y2 / lat1-lat2或x1-x2 / long1-long2,每个比率应得出相同的比率

然后相对容易,假设比率为5表示5px/l,因此您有一个距该中心点(3,-4)的点,您只需乘以倍数即可找到像素偏移量( 15,-20),并将其添加到中心=(165,80)。

由于所有图像都以相同的比例缩放,因此您可以手动计算一次比率并将其存储为常数。

sudo / unested python:

def getRatio(latlongs=[(1,1),(0,0)], xys=[(5,5),(0,0)]:
  return (xys[0][1]-xys[1][1]) / (latlongs[0][0] - latlongs[1][0])

centerLatLong = (5,5)
centerXY = (150, 100)

def getCoord(lat,long,ratio):
  y = (lat-centerLatLong[0])*ratio + centerXY[1]
  x = (long-centerLatLong[1])*ratio + centerXY[0]
  return x, y

0
投票

[基于OP注释,为简单起见,我假设所请求的图像是正方形的(TILE_SIZE可以分解为TILE_SIZE_XTILE_SIZE_Y组件)。我还假设图像的宽度为256像素TILE_SIZE=256

我同时给出相对于图像中心(distanceInPixels功能)和相对于左下角(imageCoordinates功能)的像素坐标。在必要的情况下更改为左上角是无关紧要的(X等于Y = TILE_SIZE -Y)。

<!DOCTYPE html>
<html>
<body>      
<p id="demo"></p>    
<script>
    var latLngMarker = {};
    var latLngCenter = {};  
// Image dimensions in pixels
    var TILE_SIZE = 256; 
    var zoom = 5;   
// Coordinates of the marker to be projected on the image
    latLngMarker.lat = 41.850;
    latLngMarker.lng = -87.650; 
// Coordinates of the image center  
    latLngCenter.lat = 41.850; 
    latLngCenter.lng = -87.650;
// Coordinates projected on the cartographic plane (Mercator)     
    var centerProjected = project(latLngCenter);
    var markerProjected = project(latLngMarker);

// The result should be X=Y=0, because I made Marker Lat Lng  = Center Lat Lng
    var distanceFromCenter = distanceInPixels(centerProjected, markerProjected);
    alert("X: " + distanceFromCenter.x + " Y: " + distanceFromCenter.y);

// The result should be X=Y=256/2=128 for the same reason      
    var coords = imageCoordinates(centerProjected, markerProjected);
    alert("X: " + coords.x + " Y: " + coords.y);

    // The horizontal distance represented by one pixel for a given latitude and zoom level
    function pixelResolution (latLng, zoom) {
        var radius = 6378137.0 // semi-axis of WGS84 ellipsoid
        var circumference =  2 * Math.PI * radius;
        var distancePerImage = circumference * Math.cos(latLng.lat * Math.PI / 180.0) / Math.pow(2,zoom);
        var distancePerPixel = distancePerImage / TILE_SIZE;
        return distancePerPixel
    }   

    // Web mercator projection.
    function project(latLng) {
        var siny = Math.sin(latLng.lat * Math.PI / 180);
        siny = Math.min(Math.max(siny, -0.9999), 0.9999);
        var xy = {};
        xy.x = TILE_SIZE * (0.5 + latLng.lng / 360);
        xy.y = TILE_SIZE * (0.5 - Math.log((1 + siny) / (1 - siny)) / (4 * Math.PI));       
        return xy
    }

    // Marker pixel coordinates relative to the image Center 
    function distanceInPixels(centerProjected, markerProjected) {
        var delta = {};
        var spacing = pixelResolution(latLngCenter, zoom);
        delta.x = Math.round((centerProjected.x - markerProjected.x)/spacing);
        delta.y = Math.round((centerProjected.y - markerProjected.y)/spacing);
        return delta
    }   

    // Marker pixel coordinates relative to the Lower Left Corner
    function imageCoordinates(centerProjected, markerProjected) {
        var pixelCoordinates = {};
        var spacing = pixelResolution(latLngCenter, zoom);
        var deltaPixels = distanceInPixels(centerProjected, markerProjected);
        pixelCoordinates.x = TILE_SIZE / 2 - deltaPixels.x;
        pixelCoordinates.y = TILE_SIZE / 2 - deltaPixels.y;
        return pixelCoordinates
    }       
</script>    
</body>
</html>

注意:我可以确认pixelResolution功能仅适用于2的幂次方的正方形图像图块。Math.pow(2,zoom);代码段将使游戏消失!

基于Web墨卡托功能:

https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/map-coordinates

从:的一个像素表示的水平距离

https://wiki.openstreetmap.org/wiki/Zoom_levels

另请参见:

https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale

© www.soinside.com 2019 - 2024. All rights reserved.