是否可以指定路线,然后通过指定路线的百分比来获取(长,拉特)列表? [英] Is it possible to specify a route and then get a list of (long,lat) by specifying a percentage of the route?

查看:71
本文介绍了是否可以指定路线,然后通过指定路线的百分比来获取(长,拉特)列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在指定路线点后,我想沿着路线以增量(指定为总距离[0至1]的一部分)移动,并建立(经度,纬度)点的列表。



API中的现有函数(如果有的话)有助于此路线的切分? nofollow noreferrer>张贴示例做直线距离(它最初必须修改才能完成时间...)。使用Mike Williams的 epoly图书馆版本,移植到v3。关键的方法是:
$ b

.GetPointAtDistance(米)返回点的google.maps.LatLng指定的距离。



var directionDisplay; var directionsService = new google。 maps.DirectionsService(); var map; var polyline = null;函数createMarker(latlng,label,html){// alert(createMarker(+ latlng +,+ label +,+ html +,+ color + )); var contentString ='< b>'+ label +'< / b>< br>'+ html; var marker = new google.maps.Marker({position:latlng,map:map,title:label,zIndex:Math.round(latlng.lat()* -100000)<5}); marker.myname = label; // gmarkers.push(marker); google.maps.event.addListener(marker,'click',function(){infowindow.setContent(contentString); infowindow.open(map,marker);}); return marker;} function initialize(){directionsDisplay = new google.maps.DirectionsRenderer({suppressMarkers:true}); var chicago = new google.maps.LatLng(41.850033,-87.6500523); var myOptions = {zoom:6,mapTypeId:google.maps.MapTypeId.ROADMAP,center:chicago} map = new google.maps.Map(document.getElementById(map_canvas),myOptions); polyline = new google.maps.Polyline({path:[],strokeColor:'#FF0000',strokeWeight:3}); directionsDisplay.setMap(地图); calcRoute();} google.maps.event.addDomListener(window,'load',initialize);函数calcRoute(){var start = document.getElementById(start).value; var end = document.getElementById(end).value; var travelMode = google.maps.DirectionsTravelMode.DRIVING var request = {origin:start,destination:end,travelMode:travelMode}; directionsService.route(request,function(response,status){if(status == google.maps.DirectionsStatus.OK){polyline.setPath([]); var bounds = new google.maps.LatLngBounds(); startLocation = new Object(); endLocation = new Object(); directionsDisplay.setDirections(response); var route = response.routes [0]; var summaryPanel = document.getElementById(directions_panel); summaryPanel.innerHTML =; // For每条路由显示摘要信息var path = response.routes [0] .overview_path; var legs = response.routes [0] .legs; for(i = 0; i< legs.length; i ++){if(i == 0){startLocation.latlng = legs [i] .start_location; startLocation.address = legs [i] .start_address; // marker = google.maps.Marker({map:map,position:startLocation.latlng}); marker = createMarker(legs [i] .start_location,start,legs [i] .start_address,green);} endLocation.latlng = legs [i] .end_loc通货膨胀; endLocation.address = legs [i] .end_address; var steps = legs [i] .steps; for(j = 0; j = y))|| (this.getPath()。getAt(j).lat()< y)&& amp;(this.getPath()。getAt(i).lat()> = y))){if .getPath()。getAt(i).lng()+(y - this.getPath()。getAt(i).lat())/(this.getPath()。getAt(j).lat() - this ().getPath().getAt(i).lat())*(this.getPath()。getAt(j).lng() - this.getPath()。getAt(i).lng())< x) {oddNodes =!oddNodes}}} return oddNodes;} // ===一种方法,以平方米的形式返回非交叉多边形的近似面积=== // ===它不能完全考虑球面几何,所以对于大的多边形将是不准确的=== // ===多边形不能相交=== google.maps.Polygon.prototype.Area = function(){var a = 0; var j = 0; var b = this.Bounds(); var x0 = b.getSouthWest()。lng(); var y0 = b.getSouthWest()。lat(); for(var i = 0; i< this.getPath()。getLength(); i ++){j ++; if(j == this.getPath()。getLength()){j = 0; } var x1 = this.getPath()。getAt(i).distanceFrom(new google.maps.LatLng(this.getPath()。getAt(i).lat(),x0)); var x2 = this.getPath()。getAt(j).distanceFrom(new google.maps.LatLng(this.getPath()。getAt(j).lat(),x0)); var y1 = this.getPath()。getAt(i).distanceFrom(new google.maps.LatLng(y0,this.getPath()。getAt(i).lng())); var y2 = this.getPath()。getAt(j).distanceFrom(new google.maps.LatLng(y0,this.getPath()。getAt(j).lng())); a + = x1 * y2 - x2 * y1; }返回Math.abs(a * 0.5);} // ===一种以米为单位返回路径长度的方法=== google.maps.Polygon.prototype.Distance = function(){var dist = 0; for(var i = 1; i< this.getPath()。getLength(); i ++){dist + = this.getPath()。getAt(i).distanceFrom(this.getPath()。getAt(i - 1 )); } return dist;} // ===一种将边界作为GLatLngBounds返回的方法=== google.maps.Polygon.prototype.Bounds = function(){var bounds = new google.maps.LatLngBounds(); for(var i = 0; i< this.getPath()。getLength(); i ++){bounds.extend(this.getPath()。getAt(i)); } return bounds;} // ===一个方法,该方法返回沿路径给定距离的点的GLatLng === // ===如果路径短于指定的距离,则返回null === google.maps .Polygon.prototype.GetPointAtDistance = function(meters){//如果(米== 0)返回this.getPath()。getAt(0);如果(米<0)返回空; if(this.getPath()。getLength()< 2)return null; var dist = 0; var olddist = 0;对于(var i = 1;(i< this.getPath()。getLength()& dist< meters); i ++){olddist = dist; dist + = this.getPath()。getAt(i).distanceFrom(this.getPath()。getAt(i - 1)); } if(dist = this.getPath()。getLength())||(v2 <0)||(v2> = this.getPath()。getLength() )){return; } var from = this.getPath()。getAt(v1); var to = this.getPath()。getAt(v2); if(from.equals(to)){return 0; } var lat1 = from.latRadians(); var lon1 = from.lngRadians(); var lat2 = to.latRadians(); var lon2 = to.lngRadians(); Math.cos(lat2),Math.cos(lat1)* Math.sin(lat2) - Math.sin(lat1)* Math.cos(lat2) )* Math.cos(lon1 - lon2));如果(角度<0.0)角度+ = Math.PI * 2.0; angle = angle * 180.0 / Math.PI;返回parseFloat(angle.toFixed(1));} // ===将上述所有函数复制到GPolyline === google.maps.Polyline.prototype.Contains = google.maps.Polygon.prototype.Contains; google.maps .Polyline.prototype.Area = google.maps.Polygon.prototype.Area; google.maps.Polyline.prototype.Distance = google.maps.Polygon.prototype.Distance; google.maps.Polyline.prototype.Bounds = google.maps .Polygon.prototype.Bounds; google.maps.Polyline.prototype.GetPointAtDistance = google.maps.Polygon.prototype.GetPointAtDistance; google.maps.Polyline.prototype.GetPointsAtDistance = google.maps.Polygon.prototype.GetPointsAtDistance; google.maps .Polyline.prototype.GetIndexAtDistance = google.maps.Polygon.prototype.GetIndexAtDistance; google.maps.Polyline.prototype.Bearing = google.maps.Polygon.prototype.Bearing;

html {height:100%} body {height:100%; margin:0px; < script type =text / code:

javascriptsrc =https://maps.google.com/maps/api/js>< / script>< div id =tools> start:< input type =textname =startid =startvalue =Hyderabad/> end:< input type =textname =endid =endvalue = 班加罗尔/> < input type =submitonclick =calcRoute(); /> < br />距离(以公里计):< input type =textname =distid =distvalue =0/> < input type =submitonclick =putMarkerOnRoute(parseFloat(document.getElementById('dist')。value)* 1000); />公里& nbsp;总时间:< / div>< div id =map_canvas< input type =textname =totalTimeid =totalTimevalue =0 style =float:left; width:70%; height:100%;>< / div>< div id =control_panelstyle =float:right; width:30%; text-align:left ;填充顶:20像素> < div id =directions_panelstyle =margin:20px; background-color:#FFEE77;>< / div> < div id =total>< / div>< / div>

After specify a route with way points I would like to move along the route in increments (specified as a fraction of the total distance [0 to 1]) and build a list of (longitude, latitude) points.

What existing function in the API, if any, facilitate this slicing of the route?

解决方案

Modifying the posted example to do straight distance (it had to be modified originally to do time...). Uses a version of the epoly library by Mike Williams, ported to v3. The key method being:

.GetPointAtDistance(metres) Returns the google.maps.LatLng of a point at the specified distance along the path.

var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var polyline = null;

function createMarker(latlng, label, html) {
  // alert("createMarker("+latlng+","+label+","+html+","+color+")");
  var contentString = '<b>' + label + '</b><br>' + html;
  var marker = new google.maps.Marker({
    position: latlng,
    map: map,
    title: label,
    zIndex: Math.round(latlng.lat() * -100000) << 5
  });
  marker.myname = label;
  // gmarkers.push(marker);

  google.maps.event.addListener(marker, 'click', function() {
    infowindow.setContent(contentString);
    infowindow.open(map, marker);
  });
  return marker;
}

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer({
    suppressMarkers: true
  });
  var chicago = new google.maps.LatLng(41.850033, -87.6500523);
  var myOptions = {
    zoom: 6,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: chicago
  }
  map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  polyline = new google.maps.Polyline({
    path: [],
    strokeColor: '#FF0000',
    strokeWeight: 3
  });
  directionsDisplay.setMap(map);
  calcRoute();
}
google.maps.event.addDomListener(window, 'load', initialize);

function calcRoute() {

  var start = document.getElementById("start").value;
  var end = document.getElementById("end").value;
  var travelMode = google.maps.DirectionsTravelMode.DRIVING

  var request = {
    origin: start,
    destination: end,
    travelMode: travelMode
  };
  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      polyline.setPath([]);
      var bounds = new google.maps.LatLngBounds();
      startLocation = new Object();
      endLocation = new Object();
      directionsDisplay.setDirections(response);
      var route = response.routes[0];
      var summaryPanel = document.getElementById("directions_panel");
      summaryPanel.innerHTML = "";

      // For each route, display summary information.
      var path = response.routes[0].overview_path;
      var legs = response.routes[0].legs;
      for (i = 0; i < legs.length; i++) {
        if (i == 0) {
          startLocation.latlng = legs[i].start_location;
          startLocation.address = legs[i].start_address;
          // marker = google.maps.Marker({map:map,position: startLocation.latlng});
          marker = createMarker(legs[i].start_location, "start", legs[i].start_address, "green");
        }
        endLocation.latlng = legs[i].end_location;
        endLocation.address = legs[i].end_address;
        var steps = legs[i].steps;
        for (j = 0; j < steps.length; j++) {
          var nextSegment = steps[j].path;
          for (k = 0; k < nextSegment.length; k++) {
            polyline.getPath().push(nextSegment[k]);
            bounds.extend(nextSegment[k]);
          }
        }
      }

      polyline.setMap(map);

      computeTotalDistance(response);
    } else {
      alert("directions response " + status);
    }
  });
}

