Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ public class GeoJsonLayer : Layer {
anchorU = pointStyle.getAnchorU(),
anchorV = pointStyle.getAnchorV(),
heading = pointStyle.getRotation(),
zIndex = pointStyle.getZIndex(),
)
}

Expand All @@ -304,6 +305,7 @@ public class GeoJsonLayer : Layer {
color = lineStyle.color,
width = lineStyle.getWidth(),
geodesic = lineStyle.isGeodesic(),
zIndex = lineStyle.getZIndex(),
)
}

Expand All @@ -314,6 +316,7 @@ public class GeoJsonLayer : Layer {
strokeColor = polygonStyle.getStrokeColor(),
strokeWidth = polygonStyle.getStrokeWidth(),
geodesic = polygonStyle.isGeodesic(),
zIndex = polygonStyle.getZIndex(),
)
}

Expand All @@ -325,6 +328,7 @@ public class GeoJsonLayer : Layer {
strokeColor = polygonStyle.getStrokeColor(),
strokeWidth = polygonStyle.getStrokeWidth(),
geodesic = polygonStyle.isGeodesic(),
zIndex = polygonStyle.getZIndex(),
)
} else null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,16 @@ public class KmlLayer : Layer {
inline?.mMarkerColor?.let { hue -> Color.HSVToColor(floatArrayOf(hue, 1f, 1f)) }
?: Color.BLACK,
iconUrl = inline?.getIconUrl(),
zIndex = inline?.mMarkerOptions?.zIndex ?: 0f,
)
}

is com.google.maps.android.data.renderer.model.LineString -> {
com.google.maps.android.data.renderer.model.LineStyle(
color = inline?.mPolylineOptions?.color ?: 0xFF000000.toInt(),
width = inline?.mPolylineOptions?.width ?: 1.0f,
geodesic = inline?.mPolylineOptions?.isGeodesic ?: false,
zIndex = inline?.mPolylineOptions?.zIndex ?: 0f,
)
}

