diff --git a/tutorials/java/MapWithMarker/app/.gitignore b/tutorials/java/MapWithMarker/app/.gitignore
index 796b96d1..124d4745 100644
--- a/tutorials/java/MapWithMarker/app/.gitignore
+++ b/tutorials/java/MapWithMarker/app/.gitignore
@@ -1 +1,2 @@
/build
+secure.properties
\ No newline at end of file
diff --git a/tutorials/java/Polygons/README.md b/tutorials/java/Polygons/README.md
index e32f7b36..e6a9b4e5 100644
--- a/tutorials/java/Polygons/README.md
+++ b/tutorials/java/Polygons/README.md
@@ -7,7 +7,7 @@ This sample goes hand in hand with a tutorial for the Google Maps Android API:
Prerequisites
--------------
-- Android SDK v24
+- Android SDK v29
- Latest Android Build Tools
- Android Support Repository
@@ -22,10 +22,16 @@ This sample uses the Gradle build system.
"Import Project" option.
1. Select the `Polygons` directory that you downloaded with this repository.
1. If prompted for a gradle configuration, accept the default settings.
- Alternatively use the "gradlew build" command to build the project directly.
-1. Add your API key to your app's `gradle.properties` file.
- (For information on getting an API key, see the
- [documentation](https://developers.google.com/maps/documentation/android-api/signup).)
+ Alternatively use the `gradlew build` command to build the project directly.
+
+This demo app requires that you add your own Google Maps API key:
+
+1. [Get a Maps API key](https://developers.google.com/maps/documentation/android-sdk/get-api-key)
+1. Create a file in the `tutorials/java/Polygons/app` directory called `secure.properties`
+ (this file should *NOT* be under version control to protect your API key)
+1. Add a single line to `tutorials/java/Polygons/secure.properties` that looks like
+ `MAPS_API_KEY=YOUR_API_KEY`, where `YOUR_API_KEY` is the API key you obtained in the first step
+1. Build and run
Support
-------
diff --git a/tutorials/java/Polygons/app/.gitignore b/tutorials/java/Polygons/app/.gitignore
index 796b96d1..e85aa4ef 100644
--- a/tutorials/java/Polygons/app/.gitignore
+++ b/tutorials/java/Polygons/app/.gitignore
@@ -1 +1,2 @@
/build
+secure.properties
diff --git a/tutorials/java/Polygons/app/build.gradle b/tutorials/java/Polygons/app/build.gradle
index 19b089d4..7345abe0 100644
--- a/tutorials/java/Polygons/app/build.gradle
+++ b/tutorials/java/Polygons/app/build.gradle
@@ -10,7 +10,18 @@ android {
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
+
+ // Read the API key from tutorials/java/Polygons/app/secure.properties into R.string.maps_api_key
+ def secureProps = new Properties()
+ if (file("secure.properties").exists()) {
+ file("secure.properties")?.withInputStream { secureProps.load(it) }
+ }
+ resValue "string", "maps_api_key", (secureProps.getProperty("MAPS_API_KEY") ?: "")
+
+ // To add your Maps API key to this project:
+ // 1. Create a file tutorials/java/Polygons/app/secure.properties
+ // 2. Add this line, where YOUR_API_KEY is your API key:
+ // MAPS_API_KEY=YOUR_API_KEY
}
buildTypes {
release {
diff --git a/tutorials/java/Polygons/app/src/main/AndroidManifest.xml b/tutorials/java/Polygons/app/src/main/AndroidManifest.xml
index a2305305..3c3772bc 100644
--- a/tutorials/java/Polygons/app/src/main/AndroidManifest.xml
+++ b/tutorials/java/Polygons/app/src/main/AndroidManifest.xml
@@ -18,7 +18,7 @@
-->
+ android:value="@string/maps_api_key" />
PATTERN_POLYLINE_DOTTED = Arrays.asList(GAP, DOT);
-
- // Create a stroke pattern of a gap followed by a dash.
- private static final List PATTERN_POLYGON_ALPHA = Arrays.asList(GAP, DASH);
-
- // Create a stroke pattern of a dot followed by a gap, a dash, and another gap.
- private static final List PATTERN_POLYGON_BETA =
- Arrays.asList(DOT, GAP, DASH, GAP);
-
+ // [START EXCLUDE]
+ // [START maps_poly_activity_get_map_async]
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -86,9 +60,10 @@ public class PolyActivity extends AppCompatActivity
// Get the SupportMapFragment and request notification when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
- .findFragmentById(map);
+ .findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
+ // [END maps_poly_activity_get_map_async]
/**
* Manipulates the map when it's available.
@@ -96,11 +71,14 @@ public class PolyActivity extends AppCompatActivity
* This is where we can add markers or lines, add listeners or move the camera.
* In this tutorial, we add polylines and polygons to represent routes and areas on the map.
*/
+ // [END EXCLUDE]
@Override
public void onMapReady(GoogleMap googleMap) {
// Add polylines to the map.
// Polylines are useful to show a route or some other connection between points.
+ // [START maps_poly_activity_add_polyline_set_tag]
+ // [START maps_poly_activity_add_polyline]
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions()
.clickable(true)
.add(
@@ -110,8 +88,11 @@ public class PolyActivity extends AppCompatActivity
new LatLng(-33.501, 150.217),
new LatLng(-32.306, 149.248),
new LatLng(-32.491, 147.309)));
+ // [END maps_poly_activity_add_polyline]
+ // [START_EXCLUDE silent]
// Store a data object with the polyline, used here to indicate an arbitrary type.
polyline1.setTag("A");
+ // [END maps_poly_activity_add_polyline_set_tag]
// Style the polyline.
stylePolyline(polyline1);
@@ -127,6 +108,7 @@ public class PolyActivity extends AppCompatActivity
polyline2.setTag("B");
stylePolyline(polyline2);
+ // [START maps_poly_activity_add_polygon]
// Add polygons to indicate areas on the map.
Polygon polygon1 = googleMap.addPolygon(new PolygonOptions()
.clickable(true)
@@ -137,6 +119,7 @@ public class PolyActivity extends AppCompatActivity
new LatLng(-34.928, 138.599)));
// Store a data object with the polygon, used here to indicate an arbitrary type.
polygon1.setTag("alpha");
+ // [END maps_poly_activity_add_polygon]
// Style the polygon.
stylePolygon(polygon1);
@@ -149,6 +132,7 @@ public class PolyActivity extends AppCompatActivity
new LatLng(-12.4258, 130.7932)));
polygon2.setTag("beta");
stylePolygon(polygon2);
+ // [END_EXCLUDE silent]
// Position the map's camera near Alice Springs in the center of Australia,
// and set the zoom factor so most of Australia shows on the screen.
@@ -158,6 +142,11 @@ public class PolyActivity extends AppCompatActivity
googleMap.setOnPolylineClickListener(this);
googleMap.setOnPolygonClickListener(this);
}
+ // [END maps_poly_activity_on_map_ready]
+
+ // [START maps_poly_activity_style_polyline]
+ private static final int COLOR_BLACK_ARGB = 0xff000000;
+ private static final int POLYLINE_STROKE_WIDTH_PX = 12;
/**
* Styles the polyline, based on type.
@@ -189,6 +178,67 @@ public class PolyActivity extends AppCompatActivity
polyline.setColor(COLOR_BLACK_ARGB);
polyline.setJointType(JointType.ROUND);
}
+ // [END maps_poly_activity_style_polyline]
+
+ // [START maps_poly_activity_on_polyline_click]
+ private static final int PATTERN_GAP_LENGTH_PX = 20;
+ private static final PatternItem DOT = new Dot();
+ private static final PatternItem GAP = new Gap(PATTERN_GAP_LENGTH_PX);
+
+ // Create a stroke pattern of a gap followed by a dot.
+ private static final List PATTERN_POLYLINE_DOTTED = Arrays.asList(GAP, DOT);
+
+ /**
+ * Listens for clicks on a polyline.
+ * @param polyline The polyline object that the user has clicked.
+ */
+ @Override
+ public void onPolylineClick(Polyline polyline) {
+ // Flip from solid stroke to dotted stroke pattern.
+ if ((polyline.getPattern() == null) || (!polyline.getPattern().contains(DOT))) {
+ polyline.setPattern(PATTERN_POLYLINE_DOTTED);
+ } else {
+ // The default pattern is a solid stroke.
+ polyline.setPattern(null);
+ }
+
+ Toast.makeText(this, "Route type " + polyline.getTag().toString(),
+ Toast.LENGTH_SHORT).show();
+ }
+ // [END maps_poly_activity_on_polyline_click]
+
+ /**
+ * Listens for clicks on a polygon.
+ * @param polygon The polygon object that the user has clicked.
+ */
+ @Override
+ public void onPolygonClick(Polygon polygon) {
+ // Flip the values of the red, green, and blue components of the polygon's color.
+ int color = polygon.getStrokeColor() ^ 0x00ffffff;
+ polygon.setStrokeColor(color);
+ color = polygon.getFillColor() ^ 0x00ffffff;
+ polygon.setFillColor(color);
+
+ Toast.makeText(this, "Area type " + polygon.getTag().toString(), Toast.LENGTH_SHORT).show();
+ }
+
+ // [START maps_poly_activity_style_polygon]
+ private static final int COLOR_WHITE_ARGB = 0xffffffff;
+ private static final int COLOR_GREEN_ARGB = 0xff388E3C;
+ private static final int COLOR_PURPLE_ARGB = 0xff81C784;
+ private static final int COLOR_ORANGE_ARGB = 0xffF57F17;
+ private static final int COLOR_BLUE_ARGB = 0xffF9A825;
+
+ private static final int POLYGON_STROKE_WIDTH_PX = 8;
+ private static final int PATTERN_DASH_LENGTH_PX = 20;
+ private static final PatternItem DASH = new Dash(PATTERN_DASH_LENGTH_PX);
+
+ // Create a stroke pattern of a gap followed by a dash.
+ private static final List PATTERN_POLYGON_ALPHA = Arrays.asList(GAP, DASH);
+
+ // Create a stroke pattern of a dot followed by a gap, a dash, and another gap.
+ private static final List PATTERN_POLYGON_BETA =
+ Arrays.asList(DOT, GAP, DASH, GAP);
/**
* Styles the polygon, based on type.
@@ -226,37 +276,5 @@ public class PolyActivity extends AppCompatActivity
polygon.setStrokeColor(strokeColor);
polygon.setFillColor(fillColor);
}
-
- /**
- * Listens for clicks on a polyline.
- * @param polyline The polyline object that the user has clicked.
- */
- @Override
- public void onPolylineClick(Polyline polyline) {
- // Flip from solid stroke to dotted stroke pattern.
- if ((polyline.getPattern() == null) || (!polyline.getPattern().contains(DOT))) {
- polyline.setPattern(PATTERN_POLYLINE_DOTTED);
- } else {
- // The default pattern is a solid stroke.
- polyline.setPattern(null);
- }
-
- Toast.makeText(this, "Route type " + polyline.getTag().toString(),
- Toast.LENGTH_SHORT).show();
- }
-
- /**
- * Listens for clicks on a polygon.
- * @param polygon The polygon object that the user has clicked.
- */
- @Override
- public void onPolygonClick(Polygon polygon) {
- // Flip the values of the red, green, and blue components of the polygon's color.
- int color = polygon.getStrokeColor() ^ 0x00ffffff;
- polygon.setStrokeColor(color);
- color = polygon.getFillColor() ^ 0x00ffffff;
- polygon.setFillColor(color);
-
- Toast.makeText(this, "Area type " + polygon.getTag().toString(), Toast.LENGTH_SHORT).show();
- }
+ // [END maps_poly_activity_style_polygon]
}
diff --git a/tutorials/java/Polygons/gradle.properties b/tutorials/java/Polygons/gradle.properties
index 4fad706e..01236edf 100644
--- a/tutorials/java/Polygons/gradle.properties
+++ b/tutorials/java/Polygons/gradle.properties
@@ -17,8 +17,3 @@ org.gradle.jvmargs=-Xmx1536m
# org.gradle.parallel=true
android.useAndroidX=true
-
-# Replace the value below with your own Google API key for Android app.
-# To learn how to get a Google Maps Platform API key, visit:
-# https://developers.google.com/maps/gmp-get-started
-GOOGLE_MAPS_API_KEY=YOUR_API_KEY
\ No newline at end of file
diff --git a/tutorials/kotlin/Polygons/.gitignore b/tutorials/kotlin/Polygons/.gitignore
new file mode 100644
index 00000000..3ecb6898
--- /dev/null
+++ b/tutorials/kotlin/Polygons/.gitignore
@@ -0,0 +1,11 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+/play-services-maps-10.2.0
+/app/libs
\ No newline at end of file
diff --git a/tutorials/kotlin/Polygons/README.md b/tutorials/kotlin/Polygons/README.md
new file mode 100644
index 00000000..e47c5c36
--- /dev/null
+++ b/tutorials/kotlin/Polygons/README.md
@@ -0,0 +1,52 @@
+Google Maps Android API Sample: Polylines and Polygons
+==========================================================
+
+This sample goes hand in hand with a tutorial for the Google Maps Android API:
+[Polylines and Polygons to Represent Routes and Areas](https://developers.google.com/maps/documentation/android-api/polygon-tutorial).
+
+Prerequisites
+--------------
+
+- Android SDK v29
+- Latest Android Build Tools
+- Android Support Repository
+
+Getting started
+---------------
+
+This sample uses the Gradle build system.
+
+1. Download the samples by cloning this repository or downloading an archived
+ snapshot. (See the options at the top of the page.)
+1. In Android Studio, create a new project and choose the "Import non-Android Studio project" or
+ "Import Project" option.
+1. Select the `Polygons` directory that you downloaded with this repository.
+1. If prompted for a gradle configuration, accept the default settings.
+ Alternatively use the `gradlew build` command to build the project directly.
+
+This demo app requires that you add your own Google Maps API key:
+
+1. [Get a Maps API key](https://developers.google.com/maps/documentation/android-sdk/get-api-key)
+1. Create a file in the `tutorials/kotlin/Polygons/app` directory called `secure.properties`
+ (this file should *NOT* be under version control to protect your API key)
+1. Add a single line to `tutorials/kotlin/Polygons/secure.properties` that looks like
+ `MAPS_API_KEY=YOUR_API_KEY`, where `YOUR_API_KEY` is the API key you obtained in the first step
+1. Build and run
+
+Support
+-------
+
+Stack Overflow: https://stackoverflow.com/questions/tagged/android+google-maps
+
+If you have discovered an issue with the Google Maps Android API v2, please see
+the resources here: https://developers.google.com/maps/documentation/android-api/support
+
+If you've found an error in these samples, please file an issue:
+https://github.com/googlemaps/android-samples/issues
+
+
+
+License
+-------
+
+Please refer to the [LICENSE](https://github.com/googlemaps/android-samples/blob/master/LICENSE) at the root of this repo.
diff --git a/tutorials/kotlin/Polygons/app/.gitignore b/tutorials/kotlin/Polygons/app/.gitignore
new file mode 100644
index 00000000..e85aa4ef
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/.gitignore
@@ -0,0 +1,2 @@
+/build
+secure.properties
diff --git a/tutorials/kotlin/Polygons/app/build.gradle b/tutorials/kotlin/Polygons/app/build.gradle
new file mode 100644
index 00000000..932a919e
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/build.gradle
@@ -0,0 +1,45 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android-extensions'
+apply plugin: 'kotlin-android'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion '28.0.3'
+ defaultConfig {
+ applicationId "com.example.polygons"
+ minSdkVersion 16
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+ // Read the API key from tutorials/java/Polygons/app/secure.properties into R.string.maps_api_key
+ def secureProps = new Properties()
+ if (file("secure.properties").exists()) {
+ file("secure.properties")?.withInputStream { secureProps.load(it) }
+ }
+ resValue "string", "maps_api_key", (secureProps.getProperty("MAPS_API_KEY") ?: "")
+
+ // To add your Maps API key to this project:
+ // 1. Create a file tutorials/java/Polygons/app/secure.properties
+ // 2. Add this line, where YOUR_API_KEY is your API key:
+ // MAPS_API_KEY=YOUR_API_KEY
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'com.google.android.gms:play-services-maps:17.0.0'
+ testImplementation 'junit:junit:4.13'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ implementation "androidx.core:core-ktx:+"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
diff --git a/tutorials/kotlin/Polygons/app/proguard-rules.pro b/tutorials/kotlin/Polygons/app/proguard-rules.pro
new file mode 100644
index 00000000..1bc73c70
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/sarahmaddox/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/tutorials/kotlin/Polygons/app/src/main/AndroidManifest.xml b/tutorials/kotlin/Polygons/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..3c3772bc
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/src/main/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tutorials/kotlin/Polygons/app/src/main/java/com/example/polygons/PolyActivity.kt b/tutorials/kotlin/Polygons/app/src/main/java/com/example/polygons/PolyActivity.kt
new file mode 100644
index 00000000..e004da85
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/src/main/java/com/example/polygons/PolyActivity.kt
@@ -0,0 +1,253 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.example.polygons
+
+import android.os.Bundle
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.google.android.gms.maps.CameraUpdateFactory
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.GoogleMap.OnPolygonClickListener
+import com.google.android.gms.maps.GoogleMap.OnPolylineClickListener
+import com.google.android.gms.maps.OnMapReadyCallback
+import com.google.android.gms.maps.SupportMapFragment
+import com.google.android.gms.maps.model.BitmapDescriptorFactory
+import com.google.android.gms.maps.model.CustomCap
+import com.google.android.gms.maps.model.Dash
+import com.google.android.gms.maps.model.Dot
+import com.google.android.gms.maps.model.Gap
+import com.google.android.gms.maps.model.JointType
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.PatternItem
+import com.google.android.gms.maps.model.Polygon
+import com.google.android.gms.maps.model.PolygonOptions
+import com.google.android.gms.maps.model.Polyline
+import com.google.android.gms.maps.model.PolylineOptions
+import com.google.android.gms.maps.model.RoundCap
+
+/**
+ * An activity that displays a Google map with polylines to represent paths or routes,
+ * and polygons to represent areas.
+ */
+// [START maps_poly_activity_on_map_ready]
+class PolyActivity : AppCompatActivity(), OnMapReadyCallback, OnPolylineClickListener, OnPolygonClickListener {
+
+ // [START EXCLUDE]
+ // [START maps_poly_activity_get_map_async]
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ // Retrieve the content view that renders the map.
+ setContentView(R.layout.activity_maps)
+
+ // Get the SupportMapFragment and request notification when the map is ready to be used.
+ val mapFragment = supportFragmentManager
+ .findFragmentById(R.id.map) as SupportMapFragment?
+ mapFragment?.getMapAsync(this)
+ }
+ // [END maps_poly_activity_get_map_async]
+
+ /**
+ * Manipulates the map when it's available.
+ * The API invokes this callback when the map is ready to be used.
+ * This is where we can add markers or lines, add listeners or move the camera.
+ * In this tutorial, we add polylines and polygons to represent routes and areas on the map.
+ */
+ // [END EXCLUDE]
+ override fun onMapReady(googleMap: GoogleMap) {
+
+ // Add polylines to the map.
+ // Polylines are useful to show a route or some other connection between points.
+ // [START maps_poly_activity_add_polyline_set_tag]
+ // [START maps_poly_activity_add_polyline]
+ val polyline1 = googleMap.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)))
+ // [END maps_poly_activity_add_polyline]
+ // [START_EXCLUDE silent]
+ // Store a data object with the polyline, used here to indicate an arbitrary type.
+ polyline1.tag = "A"
+ // [END maps_poly_activity_add_polyline_set_tag]
+ // Style the polyline.
+ stylePolyline(polyline1)
+
+ val polyline2 = googleMap.addPolyline(PolylineOptions()
+ .clickable(true)
+ .add(
+ LatLng(-29.501, 119.700),
+ LatLng(-27.456, 119.672),
+ LatLng(-25.971, 124.187),
+ LatLng(-28.081, 126.555),
+ LatLng(-28.848, 124.229),
+ LatLng(-28.215, 123.938)))
+ polyline2.tag = "B"
+ stylePolyline(polyline2)
+
+ // [START maps_poly_activity_add_polygon]
+ // Add polygons to indicate areas on the map.
+ val polygon1 = googleMap.addPolygon(PolygonOptions()
+ .clickable(true)
+ .add(
+ LatLng(-27.457, 153.040),
+ LatLng(-33.852, 151.211),
+ LatLng(-37.813, 144.962),
+ LatLng(-34.928, 138.599)))
+ // Store a data object with the polygon, used here to indicate an arbitrary type.
+ polygon1.tag = "alpha"
+ // Style the polygon.
+ // [END maps_poly_activity_add_polygon]
+ stylePolygon(polygon1)
+
+ val polygon2 = googleMap.addPolygon(PolygonOptions()
+ .clickable(true)
+ .add(
+ LatLng(-31.673, 128.892),
+ LatLng(-31.952, 115.857),
+ LatLng(-17.785, 122.258),
+ LatLng(-12.4258, 130.7932)))
+ polygon2.tag = "beta"
+ stylePolygon(polygon2)
+ // [END_EXCLUDE silent]
+
+ // Position the map's camera near Alice Springs in the center of Australia,
+ // and set the zoom factor so most of Australia shows on the screen.
+ googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(-23.684, 133.903), 4f))
+
+ // Set listeners for click events.
+ googleMap.setOnPolylineClickListener(this)
+ googleMap.setOnPolygonClickListener(this)
+ }
+ // [END maps_poly_activity_on_map_ready]
+
+ // [START maps_poly_activity_style_polyline]
+ private val COLOR_BLACK_ARGB = -0x1000000
+ private val POLYLINE_STROKE_WIDTH_PX = 12
+
+ /**
+ * Styles the polyline, based on type.
+ * @param polyline The polyline object that needs styling.
+ */
+ private fun stylePolyline(polyline: Polyline) {
+ // Get the data object stored with the polyline.
+ val type = polyline.tag?.toString() ?: ""
+ when (type) {
+ "A" -> {
+ // Use a custom bitmap as the cap at the start of the line.
+ polyline.startCap = CustomCap(
+ BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10f)
+ }
+ "B" -> {
+ // Use a round cap at the start of the line.
+ polyline.startCap = RoundCap()
+ }
+ }
+ polyline.endCap = RoundCap()
+ polyline.width = POLYLINE_STROKE_WIDTH_PX.toFloat()
+ polyline.color = COLOR_BLACK_ARGB
+ polyline.jointType = JointType.ROUND
+ }
+ // [END maps_poly_activity_style_polyline]
+
+ // [START maps_poly_activity_on_polyline_click]
+ private val PATTERN_GAP_LENGTH_PX = 20
+ private val DOT: PatternItem = Dot()
+ private val GAP: PatternItem = Gap(PATTERN_GAP_LENGTH_PX.toFloat())
+
+ // Create a stroke pattern of a gap followed by a dot.
+ private val PATTERN_POLYLINE_DOTTED = listOf(GAP, DOT)
+
+ /**
+ * Listens for clicks on a polyline.
+ * @param polyline The polyline object that the user has clicked.
+ */
+ override fun onPolylineClick(polyline: Polyline) {
+ // Flip from solid stroke to dotted stroke pattern.
+ if (polyline.pattern == null || !polyline.pattern!!.contains(DOT)) {
+ polyline.pattern = PATTERN_POLYLINE_DOTTED
+ } else {
+ // The default pattern is a solid stroke.
+ polyline.pattern = null
+ }
+ Toast.makeText(this, "Route type " + polyline.tag.toString(),
+ Toast.LENGTH_SHORT).show()
+ }
+ // [END maps_poly_activity_on_polyline_click]
+
+ /**
+ * Listens for clicks on a polygon.
+ * @param polygon The polygon object that the user has clicked.
+ */
+ override fun onPolygonClick(polygon: Polygon) {
+ // Flip the values of the red, green, and blue components of the polygon's color.
+ var color = polygon.strokeColor xor 0x00ffffff
+ polygon.strokeColor = color
+ color = polygon.fillColor xor 0x00ffffff
+ polygon.fillColor = color
+ Toast.makeText(this, "Area type ${polygon.tag?.toString()}", Toast.LENGTH_SHORT).show()
+ }
+
+ // [START maps_poly_activity_style_polygon]
+ private val COLOR_WHITE_ARGB = -0x1
+ private val COLOR_GREEN_ARGB = -0xc771c4
+ private val COLOR_PURPLE_ARGB = -0x7e387c
+ private val COLOR_ORANGE_ARGB = -0xa80e9
+ private val COLOR_BLUE_ARGB = -0x657db
+ private val POLYGON_STROKE_WIDTH_PX = 8
+ private val PATTERN_DASH_LENGTH_PX = 20
+
+ private val DASH: PatternItem = Dash(PATTERN_DASH_LENGTH_PX.toFloat())
+
+ // Create a stroke pattern of a gap followed by a dash.
+ private val PATTERN_POLYGON_ALPHA = listOf(GAP, DASH)
+
+ // Create a stroke pattern of a dot followed by a gap, a dash, and another gap.
+ private val PATTERN_POLYGON_BETA = listOf(DOT, GAP, DASH, GAP)
+
+ /**
+ * Styles the polygon, based on type.
+ * @param polygon The polygon object that needs styling.
+ */
+ private fun stylePolygon(polygon: Polygon) {
+ // Get the data object stored with the polygon.
+ val type = polygon.tag?.toString() ?: ""
+ var pattern: List? = null
+ var strokeColor = COLOR_BLACK_ARGB
+ var fillColor = COLOR_WHITE_ARGB
+ when (type) {
+ "alpha" -> {
+ // Apply a stroke pattern to render a dashed line, and define colors.
+ pattern = PATTERN_POLYGON_ALPHA
+ strokeColor = COLOR_GREEN_ARGB
+ fillColor = COLOR_PURPLE_ARGB
+ }
+ "beta" -> {
+ // Apply a stroke pattern to render a line of dots and dashes, and define colors.
+ pattern = PATTERN_POLYGON_BETA
+ strokeColor = COLOR_ORANGE_ARGB
+ fillColor = COLOR_BLUE_ARGB
+ }
+ }
+ polygon.strokePattern = pattern
+ polygon.strokeWidth = POLYGON_STROKE_WIDTH_PX.toFloat()
+ polygon.strokeColor = strokeColor
+ polygon.fillColor = fillColor
+ }
+ // [END maps_poly_activity_style_polygon]
+}
\ No newline at end of file
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/drawable-nodpi/ic_arrow.png b/tutorials/kotlin/Polygons/app/src/main/res/drawable-nodpi/ic_arrow.png
new file mode 100644
index 00000000..83186292
Binary files /dev/null and b/tutorials/kotlin/Polygons/app/src/main/res/drawable-nodpi/ic_arrow.png differ
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/layout/activity_maps.xml b/tutorials/kotlin/Polygons/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 00000000..d83ca0af
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/mipmap-hdpi/ic_launcher.png b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 00000000..cde69bcc
Binary files /dev/null and b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/mipmap-mdpi/ic_launcher.png b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 00000000..c133a0cb
Binary files /dev/null and b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..bfa42f0e
Binary files /dev/null and b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..324e72cd
Binary files /dev/null and b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..aee44e13
Binary files /dev/null and b/tutorials/kotlin/Polygons/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/values/colors.xml b/tutorials/kotlin/Polygons/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..3ab3e9cb
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/values/strings.xml b/tutorials/kotlin/Polygons/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..58415b03
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ Polygons
+ Polygons
+
diff --git a/tutorials/kotlin/Polygons/app/src/main/res/values/styles.xml b/tutorials/kotlin/Polygons/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000..5885930d
--- /dev/null
+++ b/tutorials/kotlin/Polygons/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/tutorials/kotlin/Polygons/build.gradle b/tutorials/kotlin/Polygons/build.gradle
new file mode 100644
index 00000000..9feef37f
--- /dev/null
+++ b/tutorials/kotlin/Polygons/build.gradle
@@ -0,0 +1,27 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext.kotlin_version = '1.3.72'
+ repositories {
+ jcenter()
+ google()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.6.3'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ google()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/tutorials/kotlin/Polygons/gradle.properties b/tutorials/kotlin/Polygons/gradle.properties
new file mode 100644
index 00000000..01236edf
--- /dev/null
+++ b/tutorials/kotlin/Polygons/gradle.properties
@@ -0,0 +1,19 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
+android.useAndroidX=true
diff --git a/tutorials/kotlin/Polygons/gradle/wrapper/gradle-wrapper.jar b/tutorials/kotlin/Polygons/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..13372aef
Binary files /dev/null and b/tutorials/kotlin/Polygons/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/tutorials/kotlin/Polygons/gradle/wrapper/gradle-wrapper.properties b/tutorials/kotlin/Polygons/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..eb8aa75a
--- /dev/null
+++ b/tutorials/kotlin/Polygons/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 15 11:28:31 PDT 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
diff --git a/tutorials/kotlin/Polygons/gradlew b/tutorials/kotlin/Polygons/gradlew
new file mode 100755
index 00000000..9d82f789
--- /dev/null
+++ b/tutorials/kotlin/Polygons/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/tutorials/kotlin/Polygons/gradlew.bat b/tutorials/kotlin/Polygons/gradlew.bat
new file mode 100644
index 00000000..aec99730
--- /dev/null
+++ b/tutorials/kotlin/Polygons/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/tutorials/kotlin/Polygons/settings.gradle b/tutorials/kotlin/Polygons/settings.gradle
new file mode 100644
index 00000000..e7b4def4
--- /dev/null
+++ b/tutorials/kotlin/Polygons/settings.gradle
@@ -0,0 +1 @@
+include ':app'