Mapbox Android学习笔记(2)地图样式、地图注释

地图样式

Android的Maps SDK允许完全定制地图的外观。您可以选择由我们的制图师设计的Mapbox的核心样式之一,或者通过调整地图的颜色、图标和字体来创建自定义地图样式,以匹配您的应用程序的UI或公司的品牌。

有两种方法可以定制地图的外观:使用Mapbox Studio创建自定义地图样式并将其加载到应用程序中,或者在运行时使用Android的Maps SDK更新地图特性。

其中,使用运行时样式,您可以实时动态地更改映射的外观和感觉。根据一天的时间调亮或变暗地图,根据用户的活动个性化图标和地图颜色,动态切换语言,或者根据用户的喜好增加标签的大小,以提高可读性。

Style对象

style对象是指在应用程序中使用的 Mapbox map style。Sources, layers, images 通过 map 样式出现在地图上,因此它们是通过 style 对象添加和检索的,而不是添加到实际的 MapboxMap 对象中。使用 style 有三种方法:

  • default Mapbox style found in the Style class constants
  • custom map style URL from a Mapbox account
  • raw style JSON string or referenced style JSON via asset:// or path://

如果样式加载失败或设置了无效的样式URL,map视图将变为空白。一个错误消息将被记录在 Android logcat 和 MapView 中。将触发OnDidFailLoadingMapListener回调。

修改样式

如果想加载一个全新的地图样式,就必须以编程方式更改地图样式URL。使用样式URL作为参数调用mapboxMap.setStyle():

mapboxMap.setStyle(new Style.Builder().fromUrl(uniqueStyleUrl), new Style.OnStyleLoaded() {
	@Override
	public void onStyleLoaded(@NonNull Style style) {
		// 自定义地图样式已经加载,现在已经准备好地图
		
	}
});

Mapbox 默认样式

Mapbox提供了六种专业设计的地图样式:

  1. Mapbox Streets
  2. Outdoor
  3. Light and Dark
  4. Satellite
  5. Satellite Streets
  6. Traffic

Maps SDK的样式类具有默认Mapbox样式URL的 “私有静态最终字符串 private static final String” ,因此当您必须通过项目中的setStyle()方法或其他方法传递样式URL时,可以方便地引用这些样式:mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded()

检索地图图层

检索地图图层是实时调整地图视觉效果的第一步。每个地图样式都有一堆地图图层,每个图层都有一个id,如 landuse, settlement-label, natural-point-label, and building。

Layer singleLayer = mapboxMap.getStyle().getLayer(UNIQUE_LAYER_ID);

可以在Mapbox Studio中查看地图样式的图层z索引顺序和图层id。

查看此信息的另一种方法是,一旦地图加载到设备上,就将每个层ID打印到Android logcat,如下:

mapView.getMapAsync(new OnMapReadyCallback() {
@Override
	public void onMapReady(@NonNull final MapboxMap mapboxMap) {

		mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
			@Override
			public void onStyleLoaded(@NonNull Style style) {
			
				// 将每个层ID打印到Android logcat
				for (Layer singleLayer : mapboxMap.getStyle().getLayers()) {
					Log.d(TAG, "onMapReady: layer id = " + singleLayer.getId());
				}
				
			}
		});
	}
});

一旦有了单独的映射层,就可以使用 data-driven styling 和表达式来调整该层的属性。例如,下面是如何使用 runtime styling 将水层的蓝色更改为更深的蓝色:

button.setOnClickListener(new View.OnClickListener() {
@Override
	public void onClick(View view) {
		mapboxMap.getStyle().getLayer("water").setProperties(PropertyFactory.fillColor(Color.parseColor("#004f6b")));

	}
});

样式相关的事件

更改地图的样式将触发“地图事件”。有关事件以及如何在地图样式加载完成后在地图上显示或重新显示数据的更多信息,请阅读地图更改事件文档



地图注释

Android 的 Mapbox Maps SDK 提供了几种不同的方法来标记一个点、创建一个圆、在多个点之间添加一条线或绘制一个多边形。通常,可以在地图的顶部或者在某些情况下,在地图本身中绘制这些对象。

注意:在针对 Android 的 Mapbox Maps SDK 的 7.0.0 发行版中,该页面的大部分代码都被弃用了。不再维护 Polygon、Polyline 和 Marker 等类。这也意味着不应该使用 PolygonOptions 和 PolylineOptions 之类的类。最后,这还意味着不应该使用 addPolygon()、addPolyline() 或 addMarker() 等方法。

如果计划向地图添加任何图标、文本、行或多边形,请查看Android的Mapbox注释插件。它简化了注释,并为显示数据提供了额外的灵活性。

1.Source和Layer

将数据源和映射层一起使用是在Mapbox map上显示数据的最有效选项。这种组合还可以让您更好地控制以下内容:

  • 表示单个点的图标
  • 多条线段
  • 多边形

有关更多信息,请参见上面的数据驱动样式。您可以探索用于创建注释的源和层组合。下面,您将发现关于显示注释的更简单(和更低性能)方法的信息。

2.标记Marker

