首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我能在Google中画一条曲线吗?

我能在Google中画一条曲线吗?
EN

Stack Overflow用户
提问于 2017-04-09 10:28:42
回答 4查看 9.9K关注 0票数 8

在具有曲线虚线的浏览器的Google中,如下所示:

但是当我在我自己的Android项目中实现Google时,它没有显示这一行

我该怎么画这条线?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-04-27 18:29:01

您可以实现两点之间的曲线虚线。为此,您可以使用具有Google API实用程序库类的SphericalUtil,并在代码中应用一些数学来创建一个polyline。

您必须将实用程序库作为

compile 'com.google.maps.android:android-maps-utils:0.5'

请看我的示例活动和函数showCurvedPolyline (LatLng p1, LatLng p2, double k),它在两点之间构造虚线曲线。最后一个参数k定义了折线的曲率,它可以是>0和<=1。

代码语言:javascript
运行
复制
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

private GoogleMap mMap;
private LatLng sydney1;
private LatLng sydney2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mMap.getUiSettings().setZoomControlsEnabled(true);

    // Add a marker in Sydney and move the camera
    sydney1 = new LatLng(-33.904438,151.249852);
    sydney2 = new LatLng(-33.905823,151.252422);

    mMap.addMarker(new MarkerOptions().position(sydney1)
            .draggable(false).visible(true).title("Marker in Sydney 1"));
    mMap.addMarker(new MarkerOptions().position(sydney2)
            .draggable(false).visible(true).title("Marker in Sydney 2"));

    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney1, 16F));

    this.showCurvedPolyline(sydney1,sydney2, 0.5);
}

private void showCurvedPolyline (LatLng p1, LatLng p2, double k) {
    //Calculate distance and heading between two points
    double d = SphericalUtil.computeDistanceBetween(p1,p2);
    double h = SphericalUtil.computeHeading(p1, p2);

    //Midpoint position
    LatLng p = SphericalUtil.computeOffset(p1, d*0.5, h);

    //Apply some mathematics to calculate position of the circle center
    double x = (1-k*k)*d*0.5/(2*k);
    double r = (1+k*k)*d*0.5/(2*k);

    LatLng c = SphericalUtil.computeOffset(p, x, h + 90.0);

    //Polyline options
    PolylineOptions options = new PolylineOptions();
    List<PatternItem> pattern = Arrays.<PatternItem>asList(new Dash(30), new Gap(20));

    //Calculate heading between circle center and two points
    double h1 = SphericalUtil.computeHeading(c, p1);
    double h2 = SphericalUtil.computeHeading(c, p2);

    //Calculate positions of points on circle border and add them to polyline options
    int numpoints = 100;
    double step = (h2 -h1) / numpoints;

    for (int i=0; i < numpoints; i++) {
        LatLng pi = SphericalUtil.computeOffset(c, r, h1 + i * step);
        options.add(pi);
    }

    //Draw polyline
    mMap.addPolyline(options.width(10).color(Color.MAGENTA).geodesic(false).pattern(pattern));
}

}

您可以从GitHub下载包含完整代码的示例项目。

https://github.com/xomena-so/so43305664

只需在app/src/debug/res/values/google_maps_api.xml中用您的API键替换

票数 33
EN

Stack Overflow用户

发布于 2020-05-05 07:40:27

感谢@xomena给出了伟大的答案。但它只有一个小虫子。有时候,它就像一个圆圈。我做了一些调试,发现我们总是在方法的第12行使用h + 90.0作为标题值。我们可以通过改变这条线来解决这个问题:

代码语言:javascript
运行
复制
LatLng c = SphericalUtil.computeOffset(p, x, h > 40 ? h + 90.0 : h - 90.0);

从现在开始,您可能不会再遇到这个问题了。

票数 5
EN

Stack Overflow用户

发布于 2020-07-24 17:40:18

当我在实线上画曲线时,我也遇到了弯曲曲线的问题。经过几个小时的网上搜索和尝试不同的解决方案。最后,我提出了解决方案(不是--一个合适的解决方案,但可以实现目标),方法是使用Polygon而不是Polyline。我修改了上面的方法,showCurvedPolyline()绘制了一条光滑的曲线,曲线的方向总是向上的。下面的截图是我修改过的版本的最终结果。

代码语言:javascript
运行
复制
fun drawCurveOnMap(googleMap: GoogleMap, latLng1: LatLng, latLng2: LatLng) {

    //Adding marker is optional here, you can move out from here.
    googleMap.addMarker(
       MarkerOptions().position(latLng1).icon(BitmapDescriptorFactory.defaultMarker()))
    googleMap.addMarker(
       MarkerOptions().position(latLng2).icon(BitmapDescriptorFactory.defaultMarker()))
    
    val k = 0.5 //curve radius
    var h = SphericalUtil.computeHeading(latLng1, latLng2)
    var d = 0.0
    val p: LatLng?

    //The if..else block is for swapping the heading, offset and distance 
    //to draw curve always in the upward direction
    if (h < 0) {
        d = SphericalUtil.computeDistanceBetween(latLng2, latLng1)
        h = SphericalUtil.computeHeading(latLng2, latLng1)
        //Midpoint position
        p = SphericalUtil.computeOffset(latLng2, d * 0.5, h)
    } else {
        d = SphericalUtil.computeDistanceBetween(latLng1, latLng2)

        //Midpoint position
        p = SphericalUtil.computeOffset(latLng1, d * 0.5, h)
    }

    //Apply some mathematics to calculate position of the circle center
    val x = (1 - k * k) * d * 0.5 / (2 * k)
    val r = (1 + k * k) * d * 0.5 / (2 * k)

    val c = SphericalUtil.computeOffset(p, x, h + 90.0)

    //Calculate heading between circle center and two points
    val h1 = SphericalUtil.computeHeading(c, latLng1)
    val h2 = SphericalUtil.computeHeading(c, latLng2)

    //Calculate positions of points on circle border and add them to polyline options
    val numberOfPoints = 1000 //more numberOfPoints more smooth curve you will get
    val step = (h2 - h1) / numberOfPoints

    //Create PolygonOptions object to draw on map
    val polygon = PolygonOptions()

    //Create a temporary list of LatLng to store the points that's being drawn on map for curve 
    val temp = arrayListOf<LatLng>()

    //iterate the numberOfPoints and add the LatLng to PolygonOptions to draw curve
    //and save in temp list to add again reversely in PolygonOptions
    for (i in 0 until numberOfPoints) {
        val latlng = SphericalUtil.computeOffset(c, r, h1 + i * step)
        polygon.add(latlng) //Adding in PolygonOptions
        temp.add(latlng)    //Storing in temp list to add again in reverse order
    }

    //iterate the temp list in reverse order and add in PolygonOptions
    for (i in (temp.size - 1) downTo 1) {
        polygon.add(temp[i])
    }

    polygon.strokeColor(Color.BLUE)
    polygon.strokeWidth(12f)
    polygon.strokePattern(listOf(Dash(30f), Gap(50f))) //Skip if you want solid line
    googleMap.addPolygon(polygon)

    temp.clear() //clear the temp list
}

为什么我们要在PolygonOptions中以相反的顺序再次添加临时列表?

如果我们不以相反的顺序再次以LatLng添加PolygonOptions,则googleMap.addPolygon()将关闭路径,最终结果如下所示。

提示:

如果您希望曲线更多为圆形,则增加k值。就像k = 0.75

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43305664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档