Shapes Stay organized with collections Save and categorize content based on your preferences.
AI-generated Key Takeaways
The Google Maps API for Android allows you to add and customize shapes like Polylines, Polygons, and Circles to your maps for visualizing paths, areas, and points of interest.
Polylines and Polygons can be customized with multicolored segments, gradients, and textures while Circles offer customization for stroke, fill, and z-index.
All shapes support click events that can be handled with designated listeners like
OnPolylineClickListener,OnPolygonClickListener, andOnCircleClickListener.Customization options for shapes include stroke color, width, pattern, fill color, z-index, and visibility, adjustable through respective options objects or methods.
Code samples and tutorials are available on GitHub for further guidance on implementation and advanced features.

The Google Maps API for Android offers some simple ways for you to add shapesto your maps in order to customize them for your application.
- A
Polylineis a series of connected line segments that canform any shape you want and can be used to mark paths and routes on the map. - A
Polygonis an enclosed shape that can be used to markareas on the map. - A
Circleis a geographically accurate projection of a circleon the Earth's surface drawn on the map.
For all these shapes, you can customize their appearance by altering anumber of properties.
Code samples
The tutorial on addingpolygons and polylines to represent areas and routesincludes all the code for a simple Android app.
In addition, theApiDemos repository on GitHub includessamples that demonstrate the use of shapes and their features:
- CircleDemoActivity (Java /Kotlin): Circle
- PolygonDemoActivity (Java /Kotlin): Polygon
- PolylineDemoActivity (Java /Kotlin): Polyline
Polylines
ThePolyline class defines a set of connected linesegments on the map. APolyline object consists of a set ofLatLng locations, and creates a series of line segments thatconnect those locations in an ordered sequence.
This video gives ideas on how to help your users get to where they're going,using polylines to draw a path on the map.
To create a Polyline, first create aPolylineOptionsobject and add points to it. Points represent a point on the earth's surface,and are expressed as aLatLng object. Line segments are drawnbetween points according to the order in which you add them to thePolylineOptions object.
To add points to aPolylineOptions object, callPolylineOptions.add().Notice that this method takes a variable number of parameters so you are able toadd multiple points at a time (you can also callPolylineOptions.addAll(Iterable<LatLng>)if the points are already in a list).
You can then add the polyline to a map by callingGoogleMap.addPolyline(PolylineOptions). Themethod returns aPolyline object with which you can alter the polyline at alater time.
The following code snippet illustrates how to add a rectangle to a map:
Kotlin
// Instantiates a new Polyline object and adds points to define a rectanglevalpolylineOptions=PolylineOptions().add(LatLng(37.35,-122.0)).add(LatLng(37.45,-122.0))// North of the previous point, but at the same longitude.add(LatLng(37.45,-122.2))// Same latitude, and 30km to the west.add(LatLng(37.35,-122.2))// Same longitude, and 16km to the south.add(LatLng(37.35,-122.0))// Closes the polyline.// Get back the mutable Polylinevalpolyline=map.addPolyline(polylineOptions)
Java
// Instantiates a new Polyline object and adds points to define a rectanglePolylineOptionspolylineOptions=newPolylineOptions().add(newLatLng(37.35,-122.0)).add(newLatLng(37.45,-122.0))// North of the previous point, but at the same longitude.add(newLatLng(37.45,-122.2))// Same latitude, and 30km to the west.add(newLatLng(37.35,-122.2))// Same longitude, and 16km to the south.add(newLatLng(37.35,-122.0));// Closes the polyline.// Get back the mutable PolylinePolylinepolyline=map.addPolyline(polylineOptions);
The rectangle appears on the map as shown below:

