map_demo_page.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. import 'dart:convert';
  2. import 'package:amap_flutter_base/amap_flutter_base.dart';
  3. import 'package:amap_flutter_map/amap_flutter_map.dart';
  4. import 'package:bbyyy/beans/address_bean_entity.dart';
  5. import 'package:bbyyy/beans/poi_bean_entity.dart';
  6. import 'package:bbyyy/my_tools/my_colors.dart';
  7. import 'package:bbyyy/my_tools/my_cookie.dart';
  8. import 'package:bbyyy/my_tools/my_tools.dart';
  9. import 'package:bbyyy/my_tools/my_views.dart';
  10. import 'package:dio/dio.dart';
  11. import 'package:flutter/cupertino.dart';
  12. import 'package:flutter/material.dart';
  13. class MapDemoPage extends StatefulWidget {
  14. @override
  15. _MapDemoPageState createState() => _MapDemoPageState();
  16. }
  17. class _MapDemoPageState extends State<MapDemoPage> {
  18. CameraPosition _kInitialPosition;
  19. List<Widget> _approvalNumberWidget = [];
  20. TextEditingController _controller = TextEditingController();
  21. Map<String, Marker> _markers = <String, Marker>{};
  22. Widget _poiInfo;
  23. List<PoiBeanPois> pois;
  24. BitmapDescriptor _markerIcon;
  25. PoiBeanPois poi;
  26. bool searchMode = true;
  27. @override
  28. void initState() {
  29. // TODO: implement initState
  30. super.initState();
  31. _kInitialPosition = CameraPosition(
  32. target:
  33. LatLng(MyCookie().location.latitude, MyCookie().location.longitude),
  34. zoom: 15.0,
  35. );
  36. }
  37. @override
  38. Widget build(BuildContext context) {
  39. if (null == _markerIcon) {
  40. _markerIcon = BitmapDescriptor.defaultMarker;
  41. }
  42. final AMapWidget map = AMapWidget(
  43. initialCameraPosition: _kInitialPosition,
  44. onMapCreated: onMapCreated,
  45. rotateGesturesEnabled: false,
  46. touchPoiEnabled: true,
  47. tiltGesturesEnabled: false,
  48. onPoiTouched: _onPoiTouched,
  49. myLocationStyleOptions: MyLocationStyleOptions(
  50. true,
  51. ),
  52. markers: Set<Marker>.of(_markers.values),
  53. onTap: (LatLng latLng){
  54. print('================|${latLng.latitude},${latLng.longitude}|===================');
  55. markTheClickLocation(latLng);
  56. },
  57. );
  58. return Scaffold(
  59. body: Column(
  60. children: [
  61. MyViews().myAppBar('选择地址', context, [
  62. GestureDetector(
  63. onTap: (){
  64. setState(() {
  65. _markers.clear();
  66. pois?.clear();
  67. poi = null;
  68. searchMode = !searchMode;
  69. _mapController.moveCamera(CameraUpdate.newCameraPosition(CameraPosition(
  70. target: LatLng(MyCookie().location.latitude, MyCookie().location.longitude),
  71. zoom: 15,
  72. )));
  73. });
  74. },
  75. behavior: HitTestBehavior.translucent,
  76. child: Container(
  77. margin: EdgeInsets.symmetric(vertical: 5,horizontal: 10),
  78. child: Text(
  79. searchMode?'手动选择':'搜索选择',
  80. style: TextStyle(color: MyColors.c333333, fontSize: 14),
  81. ),
  82. ),
  83. )
  84. ]),
  85. Expanded(
  86. child: Stack(
  87. children: [
  88. Container(
  89. height: MediaQuery.of(context).size.height,
  90. width: MediaQuery.of(context).size.width,
  91. child: map,
  92. ),
  93. if(searchMode)
  94. Container(
  95. child: Row(
  96. children: [
  97. Expanded(
  98. child: Padding(
  99. padding: EdgeInsets.symmetric(horizontal: 10),
  100. child: TextField(
  101. controller: _controller,
  102. cursorColor: MyColors.cFF4233,
  103. cursorWidth: 1.0,
  104. decoration: InputDecoration(
  105. border: InputBorder.none,
  106. disabledBorder: InputBorder.none,
  107. enabledBorder: InputBorder.none,
  108. focusedBorder: InputBorder.none,
  109. hintText: '请输入地址',
  110. hintStyle: TextStyle(
  111. color: MyColors.c999999, fontSize: 16),
  112. isDense: true,
  113. contentPadding:
  114. const EdgeInsets.fromLTRB(14, 4.5, 8, 4.5)),
  115. maxLines: 1, style: TextStyle(
  116. color: MyColors.c333333,
  117. fontSize: 16,
  118. height: 1.3,
  119. letterSpacing: 0.2),
  120. onChanged: (t) {},
  121. ),
  122. ),
  123. ),
  124. GestureDetector(
  125. onTap: () {
  126. MyTools().hideKeyboard(context);
  127. inquirePOI();
  128. },
  129. child: Container(
  130. color: MyColors.cFF4233,
  131. child: Text(
  132. '搜索',
  133. style: TextStyle(color: Colors.white, fontSize: 18),
  134. ),
  135. width: 100,
  136. height: 48,
  137. alignment: Alignment.center,
  138. ),
  139. ),
  140. ],
  141. ),
  142. color: Colors.white,
  143. margin: EdgeInsets.symmetric(horizontal: 15, vertical: 30),
  144. ),
  145. if (poi != null)
  146. Container(
  147. margin: EdgeInsets.fromLTRB(
  148. 12,
  149. MediaQuery.of(context).size.height - 200 - 12 - 45,
  150. 12,
  151. 12),
  152. width: double.infinity,
  153. height: 150,
  154. decoration: BoxDecoration(
  155. color: Colors.white,
  156. borderRadius: BorderRadius.circular(12),
  157. boxShadow: [
  158. BoxShadow(
  159. color: MyColors.c7FE1E1E1,
  160. blurRadius: 5.0,
  161. ),
  162. ]),
  163. child: Column(
  164. children: [
  165. Text(poi == null ? '' : poi.name),
  166. Text(poi == null ? '' : poi.address),
  167. GestureDetector(
  168. onTap: () {
  169. Navigator.pop(context, poi);
  170. },
  171. behavior: HitTestBehavior.translucent,
  172. child: Container(
  173. decoration: BoxDecoration(
  174. color: MyColors.cFF4233,
  175. borderRadius: BorderRadius.circular(20)),
  176. height: 40,
  177. width: 120,
  178. child: Text(
  179. '就是这里',
  180. style:
  181. TextStyle(color: Colors.white, fontSize: 16),
  182. ),
  183. alignment: Alignment.center,
  184. ),
  185. )
  186. ],
  187. mainAxisAlignment: MainAxisAlignment.spaceAround,
  188. ),
  189. )
  190. ],
  191. ),
  192. ),
  193. ],
  194. ),
  195. resizeToAvoidBottomInset: false,
  196. );
  197. }
  198. AMapController _mapController;
  199. void onMapCreated(AMapController controller) {
  200. setState(() {
  201. _mapController = controller;
  202. getApprovalNumber();
  203. });
  204. }
  205. /// 获取审图号
  206. void getApprovalNumber() async {
  207. //普通地图审图号
  208. String mapContentApprovalNumber =
  209. await _mapController?.getMapContentApprovalNumber();
  210. //卫星地图审图号
  211. String satelliteImageApprovalNumber =
  212. await _mapController?.getSatelliteImageApprovalNumber();
  213. setState(() {
  214. if (null != mapContentApprovalNumber) {
  215. _approvalNumberWidget.add(Text(mapContentApprovalNumber));
  216. }
  217. if (null != satelliteImageApprovalNumber) {
  218. _approvalNumberWidget.add(Text(satelliteImageApprovalNumber));
  219. }
  220. });
  221. print('地图审图号(普通地图): $mapContentApprovalNumber');
  222. print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
  223. }
  224. Widget showPoiInfo(AMapPoi poi) {
  225. return Container(
  226. alignment: Alignment.center,
  227. color: Color(0x8200CCFF),
  228. child: Text(
  229. '您点击了 ${poi.name}',
  230. style: TextStyle(fontWeight: FontWeight.w600),
  231. ),
  232. );
  233. }
  234. void _onPoiTouched(AMapPoi poi) {
  235. print('_onPoiTouched');
  236. print('================|${poi.latLng.latitude},${poi.latLng.longitude}|===================');
  237. markTheClickLocation(poi.latLng);
  238. }
  239. void inquirePOI() {
  240. String v1 =
  241. 'https://restapi.amap.com/v3/place/text?keywords=${_controller.text.toString()}&city=${MyCookie().location.city}&output=json&offset=25&page=1&key=5dcd9f0ed7d51aefb5b2f73dba1069cb&extensions=all';
  242. print(v1);
  243. Dio().get(v1).then((value) {
  244. print(value);
  245. PoiBeanEntity entity =
  246. PoiBeanEntity.fromJson(json.decode(value.toString()));
  247. pois = entity.pois;
  248. entity.pois.forEach((element) {
  249. print(element.name);
  250. _markers[element.id] = Marker(
  251. position: LatLng(double.parse(element.location.split(',')[1]),
  252. double.parse(element.location.split(',')[0])),
  253. icon: _markerIcon,
  254. infoWindow: InfoWindow(title: element.name),
  255. onTap: (markerId) {
  256. print(markerId);
  257. // MapUtil.gotoAMap(double.parse(element.location.split(',')[0]),
  258. // double.parse(element.location.split(',')[1]));
  259. setState(() {
  260. poi = element;
  261. });
  262. },
  263. );
  264. });
  265. setState(() {
  266. if (entity.pois.length != 0) {
  267. showBottomSheet();
  268. _mapController
  269. .moveCamera(CameraUpdate.newCameraPosition(CameraPosition(
  270. target: LatLng(double.parse(entity.pois[0].location.split(',')[1]),
  271. double.parse(entity.pois[0].location.split(',')[0])),
  272. zoom: 18,
  273. )));
  274. } else {
  275. showToast('未搜索到你查找的地点');
  276. }
  277. });
  278. });
  279. }
  280. //显示底部弹框的功能
  281. void showBottomSheet() {
  282. //用于在底部打开弹框的效果
  283. showModalBottomSheet(
  284. builder: (BuildContext context) {
  285. //构建弹框中的内容
  286. return Container(
  287. child: ListView.builder(
  288. padding: EdgeInsets.all(8),
  289. itemBuilder: (BuildContext context, int index) {
  290. return GestureDetector(
  291. onTap: () {
  292. _mapController.moveCamera(
  293. CameraUpdate.newCameraPosition(CameraPosition(
  294. target: LatLng(
  295. double.parse(pois[index].location.split(',')[1]),
  296. double.parse(pois[index].location.split(',')[0])),
  297. zoom: 15,
  298. )));
  299. Navigator.pop(context);
  300. setState(() {
  301. poi = pois[index];
  302. });
  303. },
  304. behavior: HitTestBehavior.translucent,
  305. child: Column(
  306. children: [
  307. Text(
  308. pois[index].name,
  309. style: TextStyle(fontSize: 16),
  310. ),
  311. Text(
  312. pois[index].address,
  313. style: TextStyle(fontSize: 12),
  314. ),
  315. Container(
  316. height: .5,
  317. color: Colors.grey[200],
  318. margin: EdgeInsets.symmetric(vertical: 10),
  319. )
  320. ],
  321. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  322. crossAxisAlignment: CrossAxisAlignment.start,
  323. ),
  324. );
  325. },
  326. itemCount: pois.length,
  327. ),
  328. );
  329. },
  330. context: context);
  331. }
  332. void markTheClickLocation(LatLng latLng) {
  333. print('https://restapi.amap.com/v3/geocode/regeo?output=json&location=${latLng.longitude},${latLng.latitude}&key=5dcd9f0ed7d51aefb5b2f73dba1069cb&radius=10&extensions=all');
  334. Dio()
  335. .get(
  336. 'https://restapi.amap.com/v3/geocode/regeo?output=json&location=${latLng.longitude},${latLng.latitude}&key=5dcd9f0ed7d51aefb5b2f73dba1069cb&radius=10&extensions=all')
  337. .then((value) {
  338. // print('value.toString()------------${value.toString()}');
  339. AddressBeanEntity addressBeanEntity =
  340. AddressBeanEntity.fromJson(json.decode(value.toString()));
  341. poi = PoiBeanPois();
  342. poi.location = '${latLng.longitude},${latLng.latitude}';
  343. poi.pname = addressBeanEntity.regeocode.addressComponent.province;
  344. poi.cityname = addressBeanEntity.regeocode.addressComponent.city;
  345. poi.adname = addressBeanEntity.regeocode.addressComponent.district;
  346. poi.address = addressBeanEntity.regeocode.pois[0].address;
  347. poi.name = addressBeanEntity.regeocode.pois[0].name;
  348. _markers['手动选择'] = Marker(
  349. position: latLng,
  350. icon: _markerIcon,
  351. infoWindow: InfoWindow(title: poi.name),
  352. );
  353. _mapController.moveCamera(CameraUpdate.newCameraPosition(CameraPosition(
  354. target: latLng,
  355. zoom: 20,
  356. )));
  357. setState(() {
  358. });
  359. });
  360. }
  361. }