You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, if you generate a SVG based on bounds, it will contain more than just the bounds you gave, because we have to specify output width and height, and also because zoom level are integers.
It would be awesome be able to let the program choose the output size based on the given bounds (or have a minWidth, minHeight instead).
Current behavior:
The code:
import staticmaps
import s2sphere
import sys
context = staticmaps.Context()
# add bounds on east Canada
context.add_bounds(s2sphere.LatLngRect(
s2sphere.LatLng.from_degrees(43.26120612479979, -79.859619140625),
s2sphere.LatLng.from_degrees(49.475263243037986, -63.017578125)
))
context.set_tile_provider(staticmaps.tile_provider_OSM)
svg_image = context.render_svg(2000, 2000)
with open("output.svg", "w", encoding="utf-8") as f:
svg_image.write(f, pretty=True)
I think that we should be able to call the render_svg method with minWidth and minHeight arguments which would let the program choose a better zoom level, to perfectly fit the bounds.
Here is how it could work:
User defines bounds
User defines minWidth and minHeight
The program would determine on it's own which size the output file should be to fit the bounds
It renders the SVG with the viewbox matching the size
I would be ok to work on it, I already tried to do a first version but the mathematics used in the context._determine_zoom function are complicated, I don't know the formulas and I'm not sure to understand the variables.
I know that I can return return self._clamp_zoom(zoom) instead of return self._clamp_zoom(zoom - 1) but I don't know how to determine the output size.
Thank you very much. As I said, if you think that you won't have the time to do it, maybe you can guide me (with some links on how the math works to get the zoom, and how we could get the new output dimensions for instance)
I haven't looked into the code in detail, just read through the text of pull request #19, but I suspect that it tried to solve the same issue.
You could check that code.
Thanks for your comment, it seems that indeed, it tries to solve the same issue, however it's done only for non-svg outputs, it's done by cropping the image using the min and max X and Y of the rendered objects, which (I think) won't work with SVGs
Is it possible (for all providers) to set an arbitrary tile size?
Could it be a solution to calculate the optimum tile size?
This is the result with tile size = 200px
I'm also interested in the "precision" of the bounds for cairo output in particular.
Is difficult to at leas add a flag to know ad the end of the process the "real" bound included in the output image?
Thankyou
I am afraid, I don't get Your point.
What exactly is Your question?
In my example above, the map image is "tightened" to the given boundary - plus the "extra" boundaries for the marker object.
This is for all objects - they have a "positioning point" and "extra" boundaries top, right, bottom and left which are added to the regular boundary to make sure the object is fully covered with the map image.
If You remove the objects, You should get an image with the "pure" boundaries.
BTW: the afore mentioned branch in my fork doesn't exist any more, but the feature is included in the main branch, not "master".
Activity
flopp commentedon Nov 16, 2021
That's a valid point. I will look into it.
qlereboursBS commentedon Nov 16, 2021
Thank you very much. As I said, if you think that you won't have the time to do it, maybe you can guide me (with some links on how the math works to get the zoom, and how we could get the new output dimensions for instance)
lowtower commentedon Nov 16, 2021
I haven't looked into the code in detail, just read through the text of pull request #19, but I suspect that it tried to solve the same issue.
You could check that code.
qlereboursBS commentedon Nov 16, 2021
Thanks for your comment, it seems that indeed, it tries to solve the same issue, however it's done only for non-svg outputs, it's done by cropping the image using the min and max X and Y of the rendered objects, which (I think) won't work with SVGs
lowtower commentedon Jan 19, 2022
Hello @flopp and @qlereboursBS,
as far as I understand the code:
lowtower commentedon Jan 19, 2022
Is it possible (for all providers) to set an arbitrary tile size?

Could it be a solution to calculate the optimum tile size?
This is the result with tile size = 200px
lowtower commentedon Jan 21, 2022
Hello @flopp and @qlereboursBS,
I have coded a different approach for svg:
You can check it out at my branch https://github.com/lowtower/py-staticmaps/tree/feature/tighten_to_bounds
Drawbacks up to now:
line thickness is not consideredmarker size is not considered (might get complicated to consider with custom markers)Questions:
would the consideration of marker size and line thickness be desired?at the moment it is the only behavior. Would it be better to add a command line parameter to switch it on and off?I'll have a look at cairo and pillow as well if this is of interest
netvandal commentedon Mar 8, 2023
I'm also interested in the "precision" of the bounds for cairo output in particular.
Is difficult to at leas add a flag to know ad the end of the process the "real" bound included in the output image?
Thankyou
lowtower commentedon Mar 13, 2023
Hello @netvandal,
I am afraid, I don't get Your point.
What exactly is Your question?
In my example above, the map image is "tightened" to the given boundary - plus the "extra" boundaries for the marker object.
This is for all objects - they have a "positioning point" and "extra" boundaries top, right, bottom and left which are added to the regular boundary to make sure the object is fully covered with the map image.
If You remove the objects, You should get an image with the "pure" boundaries.
BTW: the afore mentioned branch in my fork doesn't exist any more, but the feature is included in the main branch, not "master".
Cheers,
LT