You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android端MapBox无法加载自定义瓦片服务器问题求助

MapBox Android加载第三方矢量瓦片无显示问题排查

我是首次使用MapBox,想要在Android应用中复现某网页的地图效果,已按照官方文档配置第三方矢量瓦片服务器,将自有瓦片服务器对应的样式JSON放入项目assets目录,但MapBox始终无瓦片显示。以下是我的Activity代码和样式JSON文件,求指导问题所在:

Activity代码

class MapBoxActivity : AppCompatActivity() {
    private lateinit var mapboxMap: MapBoxMap
    private lateinit var mapView: MapView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mapView = MapView(this)
        setContentView(mapView)
        mapboxMap = mapView.mapboxMap

        mapboxMap.setCamera(
            CameraOptions.Builder()
                .zoom(12.0)
                .center(Point.fromLngLat(-87.622088, 41.878781))
                .build()
        )

        val styleJson = loadStyleFromAssets("mapbox_style.json")
        if (styleJson != null) {
            mapboxMap.loadStyleJson(styleJson) { style ->
                updateTileSource(style)
            }
        }
    }

    private fun updateTileSource(style: Style) {
        
        val url = "http://ts.carsprogram.org/public.rwrc_view/{z}/{x}/{y}.pbf"

        // Remove existing source if it exists
        if (style.styleSourceExists(SOURCE_ID)) {
            style.removeStyleSource(SOURCE_ID)
        }

        // Add new source with updated URL
        style.addSource(
            vectorSource(SOURCE_ID) {
                tiles(listOf(url))
                minzoom(6)
                maxzoom(14)
            }
        )

        // Add or update the layer
        if (!style.styleLayerExists(LAYER_ID)) {
            style.addLayerBelow(
                lineLayer(LAYER_ID, SOURCE_ID) {
                    sourceLayer(SOURCE_LAYER_ID)
                    lineCap(LineCap.ROUND)
                    lineJoin(LineJoin.ROUND)
                    lineOpacity(0.6)
                    lineColor(Expression.rgb(53.0, 175.0, 109.0))
                    lineWidth(2.0)
                },
                BELOW_LAYER_ID
            )
        }
    }

    private fun loadStyleFromAssets(fileName: String): String? {
        return try {
            val inputStream = assets.open(fileName)
            val size = inputStream.available()
            val buffer = ByteArray(size)
            inputStream.read(buffer)
            inputStream.close()
            String(buffer, Charsets.UTF_8)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    private companion object {
        const val SOURCE_ID = "mapillary"
        const val LAYER_ID = SOURCE_ID
        const val TAG = SOURCE_ID
        const val SOURCE_LAYER_ID = "sequence"
        const val BELOW_LAYER_ID = "road-label-simple"
    }
}

样式JSON文件

{
  "id": "public.rwrc_view",
  "schema": "public",
  "name": "rwrc_view",
  "properties": [
    {
      "name": "objectid",
      "type": "int8",
      "description": ""
    },
    {
      "name": "road_condition",
      "type": "float8",
      "description": ""
    },
    {
      "name": "color",
      "type": "text",
      "description": ""
    },
    {
      "name": "segment_id",
      "type": "text",
      "description": ""
    },
    {
      "name": "segment_name",
      "type": "text",
      "description": ""
    },
    {
      "name": "headline",
      "type": "text",
      "description": ""
    },
    {
      "name": "status",
      "type": "text",
      "description": ""
    },
    {
      "name": "route_name",
      "type": "text",
      "description": ""
    },
    {
      "name": "primarymp",
      "type": "text",
      "description": ""
    },
    {
      "name": "secondarymp",
      "type": "text",
      "description": ""
    },
    {
      "name": "primarylat",
      "type": "text",
      "description": ""
    },
    {
      "name": "primarylong",
      "type": "text",
      "description": ""
    },
    {
      "name": "secondarylat",
      "type": "text",
      "description": ""
    },
    {
      "name": "secondarylong",
      "type": "text",
      "description": ""
    },
    {
      "name": "description",
      "type": "text",
      "description": ""
    },
    {
      "name": "source",
      "type": "text",
      "description": ""
    },
    {
      "name": "source_link",
      "type": "text",
      "description": ""
    },
    {
      "name": "report_updated",
      "type": "float8",
      "description": ""
    },
    {
      "name": "report_created",
      "type": "float8",
      "description": ""
    },
    {
      "name": "report_id",
      "type": "text",
      "description": ""
    },
    {
      "name": "creationdate",
      "type": "int8",
      "description": ""
    },
    {
      "name": "creator",
      "type": "text",
      "description": ""
    },
    {
      "name": "editdate",
      "type": "int8",
      "description": ""
    },
    {
      "name": "editor",
      "type": "text",
      "description": ""
    },
    {
      "name": "route_rank",
      "type": "float8",
      "description": ""
    },
    {
      "name": "pk",
      "type": "int4",
      "description": ""
    }
  ],
  "geometrytype": "Geometry",
  "center": [
    -95.51685333251953,
    42.49988555908203
  ],
  "bounds": [
    -104.055908203125,
    35.99919891357422,
    -86.97779846191406,
    49.000572204589844
  ],
  "minzoom": 2,
  "maxzoom": 22,
  "tileurl": "http://ts.carsprogram.org/public.rwrc_view/{z}/{x}/{y}.pbf"
}

问题排查与修复建议

  • 样式JSON格式错误
    你提供的JSON是瓦片数据集的元数据,并非MapBox要求的标准样式文件。MapBox的loadStyleJson需要符合MapBox Style规范的完整样式定义,直接加载这个文件会导致地图无基础底图,自定义图层也无法渲染。
    修复:放弃加载这个自定义JSON,改用MapBox官方基础样式(比如Style.MAPBOX_STREETS)作为底图,再添加你的矢量瓦片源和图层。

  • 相机位置不在瓦片覆盖范围
    当前设置的相机中心接近瓦片服务的边界,且zoom值12虽在你设置的6-14范围内,但建议先调整到瓦片中心位置(-95.5169, 42.4999),zoom设为6,确保在瓦片覆盖区域内测试。

  • 矢量瓦片源图层名称错误
    你设置的SOURCE_LAYER_ID = "sequence"与瓦片数据集名称public.rwrc_view不符,需要确认瓦片内部的源图层名(可通过矢量瓦片查看工具验证),大概率应该是public.rwrc_view,名称错误会导致图层找不到数据。

  • HTTP明文请求限制
    Android 9及以上默认禁止HTTP明文请求,你的瓦片URL是http协议,需要在AndroidManifest.xml中添加android:usesCleartextTraffic="true",或者将服务升级为HTTPS。

  • MapView生命周期未绑定
    当前代码未处理MapView的生命周期方法,会导致地图无法正常初始化。需要在Activity中添加以下生命周期绑定代码:

    override fun onStart() {
        super.onStart()
        mapView.onStart()
    }
    
    override fun onResume() {
        super.onResume()
        mapView.onResume()
    }
    
    override fun onPause() {
        super.onPause()
        mapView.onPause()
    }
    
    override fun onStop() {
        super.onStop()
        mapView.onStop()
    }
    
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mapView.onSaveInstanceState(outState)
    }
    
    override fun onDestroy() {
        super.onDestroy()
        mapView.onDestroy()
    }
    
    override fun onLowMemory() {
        super.onLowMemory()
        mapView.onLowMemory()
    }
    
  • 缺失网络权限
    确保在AndroidManifest.xml中添加网络权限:

    <uses-permission android:name="android.permission.INTERNET" />
    

内容的提问来源于stack exchange,提问作者Roon13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 05:19:50