如何在 Google Maps JS API 中制作虚线曲线折线? [英] How to make a dashed curved polyline in Google Maps JS API?

查看:20
本文介绍了如何在 Google Maps JS API 中制作虚线曲线折线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一条虚线多段线和一条曲线多段线,我可以制作虚线曲线还是虚线曲线?

代码片段:

var map;var 曲率 = 0.5;//弧线的弯曲程度函数初始化(){var Map = google.maps.Map,LatLng = google.maps.LatLng,LatLngBounds = google.maps.LatLngBounds,标记 = google.maps.Marker,点 = google.maps.Point;//这是点的初始位置//(您可以在地图加载后拖动标记)var pos1 = new LatLng(23.634501, -102.552783);var pos2 = new LatLng(17.987557, -92.929147);var bounds = new LatLngBounds();边界.扩展(pos1);边界.扩展(pos2);map = new Map(document.getElementById('map-canvas'), {中心:bounds.getCenter(),变焦:12});map.fitBounds(bounds);var 标记P1 = 新标记({位置:pos1,地图:地图});var 标记P2 = 新标记({位置:pos2,地图:地图});var 曲线标记;函数更新曲线标记(){var pos1 = markerP1.getPosition(),//latlngpos2 = 标记P2.getPosition(),投影 = map.getProjection(),p1 =projection.fromLatLngToPoint(pos1),//xyp2 = 投影.fromLatLngToPoint(pos2);//计算弧度.//为了简化数学,这些点//都是相对于 p1:var e = new Point(p2.x - p1.x, p2.y - p1.y),//端点(p2 相对于 p1)m = new Point(e.x/2, e.y/2),//中点o = new Point(e.y, -e.x),//正交c = new Point(//曲线控制点m.x + 曲率 * o.x,m.y + 曲率 * o.y);var pathDef = 'M 0,0' +'q' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;var zoom = map.getZoom(),比例 = 1/(Math.pow(2, -zoom));var 符号 = {路径:pathDef,规模:规模,行程重量:1,填充颜​​色:'无'};//使用 SVG 路径符号定义一个符号,不透明度为 1.var lineSymbol = {路径:'M 0,-2 0,0.5',中风不透明度:1,行程重量:2,规模:4};//创建折线,在 'icons' 属性中传递符号.//赋予线条不透明度为 0.//以 20 像素的间隔重复符号以创建虚线效果.var line = new google.maps.Polyline({路径:[pos1,pos2],中风不透明度:0,strokeColor: '绿色',图标:[{图标:lineSymbol,偏移量:'0',重复:'4%'}],地图:地图});如果(!曲线标记){曲线标记 = 新标记({位置:pos1,可点击:假,图标:符号,zIndex: 0,//在其他标记后面地图:地图});} 别的 {曲线标记.setOptions({位置:pos1,图标:符号,});}}google.maps.event.addListener(map, 'projection_changed', updateCurveMarker);google.maps.event.addListener(map, 'zoom_changed', updateCurveMarker);google.maps.event.addListener(markerP1, 'position_changed', updateCurveMarker);google.maps.event.addListener(markerP2, 'position_changed', updateCurveMarker);var lineLength = google.maps.geometry.sphereal.computeDistanceBetween(markerP1.getPosition(),markerP2.getPosition());var lineHeading = google.maps.geometry.sphereal.computeHeading(markerP1.getPosition(),markerP2.getPosition());var markerA = new google.maps.Marker({位置:google.maps.geometry.sphereal.computeOffset(markerP1.getPosition(), lineLength/3, lineHeading - 60),地图:地图,图标: {url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle_blue.png",大小:新的 google.maps.Size(7, 7),锚点:新 google.maps.Point(3.5, 3.5)}});var 标记 B = 新的 google.maps.Marker({位置:google.maps.geometry.sphereal.computeOffset(markerP2.getPosition(), lineLength/3, -lineHeading + 120),图标: {url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle_blue.png",大小:新的 google.maps.Size(7, 7),锚点:新 google.maps.Point(3.5, 3.5)},地图:地图});varCurvedLine = new GmapsCubicBezier(markerP1.getPosition(),markerA.getPosition(),markerB.getPosition(),markerP2.getPosition(),0.01,map);var line = new google.maps.Polyline({路径:[markerP1.getPosition(),markerP2.getPosition()],中风不透明度:0,图标:[{图标: {路径:'M 0,-1 0,1',中风不透明度:1,规模:4},偏移量:'0',重复:'20px'}],//地图:地图});}google.maps.event.addDomListener(window, 'load', init);var GmapsCubicBezier = 函数(latlong1,latlong2,latlong3,latlong4,分辨率,地图){var lat1 = latlong1.lat();var long1 = latlong1.lng();var lat2 = latlong2.lat();var long2 = latlong2.lng();var lat3 = latlong3.lat();var long3 = latlong3.lng();var lat4 = latlong4.lat();var long4 = latlong4.lng();var 点 = [];for (it = 0; it <= 1; it += 分辨率) {点推(this.getBezier({x:纬度1,y:长1}, {x:纬度2,y:长2}, {x:纬度3,y:长3}, {x:纬度4,y:长4}, 它));}var 路径 = [];for (var i = 0; i 

