Android使用HereMap教程

关于

  前几天公司要求调研一下here map地图是否支持等值路由等线图这个功能,然后就去google了一下。因为不是国内的地图,然后在最后下载Android对应的sdk(探索版explore)需要有对应支付的功能,即使不收费,所以也需要有类似PayPal等支付账号。本篇文章即提供最新版的explore 版Android sdk(导入项目的是aar文件)
 目前最新版基于时间 2022-5-29
sdk的下载链接我会放到文章末尾,以百度网盘形式。

配置

  继续不需要下载,如果你想真正使用到项目而不是仅限于测试的话也需要注册账号然后填写一系列信息,然后创建一个项目如下:
在这里插入图片描述
  然后会有提示你下载一个文件,文件里面包括对应的项目的id和secret,打开如下图:
在这里插入图片描述
  然后我们将它写到我们项目的Androidmanifest.xml里面:

<meta-data
            android:name="com.here.sdk.access_key_id"
            android:value="JqOFpFBmTqMAMn_s49QIVw" />
        <meta-data
            android:name="com.here.sdk.access_key_secret"
            android:value="zHujQuPPQVVxb2aMrUfW-1iXkmVGBUKQ3FBR4Y3Qq7h67RA0zH8Q_PlQ-jO15ph485qlM3ITDJhFfVbDZX2hNw" />

  还有就是对应的here map的aar文件导入以及build文件的修改如下:

在这里插入图片描述
项目build文件:

implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'], exclude : ['*mock*.jar'])

  重新sync一下build,然后我们就可以使用here map地图了

简单使用

  here map 的几乎所有功能都是基于mapScene,简单实现地图展示。
  首先添加地图控件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HereMapActivity">
    
    <com.here.sdk.mapview.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </com.here.sdk.mapview.MapView>
    
</androidx.constraintlayout.widget.ConstraintLayout>

  然后在代码里面使用:

private var mapView: MapView? = null

private val locationRequest = registerForActivityResult(ActivityResultContracts.RequestPermission()){
        if(it){
            loadMapScene()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_here_map)
        mapView = findViewById(R.id.map_view)
        mapView!!.onCreate(savedInstanceState)
        locationRequest.launch(Manifest.permission.ACCESS_FINE_LOCATION)
    }
     private fun loadMapScene() {

        MapView.setPrimaryLanguage(LanguageCode.EN_US) //设置显示语言
        mapView!!.mapScene.setLayerVisibility(MapScene.Layers.EXTRUDED_BUILDINGS,VisibilityState.HIDDEN)//一些图层的显示与隐藏
        mapView!!.mapScene.setLayerVisibility(MapScene.Layers.LANDMARKS,VisibilityState.HIDDEN)
        mapView!!.mapScene.loadScene(
            MapScheme.NORMAL_NIGHT//五种模式地图,正常白黑、卫星地图、混合卫星和正常白黑
        ) { mapError ->
            if (mapError == null) {

               val distanceInMeters = (1000 * 10).toDouble()
                mapView!!.camera.lookAt(
                    GeoCoordinates(52.530932, 13.384915)
                )
            } else {

            }
        }
    }

  效果图如下:
在这里插入图片描述

关于定位

  首先是here map的开发文档
  第一种方式如下:
新建一个PlatformPositioningProvider类

public class PlatformPositioningProvider implements LocationListener {

    public static final String LOG_TAG = PlatformPositioningProvider.class.getName();
    public static final int LOCATION_UPDATE_INTERVAL_IN_MS = 100;

    private Context context;
    private LocationManager locationManager;
    @Nullable
    private PlatformLocationListener platformLocationListener;

    public interface PlatformLocationListener {
        void onLocationUpdated(Location location);
    }

    public PlatformPositioningProvider(Context context) {
        this.context = context;
    }

