diff --git a/app/build.gradle b/app/build.gradle index 8c6ec01..43e6a1a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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') } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1fc5a5d..967a2c6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -78,7 +78,7 @@ android:name="com.amap.api.v2.apikey" android:value="203d8b896f30ce1e7dd55d7c4a62c362" /> - + + + () { + 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dhsd/glowner/callback/OnMyGeocodeSearchListener.kt b/app/src/main/java/com/dhsd/glowner/callback/OnMyGeocodeSearchListener.kt new file mode 100644 index 0000000..938cf25 --- /dev/null +++ b/app/src/main/java/com/dhsd/glowner/callback/OnMyGeocodeSearchListener.kt @@ -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) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dhsd/glowner/ui/address/AddressEditOrAddActivity.kt b/app/src/main/java/com/dhsd/glowner/ui/address/AddressEditOrAddActivity.kt index 551cc57..1cddf7d 100644 --- a/app/src/main/java/com/dhsd/glowner/ui/address/AddressEditOrAddActivity.kt +++ b/app/src/main/java/com/dhsd/glowner/ui/address/AddressEditOrAddActivity.kt @@ -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(), 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(), 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) +// } + } } diff --git a/app/src/main/java/com/dhsd/glowner/ui/address/ChoiceAddressByMapActivity.kt b/app/src/main/java/com/dhsd/glowner/ui/address/ChoiceAddressByMapActivity.kt new file mode 100644 index 0000000..697c998 --- /dev/null +++ b/app/src/main/java/com/dhsd/glowner/ui/address/ChoiceAddressByMapActivity.kt @@ -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() { + + 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() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/dhsd/glowner/ui/waybill/activity/WaybillLDetailActivity.kt b/app/src/main/java/com/dhsd/glowner/ui/waybill/activity/WaybillLDetailActivity.kt index 34e684e..37a329d 100644 --- a/app/src/main/java/com/dhsd/glowner/ui/waybill/activity/WaybillLDetailActivity.kt +++ b/app/src/main/java/com/dhsd/glowner/ui/waybill/activity/WaybillLDetailActivity.kt @@ -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 diff --git a/app/src/main/java/com/dhsd/glowner/utils/GDLocationUtils.kt b/app/src/main/java/com/dhsd/glowner/utils/GDLocationUtils.kt new file mode 100644 index 0000000..a09a1c9 --- /dev/null +++ b/app/src/main/java/com/dhsd/glowner/utils/GDLocationUtils.kt @@ -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内精度最高的一次定位结果。如果设置其为true,setOnceLocation(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内精度最高的一次定位结果。如果设置其为true,setOnceLocation(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() + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-xxhdpi/position.png b/app/src/main/res/drawable-xxhdpi/position.png new file mode 100644 index 0000000..00408ec Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/position.png differ diff --git a/app/src/main/res/drawable-xxhdpi/purple_pin.png b/app/src/main/res/drawable-xxhdpi/purple_pin.png new file mode 100644 index 0000000..605de36 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/purple_pin.png differ diff --git a/app/src/main/res/layout/activity_choice_address_by_map.xml b/app/src/main/res/layout/activity_choice_address_by_map.xml new file mode 100644 index 0000000..d3f2061 --- /dev/null +++ b/app/src/main/res/layout/activity_choice_address_by_map.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_waybill_detail.xml b/app/src/main/res/layout/activity_waybill_detail.xml index 0a00293..d385759 100644 --- a/app/src/main/res/layout/activity_waybill_detail.xml +++ b/app/src/main/res/layout/activity_waybill_detail.xml @@ -16,7 +16,7 @@ - diff --git a/app/src/main/res/layout/item_address.xml b/app/src/main/res/layout/item_address.xml index d41bd57..311df66 100644 --- a/app/src/main/res/layout/item_address.xml +++ b/app/src/main/res/layout/item_address.xml @@ -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" /> + + + + + + + + + + + + + + + + \ No newline at end of file