Expand All @@ -410,6 +413,8 @@ public class KmlLayer : Layer {
fillColor = inline?.mPolygonOptions?.fillColor ?: 0x00000000,
strokeColor = inline?.mPolygonOptions?.strokeColor ?: 0xFF000000.toInt(),
strokeWidth = inline?.mPolygonOptions?.strokeWidth ?: 1.0f,
geodesic = inline?.mPolygonOptions?.isGeodesic ?: false,
zIndex = inline?.mPolygonOptions?.zIndex ?: 0f,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ class MapViewRenderer(
if (bitmap != null) {
try {
mapOverlay.setImage(BitmapDescriptorFactory.fromBitmap(bitmap))
mapOverlay.isVisible = style?.visibility ?: true // Restore visibility
mapOverlay.isVisible = style.visibility // Restore visibility
} catch (e: Exception) {
// Overlay might be removed
}
Expand Down Expand Up @@ -301,6 +301,7 @@ class MapViewRenderer(
it.heading?.let { heading -> markerOptions.rotation(heading) }
markerOptions.anchor(it.anchorU, it.anchorV)
markerOptions.alpha(android.graphics.Color.alpha(it.color) / 255.0f)
markerOptions.zIndex(it.zIndex)
}
return markerOptions
}
Expand Down Expand Up @@ -333,6 +334,7 @@ class MapViewRenderer(
.setBorderColor(android.graphics.Color.WHITE) // Default border
.build()
markerOptions.icon(BitmapDescriptorFactory.fromPinConfig(pinConfig))
markerOptions.zIndex(it.zIndex)

// AdvancedMarkerOptions does not support rotation directly in the same way as MarkerOptions for flat icons,
// but it supports collision behavior etc.
Expand All @@ -345,6 +347,13 @@ class MapViewRenderer(
return markerOptions
}

/**
* Creates the [PolylineOptions] for rendering a [LineString].
*
* Applies styling properties from [LineStyle], including color, stroke width,
* geodesic curvature, and [LineStyle.zIndex] (which determines its draw order
* relative to other map features).
*/
private fun createPolylineOptions(
lineString: LineString,
style: LineStyle?,
Expand All @@ -355,10 +364,18 @@ class MapViewRenderer(
polylineOptions.color(it.color)
polylineOptions.width(it.width)
polylineOptions.geodesic(it.geodesic)
polylineOptions.zIndex(it.zIndex)
}
return polylineOptions
}

/**
* Creates the [PolygonOptions] for rendering a [Polygon].
*
* Applies styling properties from [PolygonStyle], including fill color, stroke color,
* stroke width, geodesic curvature, and [PolygonStyle.zIndex] (which determines its draw order
* relative to other map features).
*/
private fun createPolygonOptions(
polygon: Polygon,
style: PolygonStyle?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ sealed interface Style
* @property anchorU The U-coordinate of the icon's anchor point, as a ratio of the icon's width (0.0 to 1.0). Defaults to 0.5 (center).
* @property anchorV The V-coordinate of the icon's anchor point, as a ratio of the icon's height (0.0 to 1.0). Defaults to 1.0 (bottom).
* @property scale The scale factor for the icon. Defaults to 1.0.
* @property zIndex The z-index of the marker. Higher values are drawn above lower values. Defaults to 0.0.
*/
data class PointStyle(
val color: Int = 0xFF000000.toInt(), // Default to black
Expand All @@ -39,6 +40,7 @@ data class PointStyle(
val anchorU: Float = 0.5f,
val anchorV: Float = 1.0f,
val scale: Float = 1.0f,
val zIndex: Float = 0.0f,
) : Style

/**
Expand All @@ -47,11 +49,13 @@ data class PointStyle(
* @property color The color of the line, as an integer (e.g., ARGB) or hex string. Defaults to black.
* @property width The width of the line in pixels. Defaults to 1.0.
* @property geodesic Indicates whether the line should be drawn as a geodesic (true) or a straight line (false). Defaults to false.
* @property zIndex The z-index of the line. Higher values are drawn above lower values. Defaults to 0.0.
*/
data class LineStyle(
val color: Int = 0xFF000000.toInt(), // Default to black
val width: Float = 1.0f,
val geodesic: Boolean = false,
val zIndex: Float = 0.0f,
) : Style

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,45 @@
package com.google.maps.android.data.geojson

import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
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.maps.android.data.Feature
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.slot
import io.mockk.unmockkStatic
import io.mockk.verify
import org.json.JSONObject
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertSame
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class GeoJsonLayerObserverTest {
@Before
fun setUp() {
mockkStatic(BitmapDescriptorFactory::class)
every { BitmapDescriptorFactory.defaultMarker(any()) } returns mockk()
}

@After
fun tearDown() {
unmockkStatic(BitmapDescriptorFactory::class)
}

@Test
fun addedPolygonStyleChange_removesAndRedrawsFeature() {
val map = mockk<GoogleMap>(relaxed = true)
Expand Down Expand Up @@ -196,6 +216,52 @@ class GeoJsonLayerObserverTest {
assertSame(secondFeature, clickedFeature)
}

@Test
fun addedPointStyle_appliesZIndexToMarker() {
val map = mockk<GoogleMap>(relaxed = true)
val marker = mockk<Marker>(relaxed = true)
val options = mutableListOf<MarkerOptions>()
every { map.addMarker(capture(options)) } returns marker
val layer = emptyLayer(map)
val (feature, _) = pointFeature(8.5f)

layer.addLayerToMap()
layer.addFeature(feature)

assertEquals(8.5f, options.single().zIndex, 0.001f)
}

@Test
fun addedLineStringStyle_appliesZIndexToPolyline() {
val map = mockk<GoogleMap>(relaxed = true)
val polyline = mockk<Polyline>(relaxed = true)
val options = mutableListOf<PolylineOptions>()
every { map.addPolyline(capture(options)) } returns polyline
val layer = emptyLayer(map)
val (feature, _) = lineStringFeature(4.5f)

layer.addLayerToMap()
layer.addFeature(feature)

assertEquals(4.5f, options.single().zIndex, 0.001f)
}

@Test
fun addedPolygonStyle_appliesZIndexToPolygon() {
val map = mockk<GoogleMap>(relaxed = true)
val polygon = mockk<Polygon>(relaxed = true)
val options = mutableListOf<PolygonOptions>()
every { map.addPolygon(capture(options)) } returns polygon
val layer = emptyLayer(map)
val (feature, style) = polygonFeature(INITIAL_COLOR)
style.setZIndex(3.5f)

layer.addLayerToMap()
layer.addFeature(feature)

assertEquals(3.5f, options.single().zIndex, 0.001f)
}

private fun emptyLayer(map: GoogleMap): GeoJsonLayer =
GeoJsonLayer(
map,
Expand All @@ -218,6 +284,18 @@ class GeoJsonLayerObserverTest {
return GeoJsonFeature(geometry, null, null, null).also { it.polygonStyle = style } to style
}

private fun pointFeature(zIndex: Float): Pair<GeoJsonFeature, GeoJsonPointStyle> {
val geometry = GeoJsonPoint(LatLng(10.0, 20.0))
val style = GeoJsonPointStyle().apply { setZIndex(zIndex) }
return GeoJsonFeature(geometry, null, null, null).also { it.pointStyle = style } to style
}

private fun lineStringFeature(zIndex: Float): Pair<GeoJsonFeature, GeoJsonLineStringStyle> {
val geometry = GeoJsonLineString(listOf(LatLng(0.0, 0.0), LatLng(1.0, 1.0)))
val style = GeoJsonLineStringStyle().apply { setZIndex(zIndex) }
return GeoJsonFeature(geometry, null, null, null).also { it.lineStringStyle = style } to style
}

private fun multiPolygonFeature(fillColor: Int): Pair<GeoJsonFeature, GeoJsonPolygonStyle> {
val firstPolygon = polygon(0.0)
val secondPolygon = polygon(2.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ package com.google.maps.android.data.kml
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.maps.android.data.Layer
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
Expand Down Expand Up @@ -61,4 +65,38 @@ class KmlLayerOnMapTest {
layer.removeLayerFromMap()
assertFalse(layer.isLayerOnMap())
}

@Test
fun addLayerToMap_rendersPointsLinesAndPolygons() {
mockkStatic(BitmapDescriptorFactory::class)
every { BitmapDescriptorFactory.defaultMarker(any()) } returns mockk()
try {
val kml = """
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<Placemark>
<Point><coordinates>10.0,20.0</coordinates></Point>
</Placemark>
<Placemark>
<LineString><coordinates>10.0,20.0 11.0,21.0</coordinates></LineString>
</Placemark>
<Placemark>
<Polygon>
<outerBoundaryIs>
<LinearRing><coordinates>0.0,0.0 1.0,0.0 1.0,1.0 0.0,0.0</coordinates></LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
""".trimIndent()
val context = ApplicationProvider.getApplicationContext<Context>()
val layer = KmlLayer(mockk<GoogleMap>(relaxed = true), kml.byteInputStream(), context)
layer.addLayerToMap()
assertTrue(layer.isLayerOnMap())
} finally {
unmockkStatic(BitmapDescriptorFactory::class)
}
}
}
Loading
Loading