高德地图选点

This commit is contained in:
lijia 2024-10-31 08:37:33 +08:00
parent 27bb3b8085
commit 9642fe44f0
14 changed files with 615 additions and 9 deletions

View File

@ -35,6 +35,11 @@ android {
vectorDrawables {
useSupportLibrary true
}
// ndk {
// //SO库架构so
// abiFilters "armeabi"
// }
}
buildTypes {
@ -141,7 +146,9 @@ dependencies {
debugImplementation 'androidx.compose.ui:ui-test-manifest'
//
implementation 'com.amap.api:map2d:6.0.0'
implementation 'com.amap.api:3dmap:10.0.600'
implementation 'com.amap.api:search:9.7.0'
implementation project(path: ':mylibrary')
}

View File

@ -78,7 +78,7 @@
android:name="com.amap.api.v2.apikey"
android:value="203d8b896f30ce1e7dd55d7c4a62c362" />
<service android:name="com.amap.api.location.APSService"></service>
<activity
android:name=".ui.LauncherActivity"
android:configChanges="keyboardHidden|orientation|locale"
@ -177,6 +177,12 @@
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|stateHidden" />
<activity
android:name=".ui.address.ChoiceAddressByMapActivity"
android:configChanges="keyboardHidden|orientation|locale"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|stateHidden" />
<activity
android:name=".ui.MarketsActivity"
android:configChanges="keyboardHidden|orientation|locale"

View File

@ -0,0 +1,35 @@
package com.dhsd.glowner.adapter
import android.content.Context
import android.view.ViewGroup
import com.amap.api.services.help.Tip
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.dahe.mylibrary.bean.TipsBean
import com.dhsd.glowner.R
/**
* @ClassName ChoiceAddressAdapter
* @Author john
* @Date 2024/10/30 11:17
* @Description TODO
*/
class ChoiceAddressAdapter : BaseQuickAdapter<Tip, QuickViewHolder>() {
override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: Tip?) {
item?.let {
holder.run {
setText(R.id.tvName, it.name)
setText(R.id.tvAddress, item.district + item.address)
setGone(R.id.view, items.size-1==position)
}
}
}
override fun onCreateViewHolder(
context: Context,
parent: ViewGroup,
viewType: Int
): QuickViewHolder {
return QuickViewHolder(R.layout.item_search_address_pop, parent)
}
}

View File

@ -0,0 +1,32 @@
package com.dhsd.glowner.callback
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeResult
/**
* @ClassName OnMyGeocodeSearchListener
* @Author john
* @Date 2024/10/30 17:00
* @Description TODO
*/
open class OnMyGeocodeSearchListener : GeocodeSearch.OnGeocodeSearchListener {
/**
* 逆地理编码搜索结果回调
* @param result RegeocodeResult
* @param rCode Int
*/
override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) {
}
/**
* 地理编码搜索结果回调
* @param result GeocodeResult
* @param rCode Int
*/
override fun onGeocodeSearched(result: GeocodeResult?, rCode: Int) {
}
}

View File

@ -4,14 +4,17 @@ import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.widget.LinearLayout
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.dahe.gldriver.base.AppConfig
import com.dahe.glex.bean.WayBillBean
import com.dahe.mylibrary.base.BaseActivity
import com.dahe.mylibrary.recycleviewswipe.RecycleViewDivider
import com.dahe.mylibrary.utils.ActivityUtils
import com.dahe.mylibrary.utils.ConvertUtils
import com.dahe.mylibrary.utils.PickerUtils
import com.dahe.mylibrary.utils.ToastUtils
import com.dhsd.glowner.R
import com.dhsd.glowner.adapter.SendGoodsAdapter
import com.dhsd.glowner.databinding.ActivityAddressEditBinding
@ -29,7 +32,9 @@ class AddressEditOrAddActivity : BaseActivity<ActivityAddressEditBinding>(),
private var isAdd:Boolean = true
override fun initView(savedInstanceState: Bundle?) {
setStatusBarColor(R.color.white)
setTitleBar("地址信息", true)
setTitleBar("地址信息", { finish() }, true, "地图选点") {
ActivityUtils.startActivity(mContext,ChoiceAddressByMapActivity::class.java)
}
isAdd = intent.extras?.getBoolean(AppConfig.IS_ADD,true) == true
@ -55,6 +60,13 @@ class AddressEditOrAddActivity : BaseActivity<ActivityAddressEditBinding>(),
tvSSQ.setOnClickListener(OnLimitClickHelper(this@AddressEditOrAddActivity))
tvClear.setOnClickListener { etAddressDetail.setText("") }
btnOk.setOnClickListener(OnLimitClickHelper(this@AddressEditOrAddActivity))
etAddressDetail.addTextChangedListener { text ->
// if (text?.length != 0) {
// val inputquery = InputtipsQuery(text, "")
// val inputTips = Inputtips(this, inputquery)
// }
}
}

