将 Lat/Long 转换为边界框内的 X、Y 位置
Convert Lat/Long to X,Y position within a Bounding Box
我有一个边界框:
Left -122.27671
Bottom 37.80445
Right -122.26673
Top 37.81449
也可以换成东北Lat/Long和西南Lat/Long
在该边界框内,我想找到特定 Lat/Long 的 X、Y 位置。这将使用墨卡托投影。
我看到的答案是使用墨卡托在世界地图上找到某个位置的 X、Y,但不是在特定的 lat/lon 内。
感谢任何帮助!
更新
把这个从我看到的另一个问题放在一起。任何人都可以验证这是否合法吗?
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
我们 s
是世界地图的偏移 space,以弧度为单位的底部纬度 B,顶部纬度 T。(我假设 y=0 是底部)
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
找到了一个我已经测试和验证过的更好的解决方案。将此发布给可能觉得它有用的其他人。它是用 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
我有一个边界框:
Left -122.27671
Bottom 37.80445
Right -122.26673
Top 37.81449
也可以换成东北Lat/Long和西南Lat/Long
在该边界框内,我想找到特定 Lat/Long 的 X、Y 位置。这将使用墨卡托投影。
我看到的答案是使用墨卡托在世界地图上找到某个位置的 X、Y,但不是在特定的 lat/lon 内。
感谢任何帮助!
更新 把这个从我看到的另一个问题放在一起。任何人都可以验证这是否合法吗?
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
我们 s
是世界地图的偏移 space,以弧度为单位的底部纬度 B,顶部纬度 T。(我假设 y=0 是底部)
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
找到了一个我已经测试和验证过的更好的解决方案。将此发布给可能觉得它有用的其他人。它是用 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