sforkowany z mirror/meshtastic-android
				
			Added some WMS TileOverlays, custom NOAAWmsTileSource.kt and updated copywrite overlay
							rodzic
							
								
									b03d2ea542
								
							
						
					
					
						commit
						d32a0aa069
					
				|  | @ -143,7 +143,8 @@ dependencies { | |||
|     //OSMDROID, mgrs, | ||||
|     implementation 'org.osmdroid:osmdroid-android:6.1.14' | ||||
|     implementation 'com.github.MKergall:osmbonuspack:6.9.0' | ||||
|     implementation 'mil.nga:mgrs:2.0.0' | ||||
|     implementation 'org.osmdroid:osmdroid-wms:6.1.14' | ||||
|     api 'mil.nga.mgrs:mgrs-android:2.2.0' | ||||
|     implementation 'org.osmdroid:osmdroid-geopackage:6.1.14' | ||||
| 
 | ||||
|     // optional - Kotlin Extensions and Coroutines support for Room | ||||
|  |  | |||
|  | @ -5,19 +5,21 @@ import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase | |||
| import org.osmdroid.tileprovider.tilesource.TileSourceFactory | ||||
| import org.osmdroid.tileprovider.tilesource.TileSourcePolicy | ||||
| import org.osmdroid.util.MapTileIndex | ||||
| import org.osmdroid.wms.WMSTileSource | ||||
| 
 | ||||
| 
 | ||||
| class CustomTileSource { | ||||
|     companion object { | ||||
| 
 | ||||
|         val ESRI_IMAGERY = object : OnlineTileSourceBase( | ||||
|             "ESRI World Overview", 0, 18, 256, "", arrayOf( | ||||
|                 "https://wayback.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/WMTS/1.0.0/default028mm/MapServer/tile/" | ||||
|             ), "Esri, Maxar, Earthstar Geographics, and the GIS User Community" + | ||||
|                     "URL\n" + | ||||
|                     "View\n", | ||||
|         // Map Server information: https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer | ||||
|         // Arcgis Information: https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9 | ||||
|         private val ESRI_IMAGERY = object : OnlineTileSourceBase( | ||||
|             "ESRI World Overview", 0, 18, 256, ".jpg", arrayOf( | ||||
|                 "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/" | ||||
|             ), "Esri, Maxar, Earthstar Geographics, and the GIS User Community", | ||||
|             TileSourcePolicy( | ||||
|                 2, TileSourcePolicy.FLAG_NO_BULK | ||||
|                 2, | ||||
|                 TileSourcePolicy.FLAG_NO_BULK | ||||
|                         or TileSourcePolicy.FLAG_NO_PREVENTIVE | ||||
|                         or TileSourcePolicy.FLAG_USER_AGENT_MEANINGFUL | ||||
|                         or TileSourcePolicy.FLAG_USER_AGENT_NORMALIZED | ||||
|  | @ -30,16 +32,80 @@ class CustomTileSource { | |||
|                         + mImageFilenameEnding) | ||||
|             } | ||||
|         } | ||||
|         val MAPNIK: OnlineTileSourceBase = TileSourceFactory.MAPNIK | ||||
|         val USGS_TOPO: OnlineTileSourceBase = TileSourceFactory.USGS_TOPO | ||||
|         val USGS_SAT: OnlineTileSourceBase = TileSourceFactory.USGS_SAT | ||||
|         //https://nowcoast.noaa.gov/arcgis/rest/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer | ||||
| 
 | ||||
|         private val NOAA_RADAR = object : OnlineTileSourceBase( | ||||
|             "NOAA GOES Radar", | ||||
|             0, | ||||
|             18, | ||||
|             256, | ||||
|             "", | ||||
|             arrayOf( | ||||
|                 "https://earthlive.maptiles.arcgis.com/arcgis/rest/services/GOES/GOES31C/MapServer/tile/" | ||||
|             ), | ||||
|             "Dataset Citation: GOES-R Calibration Working Group and GOES-R Series Program, (2017): NOAA GOES-R Series Advanced Baseline Imager (ABI) Level 1b Radiances Band 13. NOAA National Centers for Environmental Information. doi:10.7289/V5BV7DSR", | ||||
|             TileSourcePolicy( | ||||
|                 2, | ||||
|                 TileSourcePolicy.FLAG_NO_PREVENTIVE | ||||
|                         or TileSourcePolicy.FLAG_USER_AGENT_MEANINGFUL | ||||
|                         or TileSourcePolicy.FLAG_USER_AGENT_NORMALIZED | ||||
|             ) | ||||
|         ) { | ||||
|             override fun getTileURLString(pMapTileIndex: Long): String { | ||||
|                 return baseUrl + (MapTileIndex.getZoom(pMapTileIndex) | ||||
|                     .toString() + "/" + MapTileIndex.getY(pMapTileIndex) | ||||
|                         + "/" + MapTileIndex.getX(pMapTileIndex) | ||||
|                         + mImageFilenameEnding) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /** | ||||
|          * WMS TILE SERVER | ||||
|          * More research is required to get this to function correctly with overlays | ||||
|          */ | ||||
|         val NOAA_RADAR_WMS = NOAAWmsTileSource( | ||||
|             "Recent Weather Radar", | ||||
|             arrayOf("https://new.nowcoast.noaa.gov/arcgis/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer/WmsServer?"), | ||||
|             "1", | ||||
|             "1.3.0", | ||||
|             "", | ||||
|             "EPSG%3A3857", | ||||
|             "", | ||||
|             "image/png" | ||||
|         ) | ||||
| 
 | ||||
|         val NOAA_SATELLITE_RADAR_WMS = NOAAWmsTileSource( | ||||
|             "Weather Satellite Imagery", | ||||
|             arrayOf("https://new.nowcoast.noaa.gov/arcgis/services/nowcoast/sat_meteo_imagery_time/MapServer/WmsServer?"), | ||||
|             "1,5,9,13,17,21,25", | ||||
|             "1.3.0", | ||||
|             "", | ||||
|             "EPSG%3A3857", | ||||
|             "", | ||||
|             "image/png" | ||||
|         ) | ||||
| 
 | ||||
|         /** | ||||
|          * =============================================================================================== | ||||
|          */ | ||||
| 
 | ||||
|         private val MAPNIK: OnlineTileSourceBase = TileSourceFactory.MAPNIK | ||||
|         private val USGS_TOPO: OnlineTileSourceBase = TileSourceFactory.USGS_TOPO | ||||
|         private val USGS_SAT: OnlineTileSourceBase = TileSourceFactory.USGS_SAT | ||||
|         val DEFAULT_TILE_SOURCE: OnlineTileSourceBase = TileSourceFactory.DEFAULT_TILE_SOURCE | ||||
| 
 | ||||
|         /** | ||||
|          * The order in this list must match that in the arrays.xml under map_styles | ||||
|          */ | ||||
|         val mTileSources: List<ITileSource> = | ||||
|             listOf(MAPNIK, USGS_TOPO, USGS_SAT, ESRI_IMAGERY) | ||||
|             listOf( | ||||
|                 MAPNIK, | ||||
|                 USGS_TOPO, | ||||
|                 USGS_SAT, | ||||
|                 ESRI_IMAGERY, | ||||
|                 NOAA_RADAR | ||||
|             ) | ||||
| 
 | ||||
| 
 | ||||
|         fun getTileSource(aName: String): ITileSource { | ||||
|  |  | |||
|  | @ -0,0 +1,146 @@ | |||
| package com.geeksville.mesh.model | ||||
| 
 | ||||
| import android.content.res.Resources | ||||
| import android.util.Log | ||||
| import org.osmdroid.api.IMapView | ||||
| import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase | ||||
| import org.osmdroid.util.MapTileIndex | ||||
| import kotlin.math.atan | ||||
| import kotlin.math.pow | ||||
| import kotlin.math.sinh | ||||
| 
 | ||||
| open class NOAAWmsTileSource( | ||||
|     aName: String, | ||||
|     aBaseUrl: Array<String>, | ||||
|     layername: String, | ||||
|     version: String, | ||||
|     time: String?, | ||||
|     crs: String, | ||||
|     style: String?, | ||||
|     format: String | ||||
| ) : OnlineTileSourceBase(aName, 0, 22, 256, "png", aBaseUrl) { | ||||
| 
 | ||||
|     // array indexes for array to hold bounding boxes. | ||||
|     private val MINX = 0 | ||||
|     private val MAXX = 1 | ||||
|     private val MINY = 2 | ||||
|     private val MAXY = 3 | ||||
| 
 | ||||
|     // Web Mercator n/w corner of the map. | ||||
|     private val TILE_ORIGIN = doubleArrayOf(-20037508.34789244, 20037508.34789244) | ||||
| 
 | ||||
|     //array indexes for that data | ||||
|     private val ORIG_X = 0 | ||||
|     private val ORIG_Y = 1 // " | ||||
| 
 | ||||
|     // Size of square world map in meters, using WebMerc projection. | ||||
|     private val MAP_SIZE = 20037508.34789244 * 2 | ||||
|     private var layer = "" | ||||
|     private var version = "1.1.0" | ||||
|     private var crs = "EPSG:3A3857" //used by geo server | ||||
|     private var size = "" | ||||
|     private var format = "" | ||||
|     private var time = "" | ||||
|     private var style: String? = null | ||||
|     private var forceHttps = false | ||||
|     private var forceHttp = false | ||||
| 
 | ||||
|     init { | ||||
|         Log.i(IMapView.LOGTAG, "WMS support is BETA. Please report any issues") | ||||
|         layer = layername | ||||
|         this.version = version | ||||
|         this.crs = crs | ||||
|         this.style = style | ||||
|         this.format = format | ||||
|         if (time != null) this.time = time | ||||
|     } | ||||
| 
 | ||||
| //    fun createFrom(endpoint: WMSEndpoint, layer: WMSLayer): WMSTileSource? { | ||||
| //        var srs: String? = "EPSG:900913" | ||||
| //        if (layer.srs.isNotEmpty()) { | ||||
| //            srs = layer.srs[0] | ||||
| //        } | ||||
| //        return if (layer.styles.isEmpty()) { | ||||
| //            WMSTileSource( | ||||
| //                layer.name, arrayOf(endpoint.baseurl), layer.name, | ||||
| //                endpoint.wmsVersion, srs, null, layer.pixelSize | ||||
| //            ) | ||||
| //        } else WMSTileSource( | ||||
| //            layer.name, arrayOf(endpoint.baseurl), layer.name, | ||||
| //            endpoint.wmsVersion, srs, layer.styles[0], layer.pixelSize | ||||
| //        ) | ||||
| //    } | ||||
| 
 | ||||
| 
 | ||||
|     private fun tile2lon(x: Int, z: Int): Double { | ||||
|         return x / 2.0.pow(z.toDouble()) * 360.0 - 180 | ||||
|     } | ||||
| 
 | ||||
|     private fun tile2lat(y: Int, z: Int): Double { | ||||
|         val n = Math.PI - 2.0 * Math.PI * y / 2.0.pow(z.toDouble()) | ||||
|         return Math.toDegrees(atan(sinh(n))) | ||||
|     } | ||||
| 
 | ||||
|     // Return a web Mercator bounding box given tile x/y indexes and a zoom | ||||
|     // level. | ||||
|     private fun getBoundingBox(x: Int, y: Int, zoom: Int): DoubleArray { | ||||
|         val tileSize = MAP_SIZE / 2.0.pow(zoom.toDouble()) | ||||
|         val minx = TILE_ORIGIN[ORIG_X] + x * tileSize | ||||
|         val maxx = TILE_ORIGIN[ORIG_X] + (x + 1) * tileSize | ||||
|         val miny = TILE_ORIGIN[ORIG_Y] - (y + 1) * tileSize | ||||
|         val maxy = TILE_ORIGIN[ORIG_Y] - y * tileSize | ||||
|         val bbox = DoubleArray(4) | ||||
|         bbox[MINX] = minx | ||||
|         bbox[MINY] = miny | ||||
|         bbox[MAXX] = maxx | ||||
|         bbox[MAXY] = maxy | ||||
|         return bbox | ||||
|     } | ||||
| 
 | ||||
|     fun isForceHttps(): Boolean { | ||||
|         return forceHttps | ||||
|     } | ||||
| 
 | ||||
|     fun setForceHttps(forceHttps: Boolean) { | ||||
|         this.forceHttps = forceHttps | ||||
|     } | ||||
| 
 | ||||
|     fun isForceHttp(): Boolean { | ||||
|         return forceHttp | ||||
|     } | ||||
| 
 | ||||
|     fun setForceHttp(forceHttp: Boolean) { | ||||
|         this.forceHttp = forceHttp | ||||
|     } | ||||
| 
 | ||||
|     override fun getTileURLString(pMapTileIndex: Long): String? { | ||||
|         var baseUrl = baseUrl | ||||
|         if (forceHttps) baseUrl = baseUrl.replace("http://", "https://") | ||||
|         if (forceHttp) baseUrl = baseUrl.replace("https://", "http://") | ||||
|         val sb = StringBuilder(baseUrl) | ||||
|         if (!baseUrl.endsWith("&")) | ||||
|             sb.append("service=WMS") | ||||
|         sb.append("&request=GetMap") | ||||
|         sb.append("&version=").append(version) | ||||
|         sb.append("&layers=").append(layer) | ||||
|         if (style != null) sb.append("&styles=").append(style) | ||||
|         sb.append("&format=").append(format) | ||||
|         sb.append("&transparent=true") | ||||
|         sb.append("&height=").append(Resources.getSystem().displayMetrics.heightPixels) | ||||
|         sb.append("&width=").append(Resources.getSystem().displayMetrics.widthPixels) | ||||
|         sb.append("&crs=").append(crs) | ||||
|         sb.append("&bbox=") | ||||
|         val bbox = getBoundingBox( | ||||
|             MapTileIndex.getX(pMapTileIndex), | ||||
|             MapTileIndex.getY(pMapTileIndex), | ||||
|             MapTileIndex.getZoom(pMapTileIndex) | ||||
|         ) | ||||
|         sb.append(bbox[MINX]).append(",") | ||||
|         sb.append(bbox[MINY]).append(",") | ||||
|         sb.append(bbox[MAXX]).append(",") | ||||
|         sb.append(bbox[MAXY]) | ||||
| 
 | ||||
|         Log.i(IMapView.LOGTAG, sb.toString()) | ||||
|         return sb.toString() | ||||
|     } | ||||
| } | ||||
|  | @ -8,7 +8,6 @@ import android.graphics.Color | |||
| import android.graphics.Paint | ||||
| import android.graphics.Rect | ||||
| import android.os.Bundle | ||||
| import android.os.Environment | ||||
| import android.text.Editable | ||||
| import android.text.TextWatcher | ||||
| import android.util.Log | ||||
|  | @ -264,7 +263,7 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener, OnSeek | |||
| 
 | ||||
|                 if (startJob) { | ||||
|                     val outputName = | ||||
|                         Configuration.getInstance().osmdroidBasePath.absolutePath + File.separator + "outputName.sqlite" | ||||
|                         Configuration.getInstance().osmdroidBasePath.absolutePath + File.separator + "mainFile.sqlite" // TODO: Accept filename input param from user | ||||
|                     writer = SqliteArchiveTileWriter(outputName) | ||||
|                     try { | ||||
|                         cacheManager = CacheManager(map, writer) | ||||
|  | @ -465,10 +464,12 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener, OnSeek | |||
|      * Adds copyright to map depending on what source is showing | ||||
|      */ | ||||
|     private fun addCopyright() { | ||||
|         val copyrightNotice: String = map.tileProvider.tileSource.copyrightNotice | ||||
|         val copyrightOverlay = CopyrightOverlay(context) | ||||
|         copyrightOverlay.setCopyrightNotice(copyrightNotice) | ||||
|         map.overlays.add(copyrightOverlay) | ||||
|         if (map.tileProvider.tileSource.copyrightNotice != null) { | ||||
|             val copyrightNotice: String = map.tileProvider.tileSource.copyrightNotice | ||||
|             val copyrightOverlay = CopyrightOverlay(context) | ||||
|             copyrightOverlay.setCopyrightNotice(copyrightNotice) | ||||
|             map.overlays.add(copyrightOverlay) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun setupMapProperties() { | ||||
|  |  | |||
|  | @ -91,5 +91,6 @@ | |||
|         <item>USGS TOPO</item> | ||||
|         <item>USGS Satellite</item> | ||||
|         <item>ESRI World Overview</item> | ||||
|         <item>NOAA GOES Radar</item> | ||||
|     </string-array> | ||||
| </resources> | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 PWRxPSYCHO
						PWRxPSYCHO