{"id":13611110,"url":"https://github.com/p-lr/MapView","last_synced_at":"2025-04-13T01:34:34.655Z","repository":{"id":37767857,"uuid":"198028525","full_name":"p-lr/MapView","owner":"p-lr","description":"A Fast, memory efficient Android library to display tiled maps, with support for markers, paths, and rotation.","archived":false,"fork":false,"pushed_at":"2023-10-12T06:05:51.000Z","size":25831,"stargazers_count":202,"open_issues_count":4,"forks_count":41,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-09T23:36:26.511Z","etag":null,"topics":["android","android-library","deep-zoom-images","kotlin-library","map","mapview","tiles","tileview","tiling","zoom"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/p-lr.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-21T07:51:09.000Z","updated_at":"2025-04-08T21:40:25.000Z","dependencies_parsed_at":"2024-11-07T17:02:00.326Z","dependency_job_id":"a1011f92-76b3-47b7-a4f3-d9f2ff491ad4","html_url":"https://github.com/p-lr/MapView","commit_stats":null,"previous_names":["peterlaurence/mapview"],"tags_count":45,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-lr%2FMapView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-lr%2FMapView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-lr%2FMapView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-lr%2FMapView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/p-lr","download_url":"https://codeload.github.com/p-lr/MapView/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654031,"owners_count":21140236,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","deep-zoom-images","kotlin-library","map","mapview","tiles","tileview","tiling","zoom"],"created_at":"2024-08-01T19:01:51.891Z","updated_at":"2025-04-13T01:34:34.612Z","avatar_url":"https://github.com/p-lr.png","language":"Kotlin","readme":"[![Maven Central](https://img.shields.io/maven-central/v/ovh.plrapps/mapview)](https://mvnrepository.com/artifact/ovh.plrapps/mapview)\n[![GitHub License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)\n\nLooking for the Compose version? Check [this](https://github.com/p-lr/MapCompose) out.\n\n# MapView\n\nMapView is a fast, memory efficient Android library to display tiled maps with minimal effort.\n\n  \u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/15638794/110203419-72a74800-7e6e-11eb-8e5b-a4476f930c18.gif\"\u003e\n  \u003c/p\u003e\n\nAn example of setting up:\n\n```kotlin\nval mapView = MapView(context)\nval tileStreamProvider = TileStreamProvider { row, col, zoomLvl -\u003e\n    FileInputStream(File(\"path/{zoomLvl}/{row}/{col}.jpg\")) // or it can be a remote HTTP fetch\n}\n\nval config = MapViewConfiguration(levelCount = 7, fullWidth = 25000, fullHeight = 12500,\n                                  tileSize = 256, tileStreamProvider = tileStreamProvider)\n                                  .setMaxScale(2f)\n\n/* Configuration */\nmapView.configure(config)\n```\n\nMapView shows only the visible part of a tiled map, and supports flinging, dragging, scaling, and \nrotating. It's also possible to add markers and paths.\n\nThis project holds the source code of this library, plus a demo app (which is useful to get started).\nTo test the demo, just clone the repo and launch the demo app from Android Studio.\n\n## MapView supports map rotation\n\nTo be consistent with previous versions, this is disabled by default.\nTo enable it, use `MapViewConfiguration.enableRotation()`. You will find a code example inside the demo\n[RotatingMapFragment](demo/src/main/java/ovh/plrapps/mapview/demo/fragments/RotatingMapFragment.kt).\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/15638794/85233196-d420a700-b404-11ea-8193-2fd98ed340b3.gif\"\u003e\n\u003c/p\u003e\n\nWhen enabling rotation, the `MapView` handles rotation gestures by default. If you only want to rotate\nthe map through APIs, then you should use `enableRotation(handleRotationGesture = false)`. The `MapView`\nhas a new API `setAngle`:\n\n```kotlin\n/**\n * Programmatically set the rotation angle of the MapView, in decimal degrees.\n * It should be called after the [MapView] configuration and after the [MapView] has been laid out.\n * Attempts to set the angle before [MapView] has been laid out will be ignored.\n */\nfun MapView.setAngle(angle: AngleDegree)\n```\n\n**Migrating from 2.x.x**\n\n3.x.x introduced the following breaking changes:\n\n* The domain name of the library was changed to `ovh.plrapps`. MapView is now directly published on \nmavenCentral.\n* The interface `ReferentialOwner` has been replaced with `ReferentialListener`. Instead of expecting\n`ReferentialOwner`s to supply a default value for `ReferentialData`, `ReferentialListener` only has\na `onReferentialChanged(refData: ReferentialData)` method. Migrating to this new interface should\nbe straightforward.\nThere's an example of usage inside the `RotatingMapFragment` demo.\n\n## Installation\n\nAdd this to your module's build.gradle\n```groovy\nimplementation 'ovh.plrapps:mapview:3.1.8'\n```\n\nIn addition, update the module's build.gradle file (for each module that uses MapView), as shown below:\n\n```groovy\nandroid {\n  ...\n  // Configure only for each module that uses Java 8\n  // language features (either in its source code or\n  // through dependencies).\n  compileOptions {\n    sourceCompatibility JavaVersion.VERSION_1_8\n    targetCompatibility JavaVersion.VERSION_1_8\n  }\n  // For Kotlin projects\n  kotlinOptions {\n    jvmTarget = \"1.8\"\n    freeCompilerArgs = ['-Xjvm-default=all-compatibility']\n  }\n}\n```\n\n## Origin and motivation\n\nAs a long time contributor to [TileView](https://github.com/moagrius/TileView), I wanted to see the \nperformance we would get using idiomatic Kotlin (coroutines, flows). The result was beyond my \nexpectations. The overall design can be seen \n[here](https://github.com/p-lr/MapView/wiki/TileCollector-design).\nSpecial attention has been given to efficiency (using non-blocking algorithm to avoiding thread \ncontention). We get smooth animations and high fps.\n\nThanks for Mike (@moagrius), as this library wouldn't exist without his first contributions.\n\n## Principles\n\n### Deep-zoom map\n\nMapView is optimized to display maps that have several levels, like this:\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"doc/readme-files/deepzoom.png\"\u003e\n\u003c/p\u003e\n\nEach next level is twice bigger than the former, and provides more details. Overall, this looks like\n a pyramid. Another common name is \"deep-zoom\" map.\nThis library comes with a demo app made of a set of various use-cases such as using markers, \npaths, rotating the map, etc. All examples use the same map stored in the assets. If you wonder what\na deep-zoom maps looks like, you have a great example there.\n\nMapView can also be used with single level maps.\n\n### Usage\n\nTo use the MapView, you have to follow these steps:\n1. Create a MapView instance\n```kotlin\nval mapView = MapView(context)\n``` \n2. Create a `TileStreamProvider`. See [below](#TOC-TileStreamProvider) for the details.\n3. Create a `MapViewConfiguration`. See [below](#TOC-MapViewConfiguration) for the details.\n4. Apply the configuration\n```kotlin\nmapView.configure(config)\n```\n\nFor more insight, you can have a look at the source of the various [demos](demo/src/main/java/ovh/plrapps/mapview/demo/fragments).\n\n### Convention\n\nMapView uses the convention that the last level is at scale 1. So all levels have scales between 0 and 1.\nEven though you don't have to be aware of the details, it's important to know that. For example, if \nyou set the max scale to 2, it means that the last level will be allowed to be upscaled to twice its\n original size (since the last level is at scale 1).\nThis convention allows for a simple configuration.\n\n## Technical documentation\n\nThe MapView needs to be configured - more on that below. Once configured, you can do a lot of things\nwith your `MapView` instance. `MapView` is a subclass of\n[GestureLayout](mapview/src/main/java/ovh/plrapps/mapview/layout/GestureLayout.kt), which\nhas many features. You can:\n\n* add listeners to events like pan, fling, zoom..\n* programmatically scroll and center to a position\n* respond to various touch events by subclassing `MapView` and overload related methods declared in `GestureLayout`\n\nThis list isn't complete. You can explore the capabilities in the source of\n[GestureLayout](mapview/src/main/java/ovh/plrapps/mapview/layout/GestureLayout.kt).\n\n### \u003ca name=\"TOC-MapViewConfiguration\"\u003e\u003c/a\u003e MapViewConfiguration\n\nThe MapView must be configured using a `MapViewConfiguration`. It holds the mandatory parameters to \nbuild a MapView.\n\nThen, you can set optional properties by calling available methods on your `MapViewConfiguration` \ninstance. Here is an example:\n\n```kotlin\nval config = MapViewConfiguration(levelCount = 7, fullWidth = 25000, fullHeight = 12500,\n                                  tileSize = 256, tileStreamProvider = tileStreamProvider)\n                                  .setMaxScale(2f)\n```\n\nSee documentation [here](https://github.com/p-lr/MapView/blob/79de39ff54cd59e2ceac0247a79f372180a11aa4/mapview/src/main/java/ovh/plrapps/mapview/MapView.kt#L393).\nBelow is a description of mandatory parameters:\n\n**`levelCount`**\n\nThe provided `MapViewConfiguration.levelCount` will define the zoomLevels index that the provided \n`MapViewConfiguration.tileStreamProvider` will be given for its `TileStreamProvider.zoomLevels`.\nThe zoomLevels will be in the range [0 ; `MapViewConfiguration.levelCount`-1].\n\n**`fullWidth` and `fullHeight`**\n\nThese are respectively the width and height in pixels of the map _at scale 1_ (that is, the width \nand height of the last level).\nIn other words, if you put together all the tiles of the last level, you would obtain a big image. \n`fullWidth` and `fullHeight` are dimensions in pixels of this big image.\n\n**`tileSize`**\n\nThe size of the tiles in pixels, which are assumed to be squares and always of the same size for all\nlevels. For now, MapView doesn't support rectangular tiles or tiles of heterogeneous sizes.\n\n**`tileStreamProvider`**\n\nSee the section below.\n\n### \u003ca name=\"TOC-TileStreamProvider\"\u003e\u003c/a\u003e TileStreamProvider\n\nThe MapView will request tiles using the convention that each levels has its tiles organized like this:\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"doc/readme-files/tilematrix.png\"\u003e\n\u003c/p\u003e\n\nMapView isn't opinionated about the origination of tiles. This is the purpose of the `TileStreamProvider`:\n\n```kotlin\nfun interface TileStreamProvider {\n    fun getTileStream(row: Int, col: Int, zoomLvl: Int): InputStream?\n}\n```\nYour implementation of this interface does the necessary coordinate translation (if required). This is \nwhere you do your HTTP request if you have remote tiles, or fetch from a local database (or file system).\n\n*Tile caching*\n\nThe MapView leverages bitmap pooling to reduce the pressure on the garbage collector. However, \nthere's no tile caching by default - this is an implementation detail of the supplied \n`TileStreamProvider`.\n\n### \u003ca name=\"TOC-ReferentialListener\"\u003e\u003c/a\u003e ReferentialListener\n\nWhen the scale and/or the rotation of the MapView change, some of the child views might have to change\naccordingly. For that purpose, you can register a `ReferentialListener` to the MapView.\n\nA `ReferentialListener` is an interface:\n```kotlin\nfun interface ReferentialListener {\n    fun onReferentialChanged(refData: ReferentialData)\n}\n```\nAnd `ReferentialData` holds several useful properties:\n```kotlin\ndata class ReferentialData(var rotationEnabled: Boolean = true,\n                           var angle: AngleDegree = 0f,\n                           var scale: Float = 0f,\n                           var centerX: Double = 0.0,\n                           var centerY: Double = 0.0) : Parcelable\n```\nA `ReferentialListener` should be registered to the MapView:\n```kotlin\nmapView.addReferentialListener(refOwner)\n// If you need to unregister it:\nmapView.removeReferentialListener(refOwner)\n```\nFrom inside your `ReferentialListener` implementation, you can have any logic you want. You can rotate\nsome markers, rotate complex views taking into account the `centerX` and `centerY` properties, etc.\n\nThere's an example of usage at [RotatingMapFragment](demo/src/main/java/ovh/plrapps/mapview/demo/fragments/RotatingMapFragment.kt).\n\n## Create a deep-zoom map\n\nIf you don't already have such a map and you need to make one from a big image, follow this [tutorial](doc/libvips.md).\n\n## How do I..\n\nFollow this [cheat sheet](doc/how-do-i.md).\n\n### API documentation\n\nAPI documentation has its own [wiki page](https://github.com/p-lr/MapView/wiki/MapView-API).\n\n\n\n","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-lr%2FMapView","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp-lr%2FMapView","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-lr%2FMapView/lists"}