ArcGIS Runtime SDK for Android100.9多出行模式路径规划

基于ArcGIS for Android Runtime100.9采用kotlin实现多出行模式(TravelMode)路径规划

效果图:

示例数据:

链接:https://pan.baidu.com/s/13zTFhRvWDq0qDi22VTZabQ 
提取码:1lor 


思路:

①制作网络数据集

在travelmode下添加2个出现模式,例如:walk和automobile

http://note.youdao.com/noteshare?id=6ffa3761081a869ec68a16554ea9aac2&sub=7FBD4DEF9E104EF69A81C173206D1FEF

②发布网络分析服务

③android端代码

MainActivity.java

/*
 * Copyright 2020 Esri
 *

 *
 */

package com.esri.arcgisruntime.sample.offlinerouting

import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.esri.arcgisruntime.data.TileCache
import com.esri.arcgisruntime.geometry.Envelope
import com.esri.arcgisruntime.geometry.Point
import com.esri.arcgisruntime.geometry.SpatialReferences
import com.esri.arcgisruntime.layers.ArcGISMapImageLayer
import com.esri.arcgisruntime.layers.ArcGISTiledLayer
import com.esri.arcgisruntime.loadable.LoadStatus
import com.esri.arcgisruntime.mapping.ArcGISMap
import com.esri.arcgisruntime.mapping.Basemap
import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener
import com.esri.arcgisruntime.mapping.view.Graphic
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay
import com.esri.arcgisruntime.symbology.CompositeSymbol
import com.esri.arcgisruntime.symbology.PictureMarkerSymbol
import com.esri.arcgisruntime.symbology.SimpleLineSymbol
import com.esri.arcgisruntime.symbology.TextSymbol
import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters
import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask
import com.esri.arcgisruntime.tasks.networkanalysis.Stop
import kotlinx.android.synthetic.main.activity_main.*
import java.util.concurrent.ExecutionException
import kotlin.math.roundToInt

class MainActivity : AppCompatActivity() {

  private val stopsOverlay: GraphicsOverlay by lazy { GraphicsOverlay() }
  private val routeOverlay: GraphicsOverlay by lazy { GraphicsOverlay() }
  private var routeParameters: RouteParameters? = null
  private val routeTask: RouteTask by lazy {
    RouteTask(
      this,
      "http://192.168.1.111:6080/arcgis/rest/services/hanjieroutenew/NAServer/Route"
    )
  }

  private val TAG: String = MainActivity::class.java.simpleName

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // create a tile cache from the tpk
//    val tileCache = TileCache(getExternalFilesDir(null)?.path + getString(R.string.tpk_path))
    val tiledLayer = ArcGISMapImageLayer("http://192.168.1.111:6080/arcgis/rest/services/hanjie/hanjiewms/MapServer")
    // make a basemap with the tiled layer and add it to the mapview as an ArcGISMap
    mapView.map = ArcGISMap(Basemap(tiledLayer))

    // add the graphics overlays to the map view
    mapView.graphicsOverlays.addAll(listOf(stopsOverlay, routeOverlay))

    // load the route task
    routeTask.loadAsync()
    routeTask.addDoneLoadingListener {
      if (routeTask.loadStatus == LoadStatus.LOADED) {
        try {
          // create route parameters
          routeParameters = routeTask.createDefaultParametersAsync().get()
        } catch (e: Exception) {
          val error = "Error getting default route parameters. ${e.message}"
          Log.e(TAG, error)
          Toast.makeText(this, error, Toast.LENGTH_LONG).show()
        }
      } else {
        val error = "Error loading route task: ${routeTask.loadError.message}"
        Log.e(TAG, error)
        Toast.makeText(this, error, Toast.LENGTH_LONG).show()
      }
    }

    // set up travel mode switch
    modeSwitch.setOnCheckedChangeListener { _, isChecked ->
      routeParameters?.travelMode = when (isChecked) {
        R.id.fastest_button -> routeTask.routeTaskInfo.travelModes[0]
        R.id.shortest_button -> routeTask.routeTaskInfo.travelModes[1]
        else -> routeTask.routeTaskInfo.travelModes[0]
      }
      Toast.makeText(
        this,
        "${routeParameters?.travelMode?.name} route selected.",
        Toast.LENGTH_SHORT
      ).show()
      updateRoute()
    }

    // make a clear button to reset the stops and routes
    clearButton.setOnClickListener {
      stopsOverlay.graphics.clear()
      routeOverlay.graphics.clear()
    }
    // move the clear button above the attribution bar
    mapView.addAttributionViewLayoutChangeListener { v, _, _, _, _, _, oldTop, _, oldBottom ->
      val heightChanged = v.height - (oldBottom - oldTop)
      clearButton.y += -heightChanged
    }
    // add a graphics overlay to show the boundary
    GraphicsOverlay().let {
      val envelope = Envelope(
        Point(12727855.566  ,3574193.787  , 0.0, SpatialReferences.getWebMercator()),
        Point(12729882.279  ,3575966.499, 0.0, SpatialReferences.getWebMercator())
      )
      val boundarySymbol = SimpleLineSymbol(SimpleLineSymbol.Style.DASH, 0xFF00FF00.toInt(), 5f)
      it.graphics.add(Graphic(envelope, boundarySymbol))
      mapView.graphicsOverlays.add(it)
    }

