Skip to content
Closed
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
node_modules
.DS_Store
package-lock.json
Expand Down
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pnpm run lint
#pnpm run lint
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ export default MyMap;
* [`disableTouch()`](#disabletouch)
* [`enableClustering(...)`](#enableclustering)
* [`disableClustering()`](#disableclustering)
* [`addTileOverlay(...)`](#addtileoverlay)
* [`addMarker(...)`](#addmarker)
* [`addMarkers(...)`](#addmarkers)
* [`removeMarker(...)`](#removemarker)
Expand All @@ -319,6 +320,7 @@ export default MyMap;
* [`enableAccessibilityElements(...)`](#enableaccessibilityelements)
* [`enableCurrentLocation(...)`](#enablecurrentlocation)
* [`setPadding(...)`](#setpadding)
* [`getMapBounds()`](#getmapbounds)
* [`fitBounds(...)`](#fitbounds)
* [`setOnBoundsChangedListener(...)`](#setonboundschangedlistener)
* [`setOnCameraIdleListener(...)`](#setoncameraidlelistener)
Expand Down Expand Up @@ -401,6 +403,19 @@ disableClustering() => Promise<void>
--------------------


### addTileOverlay(...)

```typescript
addTileOverlay(tiles: TileOverlay) => Promise<void>
```

| Param | Type |
| ----------- | --------------------------------------------------- |
| **`tiles`** | <code><a href="#tileoverlay">TileOverlay</a></code> |

--------------------


### addMarker(...)

```typescript
Expand Down Expand Up @@ -654,6 +669,19 @@ setPadding(padding: MapPadding) => Promise<void>
--------------------


### getMapBounds()

```typescript
getMapBounds() => Promise<LatLngBounds>
```

Get the map's current viewport latitude and longitude bounds.

**Returns:** <code>Promise&lt;LatLngBounds&gt;</code>

--------------------


### fitBounds(...)

```typescript
Expand Down Expand Up @@ -935,6 +963,20 @@ An interface representing a pair of latitude and longitude coordinates.
| **`mapId`** | <code>string</code> |


#### TileOverlay

For web, all the javascript <a href="#tileoverlay">TileOverlay</a> options are available as
For iOS and Android only the config options declared on <a href="#tileoverlay">TileOverlay</a> are available.

| Prop | Type |
| ------------- | -------------------------------------------------------------- |
| **`getTile`** | <code>(x: number, y: number, zoom: number) =&gt; string</code> |
| **`opacity`** | <code>number</code> |
| **`visible`** | <code>boolean</code> |
| **`zIndex`** | <code>number</code> |
| **`debug`** | <code>boolean</code> |


#### Marker

A marker is an icon placed at a particular point on the map's surface.
Expand Down
2 changes: 1 addition & 1 deletion plugin/.prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"plugins": ["./node_modules/prettier-plugin-java"],
"plugins": ["../node_modules/prettier-plugin-java"],
"printWidth":120,
"tabWidth":2,
"useTabs":false,
Expand Down
28 changes: 28 additions & 0 deletions plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ export default MyMap;
* [`disableTouch()`](#disabletouch)
* [`enableClustering(...)`](#enableclustering)
* [`disableClustering()`](#disableclustering)
* [`addTileOverlay(...)`](#addtileoverlay)
* [`addMarker(...)`](#addmarker)
* [`addMarkers(...)`](#addmarkers)
* [`removeMarker(...)`](#removemarker)
Expand Down Expand Up @@ -402,6 +403,19 @@ disableClustering() => Promise<void>
--------------------


### addTileOverlay(...)

```typescript
addTileOverlay(tiles: TileOverlay) => Promise<void>
```

| Param | Type |
| ----------- | --------------------------------------------------- |
| **`tiles`** | <code><a href="#tileoverlay">TileOverlay</a></code> |

--------------------


### addMarker(...)

```typescript
Expand Down Expand Up @@ -949,6 +963,20 @@ An interface representing a pair of latitude and longitude coordinates.
| **`mapId`** | <code>string</code> |


#### TileOverlay

For web, all the javascript <a href="#tileoverlay">TileOverlay</a> options are available as
For iOS and Android only the config options declared on <a href="#tileoverlay">TileOverlay</a> are available.

| Prop | Type |
| ------------- | -------------------------------------------------------------- |
| **`getTile`** | <code>(x: number, y: number, zoom: number) =&gt; string</code> |
| **`opacity`** | <code>number</code> |
| **`visible`** | <code>boolean</code> |
| **`zIndex`** | <code>number</code> |
| **`debug`** | <code>boolean</code> |


#### Marker

A marker is an icon placed at a particular point on the map's surface.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,86 @@ class CapacitorGoogleMap(
}
}

fun addTileOverlay(tileOverlay: CapacitorGoogleMapsTileOverlay, callback: (result: Result<String>) -> Unit) {
try {
googleMap ?: throw GoogleMapNotAvailable()
var tileOverlayId: String

val bitmapFunc = CoroutineScope(Dispatchers.IO).async {
val url = URL(tileOverlay.imageSrc)
val connection: HttpURLConnection = url.openConnection() as HttpURLConnection

connection.doInput = true
connection.connect()

val input: InputStream = connection.inputStream

BitmapFactory.decodeStream(input)
}

CoroutineScope(Dispatchers.Main).launch {
/*
var tileProvider: TileProvider = object : UrlTileProvider(256, 256) {
override fun getTileUrl(x: Int, y: Int, zoom: Int): URL? {

/* Define the URL pattern for the tile images */
val url = "https://avatars.githubusercontent.com/u/103097039?v=4"
return if (!checkTileExists(x, y, zoom)) {
null
} else try {
URL(url)
} catch (e: MalformedURLException) {
throw AssertionError(e)
}
}

/*
* Check that the tile server supports the requested x, y and zoom.
* Complete this stub according to the tile range you support.
* If you support a limited range of tiles at different zoom levels, then you
* need to define the supported x, y range at each zoom level.
*/
private fun checkTileExists(x: Int, y: Int, zoom: Int): Boolean {
val minZoom = 1
val maxZoom = 16
return zoom in minZoom..maxZoom
}
}

Log.d("TileOverlay ^^^ ", "tileProvider")

val tileOverlay = googleMap?.addTileOverlay(
TileOverlayOptions()
.tileProvider(tileProvider)
)
*/

val bitmap = bitmapFunc.await()

// Now you can safely use the bitmap
if (bitmap != null) {
val imageDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap)

val groundOverlay = googleMap?.addGroundOverlay(
GroundOverlayOptions()
.image(imageDescriptor)
.positionFromBounds(tileOverlay.imageBounds)
.transparency(tileOverlay.opacity)
.zIndex(tileOverlay.zIndex)
.visible(tileOverlay.visible)
)

tileOverlay.googleMapsTileOverlay = groundOverlay
tileOverlayId = groundOverlay!!.id

callback(Result.success(tileOverlayId))
}
}
} catch (e: GoogleMapsError) {
callback(Result.failure(e))
}
}

fun addMarkers(
newMarkers: List<CapacitorGoogleMapMarker>,
callback: (ids: Result<List<String>>) -> Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,45 @@ class CapacitorGoogleMapsPlugin : Plugin(), OnMapsSdkInitializedCallback {
}
}

@PluginMethod
fun addTileOverlay(call: PluginCall) {
try {
val id = call.getString("id")
id ?: throw InvalidMapIdError()

val imageBoundsObj = call.getObject("imageBounds") ?: throw InvalidArgumentsError("imageBounds object is missing")

val imageSrc = call.getString("imageSrc")
val opacity = call.getFloat("opacity", 1.0f)
val zIndex = call.getFloat("zIndex", 0.0f)
val visible = call.getBoolean("visible", true)

val tileOverlayConfig = JSONObject()
tileOverlayConfig.put("imageBounds", imageBoundsObj)
tileOverlayConfig.put("imageSrc", imageSrc)
tileOverlayConfig.put("opacity", opacity)
tileOverlayConfig.put("zIndex", zIndex)
tileOverlayConfig.put("visible", visible)

val map = maps[id]
map ?: throw MapNotFoundError()

val tileOptions = CapacitorGoogleMapsTileOverlay(tileOverlayConfig)

map.addTileOverlay(tileOptions) { result ->
val tileOverlayId = result.getOrThrow()

val res = JSObject()
res.put("id", tileOverlayId)
call.resolve(res)
}
} catch (e: GoogleMapsError) {
handleError(call, e)
} catch (e: Exception) {
handleError(call, e)
}
}

@PluginMethod
fun addMarker(call: PluginCall) {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.capacitorjs.plugins.googlemaps

import com.google.android.gms.maps.model.GroundOverlay
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.LatLngBounds
import org.json.JSONObject

class CapacitorGoogleMapsTileOverlay(fromJSONObject: JSONObject) {
var imageBounds: LatLngBounds
var imageSrc: String? = null
var opacity: Float = 1.0f
var zIndex: Float = 0.0f
var visible: Boolean = true
var googleMapsTileOverlay: GroundOverlay? = null

init {
val latLngObj = fromJSONObject.getJSONObject("imageBounds")
val north = latLngObj.optDouble("north", 0.0)
val south = latLngObj.optDouble("south", 0.0)
val east = latLngObj.optDouble("east", 0.0)
val west = latLngObj.optDouble("west", 0.0)

imageBounds = LatLngBounds(LatLng(south, west), LatLng(north, east))
imageSrc = fromJSONObject.optString("imageSrc", null)
zIndex = fromJSONObject.optLong("zIndex", 0).toFloat()
visible = fromJSONObject.optBoolean("visible", true)
opacity = 1.0f - fromJSONObject.optDouble("opacity", 1.0).toFloat()
}
}
25 changes: 25 additions & 0 deletions plugin/ios/Plugin/CapacitorGoogleMapsPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,31 @@ public class CapacitorGoogleMapsPlugin: CAPPlugin, GMSMapViewDelegate {
}
}

@objc func addTileOverlay(_ call: CAPPluginCall) {
do {
guard let id = call.getString("id") else {
throw GoogleMapErrors.invalidMapId
}

guard let tileObj = call.getObject("tile") else {
throw GoogleMapErrors.invalidArguments("tile object is missing")
}

// let marker = try Marker(fromJSObject: markerObj)

guard let map = self.maps[id] else {
throw GoogleMapErrors.mapNotFound
}

let tileId = try map.addTileOverlay(tile: tileObj)

call.resolve(["id": String(tileId)])

} catch {
handleError(call, error: error)
}
}

@objc func addMarker(_ call: CAPPluginCall) {
do {
guard let id = call.getString("id") else {
Expand Down
20 changes: 20 additions & 0 deletions plugin/ios/Plugin/Map.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,26 @@ public class Map {
}
}

func addTileOverlay(tile: Tile) {
let floor = 1

// Implement GMSTileURLConstructor
// Returns a Tile based on the x,y,zoom coordinates, and the requested floor
let urls: GMSTileURLConstructor = { (x, y, zoom) in
// FIXME: this needs to be configurable
let url = "/\(floor)_\(zoom)_\(x)_\(y).png"
return URL(string: url)
}

// Create the GMSTileLayer
let layer = GMSURLTileLayer(urlConstructor: urls)

// Display on the map at a specific zIndex
// TODO: check if this should be configurable
layer.zIndex = 100
layer.map = mapView
}

func addMarker(marker: Marker) throws -> Int {
var markerHash = 0

Expand Down
12 changes: 12 additions & 0 deletions plugin/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ export interface Point {
y: number;
}

/**
* For web, all the javascript TileOverlay options are available as
* For iOS and Android only the config options declared on TileOverlay are available.
*/
export interface TileOverlay {
getTile: (x: number, y: number, zoom: number) => string;
opacity?: number;
visible?: boolean;
zIndex?: number;
debug?: boolean;
}

/**
* For web, all the javascript Polygon options are available as
* Polygon extends google.maps.PolygonOptions.
Expand Down
Loading