var totalDist = 0;
var totalTime = 0;

function computeTotalDistance(result) {
  totalDist = 0;
  totalTime = 0;
  var myroute = result.routes[0];
  for (i = 0; i < myroute.legs.length; i++) {
    totalDist += myroute.legs[i].distance.value;
    totalTime += myroute.legs[i].duration.value;
  }
  totalDist = totalDist / 1000.
  document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
  document.getElementById("totalTime").value = (totalTime / 60.).toFixed(2);
}

function putMarkerOnRoute(distance) {
  // alert("Time:"+time+" totalTime:"+totalTime+" totalDist:"+totalDist+" dist:"+distance);
  if (!marker) {
    marker = createMarker(polyline.GetPointAtDistance(distance), "distance: " + distance, "marker");
  } else {
    marker.setPosition(polyline.GetPointAtDistance(distance));
    marker.setTitle("distance:" + distance);
  }
}


/*********************************************************************\
*                                                                     *
* epolys.js                                          by Mike Williams *
* updated to API v3                                  by Larry Ross    *
*                                                                     *
* A Google Maps API Extension                                         *
*                                                                     *
* Adds various Methods to google.maps.Polygon and google.maps.Polyline *
*                                                                     *
* .Contains(latlng) returns true is the poly contains the specified   *
*                   GLatLng                                           *
*                                                                     *
* .Area()           returns the approximate area of a poly that is    *
*                   not self-intersecting                             *
*                                                                     *
* .Distance()       returns the length of the poly path               *
*                                                                     *
* .Bounds()         returns a GLatLngBounds that bounds the poly      *
*                                                                     *
* .GetPointAtDistance() returns a GLatLng at the specified distance   *
*                   along the path.                                   *
*                   The distance is specified in metres               *
*                   Reurns null if the path is shorter than that      *
*                                                                     *
* .GetPointsAtDistance() returns an array of GLatLngs at the          *
*                   specified interval along the path.                *
*                   The distance is specified in metres               *
*                                                                     *
* .GetIndexAtDistance() returns the vertex number at the specified    *
*                   distance along the path.                          *
*                   The distance is specified in metres               *
*                   Returns null if the path is shorter than that      *
*                                                                     *
* .Bearing(v1?,v2?) returns the bearing between two vertices          *
*                   if v1 is null, returns bearing from first to last *
*                   if v2 is null, returns bearing from v1 to next    *
*                                                                     *
*                                                                     *
***********************************************************************
*                                                                     *
*   This Javascript is provided by Mike Williams                      *
*   Blackpool Community Church Javascript Team                        *
*   http://www.blackpoolchurch.org/                                   *
*   http://econym.org.uk/gmap/                                        *
*                                                                     *
*   This work is licenced under a Creative Commons Licence            *
*   http://creativecommons.org/licenses/by/2.0/uk/                    *
*                                                                     *
***********************************************************************
*                                                                     *
* Version 1.1       6-Jun-2007                                        *
* Version 1.2       1-Jul-2007 - fix: Bounds was omitting vertex zero *
*                                add: Bearing                         *
* Version 1.3       28-Nov-2008  add: GetPointsAtDistance()           *
* Version 1.4       12-Jan-2009  fix: GetPointsAtDistance()           *
* Version 3.0       11-Aug-2010  update to v3                         *
*                                                                     *
\*********************************************************************/

