关键字检索位置信息
收到关键字检索位置的的需求,Google之后,发现可以用到google_maps_webservice
这个插件。
先上效果,实现之后可以在输入关键字的时候实时的去检索关键字匹配到的相关位置:
1598407388211995.gif具体实现:
在pubspec.yaml
导入要使用的类库
# google_maps_webservice
google_maps_webservice: ^0.0.16
1、对原始页面分析:
WX20200826-102129.png问题1:
红色部分属于独立的widget:kyc_address_widget
,我需要在这个组件中对其中蓝色的部分做处理,蓝色部分为通用输入框组件InputWidget
不宜做改造,否则影响该组件的通用性和稳定性。
分析之后得出的结论是做新的组件kyc_area_select_widget
包裹inputWidget
,放在原来InputWidget
的位置,检索的所有逻辑和搜索结果在新的组件中完成,对原始外层红色和内层蓝色组件不做变动。
问题2:
WX20200826-115517.png在不修改原始组件InputWidget
的情况下要做到搜索结果外层的边框和原始的边框重合
最简单的做法 就是用Stack
组件,把检索结果和搜索框重叠放置且顶部对齐,检索结果页面paddingTop
出InputWidget
的高度和间距即可。
UI的问题就这两处,有了解决方案之后很快就可以实现效果,具体逻辑在类kyc_area_select_widget.dart
中,不贴代码了,只说一下思路。
2、google_maps_webservice:
导入import 'package:google_maps_webservice/places.dart';
初始化对象,传入对应的Key(该key为注册google服务的唯一ID):
final GoogleMapsPlaces places = GoogleMapsPlaces(apiKey: Constants.googleMapSearchKey);
需要注意的地方,很关键:
final String sessionToken = Uuid().v4();
生成一个唯一的字符串作为当次检索的token,google在看到相同的token会合并检索为一次会话单次收费。否则,每次在输入的时候,检索一次会单独收费,这点及其关键。当然,不差钱当我没说。
下面就是googleMap 海量的Api,需要自己找到对应的来使用,google_maps_webservice
这个库中,没有对应的api说明,需要自己去googleMap的官网去查找(https://developers.google.com/places/web-service/overview)
google_maps_webservice
的api是属于map中的Places API
所以直接查看这个分支即可(https://developers.google.com/places/web-service/search#find-place-examples
):
textsearch:
刚看到api的时候天然的认为是通过文本去搜索结果,果断采用了该接口:
https://maps.googleapis.com/maps/api/place/textsearch/output?parameters
但是出现两个问题:
问题1:
因为要限制区域在香港,不在内的关键字应该无法检出出来,根据API的描述
`region`—地区代码,指定为 [ccTLD](https://en.wikipedia.org/wiki/CcTLD) (国家代码顶级域)两个字符的值。除了某些例外,大多数ccTLD代码与ISO 3166-1代码相同。此参数将仅影响而不是完全限制搜索结果。如果在指定区域之外还存在其他相关结果,则可以将其包括在内。使用此参数时,`formatted_address`指定区域中结果的结果中将省略国家/地区名称 。
`location`—用来检索位置信息的纬度/经度。必须将其指定为 *纬度*,*经度*。如果指定`location` 参数,则还必须指定`radius`参数。
`radius`—定义偏差放置结果的距离(以米为单位)。允许的最大半径为50000米。该区域内的结果将比搜索圈外的结果排名更高;但是,可以包括来自搜索半径之外的突出结果。
分别使用的 region
、location
+radius
两种方式 来限定范围,但是在说明中,都明确说明了,关键字如果匹配到更加合适的位置,即使不在限定好的位置中也会检索出来无法满需求。比如:通过 region
传入HK的代码,或者HK的经纬度+半径10km。然后检索上地地铁站
直接就返回了北京上地地铁站
。所以这个api是无法满足需求。
问题2:
这个API适合检索明确的文本,比如要检索abc
,就直接输入abc
之后再去请求,不应该在输入的时候根据文本变化直接请求a
、ab
、abc
,这样会发生三次请求,生成三次费用,针对目前的场景不适合。
autocomplete:
查询之后发现另外一个API可以满足需求
https://maps.googleapis.com/maps/api/place/autocomplete/output?parameters
从API的可选参数中,可以看到:
`sessiontoken`—一个随机字符串,标识用于计费的自动完成[会话](https://developers.google.com/places/web-service/autocomplete#session_tokens)。如果自动完成请求中省略了此参数,则该请求将独立计费。有关详细信息,请参见 [定价表](https://cloud.google.com/maps-platform/pricing/sheet/)。
`components` —您希望将结果限制到的一组位置。目前,您最多可以使用 components过滤5个国家/地区。国家/地区必须以与ISO 3166-1 Alpha-2兼容的两个字符的国家/地区代码形式传递。例如: components=country:fr将您的结果限制在法国境内。必须使用多个country:XX过滤器传递多个国家/地区,并使用竖线字符(|)作为分隔符。例如: components=country:us|country:pr|country:vi|country:gu|country:mp 将您的搜索结果限制在美国及其未合并的有组织领土内。
通过这两个可选参数,就完美的契合了项目的需求。合并了收费、规定了范围。
记录一下,这次需求开发的心得。加深记忆。
网友评论