android - 如何在谷歌地图android中以给定角度旋转多边形

标签 android

enter image description here

我正在开发一个应用程序,我必须在单击时绘制多个固定大小的多边形,例如 10 x 25。这样我现在已经成功存档,我需要以给定角度旋转选定的多边形(让我们考虑 0 到360 )当我点击 + 按钮时,多边形应向右旋转并增加 1 度角,类似地,单击 - 按钮应向左方向旋转多边形有人知道如何实现这一点吗?

添加一些代码以供考虑。

public void drawPolygonWithGivenDimention(LatLng latLng,float width,float  height,float innerDistance,boolean forUpdate,int id)
{
    model = new ModelMarker();

    model.setId(id);

    // Paras Outer Polygon
    Location clickedPoint = new Location("clicked");
    clickedPoint.setLatitude(latLng.latitude);
    clickedPoint.setLongitude(latLng.longitude);

    LatLng latLng0 = new LatLng(clickedPoint.getLatitude(), clickedPoint.getLongitude());
    pointList.add(latLng0);

    Location loc1 = locationForAngle(0.0f, clickedPoint, width);
    LatLng latLng1 = new LatLng(loc1.getLatitude(), loc1.getLongitude());
    pointList.add(latLng1);

    Location loc2 = locationForAngle(90.0f, loc1, height);
    LatLng latLng2 = new LatLng(loc2.getLatitude(), loc2.getLongitude());
    pointList.add(latLng2);

    Location loc3 = locationForAngle(180.0f, loc2, width);
    LatLng latLng3 = new LatLng(loc3.getLatitude(), loc3.getLongitude());
    pointList.add(latLng3);

    model.setPointList(pointList);


    // Paras Inner Polygon
    Location locPeri = locationForAngle(0.0f,clickedPoint,innerDistance);//Change\
    locPeri = locationForAngle(90.0f ,locPeri,innerDistance);

    LatLng latLng10 = new LatLng(locPeri.getLatitude(), locPeri.getLongitude());
    pointListInner.add(latLng10);

    Location loc11 = locationForAngle(0.0f, locPeri, width-innerDistance*2);
    LatLng latLng11 = new LatLng(loc11.getLatitude(), loc11.getLongitude());
    pointListInner.add(latLng11);

    Location loc12 = locationForAngle(90.0f, loc11, height-innerDistance*2);
    LatLng latLng12 = new LatLng(loc12.getLatitude(), loc12.getLongitude());
    pointListInner.add(latLng12);

    Location loc13 = locationForAngle(180.0f, loc12, width-innerDistance*2);
    LatLng latLng13 = new LatLng(loc13.getLatitude(), loc13.getLongitude());
    pointListInner.add(latLng13);
    model.setPointListInner(pointListInner);

    drawOuterPolygon(forUpdate);
}


