将Lat / Long转换为边界框内的X,Y位置

时间:2017-01-09 22:16:58

标签: math maps 2d mercator

我有一个方框:

Left -122.27671
Bottom 37.80445
Right -122.26673
Top 37.81449

它也可以转换为NE Lat / Long和SW Lat / Long

在该边界框内,我想找到特定Lat / Long的X,Y位置。这将使用墨卡托投影。

我已经看过使用墨卡托找到世界地图上某个位置的X,Y的答案,但不是在特定的纬度/经度内。

任何帮助表示赞赏!

更新 从我看到的另一个问题把它放在一起。任何人都可以验证这看起来是否合法?

map_width = 1240
map_height = 1279

map_lon_left = -122.296916
map_lon_right = -122.243380
map_lon_delta = map_lon_right - map_lon_left

map_lat_bottom = 37.782368
map_lat_bottom_degree = map_lat_bottom * Math::PI / 180

def convert_geo_to_pixel(lat, long)
  x = (long - map_lon_left) * (map_width / map_lon_delta)

  lat = lat * Math::PI / 180
  world_map_width = ((map_width / map_lon_delta) * 360) / (2 * Math::PI)
  map_offset_y = (world_map_width / 2 * Math.log((1 + Math.sin(map_lat_bottom_degree)) / (1 - Math.sin(map_lat_bottom_degree))))
  y = map_height - ((world_map_width / 2 * Math.log((1 + Math.sin(lat)) / (1 - Math.sin(lat)))) - map_offset_y)

  return [x, y]
end

2 个答案:

答案 0 :(得分:1)

找到了一个更好的解决方案,我已经过测试和验证。将此发布给可能发现它有用的任何其他人。它是用Ruby编写的,但很容易转换成任何其他语言

@north = to_radians(37.81449)
@south = to_radians(37.80445)
@east = to_radians(-122.26673)
@west = to_radians(-122.27671)
# Coordinates above are a subsection of Oakland, CA

@map_width = map_width
@map_height = map_height

def location_to_pixel(lat:, lon:)
  lat = to_radians(lat)
  lon = to_radians(lon)
  ymin = mercator_y(@south)
  ymax = mercator_y(@north)
  x_factor = @map_width/(@east - @west)
  y_factor = @map_height/(ymax - ymin)

  y = mercator_y(lat);
  x = (lon - @west) * x_factor
  y = (ymax - y) * y_factor
  [x, y]
end

def to_radians(deg)
  deg * Math::PI/180
end

def mercator_y(lat)
    Math.log(
      Math.tan(lat/2 + Math::PI/4)
    )
end

答案 1 :(得分:0)

让我们s是世界空间中的地图移位,弧度B的底部纬度,顶部纬度T.(我假设y = 0是底部)

enter image description here

C * Sin(B) = 0 + s
C * Sin(T) = map_height + s
=>
C = map_height / (Sin(T) - Sin(B))
s = C * Sin(B)
y = C * Sin(Lat) - s = 
    C * Sin(Lat) - C * Sin(B) = 
    C * (Sin(Lat) - Sin(B)) = 
    map_height * (Sin(Lat) - Sin(B) / (Sin(T) - Sin(B))

        // note - resembles linear interpolation is sine space