// === first support methods that don't (yet) exist in v3
google.maps.LatLng.prototype.distanceFrom = function(newLatLng) {
  var EarthRadiusMeters = 6378137.0; // meters
  var lat1 = this.lat();
  var lon1 = this.lng();
  var lat2 = newLatLng.lat();
  var lon2 = newLatLng.lng();
  var dLat = (lat2 - lat1) * Math.PI / 180;
  var dLon = (lon2 - lon1) * Math.PI / 180;
  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = EarthRadiusMeters * c;
  return d;
}

google.maps.LatLng.prototype.latRadians = function() {
  return this.lat() * Math.PI / 180;
}

google.maps.LatLng.prototype.lngRadians = function() {
  return this.lng() * Math.PI / 180;
}

// === A method for testing if a point is inside a polygon
// === Returns true if poly contains point
// === Algorithm shamelessly stolen from http://alienryderflex.com/polygon/ 
google.maps.Polygon.prototype.Contains = function(point) {
  var j = 0;
  var oddNodes = false;
  var x = point.lng();
  var y = point.lat();
  for (var i = 0; i < this.getPath().getLength(); i++) {
    j++;
    if (j == this.getPath().getLength()) {
      j = 0;
    }
    if (((this.getPath().getAt(i).lat() < y) && (this.getPath().getAt(j).lat() >= y)) || ((this.getPath().getAt(j).lat() < y) && (this.getPath().getAt(i).lat() >= y))) {
      if (this.getPath().getAt(i).lng() + (y - this.getPath().getAt(i).lat()) / (this.getPath().getAt(j).lat() - this.getPath().getAt(i).lat()) * (this.getPath().getAt(j).lng() - this.getPath().getAt(i).lng()) < x) {
        oddNodes = !oddNodes
      }
    }
  }
  return oddNodes;
}

