- Android app中查看位置,当位置没有具体地址,而是一个区镇的时候,一直没想好怎么处理。知道仔细看了一遍高德地图的官方文档,看到有行政区域这个功能,我们可以通过
DistrictSearch
类来发起一个异步的区域查询,之后在回调中处理返回的边界数据,我们可以通过画线的方式,将边界点依次连接起来,就圈出了某个行政区域,边界数据很多,需要在子线程中处理。查询的参数设置需要用到DistrictSearchQuery
类,并设置需要边界数据。需要注意的是:高德地图可以搜索的区域等级是五级:分别是国家、省、市、区、街道,到了街道之后,是没有返回边界数据的,无法实现街道的区域标识 - 具体做法如下:
第一步:初始化区域搜索,并设置回调监听
//初始化区域搜索
districtSearch = new DistrictSearch(getApplicationContext());
districtSearch.setOnDistrictSearchListener(this);//绑定监听器;
第二步:初始化区域搜索参数
//获取行政区划边界--最多只能到街道,而街道是没有边界数据的,所以不能使用街道,需要使用区
String keyword;
if (!TextUtils.isEmpty(fromLocation.county.name)) {
keyword = fromLocation.county.name;
fromQuery = new DistrictSearchQuery();
//設置關鍵字
fromQuery.setKeywords(keyword);
//設置是否返回邊界值
fromQuery.setShowBoundary(true);
//不显示子区域边界
fromQuery.setShowChild(false);
districtSearch.setQuery(fromQuery);
//开启异步搜索
districtSearch.searchDistrictAsyn();
}
第三步:在
//行政区划异步搜索的回调
@Override
public void onDistrictSearched(DistrictResult districtResult) {}
处理回调结果
if (districtResult != null && districtResult.getDistrict() != null) {
if (districtResult.getAMapException().getErrorCode() == AMapException.CODE_AMAP_SUCCESS) {
ArrayList<DistrictItem> district = districtResult.getDistrict();
if (district != null && district.size() > 0) {
//adcode 440106
//获取对应的行政区划的item
DistrictItem districtItem = getDistrictItem(district, fromLocation.county.getId());
if (districtItem == null) {
return;
}
utils.logD("---------------------------------preview------------------2");
//创建划线子线程
fromRunnable = new PolygonRunnable(districtItem, handler);
//线程池执行
ThreadWorker.execute(fromRunnable);
}
}
}
Runnable代码
private class PolygonRunnable implements Runnable {
private DistrictItem districtItem;
private Handler handler;
private boolean isCancel = false;
/**
* districtBoundary()
* 以字符串数组形式返回行政区划边界值。
* 字符串拆分规则: 经纬度,经度和纬度之间用","分隔,坐标点之间用";"分隔。
* 例如:116.076498,40.115153;116.076603,40.115071;116.076333,40.115257;116.076498,40.115153。
* 字符串数组由来: 如果行政区包括的是群岛,则坐标点是各个岛屿的边界,各个岛屿之间的经纬度使用"|"分隔。
* 一个字符串数组可包含多个封闭区域,一个字符串表示一个封闭区域
*/
public PolygonRunnable(DistrictItem districtItem, Handler handler) {
this.districtItem = districtItem;
this.handler = handler;
}
public void cancel() {
isCancel = true;
}
/**
* Starts executing the active part of the class' code. This method is
* called when a thread is started that has been created with a class which
* implements {@code Runnable}.
*/
@Override
public void run() {
utils.logD("---------------------------------preview------------------5");
if (!isCancel) {
try {
String[] boundary = districtItem.districtBoundary();
if (boundary != null && boundary.length > 0) {
utils.logD("---------------------------------preview------------------11");
utils.logD("----------- " + boundary.toString());
for (String b : boundary) {
if (!b.contains("|")) {
String[] split = b.split(";");
PolylineOptions polylineOptions = new PolylineOptions();
boolean isFirst = true;
LatLng firstLatLng = null;
for (String s : split) {
String[] ll = s.split(",");
if (isFirst) {
isFirst = false;
firstLatLng = new LatLng(Double.parseDouble(ll[1]), Double.parseDouble(ll[0]));
}
polylineOptions.add(new LatLng(Double.parseDouble(ll[1]), Double.parseDouble(ll[0])));
}
if (firstLatLng != null) {
polylineOptions.add(firstLatLng);
}
utils.logD("---------------------------------preview------------------6");
polylineOptions.width(10).color(Color.BLUE).setDottedLine(true);
Message message = handler.obtainMessage();
message.what = 18;
message.obj = polylineOptions;
handler.sendMessage(message);
}
}
}
} catch (Exception e) {
e.printStackTrace();
utils.logD("---------------------------------preview------------------7");
}
}
}
}
第四步:主线程在地图上添加边界线
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
if (18 == msg.what) {
PolylineOptions options = (PolylineOptions) msg.obj;
aMap.addPolyline(options);
}
}
};
感谢!努力!