Exceeding the Maximum size for Google static Maps
The table below shows the maximum allowable values for the size
parameter at each scale
value.
API | scale=1 |
scale=2 |
scale=4 |
---|---|---|---|
Free | 640x640 |
640x640 (returns 1280×1280 pixels) |
Not available. |
Google Maps API for Business | 2048x2048 |
1024x1024 (returns 2048×2048 pixels) |
512x512 (returns 2048×2048 pixels) |
– As per Google’s documentation, this is the largest size images you can get from the Google Static Maps API
However, there is a work-around that allows for larger images to be returned from the Google static maps API. But it requires quite a bit of work. Basically, you need to find the adjacent tile to the requested tile.
For this, you need to flatten your longitude and latitudes into a flat x / y grid. Once you have X/Y coordinates, then you can use simple maths to pick up the next tile, then with these new x/y positions, you have to re-map this to the spherical projection of the world, to give you back longitude and latitude values.
Flattening and projecting latitude/longitude coordinates to x/y grid coordinates is done using the Mercator projection. Here is a modified version of Mercator.js, that you can include in your project.
var MERCATOR_RANGE = 256;
function bound(value, opt_min, opt_max) {
if (opt_min != null) value = Math.max(value, opt_min);
if (opt_max != null) value = Math.min(value, opt_max);
return value;
}function degreesToRadians(deg) {
return deg * (Math.PI / 180);
}function radiansToDegrees(rad) {
return rad / (Math.PI / 180);
}function MercatorProjection() {
this.pixelOrigin_ = {x: MERCATOR_RANGE / 2, y: MERCATOR_RANGE / 2};
this.pixelsPerLonDegree_ = MERCATOR_RANGE / 360;
this.pixelsPerLonRadian_ = MERCATOR_RANGE / (2 * Math.PI);
};MercatorProjection.prototype.fromLatLngToPoint = function(latLng) {
var me = this;var point = {x:0,y:0};
var origin = me.pixelOrigin_;
point.x = origin.x + latLng.lng * me.pixelsPerLonDegree_;
// NOTE(appleton): Truncating to 0.9999 effectively limits latitude to
// 89.189. This is about a third of a tile past the edge of the world tile.
var siny = bound(Math.sin(degreesToRadians(latLng.lat)), -0.9999, 0.9999);
point.y = origin.y + 0.5 * Math.log((1 + siny) / (1 – siny)) * -me.pixelsPerLonRadian_;
return point;
};MercatorProjection.prototype.fromPointToLatLng = function(point) {
var me = this;
var origin = me.pixelOrigin_;
var lng = (point.x – origin.x) / me.pixelsPerLonDegree_;
var latRadians = (point.y – origin.y) / -me.pixelsPerLonRadian_;
var lat = radiansToDegrees(2 * Math.atan(Math.exp(latRadians)) – Math.PI / 2);
return {lat:lat, lng:lng};
};
Let’s just quickly have a look at how the Google static maps API works.
function renderMap(image, LatLng)
{
image.attr(“src”,”http://maps.googleapis.com/maps/api/staticmap?center=” + LatLng.lat + “,” + LatLng.lng + “&zoom=10&size=400×400&sensor=false”);
}
This displays a map of a specified latitude and longitude at zoom level 10, and a 400×400 size image. The image parameter is a jquery collection object referring to a HTML IMG tag.
Now, to display a map at 55,-7 you’d call:
renderMap($(“#img11”),{lat:55,lng:-7});
Now, to apply some magic to this, and display the map tile immediately eastward of this map location, then I use this function:
function GetTileDelta(center,zoom,mapWidth,mapHeight,delta){
var proj = new MercatorProjection();
var scale = Math.pow(2,zoom);
var centerPx = proj.fromLatLngToPoint(center);
var DeltaPx = {
x: (centerPx.x + ((mapWidth / scale) * delta.x)) ,
y: (centerPx.y + ((mapHeight/ scale) * delta.y))
};
var DeltaLatLon = proj.fromPointToLatLng(DeltaPx);
return DeltaLatLon;
}
Which is called as follows:
var RightLatLng = GetTileDelta({lat:55,lng:-7},10,400,400,{x:+1,y:0});
renderMap($(“#img12”),RightLatLng);
How this works, is by “flattening” the globe using the mercator projection, using simple maths to shift the x position the width of the map over to the right (eastward), then folding the x/y coordinates over the globe using the mercator projecion again, to provide the lat/lon coordinates.
By extension, you can then use this to obtain any size map required.
But, doesn’t this return multiple google logos in the bottom right corner of every image?
LikeLike
How could this be written in .NET? I have tried to do it myself, but I am getting errors, overflows and being unable to cast… etc.
LikeLike