To alter the shape of the polyline after it has been added, you can callPolyline.setPoints() and provide a new list of points for the polyline.
You can customize the appearance of the polyline both before adding itto the map and after it has been added to the map. See the section oncustomizing appearances below for further details.
Polyline customization
There are several ways to customize the appearance of polylines:
- Multicolored polylines set polyline segments to different colors.
- Gradient polylines color a polyline using a gradient of two colors.
- Stamped polylines style a polyline using repeating bitmaps.
To use the Polyline Customizations, you must be using18.1.0 or later of the Maps SDK for Android anduse the latest Maps SDK for Android renderer.
Creating a multicolored polyline

You can use spans to individually color segments of a polyline, by creatingStyleSpan objects, and adding them toPolylineOptions using theaddSpan()oraddSpans() methods. By default, each item in the array will set the colorof the corresponding line segment. The following example shows setting segmentcolors to create a polyline with red and green segments:
Kotlin
valline=map.addPolyline(PolylineOptions().add(LatLng(47.6677146,-122.3470447),LatLng(47.6442757,-122.2814693)).addSpan(StyleSpan(Color.RED)).addSpan(StyleSpan(Color.GREEN)))
Java
Polylineline=map.addPolyline(newPolylineOptions().add(newLatLng(47.6677146,-122.3470447),newLatLng(47.6442757,-122.2814693)).addSpan(newStyleSpan(Color.RED)).addSpan(newStyleSpan(Color.GREEN)));
Creating a gradient polyline

You can define a gradient by specifying two 32-bit alpha-red-green-blue (ARGB)integers, to specify the beginning and ending colors of the stroke. Set thisproperty on the shape's options object by callingPolylineOptions.addSpan().The following example shows creating a red to yellow gradient polyline fromWoodland Park Zoo to Kirkland, WA.
Kotlin
valline=map.addPolyline(PolylineOptions().add(LatLng(47.6677146,-122.3470447),LatLng(47.6442757,-122.2814693)).addSpan(StyleSpan(StrokeStyle.gradientBuilder(Color.RED,Color.YELLOW).build())))
Java
Polylineline=map.addPolyline(newPolylineOptions().add(newLatLng(47.6677146,-122.3470447),newLatLng(47.6442757,-122.2814693)).addSpan(newStyleSpan(StrokeStyle.gradientBuilder(Color.RED,Color.YELLOW).build())));
Creating a stamped polyline

