In this page

MapView Polygon

这篇文档目前尚未提供译文,将以原文展示。

This example shows how to add Polygons in MapView

  1. Add Polygon from a set of Latlng

  2. Query Visible Polygon in Rect

  3. Set Polygon stroke

  4. Set Polygon color

For all code examples, refer to Android Maps SDK Code Examples

activity_polygon.xml view source

1<?xml version="1.0" encoding="utf-8"?>
2<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
3    xmlns:app="http://schemas.android.com/apk/res-auto"
4    xmlns:tools="http://schemas.android.com/tools"
5    android:layout_width="match_parent"
6    android:layout_height="match_parent"
7    tools:context=".PolygonActivity">
8
9    <ai.nextbillion.maps.core.MapView
10        android:id="@+id/map_view"
11        android:layout_width="match_parent"
12        android:layout_height="match_parent"
13        app:nbmap_cameraTargetLat="53.5493093866953"
14        app:nbmap_cameraTargetLng="10.031835837897463"
15        app:nbmap_cameraZoom="10"
16        app:nbmap_uiAttribution="false" />
17
18    <androidx.core.widget.NestedScrollView
19        android:id="@+id/bottomSheet"
20        android:layout_width="match_parent"
21        android:layout_height="wrap_content"
22        android:background="@color/white"
23        app:behavior_hideable="true"
24        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
25
26        <LinearLayout
27            android:layout_width="match_parent"
28            android:layout_height="wrap_content"
29            android:orientation="vertical">
30
31            <TextView
32                android:layout_width="68dp"
33                android:layout_height="1dp"
34                android:layout_gravity="center_horizontal"
35                android:layout_marginTop="13dp"
36                android:background="@drawable/nbmap_radius_10_grey_bg" />
37
38            <TextView
39                android:layout_width="wrap_content"
40                android:layout_height="wrap_content"
41                android:layout_marginTop="13dp"
42                android:paddingHorizontal="16dp"
43                android:text="@string/polygonSetting"
44                android:textColor="@color/black"
45                android:textSize="24sp" />
46
47            <ai.nextbillion.view.SettingSwitchView
48                android:id="@+id/pointEnable"
49                android:layout_width="match_parent"
50                android:layout_height="wrap_content"
51                android:layout_marginLeft="16dp"
52                android:layout_marginRight="16dp" />
53
54            <ai.nextbillion.view.ColorSelectorView
55                android:id="@+id/polygon_color"
56                android:layout_width="match_parent"
57                android:layout_height="wrap_content"
58                android:layout_marginTop="10dp" />
59
60            <ai.nextbillion.view.ColorSelectorView
61                android:id="@+id/polygon_stroke_Color"
62                android:layout_width="match_parent"
63                android:layout_height="wrap_content"
64                android:layout_marginTop="10dp" />
65
66            <ai.nextbillion.view.SliderBarView
67                android:id="@+id/lineWidth"
68                android:layout_width="match_parent"
69                android:layout_height="wrap_content"
70                android:layout_marginBottom="10dp" />
71
72        </LinearLayout>
73
74
75    </androidx.core.widget.NestedScrollView>
76
77    <com.google.android.material.floatingactionbutton.FloatingActionButton
78        android:id="@+id/fb_clean"
79        android:layout_width="wrap_content"
80        android:layout_height="wrap_content"
81        android:layout_gravity="right"
82        android:layout_marginTop="120dp"
83        android:layout_marginRight="16dp"
84        android:backgroundTint="@color/purple_200"
85        android:src="@android:drawable/ic_menu_close_clear_cancel"
86        android:tooltipText="Clean"
87        app:fabSize="mini" />
88
89    <TextView
90        android:id="@+id/fb_check"
91        android:layout_width="40dp"
92        android:layout_height="40dp"
93        android:layout_gravity="right"
94        android:layout_marginTop="170dp"
95        android:layout_marginRight="16dp"
96        android:background="@drawable/shape_circle_40_md_grey_400"
97        android:gravity="center"
98        android:text="@string/polygonStrokeCheck" />
99
100
101    <com.google.android.material.floatingactionbutton.FloatingActionButton
102        android:id="@+id/fb_expand"
103        android:layout_width="wrap_content"
104        android:layout_height="wrap_content"
105        android:layout_gravity="right|bottom"
106        android:layout_marginRight="16dp"
107        android:layout_marginBottom="56dp"
108        android:backgroundTint="@color/purple_200"
109        android:src="@android:drawable/ic_dialog_info"
110        android:tooltipText="Create"
111        android:visibility="gone"
112        app:fabSize="mini" />
113
114    <ImageView
115        android:id="@+id/iv_back"
116        android:layout_width="40dp"
117        android:layout_height="40dp"
118        android:layout_gravity="top|left"
119        android:layout_marginLeft="16dp"
120        android:layout_marginTop="16dp"
121        android:background="@drawable/circle_white_bg"
122        android:src="@drawable/icon_back"
123        app:tint="@color/color_back_icon" />
124
125</androidx.coordinatorlayout.widget.CoordinatorLayout>

