Sandip Armal Patil
Sandip Armal Patil

Reputation: 5905

Draw Heart Shape Polygon on Google Map

I am trying to create heart shape polygon on Google Map using current location. I am able to identify some LatLngs and tried to create heart shape but as expected curves are not showing.

How can I create exact heart shape polygon using current location?

Here is code which I am using to create heart shape.

private static final int FRONT = 0;
private static final int RIGHT = 90;
private static final int LEFT = 270;

private void drawHeartPolygon(LatLng currentLatLng) {
    LatLng destLatLang = GetDestinationPoint(currentLatLng, FRONT, 0.050F);
    frontAngleCalculation(currentLatLng, destLatLang, 0.050F);
}

private void frontAngleCalculation(LatLng latLng, LatLng destLatLang, float distance) {
    PolygonOptions rectOptions = new PolygonOptions();
    LatLng centerLocation = GetDestinationPoint(latLng, FRONT, (distance + (distance/4)/2)/2);
    LatLng rightLocation = GetDestinationPoint(centerLocation, RIGHT, distance/2);
    LatLng leftLocation = GetDestinationPoint(centerLocation, LEFT, distance/2);
    LatLng centerLeftLocation = GetDestinationPoint(destLatLang, LEFT, distance/4);
    LatLng centerLeftTopLocation = GetDestinationPoint(centerLeftLocation, FRONT, (distance/4)/2);
    LatLng centerRightLocation = GetDestinationPoint(destLatLang, RIGHT, distance/4);
    LatLng centerRightTopLocation = GetDestinationPoint(centerRightLocation, FRONT, (distance/4)/2);
    rectOptions.add(new LatLng(latLng.latitude, latLng.longitude),
            leftLocation,
            centerLeftTopLocation,
            new LatLng(destLatLang.latitude, destLatLang.longitude),
            centerRightTopLocation,
            rightLocation);
    Log.d(TAG, "Current Location : "+latLng);
  
    rectOptions.strokeColor(Color.RED);

    // Get back the mutable Polygon
    Polygon polygon = mMap.addPolygon(rectOptions);
    List<PatternItem> pattern = Arrays.<PatternItem>asList(
            new Dot(), new Gap(20), new Dash(30), new Gap(20));
    polygon.setStrokePattern(pattern);
    polygon.setStrokeWidth(POLYGON_STROKE_WIDTH_PX);
    polygon.setStrokeColor(strokeColor);
   
}

public static LatLng GetDestinationPoint(LatLng startLoc, float bearing, float depth) {
    LatLng newLocation = null;

    double radius = 6371.0; // earth's mean radius in km
    double lat1 = Math.toRadians(startLoc.latitude);
    double lng1 = Math.toRadians(startLoc.longitude);
    double brng = Math.toRadians(bearing);
    double lat2 = Math.asin(Math.sin(lat1) * Math.cos(depth / radius) + Math.cos(lat1) * Math.sin(depth / radius) * Math.cos(brng));
    double lng2 = lng1 + Math.atan2(Math.sin(brng) * Math.sin(depth / radius) * Math.cos(lat1), Math.cos(depth / radius) - Math.sin(lat1) * Math.sin(lat2));
    lng2 = (lng2 + Math.PI) % (2 * Math.PI) - Math.PI;

    // normalize to -180...+180
    if (lat2 == 0 || lng2 == 0) {
        newLocation = new LatLng(0.0, 0.0);
    } else {
        newLocation = new LatLng(Math.toDegrees(lat2), Math.toDegrees(lng2));
    }

    return newLocation;
}


@Override
public void onMapReady(GoogleMap googleMap) {
    Log.d(TAG, "onMapReady");
    mMap = googleMap;
    LatLng latLng = new LatLng(latitude, longitude);
    mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mMap.setMaxZoomPreference(22.0f);
    mMap.setMinZoomPreference(17.0f);
    drawHeartPolygon(new LatLng(latitude,  longitude));


}

Here is screenshot which shows heart shape which I achieved but not as per expectation:

enter image description here

Upvotes: 1

Views: 1398

Answers (1)

Lalit Fauzdar
Lalit Fauzdar

Reputation: 6363

I don't know whether you'll like this answer or not but this will work as your requirement and is easy as hell but different.

Just place a marker:

        LatLng latLng1 = new LatLng(13.014849, 80.224343);
        mMap.addMarker(new MarkerOptions().position(latLng1).title("Name").snippet("snippet").flat(true).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker1)));
        CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng1).zoom(12).build();
        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

Here, marker1.png is an image created through photoshop which will provide the same result.

Result:
enter image description here

Marker1.png:
enter image description here

As you can see marker1 here is a whole image containing the marker + the heart but you can also create two markers on same LatLng: 1st is the red marker and 2nd is the Heart. Using this way, infowindow will open only on clicking the red marker instead of the provided result as you can disable the heart's infowindow or you can use heart's infowindow for some other info.

As I said earlier this solution is different and isn't similar to custom shaped polygon but is super easy to achieve.

Upvotes: 1

Related Questions