How do you change the color of the dotted line on

2020-02-15 06:50发布

I am working on Transit directions and have been able to change the color of polyline displayed for transit route using polylineOptions property.

However, I am not able to change the color of dotted line displayed for walking directions.

I did come across this solution, but it doesnt work for v3 (tried with v3.22)

Similar StackOverflow Question

I have included a working example in this JS Fiddle

var directions = new google.maps.DirectionsService();
var renderer = new google.maps.DirectionsRenderer({
  polylineOptions: {
    strokeColor: '#C83939',
    strokeOpacity: 0.8,
    strokeWeight: 7
  }

});
var map, transitLayer;

function initialize() {
  var mapOptions = {
    zoom: 13,
    center: new google.maps.LatLng(40.7482333, -73.8681295),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById('map'), mapOptions);

  google.maps.event.addDomListener(document.getElementById('go'), 'click',
    route);

  var input = document.getElementById('from');
  var autocomplete = new google.maps.places.Autocomplete(input);
  autocomplete.bindTo('bounds', map);

  transitLayer = new google.maps.TransitLayer();

  var control = document.getElementById('transit-wpr');
  map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control);

  google.maps.event.addDomListener(control, 'click', function() {
    transitLayer.setMap(transitLayer.getMap() ? null : map);
  });

  addDepart();
  route();
}

function addDepart() {
  var depart = document.getElementById('depart');
  for (var i = 0; i < 24; i++) {
    for (var j = 0; j < 60; j += 15) {
      var x = i < 10 ? '0' + i : i;
      var y = j < 10 ? '0' + j : j;
      depart.innerHTML += '<option>' + x + ':' + y + '</option>';
    }
  }
}

function route() {
  var departure = document.getElementById('depart').value;
  var bits = departure.split(':');
  var now = new Date();
  var tzOffset = (now.getTimezoneOffset() + 60) * 60 * 1000;

  var time = new Date();
  time.setHours(bits[0]);
  time.setMinutes(bits[1]);

  var ms = time.getTime() - tzOffset;
  if (ms < now.getTime()) {
    ms += 24 * 60 * 60 * 1000;
  }

  var departureTime = new Date(ms);

  var request = {
    origin: document.getElementById('from').value,
    destination: '51 St, New York, NY 10022, USA',
    travelMode: google.maps.DirectionsTravelMode.TRANSIT,
    provideRouteAlternatives: true,
    transitOptions: {
      departureTime: departureTime
    }
  };

  var panel = document.getElementById('panel');
  panel.innerHTML = '';
  directions.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      renderer.setDirections(response);
      renderer.setMap(map);
      renderer.setPanel(panel);
      console.log(renderer.getDirections());
    } else {
      renderer.setMap(null);
      renderer.setPanel(null);
    }

  });

}

