本博客记录使用ArcGIS for Android Runtime100.9实现路径规划功能,
效果图:
示例数据:
链接:https://pan.baidu.com/s/1XcY1aNnfTMvdDVrPCX5c8w
提取码:gigs
思路:
①制作网络数据集
②执行“new route”功能
链接:https://pan.baidu.com/s/10_eWJQmdwIkrYCWiVp3YIg
提取码:yqav
③发布网络分析服务
提示:需要arcmap具备网络分析扩展许可
④android端加载网络分析服务实现路径规划
MainActivity.java
/* Copyright 2017 Esri
*/
package com.esri.arcgisruntime.sample.findroute;
import android.app.ProgressDialog;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.SpatialReference;
import com.esri.arcgisruntime.layers.ArcGISTiledLayer;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.core.content.ContextCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.Toast;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.geometry.Geometry;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.SpatialReferences;
import com.esri.arcgisruntime.layers.ArcGISVectorTiledLayer;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.Viewpoint;
import com.esri.arcgisruntime.mapping.view.Graphic;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
import com.esri.arcgisruntime.tasks.networkanalysis.DirectionManeuver;
import com.esri.arcgisruntime.tasks.networkanalysis.Route;
import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters;
import com.esri.arcgisruntime.tasks.networkanalysis.RouteResult;
import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask;
import com.esri.arcgisruntime.tasks.networkanalysis.Stop;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private ProgressDialog mProgressDialog;
private MapView mMapView;
private RouteTask mRouteTask;
private RouteParameters mRouteParams;
private Route mRoute;
private SimpleLineSymbol mRouteSymbol;
private GraphicsOverlay mGraphicsOverlay;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.directions_drawer);
// inflate MapView from layout
mMapView = (MapView) findViewById(R.id.mapView);
ArcGISTiledLayer tiledLayer=new ArcGISTiledLayer("http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer");
Basemap basemap=new Basemap(tiledLayer);
// create a map with the basemap
ArcGISMap mMap = new ArcGISMap(basemap);
// create an initial extent envelope
Envelope initialExtent = new Envelope(12728400.933 , 3574939.478 , 12728800.736 , 3575002.978 ,
SpatialReference.create(102100));
// create a viewpoint from envelope
Viewpoint viewpoint = new Viewpoint(initialExtent);
// set initial map extent
mMap.setInitialViewpoint(viewpoint);
mMapView.setMap(mMap);
// inflate navigation drawer
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
FloatingActionButton mDirectionFab = (FloatingActionButton) findViewById(R.id.directionFAB);
// update UI when attribution view changes
final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mDirectionFab.getLayoutParams();
mMapView.addAttributionViewLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(
View view, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
int heightDelta = (bottom - oldBottom);
params.bottomMargin += heightDelta;
}
});
setupDrawer();
setupSymbols();
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setTitle(getString(R.string.progress_title));
mProgressDialog.setMessage(getString(R.string.progress_message));
mDirectionFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mProgressDialog.show();
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
setTitle(getString(R.string.app_name));
}
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
// create RouteTask instance
mRouteTask = new RouteTask(getApplicationContext(), getString(R.string.routing_service));
final ListenableFuture<RouteParameters> listenableFuture = mRouteTask.createDefaultParametersAsync();
listenableFuture.addDoneListener(new Runnable() {
@Override
public void run() {
try {
if (listenableFuture.isDone()) {
int i = 0;
mRouteParams = listenableFuture.get();
// create stops
Stop stop1 = new Stop(new Point(12728413.643 ,3574937.893 , SpatialReferences.getWebMercator()));
Stop stop2 = new Stop(new Point(12729039.403 ,3575000.992, SpatialReferences.getWebMercator()));
List<Stop> routeStops = new ArrayList<>();
// add stops
routeStops.add(stop1);
routeStops.add(stop2);
mRouteParams.setStops(routeStops);
// set return directions as true to return turn-by-turn directions in the result of
// getDirectionManeuvers().
mRouteParams.setReturnDirections(true);
// solve
RouteResult result = mRouteTask.solveRouteAsync(mRouteParams).get();
final List routes = result.getRoutes();
mRoute = (Route) routes.get(0);
// create a mRouteSymbol graphic
Graphic routeGraphic = new Graphic(mRoute.getRouteGeometry(), mRouteSymbol);
// add mRouteSymbol graphic to the map
mGraphicsOverlay.getGraphics().add(routeGraphic);
// get directions
// NOTE: to get turn-by-turn directions Route Parameters should set returnDirection flag as true
final List<DirectionManeuver> directions = mRoute.getDirectionManeuvers();
String[] directionsArray = new String[directions.size()];
for (DirectionManeuver dm : directions) {
directionsArray[i++] = dm.getDirectionText();
}
Log.d(TAG, directions.get(0).getGeometry().getExtent().getXMin() + "");
Log.d(TAG, directions.get(0).getGeometry().getExtent().getYMin() + "");
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<>(getApplicationContext(),
R.layout.directions_layout, directionsArray));
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mGraphicsOverlay.getGraphics().size() > 3) {
mGraphicsOverlay.getGraphics().remove(mGraphicsOverlay.getGraphics().size() - 1);
}
mDrawerLayout.closeDrawers();
DirectionManeuver dm = directions.get(position);
Geometry gm = dm.getGeometry();
Viewpoint vp = new Viewpoint(gm.getExtent(), 20);
mMapView.setViewpointAsync(vp, 3);
SimpleLineSymbol selectedRouteSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID,
Color.GREEN, 5);
Graphic selectedRouteGraphic = new Graphic(directions.get(position).getGeometry(),
selectedRouteSymbol);
mGraphicsOverlay.getGraphics().add(selectedRouteGraphic);
}
});
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
});
}
});
}
/**
* Set up the Source, Destination and mRouteSymbol graphics symbol
*/
private void setupSymbols() {
mGraphicsOverlay = new GraphicsOverlay();
//add the overlay to the map view
mMapView.getGraphicsOverlays().add(mGraphicsOverlay);
//[DocRef: Name=Picture Marker Symbol Drawable-android, Category=Fundamentals, Topic=Symbols and Renderers]
//Create a picture marker symbol from an app resource
BitmapDrawable startDrawable = (BitmapDrawable) ContextCompat.getDrawable(this, R.drawable.ic_source);
try {
PictureMarkerSymbol pinSourceSymbol = PictureMarkerSymbol.createAsync(startDrawable).get();
pinSourceSymbol.setOffsetY(20);
//add a new graphic as start point
Point sourcePoint = new Point(12728413.643 ,3574937.893 , SpatialReferences.getWebMercator());
Graphic pinSourceGraphic = new Graphic(sourcePoint, pinSourceSymbol);
mGraphicsOverlay.getGraphics().add(pinSourceGraphic);
} catch (InterruptedException | ExecutionException e) {
String error = "Error creating picture marker symbol: " + e.getMessage();
Log.e(TAG, error);
Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
}
//[DocRef: END]
BitmapDrawable endDrawable = (BitmapDrawable) ContextCompat.getDrawable(this, R.drawable.ic_destination);
try {
PictureMarkerSymbol pinDestinationSymbol = PictureMarkerSymbol.createAsync(endDrawable).get();
pinDestinationSymbol.setOffsetY(20);
// add a new graphic as destination point
Point destinationPoint = new Point(12729039.403 ,3575000.992, SpatialReferences.getWebMercator());
Graphic destinationGraphic = new Graphic(destinationPoint, pinDestinationSymbol);
mGraphicsOverlay.getGraphics().add(destinationGraphic);
} catch (InterruptedException | ExecutionException e) {
String error = "Error creating picture marker symbol: " + e.getMessage();
Log.e(TAG, error);
Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
}
//[DocRef: END]
mRouteSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 5);
}
@Override
protected void onPause() {
super.onPause();
mMapView.pause();
}
@Override
protected void onResume() {
super.onResume();
mMapView.resume();
}
@Override
protected void onDestroy() {
super.onDestroy();
mMapView.dispose();
}
/**
* set up the drawer
*/
private void setupDrawer() {
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) {
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerToggle.setDrawerIndicatorEnabled(true);
mDrawerLayout.addDrawerListener(mDrawerToggle);
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
// Activate the navigation drawer toggle
return (mDrawerToggle.onOptionsItemSelected(item)) || super.onOptionsItemSelected(item);
}
}
string.xml
<resources>
<string name="app_name">Find Route</string>
<!-- Navigation vector URL-->
<!-- <string name="navigation_vector">https://www.arcgis.com/sharing/rest/content/items/dcbbba0edf094eaa81af19298b9c6247/resources/styles/root.json</string>-->
<!-- <string name="routing_service1">https://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/Route</string>-->
<string name="routing_service">http://192.168.1.111:6080/arcgis/rest/services/hanjieNA1208/NAServer/Route</string>
<!-- Drawer strings-->
<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>
<string name="progress_title">Finding Route</string>
<string name="progress_message">Please wait…</string>
</resources>
参考资料:
https://developers.arcgis.com/android/latest/java/sample-code/find-route/ 查找路径