    // set up the touch listeners on the map view
    createMapGestures()
  }

  /**
   * Sets up the onTouchListener for the mapView.
   * For single taps, graphics will be selected.
   * For double touch drags, graphics will be moved.
   * */
  private fun createMapGestures() {
    mapView.onTouchListener = object : DefaultMapViewOnTouchListener(this, mapView) {
      override fun onSingleTapConfirmed(motionEvent: MotionEvent): Boolean {

        val screenPoint = android.graphics.Point(
          motionEvent.x.roundToInt(),
          motionEvent.y.roundToInt()
        )
        addOrSelectGraphic(screenPoint)
        return true
      }

      override fun onDoubleTouchDrag(motionEvent: MotionEvent): Boolean {

        val screenPoint = android.graphics.Point(
          motionEvent.x.roundToInt(),
          motionEvent.y.roundToInt()
        )

        // move the selected graphic to the new location
        if (stopsOverlay.selectedGraphics.isNotEmpty()) {
          stopsOverlay.selectedGraphics[0]?.geometry = mapView.screenToLocation(screenPoint)
          updateRoute()
        }
        // ignore default double touch drag gesture
        return true
      }

      // ignore default double tap gesture
      override fun onDoubleTap(e: MotionEvent?): Boolean {
        return true
      }
    }
  }

  /**
   * Updates the calculated route by calling routeTask.solveRouteAsync().
   * Creates a graphic to display the route.
   * */
  private fun updateRoute() {
    // get a list of stops from the graphics currently on the graphics overlay.
    val stops = stopsOverlay.graphics.map {
      Stop(it.geometry as Point)
    }

    // do not calculate a route if there is only one stop
    if (stops.size <= 1) return

    routeParameters?.setStops(stops)

    // solve the route
    val results = routeTask.solveRouteAsync(routeParameters)
    results.addDoneListener {
      try {
        val result = results.get()
        val route = result.routes[0]

        // create graphic for route
        val graphic = Graphic(
          route.routeGeometry, SimpleLineSymbol(
            SimpleLineSymbol.Style.SOLID,
            0xFF0000FF.toInt(), 3F
          )
        )

        routeOverlay.graphics.clear()
        routeOverlay.graphics.add(graphic)
      } catch (e: Exception) {
        val error = "No route solution. ${e.message}"
        Log.e(TAG, error)
        Toast.makeText(this, error, Toast.LENGTH_LONG).show()
        routeOverlay.graphics.clear()
      }
    }
  }

  /**
   * Selects a graphic if there is one at the provided tapped location or, if there is none, creates a new graphic.
   *
   * @param screenPoint a point in screen space where the user tapped
   * */
  private fun addOrSelectGraphic(screenPoint: android.graphics.Point) {
    // identify the selected graphic
    val results = mapView.identifyGraphicsOverlayAsync(stopsOverlay, screenPoint, 10.0, false)
    results.addDoneListener {
      try {
        val graphics = results.get().graphics
        // unselect everything
        if (stopsOverlay.selectedGraphics.isNotEmpty()) {
          stopsOverlay.unselectGraphics(stopsOverlay.selectedGraphics)
        }
        // if the user tapped on something, select it
        if (graphics.isNotEmpty()) {
          val firstGraphic = graphics[0]
          firstGraphic.isSelected = true
        } else { // there is no graphic at this location
          // make a new graphic at the tapped location
          val locationPoint = mapView.screenToLocation(screenPoint)
          createStopSymbol(stopsOverlay.graphics.size + 1, locationPoint)
        }
      } catch (e: Exception) {
        val error = "Error identifying graphic: ${e.stackTrace}"
        Log.e(TAG, error)
        Toast.makeText(this, error, Toast.LENGTH_LONG).show()
      }
    }
  }

  /**
   * Creates a composite symbol to represent a numbered stop.
   *
   * @param stopNumber the ordinal number of this stop
   * @param locationPoint the point in map space where the symbol should be placed
   */
  private fun createStopSymbol(stopNumber: Int, locationPoint: Point) {
    try {
      // create a new picture marker symbol and load it
      val pictureMarkerSymbol = PictureMarkerSymbol.createAsync(
        ContextCompat.getDrawable(
          this,
          R.drawable.pin_symbol
        ) as BitmapDrawable
      ).get()
      // create a text symbol with the stop number
      val textSymbol = TextSymbol(
        12f,
        stopNumber.toString(),
        0xFFFFFFFF.toInt(),
        TextSymbol.HorizontalAlignment.CENTER,
        TextSymbol.VerticalAlignment.BOTTOM
      )
      textSymbol.offsetY = -4f
      // create a composite symbol and add the picture marker symbol and text symbol
      val compositeSymbol = CompositeSymbol()
      compositeSymbol.symbols.addAll(listOf(pictureMarkerSymbol, textSymbol))
      // create a graphic to add to the overlay and update the route
      val graphic = Graphic(locationPoint, compositeSymbol)
      stopsOverlay.graphics.add(graphic)
      updateRoute()

    } catch (e: Exception) {
      Log.e(TAG, "Failed to create composite symbol: ${e.stackTrace}")
    }
  }

  override fun onPause() {
    mapView.pause()
    super.onPause()
  }

  override fun onResume() {
    super.onResume()
    mapView.resume()
  }

  override fun onDestroy() {
    mapView.dispose()
    super.onDestroy()
  }

}

参考资料:

https://developers.arcgis.com/android/latest/kotlin/sample-code/offline-routing/  

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值