// === A method which returns the approximate area of a non-intersecting polygon in square metres ===
// === It doesn't fully account for spherical geometry, so will be inaccurate for large polygons ===
// === The polygon must not intersect itself ===
google.maps.Polygon.prototype.Area = function() {
  var a = 0;
  var j = 0;
  var b = this.Bounds();
  var x0 = b.getSouthWest().lng();
  var y0 = b.getSouthWest().lat();
  for (var i = 0; i < this.getPath().getLength(); i++) {
    j++;
    if (j == this.getPath().getLength()) {
      j = 0;
    }
    var x1 = this.getPath().getAt(i).distanceFrom(new google.maps.LatLng(this.getPath().getAt(i).lat(), x0));
    var x2 = this.getPath().getAt(j).distanceFrom(new google.maps.LatLng(this.getPath().getAt(j).lat(), x0));
    var y1 = this.getPath().getAt(i).distanceFrom(new google.maps.LatLng(y0, this.getPath().getAt(i).lng()));
    var y2 = this.getPath().getAt(j).distanceFrom(new google.maps.LatLng(y0, this.getPath().getAt(j).lng()));
    a += x1 * y2 - x2 * y1;
  }
  return Math.abs(a * 0.5);
}

// === A method which returns the length of a path in metres ===
google.maps.Polygon.prototype.Distance = function() {
  var dist = 0;
  for (var i = 1; i < this.getPath().getLength(); i++) {
    dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i - 1));
  }
  return dist;
}

