You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

WMS中定义Bounding Box后,如何指定单维度获取正确图像尺寸比例

How to get correctly scaled WMS map by defining only bbox and one dimension (height or width)?

I'm connecting to a WMS service and saving cropped maps. Ideally, I want to only define the bounding box (bbox) and either the output image height or width (in pixels) to get the correct aspect ratio. However, I get an error when defining only height or width—only when specifying both dimensions in the size parameter does it work properly (example code below):

from owslib.wms import WebMapService
url = 'https://rasterdata.hunzeenaas.nl/erdas-iws/ogc/wms/Rasterdata?service=WMS&request=getmap'
wms = WebMapService(url)
img = wms.getmap(
    layers=['Luchtfoto_2015_Ortho_25cm_RGB_voorjaarsvlucht'], 
    styles=['default'], 
    srs='EPSG:3857', 
    bbox=(72865, 7022456, 730231, 7023717), 
    size=(1000,1000), 
    format='image/jpeg', 
    transparent=True
)
out = open('output.jpg', 'wb')
out.write(img.read())
out.close()

How can I get the correct image dimension ratio while only defining the bounding box and one of the two size parameters?


Solution: Calculate the missing dimension using the bbox aspect ratio

Got it, let's fix this! Most WMS implementations require explicit values for both width and height in the size parameter, but we can compute the missing dimension using the actual geographic bounds of your bbox. Here's a step-by-step approach:

  1. Extract the bbox dimensions: Calculate the real-world width and height from your bbox values (format is (minx, miny, maxx, maxy)).
  2. Compute the aspect ratio: Find the ratio of height to width (or vice versa) from the bbox.
  3. Calculate the missing pixel dimension: Use your desired width or height to derive the other value while preserving the aspect ratio.

Here's the modified code that implements this logic—let's say you want to set a fixed width of 1000 pixels and let the height adjust automatically:

from owslib.wms import WebMapService

# WMS setup
url = 'https://rasterdata.hunzeenaas.nl/erdas-iws/ogc/wms/Rasterdata?service=WMS&request=getmap'
wms = WebMapService(url)

# Define your parameters
bbox = (72865, 7022456, 730231, 7023717)
desired_width = 1000  # Or set desired_height instead
srs = 'EPSG:3857'
layer = 'Luchtfoto_2015_Ortho_25cm_RGB_voorjaarsvlucht'

# Calculate bbox dimensions
minx, miny, maxx, maxy = bbox
bbox_width = maxx - minx
bbox_height = maxy - miny

# Compute aspect ratio and missing dimension
aspect_ratio = bbox_height / bbox_width
if desired_width:
    calculated_height = int(desired_width * aspect_ratio)
    size = (desired_width, calculated_height)
else:
    # If you wanted to set desired_height instead
    desired_height = 800  # Example value
    calculated_width = int(desired_height / aspect_ratio)
    size = (calculated_width, desired_height)

# Fetch the map with correctly sized dimensions
img = wms.getmap(
    layers=[layer],
    styles=['default'],
    srs=srs,
    bbox=bbox,
    size=size,
    format='image/jpeg',
    transparent=True
)

# Save the output (using a context manager for cleaner code)
with open('output.jpg', 'wb') as out:
    out.write(img.read())

Key Notes:

  • SRS Units: This works because EPSG:3857 uses meters as units, so the bbox width/height calculations are consistent. If you're using a geographic SRS (like EPSG:4326, degrees), the aspect ratio still holds—just make sure you're calculating the ratio correctly (height in degrees divided by width in degrees).
  • Integer Pixels: We convert the calculated dimension to an integer because WMS servers expect whole pixel values.
  • Error Handling: You might want to add checks to ensure bbox_width isn't zero (to avoid division by zero) if your bbox could be invalid.

内容的提问来源于stack exchange,提问作者Jeroen

火山引擎 最新活动