我想使用Google地图使用文本文件中的位置数据和时间戳来显示路线
文本文件(route.log)包含由unix换行符分隔的行,并遵循以下格式:" Lat,Long;日期,时间"。
例如:
52.1615470947258,20.805144309997561; 14.03.2015,17:33 52.15991486090931,20.804049968719483; 14.03.2015,17:37 52.15772967999426,20.805788040161133; 14.03.2015,17:47
第一行是起点,最后一行是终点,每一行都在航点之间。每一行末尾的时间戳(日期,时间)应在每个航路点的信息文本中显示。
现在,我找到了一个使用Google地图显示航路点here的非常好的示例。
我的问题是:
如何将文本文件中的行处理为与that Google Maps example兼容的格式(数组)? 如何为每个标记信息文本添加时间戳?
如果我的文本文件只有2个点(开始+结束)或者可能是1,那么它会抛出一个错误还是有一个“故障安全”'?
我非常感谢你的帮助和提示。非常感谢你。
我一直在尝试使用AJAX / jQuery,这是我现在卡住的示例代码的一部分:
<script>
jQuery(function() {
$.ajax({
url: "route.log",
dataType: 'text',
success: function (data) {
var lines = data.match(/^.*((\r\n|\n|\r)|$)/gm);
var stops = [];
for (var i = 0; i < lines.length; i++) {
var line = lines[i].replace("\n", "").split(";");
stops.push(line);
}
//console.log(stops[0][1]);
}
});
var map = new window.google.maps.Map(document.getElementById("map"));
var directionsDisplay = new window.google.maps.DirectionsRenderer({suppressMarkers: true});
var directionsService = new window.google.maps.DirectionsService();
Tour_startUp(stops); // this here gets executed before the AJAX part has delivered the stops array > error
window.tour.loadMap(map, directionsDisplay);
window.tour.fitBounds(map);
if (stops.length > 1)
window.tour.calcRoute(directionsService, directionsDisplay);
});
function Tour_startUp(stops) {... // etc.
似乎需要AJAX结果的某些代码(停止数组)在 AJAX完成填充停止数组之前执行。
此外,在引用的example code中,停止数组如下所示:
var stops = [
{"Geometry":{"Latitude":52.1615470947258,"Longitude":20.80514430999756}},
{"Geometry":{"Latitude":52.15991486090931,"Longitude":20.804049968719482}},
{"Geometry":{"Latitude":52.15772967999426,"Longitude":20.805788040161133}}]
如果javascript可以将文本文件行转换为此格式和将时间戳添加为第三部分,我可以使用其余的示例代码而无需进一步修改它。另外,我需要删除文本文件末尾的空行(因为它添加了一个空数组元素)。
编辑2:
这是完整的代码,包括。最新的变化:
<!doctype html>
<?php
$fileContent = file('route.log', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($fileContent as $line_num => $line) {
{
$data = explode(";", rtrim($line));
$geometry[] = explode(",", trim($data[0]));
$timestamp[] = trim($data[1]);
}
};
?>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Google Maps JavaScript API v3 Example: Directions Waypoints</title>
<style>
#map{
width: 100%;
height: 450px;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script>
jQuery(function() {
var stops = <?php
echo '[ ';
foreach ($geometry as $row) {
echo '{"Geometry":{"Latitude":' . $row['0'] . ','. '"Longitude":' . $row['1'] . '}},' . "\n";
}
echo ' ]';
?>;
var map = new window.google.maps.Map(document.getElementById("map"));
// new up complex objects before passing them around
var directionsDisplay = new window.google.maps.DirectionsRenderer({suppressMarkers: true});
var directionsService = new window.google.maps.DirectionsService();
Tour_startUp(stops);
window.tour.loadMap(map, directionsDisplay);
window.tour.fitBounds(map);
if (stops.length > 1)
window.tour.calcRoute(directionsService, directionsDisplay);
});
function Tour_startUp(stops) {
var stops_timestamp = JSON.parse( '<?php echo json_encode($timestamp) ?>' );
if (!window.tour) window.tour = {
updateStops: function (newStops) {
stops = newStops;
},
// map: google map object
// directionsDisplay: google directionsDisplay object (comes in empty)
loadMap: function (map, directionsDisplay) {
var myOptions = {
zoom: 13,
center: new window.google.maps.LatLng(51.507937, -0.076188), // default to London
mapTypeId: window.google.maps.MapTypeId.ROADMAP
};
map.setOptions(myOptions);
directionsDisplay.setMap(map);
},
fitBounds: function (map) {
var bounds = new window.google.maps.LatLngBounds();
// extend bounds for each record
jQuery.each(stops, function (key, val) {
var myLatlng = new window.google.maps.LatLng(val.Geometry.Latitude, val.Geometry.Longitude);
bounds.extend(myLatlng);
});
map.fitBounds(bounds);
},
calcRoute: function (directionsService, directionsDisplay) {
var batches = [];
var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints
var itemsCounter = 0;
var wayptsExist = stops.length > 0;
while (wayptsExist) {
var subBatch = [];
var subitemsCounter = 0;
for (var j = itemsCounter; j < stops.length; j++) {
subitemsCounter++;
subBatch.push({
location: new window.google.maps.LatLng(stops[j].Geometry.Latitude, stops[j].Geometry.Longitude),
stopover: true
});
if (subitemsCounter == itemsPerBatch)
break;
}
itemsCounter += subitemsCounter;
batches.push(subBatch);
wayptsExist = itemsCounter < stops.length;
// If it runs again there are still points. Minus 1 before continuing to
// start up with end of previous tour leg
itemsCounter--;
}
// now we should have a 2 dimensional array with a list of a list of waypoints
var combinedResults;
var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort
var directionsResultsReturned = 0;
for (var k = 0; k < batches.length; k++) {
var lastIndex = batches[k].length - 1;
var start = batches[k][0].location;
var end = batches[k][lastIndex].location;
// trim first and last entry from array
var waypts = [];
waypts = batches[k];
waypts.splice(0, 1);
waypts.splice(waypts.length - 1, 1);
var request = {
origin: start,
destination: end,
waypoints: waypts,
travelMode: window.google.maps.TravelMode.WALKING
};
(function (kk) {
directionsService.route(request, function (result, status) {
if (status == window.google.maps.DirectionsStatus.OK) {
var unsortedResult = { order: kk, result: result };
unsortedResults.push(unsortedResult);
directionsResultsReturned++;
if (directionsResultsReturned == batches.length) // we've received all the results. put to map
{
// sort the returned values into their correct order
unsortedResults.sort(function (a, b) { return parseFloat(a.order) - parseFloat(b.order); });
var count = 0;
for (var key in unsortedResults) {
if (unsortedResults[key].result != null) {
if (unsortedResults.hasOwnProperty(key)) {
if (count == 0) // first results. new up the combinedResults object
combinedResults = unsortedResults[key].result;
else {
// only building up legs, overview_path, and bounds in my consolidated object. This is not a complete
// directionResults object, but enough to draw a path on the map, which is all I need
combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
}
count++;
}
}
}
directionsDisplay.setDirections(combinedResults);
var legs = combinedResults.routes[0].legs;
// alert(legs.length);
for (var i=0; i < legs.length;i++){
var markerletter = "A".charCodeAt(0);
markerletter += i;
markerletter = String.fromCharCode(markerletter);
createMarker(directionsDisplay.getMap(),legs[i].start_location,"Marker "+i,stops_timestamp[i]+"<br>"+legs[i].start_address,markerletter);
}
var i=legs.length;
var markerletter = "A".charCodeAt(0);
markerletter += i;
markerletter = String.fromCharCode(markerletter);
createMarker(directionsDisplay.getMap(),legs[legs.length-1].end_location,"Most Recent Position: Marker "+i,stops_timestamp[i]+"<br>"+legs[legs.length-1].end_address,markerletter);
}
}
//troubleshooting part follows
/*
else {
// alert an error message when the route could nog be calculated.
if (status == 'ZERO_RESULTS') {
alert('No route could be found between the origin and destination.');
} else if (status == 'UNKNOWN_ERROR') {
alert('A directions request could not be processed due to a server error. The request may succeed if you try again.');
} else if (status == 'REQUEST_DENIED') {
alert('This webpage is not allowed to use the directions service.');
} else if (status == 'OVER_QUERY_LIMIT') {
alert('The webpage has gone over the requests limit in too short a period of time.');
} else if (status == 'NOT_FOUND') {
alert('At least one of the origin, destination, or waypoints could not be geocoded.');
} else if (status == 'INVALID_REQUEST') {
alert('The DirectionsRequest provided was invalid.');
} else {
alert("There was an unknown error in your request. Requeststatus: nn"+status);
}
}
//*/
});
})(k);
}
}
};
}
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
var icons = new Array();
icons["red"] = new google.maps.MarkerImage("mapIcons/marker_red.png",
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(20, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
function getMarkerImage(iconStr) {
if ((typeof(iconStr)=="undefined") || (iconStr==null)) {
iconStr = "red";
}
if (!icons[iconStr]) {
icons[iconStr] = new google.maps.MarkerImage("http://www.google.com/mapfiles/marker"+ iconStr +".png",
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(20, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 6,20.
new google.maps.Point(9, 34));
}
return icons[iconStr];
}
// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.
// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var iconImage = new google.maps.MarkerImage('mapIcons/marker_red.png',
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(20, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
var iconShadow = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png',
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
new google.maps.Size(37, 34),
new google.maps.Point(0,0),
new google.maps.Point(9, 34));
// Shapes define the clickable region of the icon.
// The type defines an HTML <area> element 'poly' which
// traces out a polygon as a series of X,Y points. The final
// coordinate closes the poly by connecting to the first
// coordinate.
var iconShape = {
coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0],
type: 'poly'
};
function createMarker(map, latlng, label, html, color) {
// alert("createMarker("+latlng+","+label+","+html+","+color+")");
var contentString = '<b>'+label+'</b><br>'+html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
shadow: iconShadow,
icon: getMarkerImage(color),
shape: iconShape,
title: label,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
marker.myname = label;
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
return marker;
}
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
有点现在有效。如您所见,我使用php将文本行格式化为正确的格式并放入stops
Javascript数组(+将文件扩展名更改为索引。 php )。
唯一剩下的问题有时GoogleMaps JSON会返回Unknown Error
并且不会绘制路线。它与某些地理编码位置有关。一些地理坐标工作,其他人没有。
您可以自行检查,只需将一些坐标添加到文本文件名 route.log 中并进行测试。
答案 0 :(得分:1)
我将在这里回答您问题的第一部分,即如何处理文本文件中的行。
您需要使用AJAX请求打开文本文件。我强烈建议您使用jQuery。
$.ajax({
url: "route.log",
dataType: 'text',
success: function (data) {
var lines = data.match(/^.*((\r\n|\n|\r)|$)/gm);
for (var i = 0; i < lines.length; i++) {
var line = lines[i].replace("\n", "").split(";");
console.log(line);
}
}
});
这将输出:
[&#34; 52.1615470947258,20.805144309997561&#34;,&#34; 14.03.2015,17:33&#34;] [&#34; 52.15991486090931,20.804049968719483&#34;,&#34; 14.03.2015,17:37&#34;] [&#34; 52.15772967999426,20.805788040161133&#34;,&#34; 14.03.2015,17:47&#34;]
基本上,line[0]
将是您的纬度/经度坐标和line[1]
您的日期/时间信息。
通过这种方式,您可以轻松处理不同的线路(起点和终点,航点),还可以检查是否有足够的线路来请求路线。
希望这有帮助。
修改强>:
关于数据的格式,您可以这样做:
var stops = [];
$.ajax({
url: "test.txt",
dataType: 'text',
success: function(data) {
var lines = data.match(/^.*((\r\n|\n|\r)|$)/gm);
for (var i = 0; i < lines.length; i++) {
var line = lines[i].replace("\n", "").split(";");
var geometry = line[0].split(",");
stops.push({
"Geometry": {
"Latitude": geometry[0],
"Longitude": geometry[1]
},
"Timestamp": line[1]
});
}
console.log(stops);
}
});