Trying to create a 'lozenge' with google maps API
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?
google-maps-api-3 google-polyline
add a comment |
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?
google-maps-api-3 google-polyline
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
add a comment |
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?
google-maps-api-3 google-polyline
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?
google-maps-api-3 google-polyline
google-maps-api-3 google-polyline
edited Nov 13 '18 at 1:38
geocodezip
126k10143174
126k10143174
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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.
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
add a comment |
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;
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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>
edited Nov 13 '18 at 10:08
answered Nov 13 '18 at 1:55
MrUpsidownMrUpsidown
14.8k74894
14.8k74894
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
add a comment |
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
add a comment |
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;
add a comment |
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;
add a comment |
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;
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;
answered Nov 27 '18 at 19:53
jonahpupjonahpup
5010
5010
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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