当前位置: 代码迷 >> 综合 >> MapBoxMap 之CircleLayer
  详细解决方案

MapBoxMap 之CircleLayer

热度:8   发布时间:2024-03-06 20:37:43.0

CircleLayer:实心圆

一 、添加到地图(基本属性):

 如图添加了几个绿色的实现圆。

public class CircleLayerActivity extends AppCompatActivity {private static final String CIRCLE_SOURCE_ID = "circle-source-id";private static final String CIRCLE_LAYER_ID = "circle-layer-id";private MapView mapView;private MapboxMap mapboxMap;private List<Point> routeCoordinates;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);Mapbox.getInstance(this, getString(R.string.mapbox_access_token));setContentView(R.layout.activity_circle_layer);mapView = findViewById(R.id.mapView);mapView.onCreate(savedInstanceState);mapView.getMapAsync(new OnMapReadyCallback() {@Overridepublic void onMapReady(@NonNull MapboxMap mapboxMap) {CircleLayerActivity.this.mapboxMap = mapboxMap;mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(38.875,-77.035),12));mapboxMap.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {@Overridepublic void onStyleLoaded(@NonNull Style style) {initCoordinates();initCircleSource(style);initLayer(style);}});}});}private void initCoordinates() {routeCoordinates = new ArrayList<>();routeCoordinates.add(Point.fromLngLat(-77.044211, 38.852924));routeCoordinates.add(Point.fromLngLat(-77.044232, 38.862326));routeCoordinates.add(Point.fromLngLat(-77.039936, 38.867698));routeCoordinates.add(Point.fromLngLat(-77.04264, 38.872528));routeCoordinates.add(Point.fromLngLat(-77.032309, 38.87937));routeCoordinates.add(Point.fromLngLat(-77.027645, 38.881779));routeCoordinates.add(Point.fromLngLat(-77.028054, 38.887449));routeCoordinates.add(Point.fromLngLat(-77.03364, 38.892108));;}private void initCircleSource(@NonNull Style style) {FeatureCollection featureCollection = FeatureCollection.fromFeatures(new Feature[]{Feature.fromGeometry(LineString.fromLngLats(routeCoordinates))});GeoJsonSource circleGeoJsonSource = new GeoJsonSource(CIRCLE_SOURCE_ID, featureCollection);style.addSource(circleGeoJsonSource);}private void initLayer(Style style) {CircleLayer circleLayer = new CircleLayer(CIRCLE_LAYER_ID, CIRCLE_SOURCE_ID).withProperties(/**circle-blur* Paint property. Optional number. Defaults to 0. Supports feature-state and interpolateexpressions. Transitionable.* Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.*/PropertyFactory.circleBlur(0f),/**circle-color* Paint property. Optional color. Defaults to "#000000". Supports feature-state and interpolateexpressions. Transitionable.* The fill color of the circle.*/PropertyFactory.circleColor(Color.GREEN),/**circle-opacity* Paint property. Optional number between 0 and 1 inclusive. Defaults to 1. Supports feature-state and interpolateexpressions. Transitionable.* The opacity at which the circle will be drawn.*/PropertyFactory.circleOpacity(1f),/**circle-pitch-alignment* Paint property. Optional enum. One of "map", "viewport". Defaults to "viewport".* Orientation of circle when map is pitched.** "map":* The circle is aligned to the plane of the map.** "viewport":* The circle is aligned to the plane of the viewport.*/PropertyFactory.circlePitchAlignment(Property.CIRCLE_PITCH_ALIGNMENT_VIEWPORT),/**circle-pitch-scale* Paint property. Optional enum. One of "map", "viewport". Defaults to "map".* Controls the scaling behavior of the circle when the map is pitched.** "map":* Circles are scaled according to their apparent distance to the camera.** "viewport":* Circles are not scaled.*/PropertyFactory.circlePitchScale(Property.CIRCLE_PITCH_SCALE_MAP),/**circle-radius* Paint property. Optional number greater than or equal to 0. Units in pixels. Defaults to 5. Supports feature-state and interpolateexpressions. Transitionable.* Circle radius.*/PropertyFactory.circleRadius(8f),/**circle-sort-key* Layout property. Optional number.* Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.*/
//                PropertyFactory.circleSortKey(),/**circle-stroke-color* Paint property. Optional color. Defaults to "#000000". Supports feature-state and interpolateexpressions. Transitionable.* The stroke color of the circle.*/PropertyFactory.circleStrokeColor(Color.parseColor("#000000")),/** circle-stroke-opacity* Paint property. Optional number between 0 and 1 inclusive. Defaults to 1. Supports feature-state and interpolateexpressions. Transitionable.* The opacity of the circle's stroke.*/PropertyFactory.circleStrokeOpacity(1f),/**circle-stroke-width* Paint property. Optional number greater than or equal to 0. Units in pixels. Defaults to 0. Supports feature-state and interpolateexpressions. Transitionable.* The width of the circle's stroke. Strokes are placed outside of the circle-radius.*/PropertyFactory.circleStrokeWidth(0f),/** circle-translate* Paint property. Optional array of numbers. Units in pixels. Defaults to [0,0]. Supports interpolateexpressions. Transitionable.* The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.*/PropertyFactory.circleTranslate(new Float[]{0f, 0f}),/**circle-translate-anchor* Paint property. Optional enum. One of "map", "viewport". Defaults to "map". Requires circle-translate.* Controls the frame of reference for circle-translate.** "map":* The circle is translated relative to the map.** "viewport":* The circle is translated relative to the viewport.*/PropertyFactory.circleTranslateAnchor(Property.CIRCLE_TRANSLATE_ANCHOR_MAP),/** visibility* Layout property. Optional enum. One of "visible", "none". Defaults to "visible".* Whether this layer is displayed.** "visible":* The layer is shown.** "none":* The layer is not shown.*/PropertyFactory.visibility(Property.VISIBLE));style.addLayer(circleLayer);}
}

二、使用GeoJSON和CircleLayer将点数据聚合。

GeoGson格式示例:

{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id": "ak16994521", "mag": 2.3, "time": 1507425650893, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5129, 63.1016, 0.0 ] } }
]
}
package com.ming.androidmapbox.layers;import android.graphics.Color;
import android.os.Bundle;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.layers.TransitionOptions;
import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import com.ming.androidmapbox.R;import java.net.URI;
import java.net.URISyntaxException;import static com.mapbox.mapboxsdk.style.expressions.Expression.all;
import static com.mapbox.mapboxsdk.style.expressions.Expression.division;
import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential;
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.expressions.Expression.gte;
import static com.mapbox.mapboxsdk.style.expressions.Expression.has;
import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate;
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal;
import static com.mapbox.mapboxsdk.style.expressions.Expression.lt;
import static com.mapbox.mapboxsdk.style.expressions.Expression.rgb;
import static com.mapbox.mapboxsdk.style.expressions.Expression.stop;
import static com.mapbox.mapboxsdk.style.expressions.Expression.toNumber;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textSize;/*** Use GeoJSON and circle layers to visualize point data as circle clusters.*/
public class CircleLayerClusteringActivity extends AppCompatActivity {private static final String URL = "https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson";private static final String SOURCE_ID = "earthquakes";private static final String UN_CLUSTERED_LAYER_ID = "unclustered-points";private static final String CROSS_ICON_ID = "cross-icon-id";private static final String POINT_COUNT = "point_count";private static final String COUNT = "count";private static final String MAG = "mag";private static final String CLUSTER_LAYER_ID_PRE = "cluster-";private static final int CLUSTER_MAX_ZOOM = 14;private static final int CLUSTER_RADIUS = 50;private MapView mapView;private MapboxMap mapboxMap;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Mapbox.getInstance(this, getString(R.string.mapbox_access_token));setContentView(R.layout.activity_circle_layer_clustering);mapView = findViewById(R.id.mapView);mapView.onCreate(savedInstanceState);mapView.getMapAsync(new OnMapReadyCallback() {@Overridepublic void onMapReady(@NonNull MapboxMap map) {mapboxMap = map;map.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {@Overridepublic void onStyleLoaded(@NonNull Style style) {// 当图标在地图上碰撞时,禁用任何类型的衰落过渡。这增强了聚集在一起并分离的数据的视觉效果。style.setTransition(new TransitionOptions(0, 0, false));mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(12.099, -79.045), 3));addClusteredGeoJsonSource(style);style.addImage(CROSS_ICON_ID, getResources().getDrawable(R.drawable.mapbox_marker_icon_default));Toast.makeText(CircleLayerClusteringActivity.this, "缩放地图查看聚合效果",Toast.LENGTH_SHORT).show();}});}});}private void addClusteredGeoJsonSource(@NonNull Style loadedMapStyle) {//从GeoJSON数据中添加新来源,并将群集选项设置为true。try {loadedMapStyle.addSource(// 指向GeoJSON数据。此示例显示了USGS地震灾害计划记录的从12/22/15到1/21/16的所有M1.0 +地震。new GeoJsonSource(SOURCE_ID,new URI(URL),new GeoJsonOptions().withCluster(true).withClusterMaxZoom(CLUSTER_MAX_ZOOM).withClusterRadius(CLUSTER_RADIUS)));} catch (URISyntaxException uriSyntaxException) {
//            Timber.e("Check the URL %s", uriSyntaxException.getMessage());}//为单个数据点创建标记层SymbolLayer unclustered = new SymbolLayer(UN_CLUSTERED_LAYER_ID, SOURCE_ID);unclustered.setProperties(iconImage(CROSS_ICON_ID),iconSize(division(get(MAG), literal(4.0f))),iconColor(interpolate(exponential(1), get(MAG),stop(2.0, rgb(0, 255, 0)),stop(4.5, rgb(0, 0, 255)),stop(7.0, rgb(255, 0, 0)))));unclustered.setFilter(has(MAG));loadedMapStyle.addLayer(unclustered);// 使用地震GeoJSON源创建三个图层:每个群集类别一个图层。// 每个点范围将获得不同的填充颜色。int[][] layers = new int[][]{new int[]{150, ContextCompat.getColor(this, R.color.mapboxRed)},new int[]{20, ContextCompat.getColor(this, R.color.mapboxGreen)},new int[]{0, ContextCompat.getColor(this, R.color.mapbox_blue)}};for (int i = 0; i < layers.length; i++) {//添加集群的圈子CircleLayer circles = new CircleLayer(CLUSTER_LAYER_ID_PRE + i, SOURCE_ID);circles.setProperties(circleColor(layers[i][1]),circleRadius(18f));Expression pointCount = toNumber(get(POINT_COUNT));// 将过滤器添加到群集层,以基于POINT_COUNT隐藏圆circles.setFilter(i == 0? all(has(POINT_COUNT),gte(pointCount, literal(layers[i][0]))) : all(has(POINT_COUNT),gte(pointCount, literal(layers[i][0])),lt(pointCount, literal(layers[i - 1][0]))));loadedMapStyle.addLayer(circles);}//添加计数标签SymbolLayer count = new SymbolLayer(COUNT, SOURCE_ID);count.setProperties(textField(Expression.toString(get(POINT_COUNT))),textSize(12f),textColor(Color.WHITE),textIgnorePlacement(true),textAllowOverlap(true));loadedMapStyle.addLayer(count);}// 生命周期...
}

布局文件只有个mapview就不贴出来了。