当标识地图上的一个点时,标记是有用的。SDK 附带一个默认的标记图标,可以根据您的特定需求进行配置。 api 可以选择将此图标更改为您希望的任何位图图像。要为您的地图创建一个标记,您只需要提供一个 LatLng 位置,该位置定义了标记将放置在地图上的位置。调用 mapboxMap.addMarker() 将标记添加到映射中。

mapboxMap.addMarker(new MarkerOptions()
	.position(new LatLng(48.85819, 2.29458))
	.title("Eiffel Tower"));

除了提供位置之外,还可以添加显示在信息窗口内的标题和代码片段。当用户点击标记时显示信息窗口,当用户点击信息窗口外时关闭信息窗口。

对于多个地点标记:或者正在从GeoJSON文件中加载它们,那么可以使用mapboxmap . addMarkers() 添加标记列表。

移除标记

Mapbox Android SDK 提供了两种删除标记的方法。如果希望删除特定的标记,在传递要删除的标记对象时使用mapboxMap.removeMarker()
如果希望删除所有标记,请调用mapboxMap.clear()方法。注意,这还将删除添加到映射中的所有折线和多边形。

自定义标记icon

您可以通过使用 IconFactory 对象并将其传递给 Marker 来指定自定义 icon。如果在创建标记时没有指定图标,则使用默认标记图标。该标记的锚定将在中心,这意味着如果您有一个带有点的图标,您将需要添加填充到图像的底部。将自定义标记图像放在项目的 drawable 文件夹中,并注意其文件名。在下面的示例中,自定义图标的图像文件名为 blue_mark.png:

// Create an Icon object for the marker to use
IconFactory iconFactory = IconFactory.getInstance(MainActivity.this);
Icon icon = iconFactory.fromResource(R.drawable.blue_marker);

// Add the marker to the map
mapboxMap.addMarker(new MarkerViewOptions()
	.position(new LatLng(-37.821648, 144.978594))
	.icon(icon));

捕获事件标志

Android的 Mapbox Maps SDK 提供了一个方便的监听器,当用户点击一个标记时就可以捕获。默认情况下,所有标记都带有一个 onMarkerClick 事件监听器,用于显示和隐藏信息窗口。您可以覆盖这个默认事件监听器,并使用 setOnMarkerClickListener 方法设置您自己的事件监听器。

要显示带有已单击标记标题的 toast 消息,请使用 setOnMarkerClickListener 侦听一个单击事件,最后调用toast.maketext()。要防止同时显示 toast 消息和信息窗口,请在末尾返回true。示例如下:

mapboxMap.setOnMarkerClickListener(new MapboxMap.OnMarkerClickListener() {
  @Override
  public boolean onMarkerClick(@NonNull Marker marker) {
    // 用选定标记的标题显示toast
    Toast.makeText(this, marker.getTitle(), Toast.LENGTH_LONG).show();
    return true;
  }
});

更新标记

如果您打算更新标记而不是完全删除它,SDK 提供了一些更新方法。使用这些代码意味着更少的样板代码和性能的提高,因为只是在更新标记。

例如,使用这些更新 api,您可以使用 ValueAnimator 创建动画标记。您可以找到用于更新标记对象引用中的标记位置或图标位图的 api。示例:

// 修改标记marker的位置
marker.setPosition(new LatLng(-37.822884, 144.981916));

// 更新marker的图标
marker.setIcon(icon);

3.多段线和多边形

在地图中添加一条线或一个多边形就像添加一个标记。由于这些对象的性质,会公开不同的 api,比如多边形颜色或线宽。将所有 LatLng 对象捆绑在一个列表中,然后使用 addAll() 方法将它们传递进来,而不是放在一个位置。

在地图上画多段线时,需要注意,第一个点和最后一个点的坐标应该是重合的:

mapboxMap.addPolyline(new PolylineOptions()
	.addAll(points)
	.color(Color.parseColor("#3bb2d0"))
	.width(2));

在画多边形时,起点和终点同样需要重合:

List<LatLng> polygonLatLngList = new ArrayList<>();

polygonLatLngList.add(new LatLng(45.522585, -122.685699));
polygonLatLngList.add(new LatLng(45.534611, -122.708873));
polygonLatLngList.add(new LatLng(45.530883, -122.678833));
polygonLatLngList.add(new LatLng(45.515369, -122.678489));
polygonLatLngList.add(new LatLng(45.506346, -122.702007));
polygonLatLngList.add(new LatLng(45.522585, -122.685699));

mapboxMap.addPolygon(new PolygonOptions()
.addAll(polygonLatLngList)
.fillColor(Color.parseColor("#3bb2d0")));

使用线条和填充图层
要使用上面代码中的 addPolyline() 或 addPolygon() 方法,需要拥有一个 LatLng 对象列表,这些对象表示行或多边形区域。

正如本页面顶部所解释的,使用 source 和 layer 可以使您更灵活地在地图上显示地理数据。使用 LatLng 对象列表,您可以创建一个 featurecall 并使用该 featurecall 创建一个 GeoJsonSource。

  • 将 GeoJsonSource 提供给一个线性层,以显示您将通过 addPolyline() 绘制的线
  • 将 GeoJsonSource 提供给一个填充层,用于显示通过 addPolygon() 绘制的区域
上一篇:java – 设置标注图像mapbox android


下一篇:java – 从一组Geopoints Mapbox中找到边界框