问题
This Javascript plots a HUB marker with a ployline from the HUB to all surrounding markers. I would like to plot an elevation chart from the HUB to the marker a user clicks. Without the elevation portion the script runs, with the elevation portion nothing display, not the map and not the elevation chart.
<html>
<head>
<title>HUB</title>
<script src="https://maps.googleapis.com/maps/api/js"></script>
</head>
<body>
<center>
<div id="map" style="width: 900px; height: 600px;"></div>
<script type="text/javascript">
<div id="elevation_chart" style="width: 900px; height: 600px;"></div>
<script type="text/javascript">
var locations = [
{xtitle: 'Hub title', xinfo: 'Hub infowindow', lat: 38.624365, lng: -90.18503 },
{xtitle: 'Marker 1 title', xinfo: 'Marker 1 infowindow', lat: 38.920056, lng: -90.105111 },
{xtitle: 'Marker 2 title', xinfo: 'Marker 2 infowindow', lat: 38.688667, lng: -89.560639 },
{xtitle: 'Marker 3 title', xinfo: 'Marker 3 infowindow', lat: 38.416944, lng: -90.433028 },
{xtitle: 'Marker 4 title', xinfo: 'Marker 4 infowindow', lat: 38.692667, lng: -90.665944 }
];
function initMap() {
var map = new google.maps.Map(document.getElementById('map'),
{
zoom: 9,
center: new google.maps.LatLng(locations[0]),
mapTypeId: google.maps.MapTypeId.TERRAIN
}); // ---- END OF var map FUNCTION
// CREATE HUB MARKER & HUB INFOWINDOW
var marker = new google.maps.Marker({
position: locations[0],
title: locations[0].xtitle,
map: map
});
var infowindow = new google.maps.InfoWindow({
content: locations[0].xinfo
});
// CREATE SURROUNDING MARKERS AND POLYLINE TO HUB
for (var i = 1; i < locations.length; i++)
{ createMarker(i); };
function createMarker(i) {
var Xmarker = new google.maps.Marker({
map: map,
position: locations[i],
title: locations[i].xtitle,
});
var infowindow = new google.maps.InfoWindow({
content: locations[i].xinfo
});
google.maps.event.addListener(Xmarker, 'click', function() {
infowindow.open(map,Xmarker);
});
new google.maps.Polyline({
path: [ locations[0], locations[i] ],
strokeColor: '#cc0000',
strokeWeight: '3',
geodesic: true,
map: map
});
} // END OF createMarker(i) FUNCTION
marker.addListener('click', function() {
infowindow.open(map, marker);
map.setCenter(marker.getPosition());
});
}; // END OF initMap() FUNCTION
function drawPath() {
// Create a new chart in the elevation_chart DIV.
chart = new google.visualization.ColumnChart(document.getElementById('elevation_chart' ));
var path = new Array;
path.push(locations[0], locations[i]);
// Create a PathElevationRequest object using this array.
var pathRequest = {
'path': path,
'samples': 256
}
// Initiate the path request.
elevator.getElevationAlongPath(pathRequest, plotElevation);
}
// Takes an array of ElevationResult objects, draws the path on the map
// and plots the elevation profile on a Visualization API ColumnChart.
function plotElevation(results, status) {
if (status == google.maps.ElevationStatus.OK) {
elevations = results;
// Extract the elevation samples from the returned results
// and store them in an array of LatLngs.
var elevationPath = [];
for (var i = 0; i < results.length; i++) {
elevationPath.push(elevations[i].location);
}
// Extract the data from which to populate the chart.
// Because the samples are equidistant, the 'Sample'
// column here does double duty as distance along the
// X axis.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Sample');
data.addColumn('number', 'Elevation');
for (var i = 0; i < results.length; i++) {
data.addRow(['', elevations[i].elevation]);
}
// Draw the chart using the data within its DIV.
document.getElementById('elevation_chart').style.display = 'block';
chart.draw(data, {
width: 640,
height: 200,
legend: 'none',
titleY: 'Elevation (m)'
});
}
}
google.maps.event.addDomListener(window, 'load', initMap);
</script>
<br /></body></html>
回答1:
To have multiple sources for the chart, you need to keep references to the various polylines and pass something into the draw function to indicate which polyline to draw the chart for.
One option push the polylines onto an array associated with each of the "non-HUB" markers:
function createMarker(i) {
var Xmarker = new google.maps.Marker({
map: map,
position: locations[i],
title: locations[i].xtitle,
});
var infowindow = new google.maps.InfoWindow({
content: locations[i].xinfo
});
google.maps.event.addListener(Xmarker, 'click', function() {
infowindow.open(map, Xmarker);
drawPath(i);
});
var polyline = new google.maps.Polyline({
path: [locations[0], locations[i]],
strokeColor: '#cc0000',
strokeWeight: '3',
geodesic: true,
map: map
});
polylines[i] = polyline;
} // END OF createMarker(i) FUNCTION
Then pass that index into the drawPath
function (modified from one of the answers to the question: Create Elevation profile from polyline coordinate array):
function drawPath(i) {
// Create a new chart in the elevation_chart DIV.
chart = new google.visualization.ColumnChart(document.getElementById('elevation-chart'));
var path = polylines[i].getPath().getArray();
// Create a PathElevationRequest object using this array.
// Ask for 256 samples along that path.
var pathRequest = {
'path': path,
'samples': 256
}
// Initiate the path request.
elevator.getElevationAlongPath(pathRequest, plotElevation);
}
function plotElevation(results, status) {
if (status == google.maps.ElevationStatus.OK) {
elevations = results;
// Extract the elevation samples from the returned results
// and store them in an array of LatLngs.
var elevationPath = [];
for (var i = 0; i < elevations.length; i++) {
elevationPath.push(elevations[i].location);
}
// Extract the data from which to populate the chart.
// Because the samples are equidistant, the 'Sample'
// column here does double duty as distance along the
// X axis.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Sample');
data.addColumn('number', 'Elevation');
for (var i = 0; i < results.length; i++) {
data.addRow(['', elevations[i].elevation]);
}
// Draw the chart using the data within its DIV.
document.getElementById('elevation-chart').style.display = 'block';
chart.draw(data, {
width: 960,
height: 300,
legend: 'none',
titleY: 'Elevation (m)'
});
}
}
proof of concept fiddle
code snippet:
(note that the chart doesn't actually work in the code snippet, there is a security error: Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Sandbox access violation: Blocked a frame at "http://stacksnippets.net" from accessing a frame at "null". Both frames are sandboxed and lack the "allow-same-origin" flag.
, but it does work in the fiddle)
// Load the Visualization API and the columnchart package.
google.load("visualization", "1", {
packages: ["columnchart"]
});
var polylines = [];
var elevator;
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: new google.maps.LatLng(locations[0]),
mapTypeId: google.maps.MapTypeId.TERRAIN
}); // ---- END OF var map FUNCTION
// Create an ElevationService.
elevator = new google.maps.ElevationService();
// CREATE HUB MARKER & HUB INFOWINDOW
var marker = new google.maps.Marker({
position: locations[0],
title: locations[0].xtitle,
map: map
});
var infowindow = new google.maps.InfoWindow({
content: locations[0].xinfo
});
// CREATE SURROUNDING MARKERS AND POLYLINE TO HUB
for (var i = 1; i < locations.length; i++) {
createMarker(i);
};
function createMarker(i) {
var Xmarker = new google.maps.Marker({
map: map,
position: locations[i],
title: locations[i].xtitle,
});
var infowindow = new google.maps.InfoWindow({
content: locations[i].xinfo
});
google.maps.event.addListener(Xmarker, 'click', function() {
infowindow.open(map, Xmarker);
drawPath(i);
});
var polyline = new google.maps.Polyline({
path: [locations[0], locations[i]],
strokeColor: '#cc0000',
strokeWeight: '3',
geodesic: true,
map: map
});
polylines[i] = polyline;
} // END OF createMarker(i) FUNCTION
}; // END OF initMap() FUNCTION
function drawPath(i) {
// Create a new chart in the elevation_chart DIV.
chart = new google.visualization.ColumnChart(document.getElementById('elevation-chart'));
var path = polylines[i].getPath().getArray();
// Create a PathElevationRequest object using this array.
// Ask for 256 samples along that path.
var pathRequest = {
'path': path,
'samples': 256
}
// Initiate the path request.
elevator.getElevationAlongPath(pathRequest, plotElevation);
}
function plotElevation(results, status) {
if (status == google.maps.ElevationStatus.OK) {
elevations = results;
// Extract the elevation samples from the returned results
// and store them in an array of LatLngs.
var elevationPath = [];
for (var i = 0; i < elevations.length; i++) {
elevationPath.push(elevations[i].location);
}
// Extract the data from which to populate the chart.
// Because the samples are equidistant, the 'Sample'
// column here does double duty as distance along the
// X axis.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Sample');
data.addColumn('number', 'Elevation');
for (var i = 0; i < results.length; i++) {
data.addRow(['', elevations[i].elevation]);
}
// Draw the chart using the data within its DIV.
document.getElementById('elevation-chart').style.display = 'block';
chart.draw(data, {
width: 960,
height: 300,
legend: 'none',
titleY: 'Elevation (m)'
});
}
}
google.maps.event.addDomListener(window, 'load', initMap);
var locations = [{
xtitle: 'Hub title',
xinfo: 'Hub infowindow',
lat: 38.624365,
lng: -90.18503
}, {
xtitle: 'Marker 1 title',
xinfo: 'Marker 1 infowindow',
lat: 38.920056,
lng: -90.105111
}, {
xtitle: 'Marker 2 title',
xinfo: 'Marker 2 infowindow',
lat: 38.688667,
lng: -89.560639
}, {
xtitle: 'Marker 3 title',
xinfo: 'Marker 3 infowindow',
lat: 38.416944,
lng: -90.433028
}, {
xtitle: 'Marker 4 title',
xinfo: 'Marker 4 infowindow',
lat: 38.692667,
lng: -90.665944
}];
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://www.google.com/jsapi"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places&ext=.js"></script>
<div id="elevation-chart"></div>
<div id="map"></div>
来源:https://stackoverflow.com/questions/34375548/create-elevation-chart-from-markers-and-a-hub