google.maps.event.addDomListener(window, 'load', initialize);
html,
body {
  height: 100%;
  padding: 0;
  margin: 0;
  color: black;
  font-family: arial, sans-serif;
  font-size: 13px;
}
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 50%;
}
#panel-wpr {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  right: 0;
  overflow: auto;
}
#panel {
  font-family: arial;
  padding: 0 5px;
}
#info {
  padding: 5px;
}
#from {
  width: 90%;
  font-size: 1.2em;
}
.adp-directions {
  width: 100%;
}
.input {
  background-color: white;
  padding-left: 8px;
  border: 1px solid #D9D9D9;
  border-top: 1px solid silver;
  -webkit-border-radius: 1px;
  -moz-border-radius: 1px;
  border-radius: 1px;
}
.time {
  margin: 0;
  height: 17px;
  border: 1px solid;
  border-top-color: #CCC;
  border-right-color: #999;
  border-left-color: #999;
  border-bottom-color: #CCC;
  padding: 2px 15px 1px 1px;
}
button {
  border: 1px solid #3079ED;
  color: white;
  background-color: #4D90FE;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#4D90FE), to(#4787ED));
  background-image: -webkit-linear-gradient(top, #4D90FE, #4787ED);
  background-image: -moz-linear-gradient(top, #4D90FE, #4787ED);
  background-image: -ms-linear-gradient(top, #4D90FE, #4787ED);
  background-image: -o-linear-gradient(top, #4D90FE, #4787ED);
  background-image: linear-gradient(top, #4D90FE, #4787ED);
  filter: progid: DXImageTransform.Microsoft.gradient(startColorStr='#4d90fe', EndColorStr='#4787ed');
  display: inline-block;
  min-width: 54px;
  text-align: center;
  font-weight: bold;
  padding: 0 8px;
  line-height: 27px;
  -webkit-border-radius: 2px;
  -moz-border-radius: 2px;
  border-radius: 2px;
  -webkit-transition: all 0.218s;
  -moz-transition: all 0.218s;
  -o-transition: all 0.218s;
  transition: all 0.218s;
}
#info div {
  line-height: 22px;
  font-size: 110%;
}
.btn {} #panel-wpr {
  border-left: 1px solid #e6e6e6;
}
#info {
  border-bottom: 1px solid #E6E6E6;
  margin-bottom: 5px;
}
h2 {
  margin: 0;
  padding: 0;
}
<title>Google Maps JavaScript API v3 Example: Transit</title>
<div id="transit-wpr">
  <button id="transit">Toggle transit layer</button>
</div>
<div id="map"></div>
<div id="panel-wpr">
  <div id="info">
    <div>
      <h2>Transit directions</h2>
    </div>
    <div>
      <label>from:</label>
      <input class="input" id="from" value="Grand Central 42, NY">
    </div>
    <div>
      <label>to:</label>
      <strong>51 St, New York, NY 10022, USA</strong>
    </div>
    <div>Depart at
      <select id="depart"></select>
    </div>
    <div class="btn">
      <button id="go">Get Directions</button>
    </div>
  </div>
  <div id="panel"></div>
</div>

Any property available which I have missed, or this is not possible?

2条回答
走好不送
2楼-- · 2020-02-15 06:51

The options for these lines are fixed and will not be affected by the polylineOptions of the DirectionsRenderer.

The polylineOptions for these dotted lines will (currently) be set by the API to:

{
  "icons": [{
    "icon": {
      "path": 0,
      "scale": 3,
      "fillOpacity": 0.7,
      "fillColor": "#00b3fd",
      "strokeOpacity": 0.8,
      "strokeColor": "#3379c3",
      "strokeWeight": 1
    },
    "repeat": "10px"
  }],
  "strokeColor": "#000000",
  "strokeOpacity": 0,
  "strokeWeight": 5
}

...any custom polylineOption of the DirectionsRenderer will be ignored.

A possible workaround(but it will only be possible to set a single fixed value for all these dotted lines):

function initMap() {
     var  goo = google.maps,
          map = new goo.Map(document.getElementById('map'), {
                  zoom: 7,
                  center: {lat: 41.85, lng: -87.65}
                }),
          directionsService       = new goo.DirectionsService,
          directionsDisplay       = new goo.DirectionsRenderer({
                                      map:map,
                                      polylineOptions:{
                                        strokeColor:'red'
                                      }});
      google.maps.Polyline.prototype.setMap=(function(f,r){
      
        return function(map){
          if(
            this.get('icons')
              &&
            this.get('icons').length===1
              &&
            this.get('strokeOpacity')===0
              &&
            !this.get('noRoute')
          ){
            if(r.get('polylineOptions')&& r.get('polylineOptions').strokeColor){
              
              var icons=this.get('icons'),
                  color=r.get('polylineOptions').strokeColor;
              icons[0].icon.fillOpacity=1;
              icons[0].icon.fillColor=color;
              icons[0].icon.strokeColor=color;
              this.set('icons',icons);
          }}
        f.apply(this,arguments);
      }
      
     })(
          google.maps.Polyline.prototype.setMap,
          directionsDisplay);
    
  
  directionsService.route({
    origin: new google.maps.LatLng(52.549917, 13.42539669),
    destination: new google.maps.LatLng(52.541843, 13.4206566),
    travelMode: google.maps.TravelMode.TRANSIT
  }, function(response, status) {
    if (status === google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);
    } else {
      window.alert('Directions request failed due to ' + status);
    }
  });
}
html, body,#map  {
        height: 100%;
        margin: 0;
        padding: 0;
      }
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap"
        async defer></script>

It overrides the setMap-method of google.maps.Polyline