PolygonActivity view source

1public class PolygonActivity extends AppCompatActivity implements View.OnClickListener {
2
3   private NextbillionMap mMap;
4   private MapView mapView;
5   private BottomSheetBehavior bottomSheetBehavior;
6   private Polygon polygon;
7   // for stroke
8   private Polyline polyline;
9
10   // polygon
11   private List<LatLng> polygonPoints = new ArrayList<>();
12   private List<Marker> polygonMarkers = new ArrayList<>();
13   private LatLngBounds latLngBounds;
14   private Marker clickMarker;
15
16   // menu
17   private ColorSelectorView polygonColorSelectorView;
18   private ColorSelectorView polygonStrokeColorSelectorView;
19   private SliderBarView polygonStrokeWidthSliderBarView;
20   private SettingSwitchView pointSettingSwitchView;
21   private FloatingActionButton fbInfoFloatingActionButton;
22   private TextView fbNoticeButton;
23
24   private String polygonColor = "#1E58A5";
25   private String polygonStrokeColor = "#FF0000";
26   private float stockWidth = 2;
27   private int polygonIndex = 1;
28   private boolean showPolygonVertex = true;
29
30   @Override
31   protected void onCreate(Bundle savedInstanceState) {
32       super.onCreate(savedInstanceState);
33       setContentView(R.layout.activity_polygon);
34       mapView = findViewById(R.id.map_view);
35       mapView.onCreate(savedInstanceState);
36       mapView.getMapAsync(this::onMapSync);
37       // button
38       findViewById(R.id.fb_clean).setOnClickListener(this);
39       fbInfoFloatingActionButton = findViewById(R.id.fb_expand);
40       fbInfoFloatingActionButton.setOnClickListener(this);
41       fbNoticeButton = findViewById(R.id.fb_check);
42       fbNoticeButton.setOnClickListener(this);
43       // menu
44       polygonColorSelectorView = findViewById(R.id.polygon_color);
45       polygonStrokeColorSelectorView = findViewById(R.id.polygon_stroke_Color);
46       polygonStrokeWidthSliderBarView = findViewById(R.id.lineWidth);
47       pointSettingSwitchView = findViewById(R.id.pointEnable);
48       findViewById(R.id.iv_back).setOnClickListener(this);
49       initData();
50       initBottomSheet();
51   }
52
53   private void initData() {
54       polygonColorSelectorView.setTitle(getResources().getString(R.string.polygonColor));
55       polygonColorSelectorView.initColor(polygonColor);
56       polygonStrokeColorSelectorView.setTitle(getResources().getString(R.string.polygonStrokeColor));
57       polygonStrokeColorSelectorView.initColor(polygonStrokeColor);
58       polygonStrokeWidthSliderBarView.setTitle(getResources().getString(R.string.polygonStrokeWidth));
59       polygonStrokeWidthSliderBarView.initSeekBar(2, 0, 20, "px", 1);
60       pointSettingSwitchView.setTitle(getResources().getString(R.string.polygon_point_show));
61       pointSettingSwitchView.defaultValue(true);
62       polygonColorSelectorView.setOnColorChangedListener(new ColorSelectorView.OnColorChangedListener() {
63           @Override
64           public void onColorChanged(@NonNull String color) {
65               polygonColor = color;
66               if (polygon != null) {
67                   polygon.setFillColor(Color.parseColor(color));
68               }
69           }
70       });
71       polygonStrokeColorSelectorView.setOnColorChangedListener(new ColorSelectorView.OnColorChangedListener() {
72           @Override
73           public void onColorChanged(@NonNull String color) {
74               polygonStrokeColor = color;
75               int colorHex = Color.parseColor(color);
76               if (polyline != null) {
77                   polyline.setColor(colorHex);
78               }
79           }
80       });
81       polygonStrokeWidthSliderBarView.setOnSliderChangedListener(new SliderBarView.OnSliderChangedListener() {
82           @Override
83           public void onSliderChanged(float value) {
84               stockWidth = value;
85               if (polyline != null) {
86                   polyline.setWidth(value);
87               }
88           }
89       });
90
91       pointSettingSwitchView.setOnSwitchChangedLister(new SettingSwitchView.OnSwitchChangedLister() {
92           @Override
93           public void onSwitchChanged(boolean status) {
94               showPolygonVertex = status;
95               upDataMarkerBySwitchState();
96           }
97       });
98   }
99
100   private void upDataMarkerBySwitchState() {
101       if (polygonMarkers == null || polygonMarkers.isEmpty()) {
102           return;
103       }
104       for (Marker marker : polygonMarkers) {
105           marker.setIcon(IconFactory.getInstance(PolygonActivity.this)
106                   .fromResource((showPolygonVertex || polygonPoints.size() < 3) ? R.mipmap.ic_blue_dot : R.mipmap.ic_marker_transparent));
107       }
108   }
109
110   private void onMapSync(NextbillionMap map) {
111       mMap = map;
112       addMapListener();
113       mMap.setStyle( Style.Builder().fromUri(StyleConstants.LIGHT))      
114   }
115
116   private void addMapListener() {
117       mMap.addOnMapLongClickListener(new NextbillionMap.OnMapLongClickListener() {
118           @Override
119           public boolean onMapLongClick(@NonNull LatLng latLng) {
120               polygonPoints.add(latLng);
121               MarkerOptions markerOptions = new MarkerOptions()
122                       .setTitle(String.valueOf(polygonIndex))
123                       .position(latLng)
124                       .setIcon(IconFactory.getInstance(PolygonActivity.this)
125                               .fromResource((showPolygonVertex || polygonPoints.size() < 3) ? R.mipmap.ic_blue_dot : R.mipmap.ic_marker_transparent));
126               polygonMarkers.add(mMap.addMarker(markerOptions));
127               polygonIndex ++;
128               if (polygonPoints.size() > 2) {
129                   createPolygon();
130               }
131               return false;
132           }
133       });
134       mMap.addOnMapClickListener(new NextbillionMap.OnMapClickListener() {
135           @Override
136           public boolean onMapClick(@NonNull LatLng latLng) {
137               if (clickMarker != null) {
138                   mMap.removeMarker(clickMarker);
139               }
140               clickMarker = mMap.addMarker(latLng);
141               Point clickPoint = new Point(latLng.getLongitude(),latLng.getLatitude());
142               List<Point> polygonLngLatPoints = new ArrayList<>();
143               for (LatLng point : polygonPoints) {
144                   polygonLngLatPoints.add(new Point(point.getLongitude(),point.getLatitude()));
145               }
146               boolean isPointInPolygon = PolygonUtils.isPointInPolygon(clickPoint,PolygonUtils.getPolygon(true,polygonLngLatPoints));
147               if (isPointInPolygon) {
148                   Toast.makeText(PolygonActivity.this, "this point is in polygon", Toast.LENGTH_SHORT).show();
149               }
150               return false;
151           }
152       });
153       mMap.addOnMoveListener(new NextbillionMap.OnMoveListener() {
154           @Override
155           public void onMoveBegin(@NonNull MoveGestureDetector moveGestureDetector) {
156
157           }
158
159           @Override
160           public void onMove(@NonNull MoveGestureDetector moveGestureDetector) {
161
162           }
163
164           @Override
165           public void onMoveEnd(@NonNull MoveGestureDetector moveGestureDetector) {
166               boolean isPolygonInScreen = checkPolygonVisibility();
167               if (isPolygonInScreen) {
168                   fbNoticeButton.setBackgroundResource(R.drawable.shape_circle_40_purple_200);
169               } else {
170                   fbNoticeButton.setBackgroundResource(R.drawable.shape_circle_40_md_grey_400);
171               }
172           }
173       });
174       mMap.setOnMarkerClickListener(new NextbillionMap.OnMarkerClickListener() {
175           @Override
176           public boolean onMarkerClick(@NonNull Marker marker) {
177               if (marker == clickMarker) {
178                   mMap.removeMarker(clickMarker);
179                   clickMarker = null;
180               }
181               return false;
182           }
183       });
184   }
185
186   private boolean checkPolygonVisibility() {
187       if (mMap == null || mMap.getProjection() == null || latLngBounds == null) {
188           return false;
189       }
190       LatLngBounds isInScreen = mMap.getProjection().getVisibleRegion().latLngBounds.intersect(latLngBounds);
191       return isInScreen != null;
192   }
193
194   private void cleanPolygon() {
195       if (mMap == null || polygon == null) {
196           Toast.makeText(PolygonActivity.this, "No polygon need remove", Toast.LENGTH_SHORT).show();
197           return;
198       }
199       mMap.removePolygon(polygon);
200       polygon = null;
201       polygonPoints.clear();
202       latLngBounds = null;
203       // polygon marker
204       for (Marker marker : polygonMarkers) {
205           mMap.removeMarker(marker);
206       }
207       polygonMarkers.clear();
208
209       // line
210       if (polyline != null) {
211           mMap.removePolyline(polyline);
212           polyline = null;
213       }
214   }
215
216   private void createPolygon() {
217       // check map
218       if (mMap == null) {
219           Toast.makeText(this, getResources().getString(R.string.waite_notice), Toast.LENGTH_SHORT).show();
220           return;
221       }
222       // check data
223       if (polygonPoints.isEmpty()) {
224           Toast.makeText(this, getResources().getString(R.string.polygon_empty_point_notice), Toast.LENGTH_SHORT).show();
225           return;
226       }
227
228       if (polyline != null) {
229           mMap.removePolyline(polyline);
230       }
231
232       if (polygon != null) {
233           mMap.removePolygon(polygon);
234       }
235       // update marker show style
236       upDataMarkerBySwitchState();
237
238       // add polygon
239       latLngBounds = new LatLngBounds.Builder().includes(polygonPoints).build();
240       PolygonOptions polygonOptions = new PolygonOptions();
241       polygonOptions.addAll(polygonPoints)
242               .fillColor(Color.parseColor(polygonColor))
243               .strokeColor(Color.parseColor(polygonStrokeColor));
244       polygon = mMap.addPolygon(polygonOptions);
245
246       // add polygon stroke by polyline
247       List<LatLng> polylinePoints = new ArrayList<>(polygonPoints);
248       polylinePoints.add(polygonPoints.get(0));
249       polylinePoints.add(polygonPoints.get(1));
250       PolylineOptions polylineOptions = new PolylineOptions()
251               .addAll(polylinePoints)
252               .color(Color.parseColor(polygonStrokeColor))
253               .width(stockWidth);
254       polyline = mMap.addPolyline(polylineOptions);
255       // change check button color
256       fbNoticeButton.setBackgroundResource(R.drawable.shape_circle_40_purple_200);
257   }
258
259   private void initBottomSheet() {
260       bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottomSheet));
261       bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
262       bottomSheetBehavior.setPeekHeight((int) Utils.dpToPx(60));
263       bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
264           @Override
265           public void onStateChanged(@NonNull View bottomSheet, int newState) {
266               if (newState == BottomSheetBehavior.STATE_HIDDEN) {
267                   fbInfoFloatingActionButton.setVisibility(View.VISIBLE);
268               } else {
269                   fbInfoFloatingActionButton.setVisibility(View.GONE);
270               }
271           }
272
273           @Override
274           public void onSlide(@NonNull View bottomSheet, float slideOffset) {
275
276           }
277       });
278   }
279
280   ///////////////////////////////////////////////////////////////////////////
281   // Lifecycle
282   ///////////////////////////////////////////////////////////////////////////
283
284   @Override
285   protected void onStart() {
286       super.onStart();
287       mapView.onStart();
288   }
289
290   @Override
291   protected void onResume() {
292       super.onResume();
293       mapView.onResume();
294   }
295
296   @Override
297   protected void onPause() {
298       super.onPause();
299       mapView.onPause();
300   }
301
302   @Override
303   protected void onStop() {
304       super.onStop();
305       mapView.onStop();
306   }
307
308   @Override
309   protected void onSaveInstanceState(@NonNull Bundle outState) {
310       super.onSaveInstanceState(outState);
311       mapView.onSaveInstanceState(outState);
312   }
313
314   @Override
315   protected void onDestroy() {
316       super.onDestroy();
317       mapView.onDestroy();
318   }
319
320   @Override
321   public void onLowMemory() {
322       super.onLowMemory();
323       mapView.onLowMemory();
324   }
325
326   @Override
327   public void onClick(View v) {
328       if (v.getId() == R.id.fb_clean) {
329           cleanPolygon();
330       } else if (v.getId() == R.id.fb_expand) {
331           bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
332       } else if (v.getId() == R.id.fb_check) {
333           boolean isPolygonInScreen = checkPolygonVisibility();
334           String message = getResources().getString(R.string.polygin_visibility_notice);
335           if (!isPolygonInScreen) {
336               message = getResources().getString(R.string.polygon_invisibility_notice);
337           }
338           Toast.makeText(PolygonActivity.this, message, Toast.LENGTH_SHORT).show();
339       } else if (v.getId() == R.id.iv_back) {
340           finish();
341       }
342   }
343}