View File

@ -0,0 +1,200 @@
package com.dhsd.glowner.ui.address
import android.os.Bundle
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.MapsInitializer
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.CameraPosition
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.Marker
import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.MyLocationStyle
import com.amap.api.services.core.AMapException
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.RegeocodeResult
import com.amap.api.services.help.Inputtips
import com.amap.api.services.help.Inputtips.InputtipsListener
import com.amap.api.services.help.InputtipsQuery
import com.dahe.mylibrary.base.BaseActivity
import com.dhsd.glowner.R
import com.dhsd.glowner.adapter.ChoiceAddressAdapter
import com.dhsd.glowner.callback.OnMyGeocodeSearchListener
import com.dhsd.glowner.databinding.ActivityChoiceAddressByMapBinding
import com.dhsd.glowner.utils.GDLocationUtils
/**
* @ClassName ChoiceAddressByMapActivity
* @Author john
* @Date 2024/10/30 10:38
* @Description 地图选点
*/
class ChoiceAddressByMapActivity : BaseActivity<ActivityChoiceAddressByMapBinding>() {
lateinit var adapter: ChoiceAddressAdapter
var screenMarker: Marker? = null
override fun initView(savedInstanceState: Bundle?) {
setStatusBarColor(R.color.white)
setTitleBar("地图选址", true)
initMap()
binding.run {
mapView.onCreate(savedInstanceState)
adapter = recycler.run {
layoutManager = LinearLayoutManager(mContext, RecyclerView.VERTICAL, false)
adapter = ChoiceAddressAdapter()
adapter as ChoiceAddressAdapter
}.apply {
isStateViewEnable = true
}
etInput.addTextChangedListener {
it.toString().let {
getAddressListByText(it)
}
}
}
}
private lateinit var aMap: AMap
private fun initMap() {
MapsInitializer.updatePrivacyShow(mContext, true, true)
MapsInitializer.updatePrivacyAgree(mContext, true)
aMap = binding.mapView.map
aMap.run {
//定位原点
myLocationStyle = MyLocationStyle().myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW)
uiSettings.isMyLocationButtonEnabled = true
isMyLocationEnabled = true
setOnMyLocationChangeListener {
// 定位回调监听
if (it != null) {
//移动到定位点
animateCamera(
CameraUpdateFactory.newCameraPosition(
CameraPosition(
LatLng(
it.latitude,
it.longitude
), 14f, 0f, 0f
)
)
)
}
}
setOnMapLoadedListener {
//设置Marker在屏幕上,不跟随地图移动
val latLng = aMap.cameraPosition.target
val screenPosition = aMap.projection.toScreenLocation(latLng)
screenMarker = addMarker(
MarkerOptions()
.anchor(0.5f, 0.5f)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.purple_pin))
)
//设置Marker在屏幕上,不跟随地图移动
screenMarker?.setPositionByPixels(screenPosition.x, screenPosition.y)
}
setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
override fun onCameraChange(p0: CameraPosition?) {
}
override fun onCameraChangeFinish(p0: CameraPosition?) {
p0?.let {
//逆地理编码
GDLocationUtils.instance.getAddressByLatLng(
mContext,
LatLonPoint(p0.target.latitude, p0.target.longitude),
object :
OnMyGeocodeSearchListener() {
override fun onRegeocodeSearched(
result: RegeocodeResult?,
rCode: Int
) {
super.onRegeocodeSearched(result, rCode)
if (rCode == AMapException.CODE_AMAP_SUCCESS) {
getAddressListByText(result?.regeocodeAddress?.formatAddress)
}
}
})
}
}
})
}
// CommonPopUtils.getInstance().showCommCenterPop(mContext,"提示","暂未开发,敬请期待"){
//
// }
// GDLocationUtils.instance.getLocation(mContext){
// if (it.errorCode==0){
// aMap.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition(LatLng(it.latitude,it.longitude), 14f,0f,0f)))
// }else{
// showToast("定位失败:"+it.errorInfo)
// }
// }
}
override fun initDate() {
}
override fun onDestroy() {
//在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
binding.mapView.onDestroy()
super.onDestroy()
}
override fun onResume() {
super.onResume()
//在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
binding.mapView.onResume()
}
override fun onPause() {
super.onPause()
//在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
binding.mapView.onPause()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
binding.mapView.onSaveInstanceState(outState)
}
/**
* 根据文字搜索周边信息
* @param text String
*/
private fun getAddressListByText(text: String?) {
if (text == null)
return
val inputquery = InputtipsQuery(text, "")
val inputTips = Inputtips(mContext, inputquery)
inputTips.setInputtipsListener { list, i ->
if (i == AMapException.CODE_AMAP_SUCCESS) { // 正确返回
if (list.size == 0) {
adapter.submitList(null)
adapter.setStateViewLayout(mContext, R.layout.empty_view)
showToast("查询失败")
return@setInputtipsListener
}
adapter.submitList(list)
} else {
adapter.submitList(null)
adapter.setStateViewLayout(mContext, R.layout.empty_view)
showToast("查询失败")
}
}
inputTips.requestInputtipsAsyn()
}
}