You can set the appearance of a polyline to a repeating bitmap texture. To dothis, create aStampStyle ofTextureStyle, then set this property on theshape's options object by callingPolylineOptions.addSpan() as shown here:
Kotlin
valstampStyle=TextureStyle.newBuilder(BitmapDescriptorFactory.fromResource(R.drawable.walking_dot)).build()valspan=StyleSpan(StrokeStyle.colorBuilder(Color.RED).stamp(stampStyle).build())map.addPolyline(PolylineOptions().add(LatLng(47.6677146,-122.3470447),LatLng(47.6442757,-122.2814693)).addSpan(span))
Java
StampStylestampStyle=TextureStyle.newBuilder(BitmapDescriptorFactory.fromResource(R.drawable.walking_dot)).build();StyleSpanspan=newStyleSpan(StrokeStyle.colorBuilder(Color.RED).stamp(stampStyle).build());map.addPolyline(newPolylineOptions().add(newLatLng(47.6677146,-122.3470447),newLatLng(47.6442757,-122.2814693)).addSpan(span));
Polyline events
By default, polylines are not clickable. You can enable and disable theclickability by callingPolyline.setClickable(boolean).
Use anOnPolylineClickListener tolisten to click events on a clickable polyline. To set this listener on the map,callGoogleMap.setOnPolylineClickListener(OnPolylineClickListener).When a user clicks on a polyline, you will receive anonPolylineClick(Polyline) callback.
Polygons
Polygon objects are similar toPolylineobjects in that they consist of a series of coordinates in an orderedsequence. However, instead of being open-ended, polygons are designed todefine regions within a closed loop with the interior filled in.
You can add aPolygon to the map in the same way as you addaPolyline. First create aPolygonOptions objectand add some points to it. These points will form the outline of the polygon.You then add the polygon to the map by callingGoogleMap.addPolygon(PolygonOptions) which willreturn aPolygon object.
The following code snippet adds a rectangle to a map.
Note: Because you haven't defined a fill color, and the default fill color istransparent, this rectangle appears exactly the same way as the polyline rectanglefrom the snippet in the previous section.Kotlin
// Instantiates a new Polygon object and adds points to define a rectanglevalrectOptions=PolygonOptions().add(LatLng(37.35,-122.0),LatLng(37.45,-122.0),LatLng(37.45,-122.2),LatLng(37.35,-122.2),LatLng(37.35,-122.0))// Get back the mutable Polygonvalpolygon=map.addPolygon(rectOptions)
Java
// Instantiates a new Polygon object and adds points to define a rectanglePolygonOptionspolygonOptions=newPolygonOptions().add(newLatLng(37.35,-122.0),newLatLng(37.45,-122.0),newLatLng(37.45,-122.2),newLatLng(37.35,-122.2),newLatLng(37.35,-122.0));// Get back the mutable PolygonPolygonpolygon=map.addPolygon(polygonOptions);
To alter the shape of the polygon after it has been added, you can callPolygon.setPoints() and provide a new list of points for the outlineof the polygon.
You can customize the appearance of the polygon both before adding itto the map and after it has been added to the map. See the section oncustomizing appearances below for further details.
Polygon auto-completion
The Polygon in the example above consists of five coordinates, but notice thatthe first and last coordinates are the same location, which defines the loop.In practice, however, since polygons define closed areas, you don't need todefine this last coordinate. If the last coordinate differs from the first, theAPI will automatically "close" the polygon by appending the first coordinate atthe end of the sequence of coordinates.
The below two polygons are equivalent, and callingpolygon.getPoints() for each of them will return all 4 points.
Kotlin
valpolygon1=map.addPolygon(PolygonOptions().add(LatLng(0.0,0.0),LatLng(0.0,5.0),LatLng(3.0,5.0),LatLng(0.0,0.0)).strokeColor(Color.RED).fillColor(Color.BLUE))valpolygon2=map.addPolygon(PolygonOptions().add(LatLng(0.0,0.0),LatLng(0.0,5.0),LatLng(3.0,5.0)).strokeColor(Color.RED).fillColor(Color.BLUE))
Java
Polygonpolygon1=map.addPolygon(newPolygonOptions().add(newLatLng(0,0),newLatLng(0,5),newLatLng(3,5),newLatLng(0,0)).strokeColor(Color.RED).fillColor(Color.BLUE));Polygonpolygon2=map.addPolygon(newPolygonOptions().add(newLatLng(0,0),newLatLng(0,5),newLatLng(3,5)).strokeColor(Color.RED).fillColor(Color.BLUE));
Create a hollow polygon
Multiple paths can be combined in a singlePolygon object tocreate complex shapes, such as filled rings, or "donuts" (where polygonalareas appear inside the polygon as "islands"). Complex shapes are always thecomposition of multiple, simpler, paths.
Two paths must be defined in the same area. The larger of the two regionsdefines the fill area, and is a simple polygon with no additional options.Then, pass a second path to theaddHole() method. When the second, smallerpath is full enclosed by the larger path, it will appear as if a piece of thepolygon has been removed. If the hole intersects the outline of the polygon,the polygon will be rendered without any fill.
The below snippet will create a single rectangle, with a smaller rectangularhole.
Kotlin
valhole=listOf(LatLng(1.0,1.0),LatLng(1.0,2.0),LatLng(2.0,2.0),LatLng(2.0,1.0),LatLng(1.0,1.0))valhollowPolygon=map.addPolygon(PolygonOptions().add(LatLng(0.0,0.0),LatLng(0.0,5.0),LatLng(3.0,5.0),LatLng(3.0,0.0),LatLng(0.0,0.0)).addHole(hole).fillColor(Color.BLUE))
Java
List<LatLng>hole=Arrays.asList(newLatLng(1,1),newLatLng(1,2),newLatLng(2,2),newLatLng(2,1),newLatLng(1,1));PolygonhollowPolygon=map.addPolygon(newPolygonOptions().add(newLatLng(0,0),newLatLng(0,5),newLatLng(3,5),newLatLng(3,0),newLatLng(0,0)).addHole(hole).fillColor(Color.BLUE));
The hollow polygon appears on the map as shown below:

