1
+ /*
2
+ * Copyright 2018 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * https://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+
18
+ package com.example.kotlindemos
19
+
20
+ import android.graphics.Color
21
+ import android.os.Bundle
22
+ import android.support.v7.app.AppCompatActivity
23
+ import android.view.View
24
+ import android.widget.AdapterView
25
+ import android.widget.SeekBar
26
+ import android.widget.Spinner
27
+ import android.widget.CheckBox
28
+ import android.widget.ArrayAdapter
29
+ import com.google.android.gms.maps.CameraUpdateFactory
30
+ import com.google.android.gms.maps.model.Dash
31
+ import com.google.android.gms.maps.model.Dot
32
+ import com.google.android.gms.maps.model.Gap
33
+ import com.google.android.gms.maps.GoogleMap
34
+ import com.google.android.gms.maps.model.JointType
35
+ import com.google.android.gms.maps.model.LatLng
36
+ import com.google.android.gms.maps.OnMapReadyCallback
37
+ import com.google.android.gms.maps.model.PatternItem
38
+ import com.google.android.gms.maps.model.Polygon
39
+ import com.google.android.gms.maps.model.PolygonOptions
40
+ import com.google.android.gms.maps.SupportMapFragment
41
+
42
+ import java.util.Arrays
43
+
44
+ /* *
45
+ * This shows how to draw polygons on a map.
46
+ */
47
+ class PolygonDemoActivity :
48
+ AppCompatActivity (),
49
+ OnMapReadyCallback ,
50
+ SeekBar .OnSeekBarChangeListener ,
51
+ AdapterView .OnItemSelectedListener {
52
+
53
+ private val center = LatLng (- 20.0 , 130.0 )
54
+ private val MAX_WIDTH_PX = 100
55
+ private val MAX_HUE_DEGREES = 360
56
+ private val MAX_ALPHA = 255
57
+ private val PATTERN_DASH_LENGTH_PX = 50
58
+ private val PATTERN_GAP_LENGTH_PX = 10
59
+ private val dot = Dot ()
60
+ private val dash = Dash (PATTERN_DASH_LENGTH_PX .toFloat())
61
+ private val gap = Gap (PATTERN_GAP_LENGTH_PX .toFloat())
62
+ private val patternDotted = Arrays .asList(dot, gap)
63
+ private val patternDashed = Arrays .asList(dash, gap)
64
+ private val patternMixed = Arrays .asList(dot, gap, dot, dash, gap)
65
+
66
+ private lateinit var mutablePolygon: Polygon
67
+ private lateinit var fillHueBar: SeekBar
68
+ private lateinit var fillAlphaBar: SeekBar
69
+ private lateinit var strokeWidthBar: SeekBar
70
+ private lateinit var strokeHueBar: SeekBar
71
+ private lateinit var strokeAlphaBar: SeekBar
72
+ private lateinit var strokeJointTypeSpinner: Spinner
73
+ private lateinit var strokePatternSpinner: Spinner
74
+ private lateinit var clickabilityCheckbox: CheckBox
75
+
76
+ // These are the options for polygon stroke joints and patterns. We use their
77
+ // string resource IDs as identifiers.
78
+
79
+ private val jointTypeNameResourceIds = intArrayOf(R .string.joint_type_default, // Default
80
+ R .string.joint_type_bevel, R .string.joint_type_round)
81
+
82
+ private val patternTypeNameResourceIds = intArrayOf(R .string.pattern_solid, // Default
83
+ R .string.pattern_dashed, R .string.pattern_dotted, R .string.pattern_mixed)
84
+
85
+ override fun onCreate (savedInstanceState : Bundle ? ) {
86
+ super .onCreate(savedInstanceState)
87
+ setContentView(R .layout.polygon_demo)
88
+
89
+ fillHueBar = findViewById<SeekBar >(R .id.fillHueSeekBar).apply {
90
+ max = MAX_HUE_DEGREES
91
+ progress = MAX_HUE_DEGREES / 2
92
+ }
93
+
94
+ fillAlphaBar = findViewById<SeekBar >(R .id.fillAlphaSeekBar).apply {
95
+ max = MAX_ALPHA
96
+ progress = MAX_ALPHA / 2
97
+ }
98
+
99
+ strokeWidthBar = findViewById<SeekBar >(R .id.strokeWidthSeekBar).apply {
100
+ max = MAX_WIDTH_PX
101
+ progress = MAX_WIDTH_PX / 3
102
+ }
103
+
104
+ strokeHueBar = findViewById<SeekBar >(R .id.strokeHueSeekBar).apply {
105
+ max = MAX_HUE_DEGREES
106
+ progress = 0
107
+ }
108
+
109
+ strokeAlphaBar = findViewById<SeekBar >(R .id.strokeAlphaSeekBar).apply {
110
+ max = MAX_ALPHA
111
+ progress = MAX_ALPHA
112
+ }
113
+
114
+ strokeJointTypeSpinner = findViewById<Spinner >(R .id.strokeJointTypeSpinner).apply {
115
+ adapter = ArrayAdapter (
116
+ this @PolygonDemoActivity, android.R .layout.simple_spinner_item,
117
+ getResourceStrings(jointTypeNameResourceIds))
118
+ }
119
+
120
+ strokePatternSpinner = findViewById<Spinner >(R .id.strokePatternSpinner).apply {
121
+ adapter = ArrayAdapter (
122
+ this @PolygonDemoActivity, android.R .layout.simple_spinner_item,
123
+ getResourceStrings(patternTypeNameResourceIds))
124
+ }
125
+
126
+ clickabilityCheckbox = findViewById(R .id.toggleClickability)
127
+
128
+ val mapFragment = supportFragmentManager.findFragmentById(R .id.map) as SupportMapFragment
129
+ mapFragment.getMapAsync(this )
130
+ }
131
+
132
+ private fun getResourceStrings (resourceIds : IntArray ): List <String > {
133
+ return resourceIds.map { getString(it) }
134
+ }
135
+
136
+ override fun onMapReady (googleMap : GoogleMap ? ) {
137
+
138
+ // return early if the map was not initialised properly
139
+ googleMap ? : return
140
+
141
+ val fillColorArgb = Color .HSVToColor (
142
+ fillAlphaBar.progress, floatArrayOf(fillHueBar.progress.toFloat(), 1f , 1f ))
143
+ val strokeColorArgb = Color .HSVToColor (
144
+ strokeAlphaBar.progress, floatArrayOf(strokeHueBar.progress.toFloat(), 1f , 1f ))
145
+
146
+ with (googleMap) {
147
+ // Override the default content description on the view, for accessibility mode.
148
+ setContentDescription(getString(R .string.polygon_demo_description))
149
+ // Move the googleMap so that it is centered on the mutable polygon.
150
+ moveCamera(CameraUpdateFactory .newLatLngZoom(center, 4f ))
151
+
152
+ // Create a rectangle with two rectangular holes.
153
+ mutablePolygon = addPolygon(PolygonOptions ().apply {
154
+ addAll(createRectangle(center, 5.0 , 5.0 ))
155
+ addHole(createRectangle(LatLng (- 22.0 , 128.0 ), 1.0 , 1.0 ))
156
+ addHole(createRectangle(LatLng (- 18.0 , 133.0 ), 0.5 , 1.5 ))
157
+ fillColor(fillColorArgb)
158
+ strokeColor(strokeColorArgb)
159
+ strokeWidth(strokeWidthBar.progress.toFloat())
160
+ clickable(clickabilityCheckbox.isChecked)
161
+ })
162
+
163
+ // Add a listener for polygon clicks that changes the clicked polygon's stroke color.
164
+ setOnPolygonClickListener { polygon ->
165
+ // Flip the red, green and blue components of the polygon's stroke color.
166
+ polygon.strokeColor = polygon.strokeColor xor 0x00ffffff
167
+ }
168
+ }
169
+
170
+ // set listeners on seekBars
171
+ arrayOf(fillHueBar, fillAlphaBar, strokeWidthBar, strokeHueBar, strokeAlphaBar).map {
172
+ it.setOnSeekBarChangeListener(this )
173
+ }
174
+
175
+ // set listeners on spinners
176
+ arrayOf(strokeJointTypeSpinner, strokePatternSpinner).map {
177
+ it.onItemSelectedListener = this
178
+ }
179
+
180
+ // set line pattern and joint type based on current spinner position
181
+ with (mutablePolygon) {
182
+ strokeJointType = getSelectedJointType(strokeJointTypeSpinner.selectedItemPosition)
183
+ strokePattern = getSelectedPattern(strokePatternSpinner.selectedItemPosition)
184
+ }
185
+
186
+ }
187
+
188
+ /* *
189
+ * Creates a List of LatLngs that form a rectangle with the given dimensions.
190
+ */
191
+ private fun createRectangle (
192
+ center : LatLng ,
193
+ halfWidth : Double ,
194
+ halfHeight : Double
195
+ ): List <LatLng > {
196
+ return Arrays .asList(
197
+ LatLng (center.latitude - halfHeight, center.longitude - halfWidth),
198
+ LatLng (center.latitude - halfHeight, center.longitude + halfWidth),
199
+ LatLng (center.latitude + halfHeight, center.longitude + halfWidth),
200
+ LatLng (center.latitude + halfHeight, center.longitude - halfWidth),
201
+ LatLng (center.latitude - halfHeight, center.longitude - halfWidth))
202
+ }
203
+
204
+ private fun getSelectedJointType (pos : Int ): Int {
205
+ return when (jointTypeNameResourceIds[pos]) {
206
+ R .string.joint_type_bevel -> JointType .BEVEL
207
+ R .string.joint_type_round -> JointType .ROUND
208
+ R .string.joint_type_default -> JointType .DEFAULT
209
+ else -> 0
210
+ }
211
+ }
212
+
213
+ private fun getSelectedPattern (pos : Int ): List <PatternItem >? {
214
+ return when (patternTypeNameResourceIds[pos]) {
215
+ R .string.pattern_solid -> null
216
+ R .string.pattern_dotted -> patternDotted
217
+ R .string.pattern_dashed -> patternDashed
218
+ R .string.pattern_mixed -> patternMixed
219
+ else -> null
220
+ }
221
+ }
222
+
223
+ /* *
224
+ * Toggles the clickability of the polygon based on the state of the View that triggered this
225
+ * call.
226
+ * This callback is defined on the CheckBox in the layout for this Activity.
227
+ */
228
+ fun toggleClickability (view : View ) {
229
+ if (view is CheckBox ) {
230
+ mutablePolygon.isClickable = view.isChecked
231
+ }
232
+ }
233
+
234
+
235
+ /* *
236
+ * Listener that is called when a seek bar is moved.
237
+ * Can change polygon fill color/transparency, stroke color/transparency and stroke width.
238
+ */
239
+ override fun onProgressChanged (seekBar : SeekBar ? , progress : Int ,
240
+ fromUser : Boolean ) {
241
+
242
+ mutablePolygon.fillColor = when (seekBar) {
243
+ fillHueBar -> Color .HSVToColor (Color .alpha(mutablePolygon.fillColor),
244
+ floatArrayOf(progress.toFloat(), 1f , 1f ))
245
+ fillAlphaBar -> {
246
+ val prevColor = mutablePolygon.fillColor
247
+ Color .argb(progress, Color .red(prevColor), Color .green(prevColor),
248
+ Color .blue(prevColor))
249
+ }
250
+ else -> mutablePolygon.fillColor
251
+ }
252
+
253
+ mutablePolygon.strokeColor = when (seekBar) {
254
+ strokeHueBar -> Color .HSVToColor (
255
+ Color .alpha(mutablePolygon.strokeColor),
256
+ floatArrayOf(progress.toFloat(), 1f , 1f ))
257
+ strokeAlphaBar -> {
258
+ val prevColorArgb = mutablePolygon.strokeColor
259
+ Color .argb(progress, Color .red(prevColorArgb),
260
+ Color .green(prevColorArgb), Color .blue(prevColorArgb))
261
+ }
262
+ else -> mutablePolygon.strokeColor
263
+ }
264
+
265
+ if (seekBar == strokeWidthBar) mutablePolygon.strokeWidth = progress.toFloat()
266
+
267
+ }
268
+
269
+ override fun onStartTrackingTouch (seekBar : SeekBar ? ) {
270
+ // do nothing
271
+ }
272
+
273
+ override fun onStopTrackingTouch (seekBar : SeekBar ? ) {
274
+ // do nothing
275
+ }
276
+
277
+ /* *
278
+ * Listener for when an item is selected using a spinner.
279
+ * Can change line pattern and joint type.
280
+ */
281
+ override fun onItemSelected (parent : AdapterView <* >? , view : View ? , pos : Int ,
282
+ id : Long ) {
283
+ when (parent?.id) {
284
+ R .id.strokeJointTypeSpinner ->
285
+ mutablePolygon.strokeJointType = getSelectedJointType(pos)
286
+ R .id.strokePatternSpinner ->
287
+ mutablePolygon.strokePattern = getSelectedPattern(pos)
288
+ }
289
+ }
290
+
291
+ override fun onNothingSelected (parent : AdapterView <* >? ) {
292
+ // don't do anything here
293
+ }
294
+
295
+ }
0 commit comments