It checks if

  1. the strokeOpacity is 0
  2. a IconSequence with a single icon is present
  3. it doesn't have a noRoute-property(in the case that you draw polylines on your own which match the first 2 condition set a noRoute-option to true, otherwise they will be affected too)

When all 3 conditions are true, it will modify the icons-property of the polyline.

查看更多
冷血范
3楼-- · 2020-02-15 07:11

There is no property (currently) that allows that part of the polyline to be styled. One option is to hide the DirectionRenderer Polyline and render the polylines yourself, that gives you complete control over the separate polylines.

var polylineOptions = {
  strokeColor: '#C83939',
  strokeOpacity: 1,
  strokeWeight: 4
};
var walkingPolylineOptions = {
  strokeColor: '#C83939',
  strokeOpacity: 0,
  strokeWeight: 4,
  icons: [{
    icon: {
      path: google.maps.SymbolPath.CIRCLE,
      fillColor: '#C83939',
      fillOpacity: 1,
      scale: 2,
      strokeColor: '#C83939',
      strokeOpacity: 1,
    },
    offset: '0',
    repeat: '10px'
  }]
};

function renderDirectionsPolylines(response) {
  var legs = response.routes[0].legs;
  for (i = 0; i < legs.length; i++) {
    var steps = legs[i].steps;
    for (j = 0; j < steps.length; j++) {
      var nextSegment = steps[j].path;
      var stepPolyline = new google.maps.Polyline(polylineOptions);
      if (steps[j].travel_mode == google.maps.TravelMode.WALKING) {
        stepPolyline.setOptions(walkingPolylineOptions)
      }
      for (k = 0; k < nextSegment.length; k++) {
        stepPolyline.getPath().push(nextSegment[k]);
      }
      stepPolyline.setMap(map);
    }
  }
}

proof of concept fiddle

screenshot of resulting map

code snippet:

var polylineOptions = {
  strokeColor: '#C83939',
  strokeOpacity: 1,
  strokeWeight: 4
};
var walkingPolylineOptions = {
  strokeColor: '#C83939',
  strokeOpacity: 0,
  strokeWeight: 4,
  icons: [{
    icon: {
      path: google.maps.SymbolPath.CIRCLE,
      fillColor: '#C83939',
      fillOpacity: 1,
      scale: 2,
      strokeColor: '#C83939',
      strokeOpacity: 1,
    },
    offset: '0',
    repeat: '10px'
  }]
};

function renderDirectionsPolylines(response) {
  var legs = response.routes[0].legs;
  for (i = 0; i < legs.length; i++) {
    var steps = legs[i].steps;
    for (j = 0; j < steps.length; j++) {
      var nextSegment = steps[j].path;
      var stepPolyline = new google.maps.Polyline(polylineOptions);
      if (steps[j].travel_mode == google.maps.TravelMode.WALKING) {
        stepPolyline.setOptions(walkingPolylineOptions)
      }
      for (k = 0; k < nextSegment.length; k++) {
        stepPolyline.getPath().push(nextSegment[k]);
      }
      stepPolyline.setMap(map);
    }
  }
}

var directions = new google.maps.DirectionsService();
var renderer = new google.maps.DirectionsRenderer({
  suppressPolylines: true,
});
var map, transitLayer;

function initialize() {
  var mapOptions = {
    zoom: 13,
    center: new google.maps.LatLng(40.7482333, -73.8681295),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById('map'), mapOptions);

  google.maps.event.addDomListener(document.getElementById('go'), 'click',
    route);

  var input = document.getElementById('from');
  var autocomplete = new google.maps.places.Autocomplete(input);
  autocomplete.bindTo('bounds', map);

  transitLayer = new google.maps.TransitLayer();

  var control = document.getElementById('transit-wpr');
  map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control);

  google.maps.event.addDomListener(control, 'click', function() {
    transitLayer.setMap(transitLayer.getMap() ? null : map);
  });

  addDepart();
  route();
}

function addDepart() {
  var depart = document.getElementById('depart');
  for (var i = 0; i < 24; i++) {
    for (var j = 0; j < 60; j += 15) {
      var x = i < 10 ? '0' + i : i;
      var y = j < 10 ? '0' + j : j;
      depart.innerHTML += '<option>' + x + ':' + y + '</option>';
    }
  }
}