    @Override
    public void onLocationChanged(android.location.Location location) {
        if (platformLocationListener != null) {
            platformLocationListener.onLocationUpdated(location);
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        switch(status){
            case LocationProvider.AVAILABLE:
                Log.e(LOG_TAG, "PlatformPositioningProvider status: AVAILABLE");
                break;
            case LocationProvider.OUT_OF_SERVICE:
                Log.e(LOG_TAG, "PlatformPositioningProvider status: OUT_OF_SERVICE");
                break;
            case LocationProvider.TEMPORARILY_UNAVAILABLE:
                Log.e(LOG_TAG, "PlatformPositioningProvider status: TEMPORARILY_UNAVAILABLE");
                break;
            default:
                Log.e(LOG_TAG, "PlatformPositioningProvider status: UNKNOWN");
        }
    }

    @Override
    public void onProviderEnabled(String provider) {
        Log.e(LOG_TAG, "PlatformPositioningProvider enabled.");
    }

    @Override
    public void onProviderDisabled(String provider) {
        Log.e(LOG_TAG, "PlatformPositioningProvider disabled.");
    }

    public void startLocating(PlatformLocationListener locationCallback) {
        if (this.platformLocationListener != null) {
            throw new RuntimeException("Please stop locating before starting again.");
        }

        if (ActivityCompat.checkSelfPermission(context,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(context,
                        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.e(LOG_TAG, "Positioning permissions denied.");
            return;
        }

        this.platformLocationListener = locationCallback;
        locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);

        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) &&
                context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)) {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_UPDATE_INTERVAL_IN_MS, 1,this);
        } else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, LOCATION_UPDATE_INTERVAL_IN_MS, 1,this);
        } else {
            Log.e(LOG_TAG, "Positioning not possible.");
            stopLocating();
        }
    }

    public void stopLocating() {
        if (locationManager == null) {
            return;
        }

        locationManager.removeUpdates(this);
        platformLocationListener = null;
    }
}

  然后在刚才初始化地图成功那里修改:

private var locationIndicator: LocationIndicator? = null

 mapView!!.mapScene.loadScene(
            MapScheme.NORMAL_NIGHT
        ) { mapError ->
            if (mapError == null) {

               val distanceInMeters = (1000 * 10).toDouble()
                mapView!!.camera.lookAt(
                    GeoCoordinates(52.530932, 13.384915)
                )
               val platformPositioningProvide = PlatformPositioningProvide(this)
                platformPositioningProvide.startLocating {
                    addMyLocationToMap(convertLocation(it))
                }
            } else {

            }
        }
       private fun addMyLocationToMap(myLocation: Location) {
        locationIndicator = LocationIndicator()
        locationIndicator?.locationIndicatorStyle = LocationIndicator.IndicatorStyle.PEDESTRIAN
        locationIndicator?.updateLocation(myLocation)
        mapView?.addLifecycleListener(locationIndicator!!)
        mapView?.camera?.lookAt(myLocation.coordinates)
    }     
        private fun convertLocation(nativeLocation: android.location.Location): Location {
        val geoCoordinates = GeoCoordinates(
            nativeLocation.latitude,
            nativeLocation.longitude,
            nativeLocation.altitude
        )
        val location = Location(geoCoordinates)
        if (nativeLocation.hasBearing()) {
            location.bearingInDegrees = nativeLocation.bearing.toDouble()
        }
        if (nativeLocation.hasSpeed()) {
            location.speedInMetersPerSecond = nativeLocation.speed.toDouble()
        }
        if (nativeLocation.hasAccuracy()) {
            location.horizontalAccuracyInMeters = nativeLocation.accuracy.toDouble()
        }
        return location
    }

  但是没有定位成功,可能是中国的保护问题。也有可能是因为用的是explore版本的sdk原因。
也可以参考navigate版示例应用:的定位demo,这里因为项目调研目标不是这个,就没有深入研究。

使用自定义地图

  首先要有自定义好的地图资源文件放到assets文件夹内,如下:
在这里插入图片描述
然后调用方法如下:

private fun loadMapStyle() {
        // Place the style into the "assets" directory.
        // Full path example: app/src/main/assets/mymapstyle.scene.json
        // Adjust file name and path as appropriate for your project.
        val fileName = "omv/omv-traffic-traffic-normal-night.scene.json"
        val assetManager: AssetManager = assets
        try {
            assetManager.open(fileName)
        } catch (e: IOException) {
            Log.e("CustomMapStylesExample", "Error: Map style not found!")
            return
        }
        mapView!!.mapScene.loadScene(
            "" + fileName
        ) { mapError ->
            if (mapError == null) {
                val distanceInMeters = (1000 * 10).toDouble()
                mapView!!.camera.lookAt(
                    GeoCoordinates(52.530932, 13.384915), distanceInMeters
                )
               
            } else {
                Log.d("CustomMapStylesExample", "onLoadScene failed: $mapError")
            }
        }
    }

效果图如下:

在这里插入图片描述
  大致的使用方法就是这样,其他的几乎类似google地图百度地图等,就不做介绍了,文章内使用到的here的sdk以及自定义的地图资源下载链接考虑到百度网盘可能会丢失,所以放到了csdn上面,需要两积分。
  到此文章结束,有问题欢迎批评指正,觉得不错的也请点个赞,谢谢

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪の星空朝酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值