html,身体,#地图画布{高度:100%;宽度:100%;边距:0px;填充:0px}

<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></脚本><div id="map-canvas" style="border: 2px solid #3872ac;"></div>

I have a created a dashed polyline, and a curved polyline, can I make the dashed line curve, or the curved line dashed?

http://jsfiddle.net/stevenmc/re6km2wp/

var map;

var curvature = 0.5; // how curvy to make the arc

function init() {
    var Map = google.maps.Map,
        LatLng = google.maps.LatLng,
        LatLngBounds = google.maps.LatLngBounds,
        Marker = google.maps.Marker,
        Point = google.maps.Point;

    // This is the initial location of the points
    // (you can drag the markers around after the map loads)
    var pos1 = new LatLng(23.634501, -102.552783);
    var pos2 = new LatLng(17.987557, -92.929147);

    var bounds = new LatLngBounds();
    bounds.extend(pos1);
    bounds.extend(pos2);

    map = new Map(document.getElementById('map-canvas'), {
        center: bounds.getCenter(),
        zoom: 12
    });
    map.fitBounds(bounds);

    var markerP1 = new Marker({
        position: pos1,
        draggable: true,
        map: map
    });
    var markerP2 = new Marker({
        position: pos2,
        draggable: true,
        map: map
    });

    var curveMarker;

    function updateCurveMarker() {
        var pos1 = markerP1.getPosition(), // latlng
            pos2 = markerP2.getPosition(),
            projection = map.getProjection(),
            p1 = projection.fromLatLngToPoint(pos1), // xy
            p2 = projection.fromLatLngToPoint(pos2);

        // Calculate the arc.
        // To simplify the math, these points 
        // are all relative to p1:
        var e = new Point(p2.x - p1.x, p2.y - p1.y), // endpoint (p2 relative to p1)
            m = new Point(e.x / 2, e.y / 2), // midpoint
            o = new Point(e.y, -e.x), // orthogonal
            c = new Point( // curve control point
                m.x + curvature * o.x,
                m.y + curvature * o.y);

        var pathDef = 'M 0,0 ' +
            'q ' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;

        var zoom = map.getZoom(),
            scale = 1 / (Math.pow(2, -zoom));

        var symbol = {
            path: pathDef,
            scale: scale,
            strokeWeight: 1,
            fillColor: 'none'
        };

        // Define a symbol using SVG path notation, with an opacity of 1.
        var lineSymbol = {
          path: 'M 0,-2 0,0.5',
          strokeOpacity: 1,
          strokeWeight: 2,
          scale: 4
        };

        // Create the polyline, passing the symbol in the 'icons' property.
        // Give the line an opacity of 0.
        // Repeat the symbol at intervals of 20 pixels to create the dashed effect.
        var line = new google.maps.Polyline({
          path: [pos1, pos2],
          strokeOpacity: 0,
          strokeColor: 'green',
          icons: [{
            icon: lineSymbol,
            offset: '0',
            repeat: '4%'
          }],
          map: map
        });

        if (!curveMarker) {
            curveMarker = new Marker({
                position: pos1,
                clickable: false,
                icon: symbol,
                zIndex: 0, // behind the other markers
                map: map
            });
        } else {
            curveMarker.setOptions({
                position: pos1,
                icon: symbol,
            });
        }
    }

    google.maps.event.addListener(map, 'projection_changed', updateCurveMarker);
    google.maps.event.addListener(map, 'zoom_changed', updateCurveMarker);

    google.maps.event.addListener(markerP1, 'position_changed', updateCurveMarker);
    google.maps.event.addListener(markerP2, 'position_changed', updateCurveMarker);
}