initData

  1. Initialises the data for the polygon activity.

  2. Sets up various UI components such as color selectors, slider bars, and switch views. It also defines listeners for these components to handle user interactions and update the corresponding data values.

addMapListener

  1. Adds listeners to the map.

  2. Sets up event listeners for various map interactions such as long clicks, clicks, moves, and marker clicks. These listeners perform actions such as adding markers, creating polygons, checking polygon visibility, and removing markers and polygons.

checkPolygonVisibility

  1. Checks if the polygon is currently visible on the map. It relies on the map's projection and the bounds of the polygon to determine if the polygon is within the visible region of the map. It returns a boolean value indicating the visibility status of the polygon.

createPolygon

  1. Creates a polygon on the map. It checks if the necessary data, such as the map and polygon points, are available. It removes any existing polyline and polygon from the map. It updates the marker show style based on the switch state. Then it adds a polygon and a polyline to the map using the provided polygon points, colors, and stroke width.

cleanPolygon

  1. Removes the polygon and related markers from the map. It checks if the map and polygon are available and removes them from the map. It also clears the polygon points, marker list, and polyline if they exist.

These methods are part of the PolygonActivity class and are used to initialize and manage the polygon functionality in the corresponding Android activity.

The code also includes various lifecycle methods (onStart, onResume, onPause, onStop, onSaveInstanceState, onDestroy, onLowMemory) that should be implemented when using the MapView to properly manage its lifecycle and handle configuration changes.

Note: The code uses the Nextbillion Maps SDK, which provides map-related functionalities. It also utilizes the LatLng class to represent geography.

没找到你要找的内容?