function route() {
  var departure = document.getElementById('depart').value;
  var bits = departure.split(':');
  var now = new Date();
  var tzOffset = (now.getTimezoneOffset() + 60) * 60 * 1000;
  var time = new Date();
  time.setHours(bits[0]);
  time.setMinutes(bits[1]);
  var ms = time.getTime() - tzOffset;
  if (ms < now.getTime()) {
    ms += 24 * 60 * 60 * 1000;
  }
  var departureTime = new Date(ms);
  var request = {
    origin: document.getElementById('from').value,
    destination: '51 St, New York, NY 10022, USA',
    travelMode: google.maps.DirectionsTravelMode.TRANSIT,
    provideRouteAlternatives: true,
    transitOptions: {
      departureTime: departureTime
    }
  };
  var panel = document.getElementById('panel');
  panel.innerHTML = '';
  directions.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      renderer.setDirections(response);
      renderer.setMap(map);
      renderer.setPanel(panel);
      renderDirectionsPolylines(response);
      console.log(renderer.getDirections());
    } else {
      renderer.setMap(null);
      renderer.setPanel(null);
    }
  });
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body {
  height: 100%;
  padding: 0;
  margin: 0;
  color: black;
  font-family: arial, sans-serif;
  font-size: 13px;
}
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 50%;
}
#panel-wpr {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  right: 0;
  overflow: auto;
}
#panel {
  font-family: arial;
  padding: 0 5px;
}
#info {
  padding: 5px;
}
#from {
  width: 90%;
  font-size: 1.2em;
}
.adp-directions {
  width: 100%;
}
.input {
  background-color: white;
  padding-left: 8px;
  border: 1px solid #D9D9D9;
  border-top: 1px solid silver;
  -webkit-border-radius: 1px;
  -moz-border-radius: 1px;
  border-radius: 1px;
}
.time {
  margin: 0;
  height: 17px;
  border: 1px solid;
  border-top-color: #CCC;
  border-right-color: #999;
  border-left-color: #999;
  border-bottom-color: #CCC;
  padding: 2px 15px 1px 1px;
}
button {
  border: 1px solid #3079ED;
  color: white;
  background-color: #4D90FE;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#4D90FE), to(#4787ED));
  background-image: -webkit-linear-gradient(top, #4D90FE, #4787ED);
  background-image: -moz-linear-gradient(top, #4D90FE, #4787ED);
  background-image: -ms-linear-gradient(top, #4D90FE, #4787ED);
  background-image: -o-linear-gradient(top, #4D90FE, #4787ED);
  background-image: linear-gradient(top, #4D90FE, #4787ED);
  filter: progid: DXImageTransform.Microsoft.gradient(startColorStr='#4d90fe', EndColorStr='#4787ed');
  display: inline-block;
  min-width: 54px;
  text-align: center;
  font-weight: bold;
  padding: 0 8px;
  line-height: 27px;
  -webkit-border-radius: 2px;
  -moz-border-radius: 2px;
  border-radius: 2px;
  -webkit-transition: all 0.218s;
  -moz-transition: all 0.218s;
  -o-transition: all 0.218s;
  transition: all 0.218s;
}
#info div {
  line-height: 22px;
  font-size: 110%;
}
.btn {} #panel-wpr {
  border-left: 1px solid #e6e6e6;
}
#info {
  border-bottom: 1px solid #E6E6E6;
  margin-bottom: 5px;
}
h2 {
  margin: 0;
  padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.22&libraries=places"></script>
<title>Google Maps JavaScript API v3 Example: Transit</title>
<div id="transit-wpr">
  <button id="transit">Toggle transit layer</button>
</div>
<div id="map"></div>
<div id="panel-wpr">
  <div id="info">
    <div>
      <h2>Transit directions</h2>
    </div>
    <div>
      <label>from:</label>
      <input class="input" id="from" value="Grand Central 42, NY" />
    </div>
    <div>
      <label>to:</label>
      <strong>51 St, New York, NY 10022, USA</strong>
    </div>
    <div>Depart at
      <select id="depart"></select>
    </div>
    <div class="btn">
      <button id="go">Get Directions</button>
    </div>
  </div>
  <div id="panel"></div>
</div>

查看更多
登录 后发表回答