2

Ienter image description here

I am working on the app where i have to draw multiple fixed size polygons on click lets consider for example 10 x 25. so that i have archived successfully now i need to rotate the selected polygon at given angle ( let consider 0 to 360 ) when i click on + button the polygon should rotate in right direction with adding 1 degree angle, similarly clicking on - button should rotate polygon in left direction anyone have idea how to achieve this ?

adding some code for the consideration.

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));
}
Paras Valera
  • 602
  • 4
  • 13

1 Answers1

2

If all markers has same size and colors (or there is not so many different markers) seems simplest way is to use Marker.setRotation() method:

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

}

where R.drawable.ic_marker_rot is North-oriented marker icon:

Marker icon

and activity_main.xml is:

<?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>

As a result you have something like that:

Example of rotated marker

If you has several markers you need to manage it (add to list on creation, determine selected markerr, etc.)

In other case (you really need draw each marker) easiest way is to convert LatLng coords into screen coords:

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

than apply rotation on Point (e.g. like in this answer of Entreco), than convert rotated screen coords (of each point of rectangle) back into LatLng:

mGoogleMap.getProjection().fromScreenLocation(screenPosition);

and draw rectangle as you already draw.

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79