// === A method which returns the bounds as a GLatLngBounds ===
google.maps.Polygon.prototype.Bounds = function() {
  var bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < this.getPath().getLength(); i++) {
    bounds.extend(this.getPath().getAt(i));
  }
  return bounds;
}

// === A method which returns a GLatLng of a point a given distance along the path ===
// === Returns null if the path is shorter than the specified distance ===
google.maps.Polygon.prototype.GetPointAtDistance = function(metres) {
  // some awkward special cases
  if (metres == 0) return this.getPath().getAt(0);
  if (metres < 0) return null;
  if (this.getPath().getLength() < 2) return null;
  var dist = 0;
  var olddist = 0;
  for (var i = 1;
    (i < this.getPath().getLength() && dist < metres); i++) {
    olddist = dist;
    dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i - 1));
  }
  if (dist < metres) {
    return null;
  }
  var p1 = this.getPath().getAt(i - 2);
  var p2 = this.getPath().getAt(i - 1);
  var m = (metres - olddist) / (dist - olddist);
  return new google.maps.LatLng(p1.lat() + (p2.lat() - p1.lat()) * m, p1.lng() + (p2.lng() - p1.lng()) * m);
}

// === A method which returns an array of GLatLngs of points a given interval along the path ===
google.maps.Polygon.prototype.GetPointsAtDistance = function(metres) {
  var next = metres;
  var points = [];
  // some awkward special cases
  if (metres <= 0) return points;
  var dist = 0;
  var olddist = 0;
  for (var i = 1;
    (i < this.getPath().getLength()); i++) {
    olddist = dist;
    dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i - 1));
    while (dist > next) {
      var p1 = this.getPath().getAt(i - 1);
      var p2 = this.getPath().getAt(i);
      var m = (next - olddist) / (dist - olddist);
      points.push(new google.maps.LatLng(p1.lat() + (p2.lat() - p1.lat()) * m, p1.lng() + (p2.lng() - p1.lng()) * m));
      next += metres;
    }
  }
  return points;
}