google.maps.event.addDomListener(window, 'load', init);

解决方案

You just need coordinates for a curved polyline, you can use the bezier curve referenced in this question (or an arc), then style it with SVG icons as described in the documentation

proof of concept fiddle (using the bezier curve)

code snippet:

var map;

var curvature = 0.5; // how curvy to make the arc

function init() {
  var Map = google.maps.Map,
    LatLng = google.maps.LatLng,
    LatLngBounds = google.maps.LatLngBounds,
    Marker = google.maps.Marker,
    Point = google.maps.Point;

  // This is the initial location of the points
  // (you can drag the markers around after the map loads)
  var pos1 = new LatLng(23.634501, -102.552783);
  var pos2 = new LatLng(17.987557, -92.929147);

  var bounds = new LatLngBounds();
  bounds.extend(pos1);
  bounds.extend(pos2);

  map = new Map(document.getElementById('map-canvas'), {
    center: bounds.getCenter(),
    zoom: 12
  });
  map.fitBounds(bounds);

  var markerP1 = new Marker({
    position: pos1,
    map: map
  });
  var markerP2 = new Marker({
    position: pos2,
    map: map
  });

  var curveMarker;

  function updateCurveMarker() {
    var pos1 = markerP1.getPosition(), // latlng
      pos2 = markerP2.getPosition(),
      projection = map.getProjection(),
      p1 = projection.fromLatLngToPoint(pos1), // xy
      p2 = projection.fromLatLngToPoint(pos2);

    // Calculate the arc.
    // To simplify the math, these points 
    // are all relative to p1:
    var e = new Point(p2.x - p1.x, p2.y - p1.y), // endpoint (p2 relative to p1)
      m = new Point(e.x / 2, e.y / 2), // midpoint
      o = new Point(e.y, -e.x), // orthogonal
      c = new Point( // curve control point
        m.x + curvature * o.x,
        m.y + curvature * o.y);

    var pathDef = 'M 0,0 ' +
      'q ' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;

    var zoom = map.getZoom(),
      scale = 1 / (Math.pow(2, -zoom));

    var symbol = {
      path: pathDef,
      scale: scale,
      strokeWeight: 1,
      fillColor: 'none'
    };

    // Define a symbol using SVG path notation, with an opacity of 1.
    var lineSymbol = {
      path: 'M 0,-2 0,0.5',
      strokeOpacity: 1,
      strokeWeight: 2,
      scale: 4
    };

    // Create the polyline, passing the symbol in the 'icons' property.
    // Give the line an opacity of 0.
    // Repeat the symbol at intervals of 20 pixels to create the dashed effect.
    var line = new google.maps.Polyline({
      path: [pos1, pos2],
      strokeOpacity: 0,
      strokeColor: 'green',
      icons: [{
        icon: lineSymbol,
        offset: '0',
        repeat: '4%'
      }],
      map: map
    });

    if (!curveMarker) {
      curveMarker = new Marker({
        position: pos1,
        clickable: false,
        icon: symbol,
        zIndex: 0, // behind the other markers
        map: map
      });
    } else {
      curveMarker.setOptions({
        position: pos1,
        icon: symbol,
      });
    }
  }

  google.maps.event.addListener(map, 'projection_changed', updateCurveMarker);
  google.maps.event.addListener(map, 'zoom_changed', updateCurveMarker);

  google.maps.event.addListener(markerP1, 'position_changed', updateCurveMarker);
  google.maps.event.addListener(markerP2, 'position_changed', updateCurveMarker);

  var lineLength = google.maps.geometry.spherical.computeDistanceBetween(markerP1.getPosition(), markerP2.getPosition());
  var lineHeading = google.maps.geometry.spherical.computeHeading(markerP1.getPosition(), markerP2.getPosition());
  var markerA = new google.maps.Marker({
    position: google.maps.geometry.spherical.computeOffset(markerP1.getPosition(), lineLength / 3, lineHeading - 60),
    map: map,
    icon: {
      url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle_blue.png",
      size: new google.maps.Size(7, 7),
      anchor: new google.maps.Point(3.5, 3.5)
    }
  });
  var markerB = new google.maps.Marker({
    position: google.maps.geometry.spherical.computeOffset(markerP2.getPosition(), lineLength / 3, -lineHeading + 120),
    icon: {
      url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle_blue.png",
      size: new google.maps.Size(7, 7),
      anchor: new google.maps.Point(3.5, 3.5)
    },
    map: map
  });

  var curvedLine = new GmapsCubicBezier(markerP1.getPosition(), markerA.getPosition(), markerB.getPosition(), markerP2.getPosition(), 0.01, map);

  var line = new google.maps.Polyline({
    path: [markerP1.getPosition(), markerP2.getPosition()],
    strokeOpacity: 0,
    icons: [{
      icon: {
        path: 'M 0,-1 0,1',
        strokeOpacity: 1,
        scale: 4
      },
      offset: '0',
      repeat: '20px'
    }],
    // map: map
  });




}

