【问题标题】:How to curve a Polyline in react-google-maps?如何在 react-google-maps 中弯曲折线?
【发布时间】:2018-07-20 05:55:40
【问题描述】:

我是 React 新手,一直在玩 react-google-maps 包。我正在尝试弯曲连接两个地方的折线。浏览完文档后,我尝试将曲线折线函数合并到“可编辑”道具下。

这是使折线弯曲的函数:

var map;
var curvature = 0.4; // Arc of the Polyline

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

            // Initial location of the points
            var pos1 = new LatLng(this.state.srcMarker);
            var pos2 = new LatLng(this.state.desMarker);

            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(), 
                    pos2 = markerP2.getPosition(),
                    projection = map.getProjection(),
                    p1 = projection.fromLatLngToPoint(pos1), 
                    p2 = projection.fromLatLngToPoint(pos2);

                    // Calculating the arc.
                    var e = new Point(p2.x - p1.x, p2.y - p1.y), // endpoint
                        m = new Point(e.x / 2, e.y / 2), // midpoint
                        o = new Point(e.y, -e.x), // orthogonal
                        c = new Point( m.x + curvature * o.x, m.y + curvature * o.y); //curve control point

                    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'
                    };

                    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);

我无法理解如何在折线组件中使用此功能。我可以在任何两个地方之间标记一条线,但不能使用此功能来弯曲给定的折线。这是我正在使用的折线组件。

<Polyline
        path={pathCoordinates} 
        geodesic={true} 
        options={{ 
                strokeColor: '#ff2527',
                        strokeOpacity: 1.0,
                        strokeWeight: 5,
        }}
/>

我的州有两个标记(srcMarker、desMarker),一旦用户输入城市名称,它们就会存储给定城市的坐标。在将此功能与折线组件结合使用时,我们将不胜感激。我还没有遇到任何允许折线弯曲的内置功能。提前致谢!

【问题讨论】:

    标签: javascript reactjs google-maps react-google-maps


    【解决方案1】:

    我采用了您提供的代码并对其进行了调整,以便与 React 和 react-google-maps 一起使用。查看this CodeSandbox,查看一个包含两个标记和它们之间的曲线的简单应用程序。

    连接两个标记的曲线实际上也是一个标记。它和两个红色标记的唯一区别是它的图标道具设置为曲线(这是预先计算好的)。

    这是CurveMarker 组件的代码:

    const CurveMarker = ({ pos1, pos2, mapProjection, zoom }) => {
      if (!mapProjection) return <div/>;
      var curvature = 0.4
    
      const p1 = mapProjection.fromLatLngToPoint(pos1),
            p2 = mapProjection.fromLatLngToPoint(pos2);
    
      // Calculating the arc.
      const e = new google.maps.Point(p2.x - p1.x, p2.y - p1.y), // endpoint
        m = new google.maps.Point(e.x / 2, e.y / 2), // midpoint
        o = new google.maps.Point(e.y, -e.x), // orthogonal
        c = new google.maps.Point(m.x + curvature * o.x, m.y + curvature * o.y); //curve control point
    
      const pathDef = 'M 0,0 ' + 'q ' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;
    
      const scale = 1 / (Math.pow(2, -zoom));
    
      const symbol = {
        path: pathDef,
        scale: scale,
        strokeWeight: 2,
        fillColor: 'none'
      };
    
      return <Marker 
                position={pos1} 
                clickable={false} 
                icon={symbol}
                zIndex={0}
              />;
    };
    

    如果您有任何问题,请告诉我。

    【讨论】:

    • 非常感谢,能够让它工作。如果我要计算两个地方之间弯曲标记的中点,我怎么能做到这一点?当它是一条直线时,我能够弄清楚如何找到中点。
    • 试图弄清楚如何做到这一点。如果我有什么想法,我会告诉你的。是否要在曲线的中点放置一个标记?
    • 我认为常量c 存储曲线的中点。但是,当我尝试使用 the point2LatLng function here 将其转换回 LatLng 坐标(并在该位置放置一个标记)时,它不起作用。
    • 能够在曲线的中点放置信息窗口。已查找 this 以获取计算贝塞尔曲线上不同点的方程。
    • 使用上面的CurveMarker函数,我使用了计算曲线控制点的方程(常数c),只是用贝塞尔曲线方程替换了中点m。曲线中点的 x 和 y 坐标为 mpc_x = ((0.5 * p1.x) + (0.5 * p2.x)) + ((curvature / 2) * (p2.y - p1.y))mpc_y = ((0.5 * p1.y) + (0.5 * p2.y)) + ((curvature / 2) * (p1.x - p2.x))。希望这很清楚。
    猜你喜欢
    • 2018-05-03
    • 2018-09-01
    • 2023-02-06
    • 1970-01-01
    • 2014-10-21
    • 2018-01-07
    • 2016-03-24
    • 1970-01-01
    • 2023-02-12
    相关资源
    最近更新 更多