// === A method which returns the Vertex number at a given distance along the path ===
// === Returns null if the path is shorter than the specified distance ===
google.maps.Polygon.prototype.GetIndexAtDistance = function(metres) {
  // some awkward special cases
  if (metres == 0) return this.getPath().getAt(0);
  if (metres < 0) return null;
  var dist = 0;
  var olddist = 0;
  for (var i = 1;
    (i < this.getPath().getLength() && dist < metres); i++) {
    olddist = dist;
    dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i - 1));
  }
  if (dist < metres) {
    return null;
  }
  return i;
}

// === A function which returns the bearing between two vertices in decgrees from 0 to 360===
// === If v1 is null, it returns the bearing between the first and last vertex ===
// === If v1 is present but v2 is null, returns the bearing from v1 to the next vertex ===
// === If either vertex is out of range, returns void ===
google.maps.Polygon.prototype.Bearing = function(v1, v2) {
  if (v1 == null) {
    v1 = 0;
    v2 = this.getPath().getLength() - 1;
  } else if (v2 == null) {
    v2 = v1 + 1;
  }
  if ((v1 < 0) || (v1 >= this.getPath().getLength()) || (v2 < 0) || (v2 >= this.getPath().getLength())) {
    return;
  }
  var from = this.getPath().getAt(v1);
  var to = this.getPath().getAt(v2);
  if (from.equals(to)) {
    return 0;
  }
  var lat1 = from.latRadians();
  var lon1 = from.lngRadians();
  var lat2 = to.latRadians();
  var lon2 = to.lngRadians();
  var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
  if (angle < 0.0) angle += Math.PI * 2.0;
  angle = angle * 180.0 / Math.PI;
  return parseFloat(angle.toFixed(1));
}




// === Copy all the above functions to GPolyline ===
google.maps.Polyline.prototype.Contains = google.maps.Polygon.prototype.Contains;
google.maps.Polyline.prototype.Area = google.maps.Polygon.prototype.Area;
google.maps.Polyline.prototype.Distance = google.maps.Polygon.prototype.Distance;
google.maps.Polyline.prototype.Bounds = google.maps.Polygon.prototype.Bounds;
google.maps.Polyline.prototype.GetPointAtDistance = google.maps.Polygon.prototype.GetPointAtDistance;
google.maps.Polyline.prototype.GetPointsAtDistance = google.maps.Polygon.prototype.GetPointsAtDistance;
google.maps.Polyline.prototype.GetIndexAtDistance = google.maps.Polygon.prototype.GetIndexAtDistance;
google.maps.Polyline.prototype.Bearing = google.maps.Polygon.prototype.Bearing;

html {
  height: 100%
}
body {
  height: 100%;
  margin: 0px;
  padding: 0px
}

<script type="text/javascript" src="https://maps.google.com/maps/api/js"></script>

<div id="tools">
  start:
  <input type="text" name="start" id="start" value="Hyderabad" />end:
  <input type="text" name="end" id="end" value="Bangalore" />
  <input type="submit" onclick="calcRoute();" />
  <br />distance (in km):
  <input type="text" name="dist" id="dist" value="0" />
  <input type="submit" onclick="putMarkerOnRoute(parseFloat(document.getElementById('dist').value)*1000);" />km &nbsp;total time:
  <input type="text" name="totalTime" id="totalTime" value="0" />
</div>
<div id="map_canvas" style="float:left;width:70%;height:100%;"></div>
<div id="control_panel" style="float:right;width:30%;text-align:left;padding-top:20px">
  <div id="directions_panel" style="margin:20px;background-color:#FFEE77;"></div>
  <div id="total"></div>
</div>

这篇关于是否可以指定路线,然后通过指定路线的百分比来获取(长,拉特)列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