google.maps.event.addDomListener(window, 'load', init);

var GmapsCubicBezier = function(latlong1, latlong2, latlong3, latlong4, resolution, map) {
  var lat1 = latlong1.lat();
  var long1 = latlong1.lng();
  var lat2 = latlong2.lat();
  var long2 = latlong2.lng();
  var lat3 = latlong3.lat();
  var long3 = latlong3.lng();
  var lat4 = latlong4.lat();
  var long4 = latlong4.lng();

  var points = [];

  for (it = 0; it <= 1; it += resolution) {
    points.push(this.getBezier({
      x: lat1,
      y: long1
    }, {
      x: lat2,
      y: long2
    }, {
      x: lat3,
      y: long3
    }, {
      x: lat4,
      y: long4
    }, it));
  }
  var path = [];
  for (var i = 0; i < points.length - 1; i++) {
    path.push(new google.maps.LatLng(points[i].x, points[i].y));
    path.push(new google.maps.LatLng(points[i + 1].x, points[i + 1].y, false));
  }

  var Line = new google.maps.Polyline({
    path: path,
    geodesic: true,
    strokeOpacity: 0.0,
    icons: [{
      icon: {
        path: 'M 0,-1 0,1',
        strokeOpacity: 1,
        scale: 4
      },
      offset: '0',
      repeat: '20px'
    }],
    strokeColor: 'grey'
  });

  Line.setMap(map);

  return Line;
};


GmapsCubicBezier.prototype = {

  B1: function(t) {
    return t * t * t;
  },
  B2: function(t) {
    return 3 * t * t * (1 - t);
  },
  B3: function(t) {
    return 3 * t * (1 - t) * (1 - t);
  },
  B4: function(t) {
    return (1 - t) * (1 - t) * (1 - t);
  },
  getBezier: function(C1, C2, C3, C4, percent) {
    var pos = {};
    pos.x = C1.x * this.B1(percent) + C2.x * this.B2(percent) + C3.x * this.B3(percent) + C4.x * this.B4(percent);
    pos.y = C1.y * this.B1(percent) + C2.y * this.B2(percent) + C3.y * this.B3(percent) + C4.y * this.B4(percent);
    return pos;
  }
};

html,
body,
#map-canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}

<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas" style="border: 2px solid #3872ac;"></div>

这篇关于如何在 Google Maps JS API 中制作虚线曲线折线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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