Trying to create a 'lozenge' with google maps API










-1















I am current using google maps API to plot points on a map. I am looking for the best way to achieve a 'lozenge' type effect between points (see image).
Essentially the thickness of the lozenge will be determined dynamically.



The only way I can see to do this, is to draw 2 circles at the ends of my points, and create a rectangle in between them, with no borders. I don't like this idea, as it essentially adds 3 polygons to my map for each line I have, and means that I would have to then add 3 click events for each line (one on each polygon) to display data that I want to show, when clicking on the line.



Is there any better way to achieve this?



enter image description here










share|improve this question



















  • 1





    possible duplicate of How to draw a polygon around a polyline in JavaScript?

    – geocodezip
    Nov 13 '18 at 1:02











  • fiddle using code from that duplicate

    – geocodezip
    Nov 13 '18 at 1:44















-1















I am current using google maps API to plot points on a map. I am looking for the best way to achieve a 'lozenge' type effect between points (see image).
Essentially the thickness of the lozenge will be determined dynamically.



The only way I can see to do this, is to draw 2 circles at the ends of my points, and create a rectangle in between them, with no borders. I don't like this idea, as it essentially adds 3 polygons to my map for each line I have, and means that I would have to then add 3 click events for each line (one on each polygon) to display data that I want to show, when clicking on the line.



Is there any better way to achieve this?



enter image description here










share|improve this question



















  • 1





    possible duplicate of How to draw a polygon around a polyline in JavaScript?

    – geocodezip
    Nov 13 '18 at 1:02











  • fiddle using code from that duplicate

    – geocodezip
    Nov 13 '18 at 1:44













-1












-1








-1








I am current using google maps API to plot points on a map. I am looking for the best way to achieve a 'lozenge' type effect between points (see image).
Essentially the thickness of the lozenge will be determined dynamically.



The only way I can see to do this, is to draw 2 circles at the ends of my points, and create a rectangle in between them, with no borders. I don't like this idea, as it essentially adds 3 polygons to my map for each line I have, and means that I would have to then add 3 click events for each line (one on each polygon) to display data that I want to show, when clicking on the line.



Is there any better way to achieve this?



enter image description here










share|improve this question
















I am current using google maps API to plot points on a map. I am looking for the best way to achieve a 'lozenge' type effect between points (see image).
Essentially the thickness of the lozenge will be determined dynamically.



The only way I can see to do this, is to draw 2 circles at the ends of my points, and create a rectangle in between them, with no borders. I don't like this idea, as it essentially adds 3 polygons to my map for each line I have, and means that I would have to then add 3 click events for each line (one on each polygon) to display data that I want to show, when clicking on the line.



Is there any better way to achieve this?



enter image description here







google-maps-api-3 google-polyline






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 1:38









geocodezip

125k10142172




125k10142172










asked Nov 13 '18 at 0:57









jonahpupjonahpup

5010




5010







  • 1





    possible duplicate of How to draw a polygon around a polyline in JavaScript?

    – geocodezip
    Nov 13 '18 at 1:02











  • fiddle using code from that duplicate

    – geocodezip
    Nov 13 '18 at 1:44












  • 1





    possible duplicate of How to draw a polygon around a polyline in JavaScript?

    – geocodezip
    Nov 13 '18 at 1:02











  • fiddle using code from that duplicate

    – geocodezip
    Nov 13 '18 at 1:44







1




1





possible duplicate of How to draw a polygon around a polyline in JavaScript?

– geocodezip
Nov 13 '18 at 1:02





possible duplicate of How to draw a polygon around a polyline in JavaScript?

– geocodezip
Nov 13 '18 at 1:02













fiddle using code from that duplicate

– geocodezip
Nov 13 '18 at 1:44





fiddle using code from that duplicate

– geocodezip
Nov 13 '18 at 1:44












2 Answers
2






active

oldest

votes


















1














Just create 2 Polylines...






function initialize() 

var map = new google.maps.Map(document.getElementById('map-canvas'),
zoom: 3,
center: lat: 20, lng: 0,
mapTypeId: 'terrain'
);

var flightPlanCoordinates = [
lat: 20, lng: -20,
lat: 20, lng: 20
];

new google.maps.Polyline(
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: .3,
strokeWeight: 20,
map: map
);