private void drawOuterPolygon(boolean forUpdate)
{
    try
    {
        pointList = model.getPointList();
        Polygon poligone;
        PolygonOptions polygoneOptions = new PolygonOptions();
        polygoneOptions.addAll(pointList);
        polygoneOptions.strokeWidth(2);
        polygoneOptions.strokeColor(Color.BLACK);

        polygoneOptions.fillColor(drawColor);

        poligone = googleMap.addPolygon(polygoneOptions);
        poligone.setClickable(true);
        if(forUpdate)
            polygons.set(selectedMarkerPosition,poligone);
        else
            polygons.add(poligone);


        model.setPolygon(poligone);
        model.setPolygons(polygons);

        drawInnerPolygon(forUpdate);
        //getCenterPoint();

    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
 }

 public Location locationForAngle(float angle,Location center,float distances)
{
    //in Yard 6975174.98 radius of earth
    double distanceRadians = distances / 6967410.0; // Yards
    //6,371 = Earth's radius in km
    double bearingRadians = deg2rad(angle);
    double fromLatRadians = deg2rad(center.getLatitude());
    double fromLonRadians = deg2rad(center.getLongitude());
    double toLatRadians = Math.asin( Math.sin(fromLatRadians) * Math.cos(distanceRadians)+ Math.cos(fromLatRadians) *  Math.sin(distanceRadians) * Math.cos(bearingRadians) );
    double toLonRadians = fromLonRadians + Math.atan2(Math.sin(bearingRadians) * Math.sin(distanceRadians) * Math.cos(fromLatRadians), Math.cos(distanceRadians)- Math.sin(fromLatRadians) * Math.sin(toLatRadians));
    // adjust toLonRadians to be in the range -180 to +180...
    toLonRadians = Math.IEEEremainder((toLonRadians + 3*M_PI), ((2*M_PI)) - M_PI);
    Location result = new Location("");
    result.setLatitude(rad2deg(toLatRadians));
    result.setLongitude(rad2deg(toLonRadians));
    return result;
}

double M_PI  = 3.14159265358979323846264338327950288;

public double deg2rad(double degrees)
{
    return  (degrees * (M_PI/180));
}
public double rad2deg(double radians)
{
    return  (radians * (180/M_PI));
}

最佳答案

如果所有标记具有相同的大小和颜色(或者没有那么多不同的标记),似乎最简单的方法是使用 Marker.setRotation() 方法:

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    private static final LatLng MAP_CENTER = new LatLng(22.3038715,70.8009047);

    private GoogleMap mGoogleMap;
    private MapFragment mMapFragment;

    private Button mButtonMinus;
    private Button mButtonPlus;

    private Marker mMarker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButtonMinus = (Button) findViewById(R.id.button_minus);
        mButtonMinus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mMarker.setRotation(mMarker.getRotation() - 1);
            }
        });

        mButtonPlus = (Button) findViewById(R.id.button_plus);
        mButtonPlus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mMarker.setRotation(mMarker.getRotation() + 1);
            }
        });

        mMapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map_fragment);
        mMapFragment.getMapAsync(this);
    }

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

        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(MAP_CENTER, 16));

        mMarker = mGoogleMap.addMarker(new MarkerOptions()
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_marker_rot))
                .position(MAP_CENTER)
                .alpha(0.75f)
                .anchor(0.5f, 0.5f)
                .rotation(0));
    }

}

其中 R.drawable.ic_marker_rot 是北向标记图标:

Marker icon

activity_main.xml是:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="<your_package>.MainActivity">

    <fragment
        android:id="@+id/map_fragment"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:id="@+id/buttons_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button_minus"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="-"/>

        <Button
            android:id="@+id/button_plus"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="+"/>

    </LinearLayout>

</RelativeLayout>

结果你会得到类似的结果:

Example of rotated marker

如果您有多个标记,则需要对其进行管理(在创建时添加到列表、确定选定的标记等)

在其他情况下(您确实需要绘制每个标记),最简单的方法是将 LatLng 坐标转换为屏幕坐标:

Projection projection = mGoogleMap.getProjection();
Point screenPosition = projection.toScreenLocation(mMarker.getPosition());

比在 Point 上应用旋转(例如,像 thisEntreco 答案),而不是将旋转的屏幕坐标(矩形的每个点)转换回 LatLng:

mGoogleMap.getProjection().fromScreenLocation(screenPosition);

并按照您已经绘制的方式绘制矩形。

关于android - 如何在谷歌地图android中以给定角度旋转多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41830501/

相关文章:

java - 如何在 Java 而不是 XML 中以编程方式设置 View 的重力和布局重力?

android - OOM(内存不足异常)如何在android中发生?

android - Android Wifi P2P : failed to connect to/192. 168.49.1(端口1080):isConnected失败:ECONNREFUSED(连接被拒绝)

Android ExpandableListView 组位置始终为 0

android - 如何在 Android Graph 中绘制实时传感器值?

android - 更新到android studio 3.0后无法mergedex

android - 在 onCreateView 中向 listFragment 添加静态 header

android - 如何使 ZXing 4.4 条码扫描器直接转到“URL”?

android - ionic : unable to build app after installing `cordova-plugin-fcm`

android - 用于 Facebook 登录的 Google 智能锁