Polygon events
By default, polygons are not clickable. You can enable and disable theclickability by callingPolygon.setClickable(boolean).
Use anOnPolygonClickListener tolisten to click events on a clickable polygon. To set this listener on the map,callGoogleMap.setOnPolygonClickListener(OnPolygonClickListener).When a user clicks on a polygon, you will receive anonPolygonClick(Polygon) callback.
Circles

In addition to a genericPolygon class, the Maps API also includes specificclasses forCircle objects, to simplify their construction.
To construct a circle, you must specify the following two properties:
centeras aLatLng.radiusin meters.
A circle is then defined to be the set of all points on the Earth's surfacewhich areradius meters away from the givencenter. Because of howthe Mercator projection used by the Maps API renders a sphere on a flat surface,this will appear as an almost perfect circle on the map when located near theequator, and will appear increasingly non-circular (on the screen) as thecircle moves away from the equator.
To alter the shape of the circle after it has been added, you can callCircle.setRadius() orCircle.setCenter() and provide new values.
You can customize the appearance of the circle both before adding itto the map and after it has been added to the map. See the section oncustomizing appearances below for further details.
The following code snippet adds a circle to the map by constructing aCircleOptions object and callingGoogleMap.addCircle(CircleOptions):
Kotlin
// Instantiates a new CircleOptions object and defines the center and radiusvalcircleOptions=CircleOptions().center(LatLng(37.4,-122.1)).radius(1000.0)// In meters// Get back the mutable Circlevalcircle=map.addCircle(circleOptions)
Java
// Instantiates a new CircleOptions object and defines the center and radiusCircleOptionscircleOptions=newCircleOptions().center(newLatLng(37.4,-122.1)).radius(1000);// In meters// Get back the mutable CircleCirclecircle=map.addCircle(circleOptions);
Circle events
By default, circles are not clickable. You can enable and disable theclickability by callingGoogleMap.addCircle() withCircleOptions.clickable(boolean), or by callingCircle.setClickable(boolean).
Use anOnCircleClickListener tolisten to click events on a clickable circle. To set this listener on the map,callGoogleMap.setOnCircleClickListener(OnCircleClickListener).
When a user clicks on a circle, you will receive anonCircleClick(Circle) callback, as shown in the following code sample:
Kotlin
valcircle=map.addCircle(CircleOptions().center(LatLng(37.4,-122.1)).radius(1000.0).strokeWidth(10f).strokeColor(Color.GREEN).fillColor(Color.argb(128,255,0,0)).clickable(true))map.setOnCircleClickListener{// Flip the r, g and b components of the circle's stroke color.valstrokeColor=it.strokeColorxor0x00ffffffit.strokeColor=strokeColor}
Java
Circlecircle=map.addCircle(newCircleOptions().center(newLatLng(37.4,-122.1)).radius(1000).strokeWidth(10).strokeColor(Color.GREEN).fillColor(Color.argb(128,255,0,0)).clickable(true));map.setOnCircleClickListener(newGoogleMap.OnCircleClickListener(){@OverridepublicvoidonCircleClick(Circlecircle){// Flip the r, g and b components of the circle's stroke color.intstrokeColor=circle.getStrokeColor()^0x00ffffff;circle.setStrokeColor(strokeColor);}});
Customizing appearances
You can alter the appearance of a shapeboth before it has been added to the map (by specifying the desired propertyon the options object) or after it has been added to the map. Getters arealso exposed for all properties so that you can easily access the currentstate of the shape.
The following snippet adds a thick blue polyline with geodesic segments fromMelbourne to Perth. The sections below will explain these properties in moredetail.
Kotlin
valpolyline=map.addPolyline(PolylineOptions().add(LatLng(-37.81319,144.96298),LatLng(-31.95285,115.85734)).width(25f).color(Color.BLUE).geodesic(true))
Java
Polylinepolyline=map.addPolyline(newPolylineOptions().add(newLatLng(-37.81319,144.96298),newLatLng(-31.95285,115.85734)).width(25).color(Color.BLUE).geodesic(true));
The map appears as shown below:

Note: While most of these can be applied toany of the shapes described, some of the properties may not makesense for certain shapes (e.g., a Polyline can't have a fill color because itdoesn't have an interior).
Stroke color
The stroke color is a 32-bit alpha-red-green-blue (ARGB) integer specifying theopacity and color of the stroke of the shape. Set this property on the shape'soptions object by calling*Options.strokeColor() (orPolylineOptions.color() in the case of a polyline). If unspecified, thedefault stroke color is black (Color.BLACK).
After the shape has been added to the map, the stroke color may be accessed bycallinggetStrokeColor() (orgetColor() for a polyline) and may be changedby callingsetStrokeColor() (setColor() for a polyline).
Fill color
Fill color only applies to polygons and circles. It does not apply topolylines as they do not have defined interiors. For a polygon, the regionsinside its holes are not part of the interior of the polygon and will not becolored in if a fill color is set.
The fill color is a 32-bit alpha-red-green-blue (ARGB) integer specifying theopacity and color of the interior of the shape. Set this property on theshape's options object by calling*Options.fillColor(). If unspecified, thedefault stroke color is transparent (Color.TRANSPARENT).
After the shape has been added to the map, the fill color may be accessed bycallinggetFillColor() and may be changed by callingsetFillColor().
Stroke width
The width of the line stroke, as a float inpixels(px). The width does not scale when the map is zoomed (i.e., a shape will havethe same stroke width at all zoom levels). Set this property on the shape'soption object by calling*Options.strokeWidth() (orPolylineOptions.width()for a polyline). If unspecified, the default stroke with is 10 pixels.
After the shape has been added to the map, the stroke width may be accessed bycallinggetStrokeWidth() (orgetWidth() for a polyline) and may be changedby callingsetStrokeWidth() (setWidth() for a polyline).
Stroke pattern
The default stroke pattern is a solid line for polylines and for the outlines ofpolygons and circles. You can specify a custom stroke pattern ofPatternItem objects, where each item is a dash, a dot, or agap.
The following sample sets the pattern for a polyline to a repeatedsequence of a dot, followed by a gap of length 20 pixels, a dash of length30 pixels, and another 20-pixel gap.
Kotlin
valpattern=listOf(Dot(),Gap(20F),Dash(30F),Gap(20F))polyline.pattern=pattern
Java
List<PatternItem>pattern=Arrays.asList(newDot(),newGap(20),newDash(30),newGap(20));polyline.setPattern(pattern);
The pattern repeats along the line, starting with the first pattern item at thefirst vertex specified for the shape.
Joint types
For polylines and the outlines of polygons, you can specify a bevel or roundJointType to replace the default fixed miter joint type.
The following sample applies a round joint type to a polyline:
Kotlin
polyline.jointType=JointType.ROUND
Java
polyline.setJointType(JointType.ROUND);
The joint type affects the internal bends in the line. If the line has a strokepattern that includes dashes, the joint type also applies when a dash straddlesa joint. Joint types do not affect dots, as they are always circular.
Line caps
You can specify aCap style for each end of a polyline. The optionsare butt (default), square, round, or a custom bitmap.Set the style inPolylineOptions.startCap andPolylineOptions.endCap, or use theappropriate getter and setter methods.
The following snippet specifies a round cap at the start of a polyline.
Kotlin
polyline.startCap=RoundCap()
Java
polyline.setStartCap(newRoundCap());
The following snippet specifies a custom bitmap for the end cap:
Kotlin
polyline.endCap=CustomCap(BitmapDescriptorFactory.fromResource(R.drawable.arrow),16F)
Java
polyline.setEndCap(newCustomCap(BitmapDescriptorFactory.fromResource(R.drawable.arrow),16));
When you use a custom bitmap, you should specify a reference stroke width inpixels. The API scales the bitmap accordingly. The reference stroke width is thestroke width that you used when designing the bitmap image for the cap, at theoriginal dimension of the image. The default reference stroke width is 10pixels. Hint: To determine the reference stroke width, open your bitmap image at100% zoom in an image editor, and plot the desired width of the line strokerelative to the image.
If you useBitmapDescriptorFactory.fromResource()to create the bitmap, make sure you use a density-independent resource(nodpi).
Geodesic segments
The geodesic setting only applies to polylines and polygons. It does not applyto circles because they are not defined as a collection of segments.
The geodesic setting determines how the line segments between consecutivevertices of the polyline/polygon are drawn. Geodesic segments are those thatfollow the shortest path along the Earth's surface (a sphere) and oftenappear as curved lines on a map with a Mercator projection. Non-geodesicsegments are drawn as straight lines on the map.
Set this property on the shape's option object by calling*Options.geodesic() wheretrue indicates the segments should be drawn asgeodesics andfalse indicates the segments should be drawn as straight lines.If unspecified, the default is non-geodesic segments (false).
After the shape has been added to the map, the geodesic setting may be accessedby callingisGeodesic() and may be changed by callingsetGeodesic().
Z-index
The z-index specifies the stack order of this shape, relative to otheroverlays (other shapes, ground overlays and tile overlays) on the map.An overlay with a high z-index is drawn above overlays with lower z-indexes.Two overlays with the same z-index are drawn in an arbitrary order.
Note that markers are always drawn above other overlays, regardless of thez-index of the other overlays.
Set this property on the shape's options object by calling*Options.zIndex().If unspecified, the default z-index is0. After the shape has been added tothe map, the z-index may be accessed bycallinggetZIndex() and may be changed by callingsetZIndex().
Visibility
The visibility specifies whether the shape should be drawn on the map, wheretrue indicates it should be drawn andfalse indicates it should not. Itallows you to temporarily not display a shape on the map. To permanentlyremove shape from the map, callremove() on that shape.
Set this property on the shape's options object by calling*Options.visible(). If unspecified, the default visibility istrue.After the shape has been added to the map, the visibility may be accessed bycallingisVisible() and may be changed by callingsetVisible().
Associate data with a shape
You can store an arbitrary data object with a polyline, polygon or circleusing the shape'ssetTag() method, and retrieve the object usinggetTag().For example, callPolyline.setTag() to store a dataobject with a polyline, and callPolyline.getTag() toretrieve the data object.
The code below defines an arbitrary tag (A) for the specified polyline:
Kotlin
valpolyline=map.addPolyline(PolylineOptions().clickable(true).add(LatLng(-35.016,143.321),LatLng(-34.747,145.592),LatLng(-34.364,147.891),LatLng(-33.501,150.217),LatLng(-32.306,149.248),LatLng(-32.491,147.309)))polyline.tag="A"
Java
Polylinepolyline=map.addPolyline((newPolylineOptions()).clickable(true).add(newLatLng(-35.016,143.321),newLatLng(-34.747,145.592),newLatLng(-34.364,147.891),newLatLng(-33.501,150.217),newLatLng(-32.306,149.248),newLatLng(-32.491,147.309)));polyline.setTag("A");
Here are some examples of scenarios when it's useful to store and retrieve datawith shapes:
- Your app may cater for different types of shapes, and you want to treat themdifferently when the user clicks them.
- You may be interfacing with a system that has unique record identifiers,where the shapes represent specific records in that system.
- The shape data may indicate a priority to determine the z-index for theshape.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-11-21 UTC.