new google.maps.Polyline(
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 1,
map: map
);


initialize();

#map-canvas 
height: 200px;

<div id="map-canvas"></div>

<script src="https://maps.googleapis.com/maps/api/js"></script>





Edit:



You mentioned in your comment you need the stroke to be fixed at a given distance from the center line.



You could still use that technique I think, as you can calculate the size in meters of a map pixel, based on the latitude and the zoom level, and as the size of the stroke is also in pixels, you should be able to recalculate the stroke each time you zoom-in/out. It won't be 100% precise since the stroke width must be an integer, but it should work.



It should work if the various Polyline points are more or less on the same latitude, because the resolution of a map with the Mercator projection is dependent on the latitude. So, for example if you have a big Polyline crossing from -70 to +70 latitude, it won't be accurate all the way.



This is the formula you can use to compute the size of 1 map pixel. You would need to replace map.getCenter().lat() by your Polyline center point.



// Calculate the width of 1 map pixel in meters
let scale = 156543.03392 * Math.cos(map.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());


Unfortunately, there is an issue with this approach. Although it's undocumented, a Polyline stroke width can't be bigger than 32px.






var map;
var polyBounds;
var polyStroke;
var polyWidth = 50; // Width in meters

function initialize()

map = new google.maps.Map(document.getElementById('map-canvas'),
zoom: 12,
center:
lat: 20,
lng: 0
,
mapTypeId: 'terrain'
);

var flightPlanCoordinates = [
lat: 20,
lng: -0.5
,

lat: 20,
lng: 0.5

];

polyStroke = new google.maps.Polyline(
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: .3,
strokeWeight: 0,
map: map
);

new google.maps.Polyline(
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 1,
map: map
);

polyBounds = new google.maps.LatLngBounds();

for (var i = 0; i < flightPlanCoordinates.length; i++)

polyBounds.extend(flightPlanCoordinates[i]);


google.maps.event.addListenerOnce(map, 'idle', setStroke);
google.maps.event.addListener(map, 'zoom_changed', setStroke);


function setStroke()

// Calculate the width of 1 map pixel in meters
let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

polyStroke.setOptions(
strokeWeight: Math.ceil(polyWidth / scale)
);


initialize();

#map-canvas 
height: 200px;

<div id="map-canvas"></div>

<script src="https://maps.googleapis.com/maps/api/js"></script>





So unless you find out that these values allow for your use case, this won't be a viable solution...



The solution you were pointed to in the comments (How to draw a polygon around a polyline in JavaScript?) is still probably your best option.






