Reputation: 1625
Trying to create a static map with a circle like this
In the path
parameter I do not understand how to obtain the enc
part. This appears to be some encoded path that includes the lat/long and size of the circle.
https://maps.googleapis.com/maps/api/staticmap?
center=51.44208,5.47308&
zoom=14&
size=693x648&
path=color:blue|fillcolor:0x00d2c196|weight:1|
enc%3Aad_yHofn%60%40JyFh%40sF%60AcFxAmElBqD~BoCnCiBtC_AzCUzCTvC~%40lChB~BnCnBpDxAlE%60AbFf%40rFLxFMxFg%40rFaAbFyAlEoBpD_CnCmChBwC~%40%7BCT%7BCUuC_AoCiB_CoCmBqDyAmEaAcFi%40sFKyF%3F%3F
Link to Google's documentation
**EDIT: Found these:
Drawing a circle Google Static Maps
Encoded Polyline Algorithm Format
Upvotes: 2
Views: 9041
Reputation: 811
All the answers with GMapCircle could create a huge URL that will make Google respond with an error. If you have 2 or more circles, will get impossible to create this static map.
To create a circle, I did a small hack, instead of a real circle what I did was just a really small line, but with brush size the same of the circle diameter. What will happen is that it will look like a circle.
My GMapCircle function:
function GMapCircle(color, lat,lng,rad, zoom){
var staticMapSrc = '&path=color:0x' + color + '|weight:' + parseInt(rad*Math.pow(2, zoom)/72223);
staticMapSrc += "|" + lat.toFixed(4) + "," + lng.toFixed(4);
staticMapSrc += "|" + lat.toFixed(4) + "," + (lng + 0.0001).toFixed(4);
return staticMapSrc
}
In the above function, I add a small 0.0001 value to the longitude just to make a line, but so small that what will matter is the size of the brush (weight).
The weight (the size of the brush) depends of the diameter you want (rad) and it will decrease with your zoom.
This will create small lines for each circle you want that will look like a circle. I can fit almost 200 circles with this code without making the URL too long.
Upvotes: 0
Reputation: 93
I have rewritten it in javascript (as an Angular Service).
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { environment } from "environments/environment";
@Injectable({
providedIn: "root",
})
export class StaticMapService {
constructor(private httpClient: HttpClient) {}
getStaticMapBase64(
lat: number,
lng: number,
radius: string,
zoom: number
): Promise<string> {
return new Promise((resolve) => {
this.httpClient
.get(`https://maps.googleapis.com/maps/api/staticmap`, {
params: {
key: environment.googleMapsApiKey,
center: `${lat},${lng}`,
size: `640x480`,
zoom: `${zoom}`,
path: `fillcolor:0xff00002D|color:0xf96332ff|enc:${this.drawCirclePath(
lat,
lng,
radius
)}`,
},
responseType: "blob",
})
.toPromise()
.then((imgBlob) => {
const reader = new FileReader();
reader.readAsDataURL(imgBlob);
reader.onloadend = function () {
resolve(reader.result.toString());
};
});
});
}
private drawCirclePath(lat, lng, radius, detail = 8) {
let R = 6371;
let pi = Math.PI;
lat = (lat * pi) / 180;
lng = (lng * pi) / 180;
let d = radius / R;
let points: any = [];
let i = 0;
for (i = 0; i <= 360; i += detail) {
let brng = (i * pi) / 180;
let plat = Math.asin(
Math.sin(lat) * Math.cos(d) +
Math.cos(lat) * Math.sin(d) * Math.cos(brng)
);
let plng =
((lng +
Math.atan2(
Math.sin(brng) * Math.sin(d) * Math.cos(lat),
Math.cos(d) - Math.sin(lat) * Math.sin(plat)
)) *
180) /
pi;
plat = (plat * 180) / pi;
let currentPoints: any = [plat, plng];
points.push(currentPoints);
}
return this.createEncodings(points);
}
private createEncodings(coords) {
var i = 0;
var plat = 0;
var plng = 0;
var encoded_points = "";
for (i = 0; i < coords.length; ++i) {
var lat = coords[i][0];
var lng = coords[i][1];
encoded_points += this.encodePoint(plat, plng, lat, lng);
plat = lat;
plng = lng;
}
return encoded_points;
}
private encodePoint(plat, plng, lat, lng) {
var dlng = 0;
var dlat = 0;
var late5 = Math.round(lat * 1e5);
var plate5 = Math.round(plat * 1e5);
var lnge5 = Math.round(lng * 1e5);
var plnge5 = Math.round(plng * 1e5);
dlng = lnge5 - plnge5;
dlat = late5 - plate5;
return this.encodeSignedNumber(dlat) + this.encodeSignedNumber(dlng);
}
private encodeSignedNumber(num) {
var sgn_num = num << 1;
if (num < 0) {
sgn_num = ~sgn_num;
}
return this.encodeNumber(sgn_num);
}
private encodeNumber(num) {
var encodeString = "";
while (num >= 0x20) {
encodeString += String.fromCharCode((0x20 | (num & 0x1f)) + 63);
num >>= 5;
}
encodeString += String.fromCharCode(num + 63);
return encodeString;
}
}
Upvotes: 4
Reputation: 1625
Here's what I came up with:
function funcStaticMapWithCircle($lat, $lng) {
//$lat & $lng are center of circle
$mapCentLat = $lat + 0.002;
$mapCentLng = $lng - 0.011;
$mapW = 600;
$mapH = 600;
$zoom = 14;
$circRadius = 0.75; //Radius in km
$circRadiusThick = 1;
$circFill = '00BFFF';
$circFillOpacity = '60';
$circBorder = 'red';
$encString = GMapCircle($lat,$lng,$circRadius); //Encoded polyline string
$src = 'https://maps.googleapis.com/maps/api/staticmap?';
$src .= 'center=' .$mapCentLat. ',' .$mapCentLng. '&';
$src .= 'zoom=' .$zoom. '&';
$src .= 'size=' .$mapW. 'x' .$mapH.'&';
$src .= 'maptype=roadmap&';
$src .= 'style=feature:water|element:geometry.fill|color:0x9bd3ff&';
$src .= 'path=';
$src .= 'color:0x' .$circBorder. '00|';
$src .= 'fillcolor:0x' .$circFill.$circFillOpacity. '|';
$src .= 'weight:' .$circRadiusThick. '|';
$src .= 'enc:' .$encString;
return $src;
}
GMapCircle function is from: Drawing a circle Google Static Maps
Upvotes: 3