使用Google maps API 绘制变色折线
Use Google maps API to draw a polyline that changes color
我正在开发一个项目,将 GPX 文件中的轨迹绘制到 google 地图上,并使用属性对其进行颜色编码(我们称之为 Score
)。我已经做了一些编辑,现在这个 GPX 文件中的每个坐标都有一个额外的标签 Score
。这是我修改后的 GPX 文件的片段。
<trkpt lat="50.834048" lon="-0.127354"> <ele>31.0</ele>
<Score>-0.64730385</Score>
<time>2016-07-07T14:31:51Z</time>
</trkpt>
<trkpt lat="50.833833" lon="-0.127600"> <ele>31.0</ele>
<Score>-0.647203</Score>
<time>2016-07-07T14:32:09Z</time>
</trkpt>
我正在学习 Google 地图的 javascript API 来完成绘图部分。我的问题是,如何创建一条根据 Score
改变颜色的多段线?我知道我可以只用两个点绘制成千上万条迷你多段线,并为每条多段线设置颜色。但是感觉很原始。有更好的方法吗?另外,我可以编写自己的函数来解析这个 GPX 文件,但为什么 google 地图不支持 GPX?
如果它有助于说明我的目的,这就是我试图实现的目标:
一个选项是为每个线段制作一条单独的折线,并根据该线段第一个点的分数为其分配颜色。
for (var i=0;i<(trkpts.length-1);i++) {
var coord1 = new google.maps.LatLng(parseFloat(trkpts[i].getAttribute("lat")),
parseFloat(trkpts[i].getAttribute("lon")));
var coord2 = new google.maps.LatLng(parseFloat(trkpts[i+1].getAttribute("lat")),
parseFloat(trkpts[i+1].getAttribute("lon")));
var score = parseFloat(nodeValue(trkpts[i].getElementsByTagName("Score")[0]));
var polyline = new google.maps.Polyline({
map: map,
path: [coord1, coord2],
strokeColor: rgb(-1,1,score),
strokeWeight: 4,
strokeOpacity: 1.0
});
}
代码片段:
var map;
var bounds = new google.maps.LatLngBounds();
function initialize() {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(34, 108),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var gpxStr = '<gpx><trk><trkseg><trkpt lat="50.834048" lon="-0.127354"> <ele>31.0</ele><Score>-0.64730385</Score><time>2016-07-07T14:31:51Z</time></trkpt><trkpt lat="50.833833" lon="-0.127600"> <ele>31.0</ele><Score>-0.647203</Score><time>2016-07-07T14:32:09Z</time></trkpt><trkpt lat="50.833715" lon="-0.127768"> <ele>31.0</ele><Score>0.647203</Score><time>2016-07-07T14:32:50Z</time></trkpt><trkpt lat="50.833171" lon="-0.128468"> <ele>31.0</ele><Score>0.99609375</Score><time>2016-07-07T14:32:50Z</time></trkpt><trkpt lat="50.832951" lon="-0.128771"> <ele>31.0</ele><Score>-0.5</Score><time>2016-07-07T14:32:50Z</time></trkpt></trkseg></trk></gpx>';
var xml = parseXml(gpxStr);
var trkpts = xml.getElementsByTagName("trkpt");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < (trkpts.length - 1); i++) {
var coord1 = new google.maps.LatLng(parseFloat(trkpts[i].getAttribute("lat")),
parseFloat(trkpts[i].getAttribute("lon")));
bounds.extend(coord1);
var coord2 = new google.maps.LatLng(parseFloat(trkpts[i + 1].getAttribute("lat")),
parseFloat(trkpts[i + 1].getAttribute("lon")));
bounds.extend(coord2);
var score = parseFloat(nodeValue(trkpts[i].getElementsByTagName("Score")[0]));
var polyline = new google.maps.Polyline({
map: map,
path: [coord1, coord2],
strokeColor: rgb(-1, 1, score),
strokeWeight: 4,
strokeOpacity: 1.0
})
}
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, "load", initialize);
function rgb(minimum, maximum, value) {
var ratio = 2 * (value - minimum) / (maximum - minimum);
b = Math.floor(Math.max(0, 255 * (1 - ratio)));
r = Math.floor(Math.max(0, 255 * (ratio - 1)));
g = 255 - b - r;
var hexStr = ("00" + r.toString(16)).slice(-2);
hexStr += ("00" + g.toString(16)).slice(-2);
hexStr += ("00" + b.toString(16)).slice(-2);
hexStr = "#" + hexStr;
return hexStr
}
function parseXml(str) {
if (window.ActiveXObject) {
var doc = new ActiveXObject('MicrosoftXMLDOM');
doc.loadXML(str);
return doc;
} else if (window.DOMParser) {
return (new DOMParser()).parseFromString(str, 'text/xml');
}
}
//nodeValue: Extract the text value of a DOM node, with leading and trailing whitespace trimmed
function nodeValue(node, defVal) {
var retStr = "";
if (!node) {
return (typeof defVal === 'undefined' || defVal === null) ? '' : defVal;
}
if (node.nodeType == 3 || node.nodeType == 4 || node.nodeType == 2) {
retStr += node.nodeValue;
} else if (node.nodeType == 1 || node.nodeType == 9 || node.nodeType == 11) {
for (var i = 0; i < node.childNodes.length; ++i) {
retStr += arguments.callee(node.childNodes[i]);
}
}
return retStr;
};
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas" style="border: 2px solid #3872ac;"></div>
我正在开发一个项目,将 GPX 文件中的轨迹绘制到 google 地图上,并使用属性对其进行颜色编码(我们称之为 Score
)。我已经做了一些编辑,现在这个 GPX 文件中的每个坐标都有一个额外的标签 Score
。这是我修改后的 GPX 文件的片段。
<trkpt lat="50.834048" lon="-0.127354"> <ele>31.0</ele>
<Score>-0.64730385</Score>
<time>2016-07-07T14:31:51Z</time>
</trkpt>
<trkpt lat="50.833833" lon="-0.127600"> <ele>31.0</ele>
<Score>-0.647203</Score>
<time>2016-07-07T14:32:09Z</time>
</trkpt>
我正在学习 Google 地图的 javascript API 来完成绘图部分。我的问题是,如何创建一条根据 Score
改变颜色的多段线?我知道我可以只用两个点绘制成千上万条迷你多段线,并为每条多段线设置颜色。但是感觉很原始。有更好的方法吗?另外,我可以编写自己的函数来解析这个 GPX 文件,但为什么 google 地图不支持 GPX?
如果它有助于说明我的目的,这就是我试图实现的目标:
一个选项是为每个线段制作一条单独的折线,并根据该线段第一个点的分数为其分配颜色。
for (var i=0;i<(trkpts.length-1);i++) {
var coord1 = new google.maps.LatLng(parseFloat(trkpts[i].getAttribute("lat")),
parseFloat(trkpts[i].getAttribute("lon")));
var coord2 = new google.maps.LatLng(parseFloat(trkpts[i+1].getAttribute("lat")),
parseFloat(trkpts[i+1].getAttribute("lon")));
var score = parseFloat(nodeValue(trkpts[i].getElementsByTagName("Score")[0]));
var polyline = new google.maps.Polyline({
map: map,
path: [coord1, coord2],
strokeColor: rgb(-1,1,score),
strokeWeight: 4,
strokeOpacity: 1.0
});
}
代码片段:
var map;
var bounds = new google.maps.LatLngBounds();
function initialize() {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(34, 108),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var gpxStr = '<gpx><trk><trkseg><trkpt lat="50.834048" lon="-0.127354"> <ele>31.0</ele><Score>-0.64730385</Score><time>2016-07-07T14:31:51Z</time></trkpt><trkpt lat="50.833833" lon="-0.127600"> <ele>31.0</ele><Score>-0.647203</Score><time>2016-07-07T14:32:09Z</time></trkpt><trkpt lat="50.833715" lon="-0.127768"> <ele>31.0</ele><Score>0.647203</Score><time>2016-07-07T14:32:50Z</time></trkpt><trkpt lat="50.833171" lon="-0.128468"> <ele>31.0</ele><Score>0.99609375</Score><time>2016-07-07T14:32:50Z</time></trkpt><trkpt lat="50.832951" lon="-0.128771"> <ele>31.0</ele><Score>-0.5</Score><time>2016-07-07T14:32:50Z</time></trkpt></trkseg></trk></gpx>';
var xml = parseXml(gpxStr);
var trkpts = xml.getElementsByTagName("trkpt");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < (trkpts.length - 1); i++) {
var coord1 = new google.maps.LatLng(parseFloat(trkpts[i].getAttribute("lat")),
parseFloat(trkpts[i].getAttribute("lon")));
bounds.extend(coord1);
var coord2 = new google.maps.LatLng(parseFloat(trkpts[i + 1].getAttribute("lat")),
parseFloat(trkpts[i + 1].getAttribute("lon")));
bounds.extend(coord2);
var score = parseFloat(nodeValue(trkpts[i].getElementsByTagName("Score")[0]));
var polyline = new google.maps.Polyline({
map: map,
path: [coord1, coord2],
strokeColor: rgb(-1, 1, score),
strokeWeight: 4,
strokeOpacity: 1.0
})
}
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, "load", initialize);
function rgb(minimum, maximum, value) {
var ratio = 2 * (value - minimum) / (maximum - minimum);
b = Math.floor(Math.max(0, 255 * (1 - ratio)));
r = Math.floor(Math.max(0, 255 * (ratio - 1)));
g = 255 - b - r;
var hexStr = ("00" + r.toString(16)).slice(-2);
hexStr += ("00" + g.toString(16)).slice(-2);
hexStr += ("00" + b.toString(16)).slice(-2);
hexStr = "#" + hexStr;
return hexStr
}
function parseXml(str) {
if (window.ActiveXObject) {
var doc = new ActiveXObject('MicrosoftXMLDOM');
doc.loadXML(str);
return doc;
} else if (window.DOMParser) {
return (new DOMParser()).parseFromString(str, 'text/xml');
}
}
//nodeValue: Extract the text value of a DOM node, with leading and trailing whitespace trimmed
function nodeValue(node, defVal) {
var retStr = "";
if (!node) {
return (typeof defVal === 'undefined' || defVal === null) ? '' : defVal;
}
if (node.nodeType == 3 || node.nodeType == 4 || node.nodeType == 2) {
retStr += node.nodeValue;
} else if (node.nodeType == 1 || node.nodeType == 9 || node.nodeType == 11) {
for (var i = 0; i < node.childNodes.length; ++i) {
retStr += arguments.callee(node.childNodes[i]);
}
}
return retStr;
};
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas" style="border: 2px solid #3872ac;"></div>