View File

@ -2,10 +2,9 @@ package com.dhsd.glowner.ui.waybill.activity
import android.os.Bundle
import android.view.View
import com.amap.api.maps2d.AMap
import com.dahe.gldriver.base.AppConfig
import com.amap.api.maps.AMap
import com.dahe.mylibrary.base.BaseActivity
import com.dahe.mylibrary.utils.ActivityUtils
import com.dahe.mylibrary.utils.ToastUtils
import com.dhsd.glowner.databinding.ActivityWaybillDetailBinding

View File

@ -0,0 +1,192 @@
package com.dhsd.glowner.utils
import android.content.Context
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.maps.CoordinateConverter
import com.amap.api.maps.model.LatLng
import com.amap.api.services.core.AMapException
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.GeocodeSearch.OnGeocodeSearchListener
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import com.dhsd.glowner.callback.OnMyGeocodeSearchListener
import kotlin.math.atan2
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt
class GDLocationUtils private constructor() {
//声明AMapLocationClient类对象
private var mLocationClient: AMapLocationClient? = null;
//声明AMapLocationClientOption对象
private var mLocationOption: AMapLocationClientOption? = null
companion object {
val instance = Holder.holder
}
object Holder {
val holder = GDLocationUtils()
}
fun getLocation(ctx: Context, mLocationListener: AMapLocationListener) {
//初始化定位
mLocationClient = AMapLocationClient(ctx)
//设置定位回调监听
mLocationClient?.setLocationListener(mLocationListener)
//初始化AMapLocationClientOption对象
mLocationOption = AMapLocationClientOption()
/**
* 设置定位场景目前支持三种场景签到出行运动默认无场景
*/
mLocationOption?.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn)
//设置定位模式为AMapLocationMode.Hight_Accuracy高精度模式。
mLocationOption?.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy)
// mLocationOption?.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving)
//获取一次定位结果:
//该方法默认为false。
mLocationOption?.setOnceLocation(true)
//获取最近3s内精度最高的一次定位结果
//设置setOnceLocationLatest(boolean b)接口为true启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为truesetOnceLocation(boolean b)接口也会被设置为true反之不会默认为false。
mLocationOption?.setOnceLocationLatest(true)
//设置是否允许模拟位置,默认为true允许模拟位置
mLocationOption?.setMockEnable(true)
//启动后台定位第一个参数为通知栏ID建议整个APP使用一个
// mLocationClient?.enableBackgroundLocation(1,buildNotification(ctx))
//给定位客户端对象设置定位参数
mLocationClient?.setLocationOption(mLocationOption);
if (null != mLocationClient) {
mLocationClient?.setLocationOption(mLocationOption);
//设置场景模式后最好调用一次stop再调用start以保证场景模式生效
mLocationClient?.stopLocation()
mLocationClient?.startLocation()
}
}
/**
* 通过经纬度获取地址(逆地理编码)
* @param ctx Context
* @param latLng LatLonPoint
* @param listener OnMyGeocodeSearchListener
*/
fun getAddressByLatLng(ctx: Context,latLng: LatLonPoint,listener: OnMyGeocodeSearchListener) {
var geocoderSearch = GeocodeSearch(ctx)
geocoderSearch.setOnGeocodeSearchListener(listener)
val query = RegeocodeQuery(
latLng, 1000f,
GeocodeSearch.AMAP
) // 第一个参数表示一个Latlng第二参数表示范围多少米第三个参数表示是火系坐标系还是GPS原生坐标系
geocoderSearch.getFromLocationAsyn(query) // 设置异步逆地理编码请求
}
/**
* 上传轨迹专用
* @param ctx Context
* @param mLocationListener AMapLocationListener
*/
fun getLocation2(ctx: Context, mLocationListener: AMapLocationListener) {
//初始化定位
mLocationClient = AMapLocationClient(ctx)
//设置定位回调监听
mLocationClient?.setLocationListener(mLocationListener)
//初始化AMapLocationClientOption对象
mLocationOption = AMapLocationClientOption()
/**
* 设置定位场景目前支持三种场景签到出行运动默认无场景
*/
mLocationOption?.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn)
//设置定位模式为AMapLocationMode.Hight_Accuracy高精度模式。
mLocationOption?.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving)
// mLocationOption?.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving)
//获取一次定位结果:
//该方法默认为false。
mLocationOption?.setOnceLocation(true)
//获取最近3s内精度最高的一次定位结果
//设置setOnceLocationLatest(boolean b)接口为true启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为truesetOnceLocation(boolean b)接口也会被设置为true反之不会默认为false。
mLocationOption?.setOnceLocationLatest(true)
//设置是否允许模拟位置,默认为true允许模拟位置
mLocationOption?.setMockEnable(true)
//启动后台定位第一个参数为通知栏ID建议整个APP使用一个
// mLocationClient?.enableBackgroundLocation(
// 1,
// MyNotification.getInstance().getNotification(ctx)
// )
//给定位客户端对象设置定位参数
mLocationClient?.setLocationOption(mLocationOption);
if (null != mLocationClient) {
mLocationClient?.setLocationOption(mLocationOption);
//设置场景模式后最好调用一次stop再调用start以保证场景模式生效
mLocationClient?.stopLocation()
mLocationClient?.startLocation()
}
}
fun convertGPSToBaidu(context: Context, srLatLng: LatLng): LatLng {
val converter = CoordinateConverter(context)
converter.from(CoordinateConverter.CoordType.GPS)
converter.coord(LatLng(srLatLng.latitude, srLatLng.longitude))
val convert = converter.convert()
return LatLng(convert.latitude, convert.longitude)
}
/**
* 高德转百度火星坐标gcj02ll>百度坐标bd09ll
* @param srLatLng LatLng
* @return LatLng
*/
fun gaoDeToBaidu(srLatLng: LatLng): LatLng {
var PI = 3.14159265358979324 * 3000.0 / 180.0;
var x = srLatLng.latitude
var y = srLatLng.longitude
var z = sqrt(x * x + y * y) + 0.00002 * sin(y * PI);
var theta = atan2(y, x) + 0.000003 * cos(x * PI);
return LatLng(z * cos(theta) + 0.0065, z * sin(theta) + 0.006);
}
/**
* 百度转高德百度坐标bd09ll>火星坐标gcj02ll
* @param srLatLng LatLng
* @return LatLng
*/
fun bdToGaoDe(srLatLng: LatLng): LatLng {
var PI = 3.14159265358979324 * 3000.0 / 180.0;
var x = srLatLng.longitude - 0.0065
var y = srLatLng.latitude - 0.006
var z = sqrt(x * x + y * y) - 0.00002 * sin(y * PI);
var theta = atan2(y, x) - 0.000003 * cos(x * PI);
return LatLng(z * cos(theta) + 0.0065, z * sin(theta) + 0.006);
}
fun stopLocation() {
if (null != mLocationClient) {
mLocationClient?.disableBackgroundLocation(true)
mLocationClient?.stopLocation()
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:background="@color/color_F3"
android:orientation="vertical">
<include layout="@layout/common_toolbar"></include>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingLeft="@dimen/dp_15"
android:paddingTop="@dimen/dp_8"
android:paddingRight="@dimen/dp_15"
android:paddingBottom="@dimen/dp_8">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:background="@drawable/shape_gray_bg20"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="@dimen/dp_16"
android:layout_height="@dimen/dp_16"
android:layout_marginLeft="@dimen/dp_10"
android:background="@drawable/search_icon_white"></ImageView>
<AutoCompleteTextView
android:id="@+id/etInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/dp_6"
android:background="#00000000"
android:hint="请输入地址"
android:inputType="text|textAutoComplete"
android:singleLine="true"
android:text=""
android:textColor="@color/black"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
<com.amap.api.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.5" />
</LinearLayout>

View File

@ -16,7 +16,7 @@
<include layout="@layout/common_toolbar"></include>
</RelativeLayout>
<com.amap.api.maps2d.MapView
<com.amap.api.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_200" />

View File

@ -11,7 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_6"
android:background="@drawable/shape_gray_8"
android:background="@drawable/shape_white_8"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/dp_11">
@ -47,7 +47,7 @@
android:layout_height="@dimen/dp_42"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_10"
android:background="@color/color_9" />
android:background="@color/color_c" />
<TextView
android:id="@+id/tvEdit"

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/invoice_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center_vertical"
android:paddingLeft="@dimen/dp_8"
android:orientation="horizontal">
<ImageView
android:layout_width="@dimen/dp_28"
android:layout_height="@dimen/dp_28"
android:background="@drawable/position"
/>
<LinearLayout
android:id="@+id/llContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/dp_12"
android:paddingBottom="@dimen/dp_8">
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_4"
android:layout_marginBottom="@dimen/dp_8"
android:textColor="@color/black"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
tools:text="地址" />
<TextView
android:id="@+id/tvAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp_4"
android:textColor="#ff999999"
android:textSize="@dimen/sp_14"
tools:text="电话" />
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_1"
android:background="@color/color_c"
></View>
</LinearLayout>
</LinearLayout>