Reputation: 135
I would like to draw a shape which consists of a circle with a certain diameter and a rectangle with the same center, but less wide and longer.
An example is the grey shape in the right top corner of this image: http://nl.ivao.aero/extern/pictures/AIRSP004.jpg
Now I could obviously use a seperate circle and rectangle on top of eachother, but that wouldn't yield the results I'm looking for since the overlapping part would have double opacity and/or an ugly border on the internal overlapping part.
Is there a possibility to create such a "complex" shape/polygon? Or a way to fake it without having the aforementioned problem of double opacity?
This is the code I came up with, fully based on Dr.Molle's answer.
Screenshot of the result: Groningen Airport Eelde CTR
var CTRs = [{
name: 'Eelde CTR',
segments: [{
type: 'point',
coords: {"lat":53.041097,"lng":6.271475}
},{
type: 'curve',
start: {"lat":53.105131,"lng":6.406608},
end: {"lat":53.223394,"lng":6.658117},
center: {"lat":53.125000,"lng":6.583333},
radius: 6.5
},{
type: 'point',
coords: {"lat":53.286983,"lng":6.794394}
},{
type: 'point',
coords: {"lat":53.208306,"lng":6.896883}
},{
type: 'curve',
start: {"lat":53.144606,"lng":6.760219},
end: {"lat":53.026556,"lng":6.508892},
center: {"lat":53.125000,"lng":6.583333},
radius: 6.5
},{
type: 'point',
coords: {"lat":52.962414,"lng":6.373378}
}]
}];
function drawCTRs()
{
for ( var i = 0; i < CTRs.length; i++ )
{
drawAirspace(CTRs[i]);
}
}
function circleSegment(start, end, center, radius, points)
{
points = points || 180;
var a = [];
var startHeading = ( google.maps.geometry.spherical.computeHeading(center, start) + 360 ) % 360;
var endHeading = ( google.maps.geometry.spherical.computeHeading(center, end) + 360 ) % 360;
var heading = startHeading;
radius *= 1852;
var headingIncr = Math.abs((((endHeading - startHeading) + 360) % 360) / points);
for ( var i = 0; i < points; i++, heading += headingIncr )
{
heading = heading % 360;
a.push(new google.maps.geometry.spherical.computeOffset(center, radius, heading));
}
return a;
}
function drawAirspace( airspace )
{
var path = [];
for ( var i = 0; i < airspace.segments.length; i++ )
{
if ( airspace.segments[i].type == 'point' )
{
path.push(new google.maps.LatLng(airspace.segments[i].coords.lat, airspace.segments[i].coords.lng));
} else if ( airspace.segments[i].type == 'curve' )
{
path = path.concat(circleSegment(
new google.maps.LatLng(airspace.segments[i].start.lat, airspace.segments[i].start.lng),
new google.maps.LatLng(airspace.segments[i].end.lat, airspace.segments[i].end.lng),
new google.maps.LatLng(airspace.segments[i].center.lat, airspace.segments[i].center.lng),
airspace.segments[i].radius,
100
));
}
}
var airspaceOverlay = new google.maps.Polygon({
paths: path,
map: map,
title: airspace.name,
strokeColor: '#770000',
strokeWeight: 2,
fillColor: '#770000',
fillOpacity: .2
})
}
Upvotes: 0
Views: 777
Reputation: 117314
First you'll need to get the points for the circle to be able to create a polygon that looks like a circle(See: How to draw a circle using polygon in GoogleMaps)
Based on this path it's not hard to break the circle and add custom points. Modified function based on the linked answer:
function circlePath(center,radius,points){
var a=[],p=360/points,d=0,pp;
for(var i=0;i<points;++i,d+=p){
pp=google.maps.geometry.spherical.computeOffset(center,radius,d);
if(d%180==20){
a.push(google.maps.geometry.spherical.computeOffset(pp,radius*.7,45+(d-(d%180))));
i+=44;d+=(44*p);
}
else if(d%180==65){
a.push(google.maps.geometry.spherical.computeOffset(pp,radius*.7,45+(d-(d%180))));
}
else{
a.push(pp);
}
}
return a;
}
Demo: http://jsfiddle.net/doktormolle/1nmcd2nv/
Upvotes: 2