Skip to content

Commit

Permalink
adds android gmaps extensions, renames internal Location class
Browse files Browse the repository at this point in the history
  • Loading branch information
ivoberger committed Sep 14, 2019
1 parent dc76b34 commit beb2cd9
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 91 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ URL does not exceed 8192 characters.
// supply your API key followed by a lambda to set the options
val staticMap = StatikGMapsUrl("yourApiKey") {
size = 500 to 250
center = Location(.0, .0)
markers = listOf(Location(51.507222, -0.1275), Location(address = "London"), Location(48.8589507, 2.2770204))
center = StatikMapsLocation(.0, .0)
markers = listOf(StatikMapsLocation(51.507222, -0.1275), StatikMapsLocation(address = "London"), StatikMapsLocation(48.8589507, 2.2770204))
zoom = 4
scale = 2
}
Expand All @@ -53,9 +53,9 @@ val staticMap = StatikGMapsUrl("yourApiKey", baseUrl = "customBaseUrlWithoutHttp
// either center & zoom or markers, path or visible required
center = null
zoom = null
markers = listOf<Location>() // each list entry equals one marker
path = listOf<Location>()
visible = listOf<Location>() // specifies locations that should be in the viewport
markers = listOf<StatikMapsLocation>() // each list entry equals one marker
path = listOf<StatikMapsLocation>()
visible = listOf<StatikMapsLocation>() // specifies locations that should be in the viewport

scale = 1
mapType = null
Expand Down Expand Up @@ -129,7 +129,7 @@ dependencies {

[google-api-specs]: https://developers.google.com/maps/documentation/maps-static/dev-guide
[google-api-params]: https://developers.google.com/maps/documentation/maps-static/dev-guide#URL_Parameters
[google-api-locations]: https://developers.google.com/maps/documentation/maps-static/dev-guide#Locations
[google-api-locations]: https://developers.google.com/maps/documentation/maps-static/dev-guide#StatikMapsLocations
[google-api-url]: https://developers.google.com/maps/documentation/maps-static/dev-guide#url-size-restriction
[google-maps-styling]: https://developers.google.com/maps/documentation/maps-static/styling
[google-api-imagesize]: https://developers.google.com/maps/documentation/maps-static/dev-guide#Imagesizes
Expand Down
8 changes: 6 additions & 2 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import com.dicedmelon.gradle.jacoco.android.JacocoAndroidUnitTestReportExtension

plugins {
id("com.android.library")
kotlin("android")
Expand Down Expand Up @@ -33,3 +31,9 @@ publishing {
}
}
}

dependencies {
api(Libs.play_services_location)
api(Libs.play_services_maps)
api(project(":core"))
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,52 @@
package com.ivoberger.statikgmapsapi.android

import android.location.Location
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.Polyline
import com.google.android.gms.maps.model.PolylineOptions
import com.ivoberger.statikgmapsapi.core.StatikGMapsUrl
import com.ivoberger.statikgmapsapi.core.StatikMapsLocation

fun Marker.toStatikMapsLocation() = position.toStatikMapsLocation()
fun Location.toStatikMapsLocation() = StatikMapsLocation(latitude, longitude)
fun LatLng.toStatikMapsLocation() = StatikMapsLocation(latitude, longitude)

fun List<Location>.toPath() = map { StatikMapsLocation(it.latitude, it.longitude) }

/**
* Sets the path from the points of the given [Polyline]
*/
fun StatikGMapsUrl.path(polyline: Polyline) =
run { path = polyline.points.map { StatikMapsLocation(it.latitude, it.longitude) } }

/**
* Sets the path from the points of the given [PolylineOptions]
*/
fun StatikGMapsUrl.path(polyline: PolylineOptions) =
run { path = polyline.points.map { it.toStatikMapsLocation() } }

/**
* Sets the path from the points of the given [List] of [LatLng]
*/
fun StatikGMapsUrl.path(latLngPath: List<LatLng>) =
run { path = latLngPath.map { it.toStatikMapsLocation() } }

/**
* Adds the given [Marker] to [StatikGMapsUrl.markers]
*/
fun StatikGMapsUrl.marker(marker: Marker) = marker(marker.position)

/**
* Adds the given [LatLng] to [StatikGMapsUrl.markers]
*/
fun StatikGMapsUrl.marker(marker: LatLng) = markers.add(marker.toStatikMapsLocation())

/**
* Adds the given [Location] to [StatikGMapsUrl.markers]
*/
fun StatikGMapsUrl.marker(marker: Location) = markers.add(marker.toStatikMapsLocation())


fun StatikGMapsUrl.visible(latLng: LatLng) = visible.add(latLng.toStatikMapsLocation())
fun StatikGMapsUrl.visible(location: Location) = visible.add(location.toStatikMapsLocation())
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ allprojects {

subprojects {
group = "com.ivoberger.statikgmapsapi"
version = "0.4.0"
version = "0.5.0"

apply(plugin = "org.jetbrains.dokka")

Expand Down
6 changes: 6 additions & 0 deletions buildSrc/src/main/kotlin/Libs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ object Libs {
const val jacoco_android: String = "com.dicedmelon.gradle:jacoco-android:" +
Versions.jacoco_android

const val play_services_location: String = "com.google.android.gms:play-services-location:" +
Versions.com_google_android_gms

const val play_services_maps: String = "com.google.android.gms:play-services-maps:" +
Versions.com_google_android_gms

const val de_fayard_buildsrcversions_gradle_plugin: String =
"de.fayard.buildSrcVersions:de.fayard.buildSrcVersions.gradle.plugin:" +
Versions.de_fayard_buildsrcversions_gradle_plugin
Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ object Versions {

const val jacoco_android: String = "0.1.4"

const val com_google_android_gms: String = "17.0.0"

const val de_fayard_buildsrcversions_gradle_plugin: String = "0.5.0"

const val android_maven_publish: String = "3.6.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import kotlin.math.sqrt
* @receiver path as pair of doubles
* @return encoded polyline
*/
fun List<Location>.encode(): String {
fun List<StatikMapsLocation>.encode(): String {
val result: MutableList<String> = mutableListOf()

var prevLat = 0
Expand Down Expand Up @@ -61,7 +61,7 @@ private fun splitIntoChunks(toEncode: Int): List<Int> {
/**
* https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
*/
internal fun List<Location>.simplify(epsilon: Double): List<Location> {
internal fun List<StatikMapsLocation>.simplify(epsilon: Double): List<StatikMapsLocation> {
// Find the point with the maximum distance
var dmax = 0.0
var index = 0
Expand All @@ -77,8 +77,8 @@ internal fun List<Location>.simplify(epsilon: Double): List<Location> {
// If max distance is greater than epsilon, recursively simplify
return if (dmax > epsilon) {
// Recursive call
val recResults1: List<Location> = subList(0, index + 1).simplify(epsilon)
val recResults2: List<Location> = subList(index, end).simplify(epsilon)
val recResults1: List<StatikMapsLocation> = subList(0, index + 1).simplify(epsilon)
val recResults2: List<StatikMapsLocation> = subList(index, end).simplify(epsilon)

// Build the result list
listOf(recResults1.subList(0, recResults1.lastIndex), recResults2).flatMap { it.toList() }
Expand All @@ -88,7 +88,7 @@ internal fun List<Location>.simplify(epsilon: Double): List<Location> {
}

private fun perpendicularDistance(
pt: Location, lineFrom: Location, lineTo: Location
pt: StatikMapsLocation, lineFrom: StatikMapsLocation, lineTo: StatikMapsLocation
): Double =
abs(
(lineTo.longitude!! - lineFrom.longitude!!)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class StatikGMapsUrl(
* (required if markers, path or visible not present)
* defines the center of the map, equidistant from all edges of the map.
*/
var center: Location? = null
var center: StatikMapsLocation? = null
/**
* (required if markers, path or visible not present)
* defines the zoom level of the map, which determines the magnification level of the map.
Expand All @@ -89,15 +89,15 @@ class StatikGMapsUrl(
/**
* List of markers to display on the map
*/
var markers: List<Location> = listOf()
var markers: MutableList<StatikMapsLocation> = mutableListOf()
/**
* List of locations constituting a path to be drawn on the map
*/
var path: List<Location> = listOf()
var path: List<StatikMapsLocation> = listOf()
/**
* List of locations to be wihtin the maps viewport
*/
var visible: List<Location> = listOf()
var visible: MutableList<StatikMapsLocation> = mutableListOf()
/**
* Specifies if the path should be encoded
* See https://developers.google.com/maps/documentation/utilities/polylinealgorithm for more information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package com.ivoberger.statikgmapsapi.core
* Container to hold a location either by latitude and longitude or an address
* Latitude and longitude will be checked for validity, addresses won't.
*/
data class Location(
data class StatikMapsLocation(
val latitude: Double? = null,
val longitude: Double? = null,
val address: String? = null
Expand All @@ -25,18 +25,18 @@ data class Location(


/**
* Creates a [Location] from a [Pair] of [Double]
* Creates a [StatikMapsLocation] from a [Pair] of [Double]
*/
fun Pair<Double, Double>.toLocation() = Location(first, second)
fun Pair<Double, Double>.toLocation() = StatikMapsLocation(first, second)

/**
* Creates a [List] of [Location] from a [List] of [Pair] of [Double]
* Creates a [List] of [StatikMapsLocation] from a [List] of [Pair] of [Double]
*/
fun List<Pair<Double, Double>>.toLocations() = map { it.toLocation() }

/**
* Converts a list of [Location]s to a valid URL parameter string
* Converts a list of [StatikMapsLocation]s to a valid URL parameter string
*/
internal fun List<Location>.toUrlParam(): String = fold("") { param, location ->
internal fun List<StatikMapsLocation>.toUrlParam(): String = fold("") { param, location ->
"${if (param.isNotBlank()) "$param|" else ""}$location"
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Downscale : StringSpec({
var origSize = 300 to 170
val url = StatikGMapsUrl("placeholder") {
size = origSize
center = Location(.0, .0)
center = StatikMapsLocation(.0, .0)
zoom = 14
}
url.toString()
Expand All @@ -31,7 +31,7 @@ class Downscale : StringSpec({
var origSize = 300 to 170
val url = StatikGMapsUrl("placeholder") {
size = origSize
center = Location(.0, .0)
center = StatikMapsLocation(.0, .0)
zoom = 14
downscale = false
}
Expand All @@ -49,7 +49,7 @@ class Downscale : StringSpec({

"IllegalArgumentException should be thrown as size exceeds limits but downscaling is forbidden" {
val url = StatikGMapsUrl("placeholder") {
center = Location(address = "London")
center = StatikMapsLocation(address = "London")
zoom = 14
downscale = false
}.apply { size = 700 to 100 }
Expand Down Expand Up @@ -79,7 +79,7 @@ class Downscale : StringSpec({
var origRatio = origSize.first / origSize.second.toFloat()
var url = StatikGMapsUrl("placeholder") {
size = origSize
center = Location(.0, .0)
center = StatikMapsLocation(.0, .0)
zoom = 14
}
url.toString()
Expand All @@ -91,7 +91,7 @@ class Downscale : StringSpec({
origRatio = origSize.first / origSize.second.toFloat()
url = StatikGMapsUrl("placeholder") {
size = origSize
center = Location(.0, .0)
center = StatikMapsLocation(.0, .0)
zoom = 14
}
url.toString()
Expand All @@ -103,7 +103,7 @@ class Downscale : StringSpec({
origRatio = origSize.first / origSize.second.toFloat()
url = StatikGMapsUrl("placeholder") {
size = origSize
center = Location(.0, .0)
center = StatikMapsLocation(.0, .0)
zoom = 14
scale = 4
premiumPlan = true
Expand All @@ -117,7 +117,7 @@ class Downscale : StringSpec({
origRatio = origSize.first / origSize.second.toFloat()
url = StatikGMapsUrl("placeholder") {
size = origSize
center = Location(.0, .0)
center = StatikMapsLocation(.0, .0)
zoom = 14
scale = 4
premiumPlan = true
Expand Down
40 changes: 40 additions & 0 deletions core/src/test/kotlin/com/ivoberger/statikgmapsapi/core/Location.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.ivoberger.statikgmapsapi.core

import io.kotlintest.shouldThrow
import io.kotlintest.specs.StringSpec

class Location : StringSpec({
"Should create a valid location" {
for (lat in -90..90) {
for (lng in -180..180) {
StatikMapsLocation(lat.toDouble(), lng.toDouble())
}
}
StatikMapsLocation(address = "London")
}
"Missing parameters should result in an exception" {
shouldThrow<IllegalArgumentException> { StatikMapsLocation() }
shouldThrow<IllegalArgumentException> { StatikMapsLocation(.0) }
shouldThrow<IllegalArgumentException> { StatikMapsLocation(longitude = .0) }
}
"Providing wrong combinations of parameters should result on an exception" {
shouldThrow<IllegalArgumentException> { StatikMapsLocation(90.0, .0, "London") }
shouldThrow<IllegalArgumentException> {
StatikMapsLocation(
longitude = .0,
address = "London"
)
}
shouldThrow<IllegalArgumentException> { StatikMapsLocation(.0, address = "London") }
}
"Out of range coordinates should result in an exception" {
shouldThrow<IllegalArgumentException> { StatikMapsLocation(91.0, .0) }
shouldThrow<IllegalArgumentException> { StatikMapsLocation(-91.0, .0) }
shouldThrow<IllegalArgumentException> { StatikMapsLocation(.0, 181.0) }
shouldThrow<IllegalArgumentException> { StatikMapsLocation(.0, -181.0) }
}
"A non-null but blank or empty address should result in an exception" {
shouldThrow<IllegalArgumentException> { StatikMapsLocation(address = "") }
shouldThrow<IllegalArgumentException> { StatikMapsLocation(address = " ") }
}
})

This file was deleted.

Loading

0 comments on commit beb2cd9

Please sign in to comment.