WMS中定义Bounding Box后,如何指定单维度获取正确图像尺寸比例
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?
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:
- Extract the bbox dimensions: Calculate the real-world width and height from your bbox values (format is
(minx, miny, maxx, maxy)). - Compute the aspect ratio: Find the ratio of height to width (or vice versa) from the bbox.
- 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_widthisn't zero (to avoid division by zero) if your bbox could be invalid.
内容的提问来源于stack exchange,提问作者Jeroen




