从中心坐标创建边界框
Create bounding box from center coordinate
我正在尝试从中心坐标创建一个特定比例的边界框。我试图将其保持在 8.5x11 英寸纸的纵横比范围内(612x792 像素 @ 72dpi)。
我在下面使用的代码大部分都有效,但高度对于字母的纵横比来说似乎有点太高了。我不考虑墨卡托投影吗?我在这里错过了什么?
def bounding_box_from_point(center:, size:, scale_denominator:)
dpi = 72
inches_per_unit = 4374754
resolution = 1 / (scale_denominator * inches_per_unit * dpi)
half_width_deg = (size.width * resolution) / 2
half_height_deg = (size.height * resolution) / 2
BoundingBox.new(
north: center.lat + half_height_deg,
south: center.lat - half_height_deg,
east: center.lon + half_width_deg,
west: center.lon - half_width_deg
)
end
通过以下方式调用 bounding_box_from_point(center: center, size: size, scale_denominator: scale)
:
scale = 0.0008861342166177423 (i.e. 1/18055.955520)
center = Geometry::Location.new(lat: 37.806336, lon: -122.270625)
size.width = 612,
size.height = 792
它returns:
west: -122.27172131608657,
east: -122.26952868391342,
south: 37.804917238005615
north: 37.80775476199439
如果您转到 http://www.openstreetmap.org/export 并输入那些边界框坐标,您会看到该比例与 8.5x11 英寸的纸的比例不匹配...它有点太高了。我哪里做错了或者没理解?
我的实现解决了这个问题!
def self.bounding_box_from_location(location:, scale:)
scale_meters_per_pixel = 0.0003
# scale.zoom is an integer between 0-19
# See http://wiki.openstreetmap.org/wiki/Zoom_levels for a description on `zoom`
# location.lat_rad is the latitude in radians, same for lon_rad
meters_per_pixel = EARTH_CIR * Math.cos(location.lat_rad) / (2 ** (scale.zoom + 8))
earth_meters_per_pictureMeters = meters_per_pixel / scale_meters_per_pixel
# height/width in meters is the height/width of the box you're applying this to
# In my case I'm using the heigh/width of a Letter of paper
# You can convert Pixels to meters (@ 72dpi) with
# pixels * 0.00035277777777777776
meters_north = earth_meters_per_pictureMeters * scale.height_in_meters / 2
meters_east = earth_meters_per_pictureMeters * scale.width_in_meters / 2
meters_per_degree_lat = 111111.0
meters_per_degree_long = 111111.0 * Math.cos(location.lat_rad)
degrees_north = meters_north / meters_per_degree_lat
degrees_east = meters_east / meters_per_degree_long
BoundingBox.new(
north: (location.lat + degrees_north),
south: location.lat - degrees_north,
east: location.lon + degrees_east,
west: location.lon - degrees_east,
width: scale.width_in_pixels,
height: scale.height_in_pixels
)
end
我正在尝试从中心坐标创建一个特定比例的边界框。我试图将其保持在 8.5x11 英寸纸的纵横比范围内(612x792 像素 @ 72dpi)。
我在下面使用的代码大部分都有效,但高度对于字母的纵横比来说似乎有点太高了。我不考虑墨卡托投影吗?我在这里错过了什么?
def bounding_box_from_point(center:, size:, scale_denominator:)
dpi = 72
inches_per_unit = 4374754
resolution = 1 / (scale_denominator * inches_per_unit * dpi)
half_width_deg = (size.width * resolution) / 2
half_height_deg = (size.height * resolution) / 2
BoundingBox.new(
north: center.lat + half_height_deg,
south: center.lat - half_height_deg,
east: center.lon + half_width_deg,
west: center.lon - half_width_deg
)
end
通过以下方式调用 bounding_box_from_point(center: center, size: size, scale_denominator: scale)
:
scale = 0.0008861342166177423 (i.e. 1/18055.955520)
center = Geometry::Location.new(lat: 37.806336, lon: -122.270625)
size.width = 612,
size.height = 792
它returns:
west: -122.27172131608657,
east: -122.26952868391342,
south: 37.804917238005615
north: 37.80775476199439
如果您转到 http://www.openstreetmap.org/export 并输入那些边界框坐标,您会看到该比例与 8.5x11 英寸的纸的比例不匹配...它有点太高了。我哪里做错了或者没理解?
我的实现解决了这个问题!
def self.bounding_box_from_location(location:, scale:)
scale_meters_per_pixel = 0.0003
# scale.zoom is an integer between 0-19
# See http://wiki.openstreetmap.org/wiki/Zoom_levels for a description on `zoom`
# location.lat_rad is the latitude in radians, same for lon_rad
meters_per_pixel = EARTH_CIR * Math.cos(location.lat_rad) / (2 ** (scale.zoom + 8))
earth_meters_per_pictureMeters = meters_per_pixel / scale_meters_per_pixel
# height/width in meters is the height/width of the box you're applying this to
# In my case I'm using the heigh/width of a Letter of paper
# You can convert Pixels to meters (@ 72dpi) with
# pixels * 0.00035277777777777776
meters_north = earth_meters_per_pictureMeters * scale.height_in_meters / 2
meters_east = earth_meters_per_pictureMeters * scale.width_in_meters / 2
meters_per_degree_lat = 111111.0
meters_per_degree_long = 111111.0 * Math.cos(location.lat_rad)
degrees_north = meters_north / meters_per_degree_lat
degrees_east = meters_east / meters_per_degree_long
BoundingBox.new(
north: (location.lat + degrees_north),
south: location.lat - degrees_north,
east: location.lon + degrees_east,
west: location.lon - degrees_east,
width: scale.width_in_pixels,
height: scale.height_in_pixels
)
end