Skip to content

Commit a881c4d

Browse files
committed
Add Example04Polylines
1 parent 8218d0c commit a881c4d

10 files changed

Lines changed: 745 additions & 0 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ Shows zoom functionality with FAB controls and pinch-to-zoom gestures.
101101

102102
Demonstrates marker system with custom icons and click handling.
103103

104+
### [Example04Polylines](examples/Example04Polylines) - Polylines and Polygons
105+
106+
![Example04Polylines](examples/Example04Polylines/screenshot.gif)
107+
108+
Shows how to draw vector shapes including polylines, filled polygons, and polygons with holes.
109+
104110
## Documentation
105111

106112
- [Contributing Guide](docs/CONTRIBUTING.md) - Code quality requirements, formatting, git hooks, and PR process
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
# Example04Polylines - Polylines and Polygons
2+
3+
This example demonstrates drawing vector shapes (polylines and polygons) on OpenMapView, including styled lines, filled areas, and polygons with holes.
4+
5+
## Features Demonstrated
6+
7+
- Polylines with custom stroke colors and widths
8+
- Filled polygons with stroke and fill colors
9+
- Polygons with holes (donut shapes)
10+
- Multiple overlapping shapes on a single map
11+
- Shapes that properly pan and zoom with the map
12+
- Semi-transparent polygon fills
13+
14+
## Screenshot
15+
16+
![Example04Polylines Demo](screenshot.gif)
17+
18+
## Quick Start
19+
20+
### Option 1: Run in Android Studio
21+
22+
1. Open the OpenMapView project in Android Studio
23+
2. Select `examples.Example04Polylines` from the run configuration dropdown
24+
3. Click Run (green play button)
25+
4. Deploy to your device or emulator
26+
27+
### Option 2: Build and Install from Command Line
28+
29+
```bash
30+
# From project root - build, install, and launch
31+
./gradlew :examples:Example04Polylines:installDebug
32+
33+
# Launch the app
34+
adb shell am start -n de.afarber.openmapview.example04polylines/.MainActivity
35+
```
36+
37+
## Code Highlights
38+
39+
### Adding a Polyline
40+
41+
```kotlin
42+
OpenMapView(context).apply {
43+
setCenter(LatLng(51.4661, 7.2491)) // Bochum, Germany
44+
setZoom(14.0)
45+
46+
// Add a blue route line
47+
addPolyline(
48+
Polyline(
49+
points = listOf(
50+
LatLng(51.4700, 7.2400),
51+
LatLng(51.4680, 7.2450),
52+
LatLng(51.4650, 7.2500),
53+
LatLng(51.4620, 7.2550),
54+
),
55+
strokeColor = Color.BLUE,
56+
strokeWidth = 8f,
57+
)
58+
)
59+
}
60+
```
61+
62+
### Adding a Polygon
63+
64+
```kotlin
65+
// Add a green area (park)
66+
addPolygon(
67+
Polygon(
68+
points = listOf(
69+
LatLng(51.4640, 7.2380),
70+
LatLng(51.4660, 7.2380),
71+
LatLng(51.4660, 7.2420),
72+
LatLng(51.4640, 7.2420),
73+
),
74+
strokeColor = Color.rgb(0, 128, 0),
75+
strokeWidth = 4f,
76+
fillColor = Color.argb(100, 0, 255, 0), // Semi-transparent green
77+
)
78+
)
79+
```
80+
81+
### Adding a Polygon with a Hole
82+
83+
```kotlin
84+
// Add a donut-shaped polygon
85+
addPolygon(
86+
Polygon(
87+
points = listOf(
88+
LatLng(51.4700, 7.2580),
89+
LatLng(51.4720, 7.2580),
90+
LatLng(51.4720, 7.2620),
91+
LatLng(51.4700, 7.2620),
92+
),
93+
holes = listOf(
94+
listOf(
95+
LatLng(51.4706, 7.2590),
96+
LatLng(51.4714, 7.2590),
97+
LatLng(51.4714, 7.2610),
98+
LatLng(51.4706, 7.2610),
99+
),
100+
),
101+
strokeColor = Color.CYAN,
102+
strokeWidth = 4f,
103+
fillColor = Color.argb(100, 0, 255, 255), // Semi-transparent cyan
104+
)
105+
)
106+
```
107+
108+
### Key Concepts
109+
110+
- **Polyline**: Connected line segments defined by a list of LatLng points
111+
- **Polygon**: Closed shape with fill color, automatically closed between last and first point
112+
- **Holes**: Polygons can have interior cutouts (donut shapes)
113+
- **addPolyline()**: Add a polyline to the map
114+
- **addPolygon()**: Add a polygon to the map
115+
- **removePolyline()/removePolygon()**: Remove specific shapes
116+
- **clearPolylines()/clearPolygons()**: Remove all shapes of that type
117+
118+
## What to Test
119+
120+
1. **Launch the app** - you should see two polylines and two polygons
121+
2. **Pan the map** - shapes stay at correct geographic positions
122+
3. **Zoom in/out** - shapes scale and remain properly positioned
123+
4. **Observe layering** - polygons render below polylines, polylines below markers
124+
5. **Notice transparency** - polygon fills are semi-transparent
125+
126+
## Shapes in this Example
127+
128+
This example displays 4 shapes around Bochum, Germany:
129+
130+
| Shape Type | Color | Description |
131+
| ---------- | ----- | -------------------------------- |
132+
| Polyline | Blue | Route path (8px wide) |
133+
| Polyline | Red | Alternative route (6px wide) |
134+
| Polygon | Green | Rectangular area (park/zone) |
135+
| Polygon | Cyan | Rectangular area with inner hole |
136+
137+
## Styling Options
138+
139+
### Polyline Properties
140+
141+
- **points**: List of LatLng coordinates (minimum 2 points)
142+
- **strokeColor**: Line color (Int from Color class)
143+
- **strokeWidth**: Line width in pixels (Float)
144+
- **tag**: Optional user data (Any?)
145+
146+
### Polygon Properties
147+
148+
- **points**: List of LatLng coordinates (minimum 3 points)
149+
- **strokeColor**: Outline color (Int from Color class)
150+
- **strokeWidth**: Outline width in pixels (Float)
151+
- **fillColor**: Interior fill color with alpha channel support
152+
- **holes**: List of hole definitions, each a List<LatLng> (minimum 3 points per hole)
153+
- **tag**: Optional user data (Any?)
154+
155+
## Technical Details
156+
157+
### Rendering Order (Z-Index)
158+
159+
Shapes are drawn in this order (bottom to top):
160+
161+
1. Map tiles (base layer)
162+
2. Polygons (filled areas)
163+
3. Polylines (lines)
164+
4. Markers (icons)
165+
5. Attribution overlay
166+
167+
Shapes of the same type are drawn in the order they were added.
168+
169+
### Coordinate System
170+
171+
- Uses Web Mercator projection (EPSG:3857)
172+
- Geographic coordinates (LatLng) automatically converted to screen pixels
173+
- Shapes properly transform during pan and zoom operations
174+
175+
### Performance
176+
177+
- Paths are created on-the-fly during rendering
178+
- Paint objects configured per shape for accurate styling
179+
- Anti-aliasing enabled for smooth lines
180+
- Round caps and joins for professional appearance
181+
182+
## Advanced Usage
183+
184+
### Create Complex Routes
185+
186+
```kotlin
187+
val route = Polyline(
188+
points = listOf(
189+
LatLng(51.4700, 7.2400),
190+
LatLng(51.4680, 7.2450),
191+
// ... add more waypoints
192+
),
193+
strokeColor = Color.BLUE,
194+
strokeWidth = 10f,
195+
tag = "main_route" // Custom metadata
196+
)
197+
addPolyline(route)
198+
```
199+
200+
### Create Multi-Hole Polygons
201+
202+
```kotlin
203+
val complexPolygon = Polygon(
204+
points = outerBoundary,
205+
holes = listOf(
206+
hole1Points,
207+
hole2Points,
208+
hole3Points,
209+
),
210+
strokeColor = Color.BLACK,
211+
strokeWidth = 2f,
212+
fillColor = Color.argb(80, 255, 255, 0),
213+
)
214+
addPolygon(complexPolygon)
215+
```
216+
217+
### Remove Shapes
218+
219+
```kotlin
220+
val polyline = addPolyline(...)
221+
// Later:
222+
removePolyline(polyline)
223+
224+
// Or remove all:
225+
clearPolylines()
226+
clearPolygons()
227+
```
228+
229+
## Next Steps
230+
231+
- Try **Example01Pan** for basic map panning
232+
- Try **Example02Zoom** for zoom controls
233+
- Try **Example03Markers** for marker overlays
234+
- Add your own geographic data (routes, boundaries, zones)
235+
- Experiment with different colors and transparency levels
236+
237+
## Map Location
238+
239+
**Default Center:** Bochum, Germany (51.4661°N, 7.2491°E) at zoom 14.0
240+
241+
All shapes are positioned around Bochum within approximately 1km radius.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
plugins {
2+
id("com.android.application")
3+
id("org.jetbrains.kotlin.android")
4+
id("org.jetbrains.kotlin.plugin.compose")
5+
id("com.diffplug.spotless")
6+
}
7+
8+
android {
9+
namespace = "de.afarber.openmapview.example04polylines"
10+
compileSdk = 35
11+
12+
defaultConfig {
13+
applicationId = "de.afarber.openmapview.example04polylines"
14+
minSdk = 23
15+
targetSdk = 35
16+
versionCode = 1
17+
versionName = "1.0"
18+
}
19+
20+
buildTypes {
21+
release {
22+
isMinifyEnabled = false
23+
}
24+
}
25+
26+
compileOptions {
27+
sourceCompatibility = JavaVersion.VERSION_17
28+
targetCompatibility = JavaVersion.VERSION_17
29+
}
30+
31+
kotlinOptions {
32+
jvmTarget = "17"
33+
}
34+
35+
buildFeatures {
36+
compose = true
37+
}
38+
39+
composeOptions {
40+
kotlinCompilerExtensionVersion = "1.5.3"
41+
}
42+
43+
sourceSets {
44+
getByName("main").java.srcDirs("src/main/kotlin")
45+
}
46+
}
47+
48+
dependencies {
49+
implementation(project(":openmapview"))
50+
implementation("androidx.core:core-ktx:1.15.0")
51+
implementation("androidx.activity:activity-compose:1.9.3")
52+
implementation("androidx.compose.ui:ui:1.7.5")
53+
implementation("androidx.compose.material3:material3:1.3.1")
54+
implementation("androidx.compose.ui:ui-viewbinding:1.7.5")
55+
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.7")
56+
}
57+
58+
spotless {
59+
kotlin {
60+
target("src/**/*.kt")
61+
ktlint("1.3.1").editorConfigOverride(
62+
mapOf(
63+
"ktlint_function_naming_ignore_when_annotated_with" to "Composable",
64+
),
65+
)
66+
trimTrailingWhitespace()
67+
endWithNewline()
68+
indentWithSpaces(4)
69+
licenseHeaderFile(rootProject.file("spotless.license.kt"), "(package|import)")
70+
}
71+
kotlinGradle {
72+
target("*.kts")
73+
ktlint("1.3.1")
74+
}
75+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<uses-permission android:name="android.permission.INTERNET" />
5+
6+
<application
7+
android:allowBackup="true"
8+
android:icon="@android:drawable/sym_def_app_icon"
9+
android:label="Example04Polylines"
10+
android:theme="@android:style/Theme.Material.Light.NoActionBar">
11+
<activity
12+
android:name=".MainActivity"
13+
android:exported="true">
14+
<intent-filter>
15+
<action android:name="android.intent.action.MAIN" />
16+
<category android:name="android.intent.category.LAUNCHER" />
17+
</intent-filter>
18+
</activity>
19+
</application>
20+
21+
</manifest>

0 commit comments

Comments
 (0)