share|improve this answer

























  • Hi, thanks. The problem with that though is when you zoom, it doesn't scale the width of the shadow with it... I looked at using svg as well, but that had the same effect. I need to keep the outline constrained to x metres from the line.

    – jonahpup
    Nov 13 '18 at 2:30











  • See my edits. That's a fail, for one simple reason... you can't set a Polyline stroke width that is bigger than 32px :( It might be worth opening a feature request to allow for bigger values...

    – MrUpsidown
    Nov 13 '18 at 10:10






  • 1





    FYI, I have created this feature request to which you can subscribe in the hope that Google will change something... at some point. But that can take a very long time... :(

    – MrUpsidown
    Nov 13 '18 at 10:35






  • 1





    Hi, thanks for you help.. what i've ended up doing is just creating a polyline to show the path... and then using the start and end points, and racking my brain back to high school trigonometry, I have just created an arc at each end of the line with a set radius... this works perfectly, was just a bit more heavy lifting than I would have liked..

    – jonahpup
    Nov 14 '18 at 21:32











  • Cool. Feel free to post your solution as a separate answer as it might help someone else!

    – MrUpsidown
    Nov 15 '18 at 9:45


















0














I actually discovered a much easier way to achieve this using the google maps API.
There are built in functions for getting a bearing of a point based on a start point...
So I created a function that takes the start and end points of a line, and then creates points around these based on the heading - then create a polygon using those points.



var pointCount = 12;
function setLozengePath(startPoint, endPoint)
var sp = google.maps.geometry.spherical;
var heading = sp.computeHeading(startPoint, endPoint);

var points = ;

for (var i = 0; i <= pointCount; ++i)
points.push(sp.computeOffset(endPoint, radius, heading + 90 - i * 15));


for (var i = 0; i <= pointCount; ++i)
points.push(sp.computeOffset(startPoint, radius, heading - 90 - i * 15));


return points;






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272250%2ftrying-to-create-a-lozenge-with-google-maps-api%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Just create 2 Polylines...






    function initialize() 

    var map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 3,
    center: lat: 20, lng: 0,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20, lng: -20,
    lat: 20, lng: 20
    ];

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 20,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    Edit:



    You mentioned in your comment you need the stroke to be fixed at a given distance from the center line.



    You could still use that technique I think, as you can calculate the size in meters of a map pixel, based on the latitude and the zoom level, and as the size of the stroke is also in pixels, you should be able to recalculate the stroke each time you zoom-in/out. It won't be 100% precise since the stroke width must be an integer, but it should work.



    It should work if the various Polyline points are more or less on the same latitude, because the resolution of a map with the Mercator projection is dependent on the latitude. So, for example if you have a big Polyline crossing from -70 to +70 latitude, it won't be accurate all the way.



    This is the formula you can use to compute the size of 1 map pixel. You would need to replace map.getCenter().lat() by your Polyline center point.



    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(map.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());


    Unfortunately, there is an issue with this approach. Although it's undocumented, a Polyline stroke width can't be bigger than 32px.






    var map;
    var polyBounds;
    var polyStroke;
    var polyWidth = 50; // Width in meters

    function initialize()

    map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 12,
    center:
    lat: 20,
    lng: 0
    ,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20,
    lng: -0.5
    ,

    lat: 20,
    lng: 0.5

    ];

    polyStroke = new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 0,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );

    polyBounds = new google.maps.LatLngBounds();

    for (var i = 0; i < flightPlanCoordinates.length; i++)

    polyBounds.extend(flightPlanCoordinates[i]);


    google.maps.event.addListenerOnce(map, 'idle', setStroke);
    google.maps.event.addListener(map, 'zoom_changed', setStroke);


    function setStroke()

    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

    polyStroke.setOptions(
    strokeWeight: Math.ceil(polyWidth / scale)
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    So unless you find out that these values allow for your use case, this won't be a viable solution...



    The solution you were pointed to in the comments (How to draw a polygon around a polyline in JavaScript?) is still probably your best option.






    share|improve this answer

























    • Hi, thanks. The problem with that though is when you zoom, it doesn't scale the width of the shadow with it... I looked at using svg as well, but that had the same effect. I need to keep the outline constrained to x metres from the line.

      – jonahpup
      Nov 13 '18 at 2:30











    • See my edits. That's a fail, for one simple reason... you can't set a Polyline stroke width that is bigger than 32px :( It might be worth opening a feature request to allow for bigger values...

      – MrUpsidown
      Nov 13 '18 at 10:10






    • 1





      FYI, I have created this feature request to which you can subscribe in the hope that Google will change something... at some point. But that can take a very long time... :(

      – MrUpsidown
      Nov 13 '18 at 10:35






    • 1





      Hi, thanks for you help.. what i've ended up doing is just creating a polyline to show the path... and then using the start and end points, and racking my brain back to high school trigonometry, I have just created an arc at each end of the line with a set radius... this works perfectly, was just a bit more heavy lifting than I would have liked..

      – jonahpup
      Nov 14 '18 at 21:32











    • Cool. Feel free to post your solution as a separate answer as it might help someone else!

      – MrUpsidown
      Nov 15 '18 at 9:45















    1














    Just create 2 Polylines...






    function initialize() 

    var map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 3,
    center: lat: 20, lng: 0,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20, lng: -20,
    lat: 20, lng: 20
    ];

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 20,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    Edit:



    You mentioned in your comment you need the stroke to be fixed at a given distance from the center line.



    You could still use that technique I think, as you can calculate the size in meters of a map pixel, based on the latitude and the zoom level, and as the size of the stroke is also in pixels, you should be able to recalculate the stroke each time you zoom-in/out. It won't be 100% precise since the stroke width must be an integer, but it should work.



    It should work if the various Polyline points are more or less on the same latitude, because the resolution of a map with the Mercator projection is dependent on the latitude. So, for example if you have a big Polyline crossing from -70 to +70 latitude, it won't be accurate all the way.



    This is the formula you can use to compute the size of 1 map pixel. You would need to replace map.getCenter().lat() by your Polyline center point.



    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(map.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());


    Unfortunately, there is an issue with this approach. Although it's undocumented, a Polyline stroke width can't be bigger than 32px.






    var map;
    var polyBounds;
    var polyStroke;
    var polyWidth = 50; // Width in meters

    function initialize()

    map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 12,
    center:
    lat: 20,
    lng: 0
    ,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20,
    lng: -0.5
    ,

    lat: 20,
    lng: 0.5

    ];

    polyStroke = new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 0,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );

    polyBounds = new google.maps.LatLngBounds();

    for (var i = 0; i < flightPlanCoordinates.length; i++)

    polyBounds.extend(flightPlanCoordinates[i]);


    google.maps.event.addListenerOnce(map, 'idle', setStroke);
    google.maps.event.addListener(map, 'zoom_changed', setStroke);


    function setStroke()

    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

    polyStroke.setOptions(
    strokeWeight: Math.ceil(polyWidth / scale)
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    So unless you find out that these values allow for your use case, this won't be a viable solution...



    The solution you were pointed to in the comments (How to draw a polygon around a polyline in JavaScript?) is still probably your best option.






    share|improve this answer

























    • Hi, thanks. The problem with that though is when you zoom, it doesn't scale the width of the shadow with it... I looked at using svg as well, but that had the same effect. I need to keep the outline constrained to x metres from the line.

      – jonahpup
      Nov 13 '18 at 2:30











    • See my edits. That's a fail, for one simple reason... you can't set a Polyline stroke width that is bigger than 32px :( It might be worth opening a feature request to allow for bigger values...

      – MrUpsidown
      Nov 13 '18 at 10:10






    • 1





      FYI, I have created this feature request to which you can subscribe in the hope that Google will change something... at some point. But that can take a very long time... :(

      – MrUpsidown
      Nov 13 '18 at 10:35






    • 1





      Hi, thanks for you help.. what i've ended up doing is just creating a polyline to show the path... and then using the start and end points, and racking my brain back to high school trigonometry, I have just created an arc at each end of the line with a set radius... this works perfectly, was just a bit more heavy lifting than I would have liked..

      – jonahpup
      Nov 14 '18 at 21:32











    • Cool. Feel free to post your solution as a separate answer as it might help someone else!

      – MrUpsidown
      Nov 15 '18 at 9:45













    1












    1








    1







    Just create 2 Polylines...






    function initialize() 

    var map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 3,
    center: lat: 20, lng: 0,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20, lng: -20,
    lat: 20, lng: 20
    ];

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 20,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    Edit:



    You mentioned in your comment you need the stroke to be fixed at a given distance from the center line.



    You could still use that technique I think, as you can calculate the size in meters of a map pixel, based on the latitude and the zoom level, and as the size of the stroke is also in pixels, you should be able to recalculate the stroke each time you zoom-in/out. It won't be 100% precise since the stroke width must be an integer, but it should work.



    It should work if the various Polyline points are more or less on the same latitude, because the resolution of a map with the Mercator projection is dependent on the latitude. So, for example if you have a big Polyline crossing from -70 to +70 latitude, it won't be accurate all the way.



    This is the formula you can use to compute the size of 1 map pixel. You would need to replace map.getCenter().lat() by your Polyline center point.



    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(map.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());


    Unfortunately, there is an issue with this approach. Although it's undocumented, a Polyline stroke width can't be bigger than 32px.






    var map;
    var polyBounds;
    var polyStroke;
    var polyWidth = 50; // Width in meters

    function initialize()

    map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 12,
    center:
    lat: 20,
    lng: 0
    ,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20,
    lng: -0.5
    ,

    lat: 20,
    lng: 0.5

    ];

    polyStroke = new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 0,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );

    polyBounds = new google.maps.LatLngBounds();

    for (var i = 0; i < flightPlanCoordinates.length; i++)

    polyBounds.extend(flightPlanCoordinates[i]);


    google.maps.event.addListenerOnce(map, 'idle', setStroke);
    google.maps.event.addListener(map, 'zoom_changed', setStroke);


    function setStroke()

    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

    polyStroke.setOptions(
    strokeWeight: Math.ceil(polyWidth / scale)
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    So unless you find out that these values allow for your use case, this won't be a viable solution...



    The solution you were pointed to in the comments (How to draw a polygon around a polyline in JavaScript?) is still probably your best option.






    share|improve this answer















    Just create 2 Polylines...






    function initialize() 

    var map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 3,
    center: lat: 20, lng: 0,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20, lng: -20,
    lat: 20, lng: 20
    ];

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 20,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    Edit:



    You mentioned in your comment you need the stroke to be fixed at a given distance from the center line.



    You could still use that technique I think, as you can calculate the size in meters of a map pixel, based on the latitude and the zoom level, and as the size of the stroke is also in pixels, you should be able to recalculate the stroke each time you zoom-in/out. It won't be 100% precise since the stroke width must be an integer, but it should work.



    It should work if the various Polyline points are more or less on the same latitude, because the resolution of a map with the Mercator projection is dependent on the latitude. So, for example if you have a big Polyline crossing from -70 to +70 latitude, it won't be accurate all the way.



    This is the formula you can use to compute the size of 1 map pixel. You would need to replace map.getCenter().lat() by your Polyline center point.



    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(map.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());


    Unfortunately, there is an issue with this approach. Although it's undocumented, a Polyline stroke width can't be bigger than 32px.






    var map;
    var polyBounds;
    var polyStroke;
    var polyWidth = 50; // Width in meters

    function initialize()

    map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 12,
    center:
    lat: 20,
    lng: 0
    ,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20,
    lng: -0.5
    ,

    lat: 20,
    lng: 0.5

    ];

    polyStroke = new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 0,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );

    polyBounds = new google.maps.LatLngBounds();

    for (var i = 0; i < flightPlanCoordinates.length; i++)

    polyBounds.extend(flightPlanCoordinates[i]);


    google.maps.event.addListenerOnce(map, 'idle', setStroke);
    google.maps.event.addListener(map, 'zoom_changed', setStroke);


    function setStroke()

    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

    polyStroke.setOptions(
    strokeWeight: Math.ceil(polyWidth / scale)
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    So unless you find out that these values allow for your use case, this won't be a viable solution...



    The solution you were pointed to in the comments (How to draw a polygon around a polyline in JavaScript?) is still probably your best option.






    function initialize() 

    var map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 3,
    center: lat: 20, lng: 0,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20, lng: -20,
    lat: 20, lng: 20
    ];

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 20,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    function initialize() 

    var map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 3,
    center: lat: 20, lng: 0,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20, lng: -20,
    lat: 20, lng: 20
    ];

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 20,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    var map;
    var polyBounds;
    var polyStroke;
    var polyWidth = 50; // Width in meters

    function initialize()

    map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 12,
    center:
    lat: 20,
    lng: 0
    ,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20,
    lng: -0.5
    ,

    lat: 20,
    lng: 0.5

    ];

    polyStroke = new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 0,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );

    polyBounds = new google.maps.LatLngBounds();

    for (var i = 0; i < flightPlanCoordinates.length; i++)

    polyBounds.extend(flightPlanCoordinates[i]);


    google.maps.event.addListenerOnce(map, 'idle', setStroke);
    google.maps.event.addListener(map, 'zoom_changed', setStroke);


    function setStroke()

    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

    polyStroke.setOptions(
    strokeWeight: Math.ceil(polyWidth / scale)
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>





    var map;
    var polyBounds;
    var polyStroke;
    var polyWidth = 50; // Width in meters

    function initialize()

    map = new google.maps.Map(document.getElementById('map-canvas'),
    zoom: 12,
    center:
    lat: 20,
    lng: 0
    ,
    mapTypeId: 'terrain'
    );

    var flightPlanCoordinates = [
    lat: 20,
    lng: -0.5
    ,

    lat: 20,
    lng: 0.5

    ];

    polyStroke = new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: .3,
    strokeWeight: 0,
    map: map
    );

    new google.maps.Polyline(
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 1,
    map: map
    );

    polyBounds = new google.maps.LatLngBounds();

    for (var i = 0; i < flightPlanCoordinates.length; i++)

    polyBounds.extend(flightPlanCoordinates[i]);


    google.maps.event.addListenerOnce(map, 'idle', setStroke);
    google.maps.event.addListener(map, 'zoom_changed', setStroke);


    function setStroke()

    // Calculate the width of 1 map pixel in meters
    let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());

    polyStroke.setOptions(
    strokeWeight: Math.ceil(polyWidth / scale)
    );


    initialize();

    #map-canvas 
    height: 200px;

    <div id="map-canvas"></div>

    <script src="https://maps.googleapis.com/maps/api/js"></script>






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 13 '18 at 10:08

























    answered Nov 13 '18 at 1:55









    MrUpsidownMrUpsidown

    14.7k74894




    14.7k74894












    • Hi, thanks. The problem with that though is when you zoom, it doesn't scale the width of the shadow with it... I looked at using svg as well, but that had the same effect. I need to keep the outline constrained to x metres from the line.

      – jonahpup
      Nov 13 '18 at 2:30











    • See my edits. That's a fail, for one simple reason... you can't set a Polyline stroke width that is bigger than 32px :( It might be worth opening a feature request to allow for bigger values...

      – MrUpsidown
      Nov 13 '18 at 10:10






    • 1





      FYI, I have created this feature request to which you can subscribe in the hope that Google will change something... at some point. But that can take a very long time... :(

      – MrUpsidown
      Nov 13 '18 at 10:35






    • 1





      Hi, thanks for you help.. what i've ended up doing is just creating a polyline to show the path... and then using the start and end points, and racking my brain back to high school trigonometry, I have just created an arc at each end of the line with a set radius... this works perfectly, was just a bit more heavy lifting than I would have liked..

      – jonahpup
      Nov 14 '18 at 21:32











    • Cool. Feel free to post your solution as a separate answer as it might help someone else!

      – MrUpsidown
      Nov 15 '18 at 9:45

















    • Hi, thanks. The problem with that though is when you zoom, it doesn't scale the width of the shadow with it... I looked at using svg as well, but that had the same effect. I need to keep the outline constrained to x metres from the line.

      – jonahpup
      Nov 13 '18 at 2:30











    • See my edits. That's a fail, for one simple reason... you can't set a Polyline stroke width that is bigger than 32px :( It might be worth opening a feature request to allow for bigger values...

      – MrUpsidown
      Nov 13 '18 at 10:10






    • 1





      FYI, I have created this feature request to which you can subscribe in the hope that Google will change something... at some point. But that can take a very long time... :(

      – MrUpsidown
      Nov 13 '18 at 10:35






    • 1





      Hi, thanks for you help.. what i've ended up doing is just creating a polyline to show the path... and then using the start and end points, and racking my brain back to high school trigonometry, I have just created an arc at each end of the line with a set radius... this works perfectly, was just a bit more heavy lifting than I would have liked..

      – jonahpup
      Nov 14 '18 at 21:32











    • Cool. Feel free to post your solution as a separate answer as it might help someone else!

      – MrUpsidown
      Nov 15 '18 at 9:45
















    Hi, thanks. The problem with that though is when you zoom, it doesn't scale the width of the shadow with it... I looked at using svg as well, but that had the same effect. I need to keep the outline constrained to x metres from the line.

    – jonahpup
    Nov 13 '18 at 2:30





    Hi, thanks. The problem with that though is when you zoom, it doesn't scale the width of the shadow with it... I looked at using svg as well, but that had the same effect. I need to keep the outline constrained to x metres from the line.

    – jonahpup
    Nov 13 '18 at 2:30













    See my edits. That's a fail, for one simple reason... you can't set a Polyline stroke width that is bigger than 32px :( It might be worth opening a feature request to allow for bigger values...

    – MrUpsidown
    Nov 13 '18 at 10:10





    See my edits. That's a fail, for one simple reason... you can't set a Polyline stroke width that is bigger than 32px :( It might be worth opening a feature request to allow for bigger values...

    – MrUpsidown
    Nov 13 '18 at 10:10




    1




    1





    FYI, I have created this feature request to which you can subscribe in the hope that Google will change something... at some point. But that can take a very long time... :(

    – MrUpsidown
    Nov 13 '18 at 10:35





    FYI, I have created this feature request to which you can subscribe in the hope that Google will change something... at some point. But that can take a very long time... :(

    – MrUpsidown
    Nov 13 '18 at 10:35




    1




    1





    Hi, thanks for you help.. what i've ended up doing is just creating a polyline to show the path... and then using the start and end points, and racking my brain back to high school trigonometry, I have just created an arc at each end of the line with a set radius... this works perfectly, was just a bit more heavy lifting than I would have liked..

    – jonahpup
    Nov 14 '18 at 21:32





    Hi, thanks for you help.. what i've ended up doing is just creating a polyline to show the path... and then using the start and end points, and racking my brain back to high school trigonometry, I have just created an arc at each end of the line with a set radius... this works perfectly, was just a bit more heavy lifting than I would have liked..

    – jonahpup
    Nov 14 '18 at 21:32













    Cool. Feel free to post your solution as a separate answer as it might help someone else!

    – MrUpsidown
    Nov 15 '18 at 9:45





    Cool. Feel free to post your solution as a separate answer as it might help someone else!

    – MrUpsidown
    Nov 15 '18 at 9:45













    0














    I actually discovered a much easier way to achieve this using the google maps API.
    There are built in functions for getting a bearing of a point based on a start point...
    So I created a function that takes the start and end points of a line, and then creates points around these based on the heading - then create a polygon using those points.



    var pointCount = 12;
    function setLozengePath(startPoint, endPoint)
    var sp = google.maps.geometry.spherical;
    var heading = sp.computeHeading(startPoint, endPoint);

    var points = ;

    for (var i = 0; i <= pointCount; ++i)
    points.push(sp.computeOffset(endPoint, radius, heading + 90 - i * 15));


    for (var i = 0; i <= pointCount; ++i)
    points.push(sp.computeOffset(startPoint, radius, heading - 90 - i * 15));


    return points;






    share|improve this answer



























      0














      I actually discovered a much easier way to achieve this using the google maps API.
      There are built in functions for getting a bearing of a point based on a start point...
      So I created a function that takes the start and end points of a line, and then creates points around these based on the heading - then create a polygon using those points.



      var pointCount = 12;
      function setLozengePath(startPoint, endPoint)
      var sp = google.maps.geometry.spherical;
      var heading = sp.computeHeading(startPoint, endPoint);

      var points = ;

      for (var i = 0; i <= pointCount; ++i)
      points.push(sp.computeOffset(endPoint, radius, heading + 90 - i * 15));


      for (var i = 0; i <= pointCount; ++i)
      points.push(sp.computeOffset(startPoint, radius, heading - 90 - i * 15));


      return points;






      share|improve this answer

























        0












        0








        0







        I actually discovered a much easier way to achieve this using the google maps API.
        There are built in functions for getting a bearing of a point based on a start point...
        So I created a function that takes the start and end points of a line, and then creates points around these based on the heading - then create a polygon using those points.



        var pointCount = 12;
        function setLozengePath(startPoint, endPoint)
        var sp = google.maps.geometry.spherical;
        var heading = sp.computeHeading(startPoint, endPoint);

        var points = ;

        for (var i = 0; i <= pointCount; ++i)
        points.push(sp.computeOffset(endPoint, radius, heading + 90 - i * 15));


        for (var i = 0; i <= pointCount; ++i)
        points.push(sp.computeOffset(startPoint, radius, heading - 90 - i * 15));


        return points;






        share|improve this answer













        I actually discovered a much easier way to achieve this using the google maps API.
        There are built in functions for getting a bearing of a point based on a start point...
        So I created a function that takes the start and end points of a line, and then creates points around these based on the heading - then create a polygon using those points.



        var pointCount = 12;
        function setLozengePath(startPoint, endPoint)
        var sp = google.maps.geometry.spherical;
        var heading = sp.computeHeading(startPoint, endPoint);

        var points = ;

        for (var i = 0; i <= pointCount; ++i)
        points.push(sp.computeOffset(endPoint, radius, heading + 90 - i * 15));


        for (var i = 0; i <= pointCount; ++i)
        points.push(sp.computeOffset(startPoint, radius, heading - 90 - i * 15));


        return points;







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 27 '18 at 19:53









        jonahpupjonahpup

        5010




        5010



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272250%2ftrying-to-create-a-lozenge-with-google-maps-api%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Barbados

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3