2017-02-13 70 views
1

我试图从中心坐标以特定比例创建边界框。我试图将其保持在8.5x11英寸纸张(612x792像素@ 72dpi)的宽高比内。从中心坐标创建边界框

我在下面使用的代码主要是作品,但高度似乎有点过高,一个字母的长宽比。我没有考虑mercator投影吗?我在这里错过了什么?

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 

它返回:

west: -122.27172131608657, 
east: -122.26952868391342, 
south: 37.804917238005615 
north: 37.80775476199439 

如果你去http://www.openstreetmap.org/export和输入这些边界框坐标,你可以看到,比例不匹配一张8.5x11英寸的纸......它稍微高一点。我在这里做错了什么或不理解?

+0

它不像墨卡托投影那么重要,因为当你离开赤道时,经线距离越近越好。你的地图不是太高,太瘦了, –

+0

@RonJensen请看http://stackoverflow.com/a/2913249/4504607 –

+0

那么你如何调整呢? – theartofbeing

回答

0

这是我的解决方案!

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