集成地图SDK
国内常用的地图SDK就是百度和高德了,二者的用法大同小异,可按照官网上的开发指南一步步来。下面是我在集成地图SDK时遇到的问题说明:
1、点击基本地图功能选项,不能打开地图,弹出“key验证出错!请在AndroidManifest.xml文件中检查key设置的”的红色字提示。查看日志提示“galaxy lib host missing meta-data,make sure you know the right way to integrate galaxy”
该问题是因为key值对应的签名与app打包用的签名不一致。app在开发时与发布时有两个不同的签名,开发时用的是ADT默认签名,查看默认签名的SHA1值可依次选择“Window”->“Preferences”->“Android”->“Build SHA1 fingerprint”。app发布时的签名是密钥文件的签名,查看发布签名的SHA1值可依次选择“File”->“Export”->“Export Android Application”->“Next”后选择密钥文件并输入密码与app输出路径->在“Certificate fingerprints”下查看SHA1值。
2、百度地图SDK3.6及以上版本找不到overlayutil包。
这是因为新版SDK的jar包不再包含这部分源码,得到官方demo的src目录下获取源码加入到开发者自己的工程中,源码路径为:BaiduMap_AndroidMapSDK_v3.7.1_Sample\BaiduMapsApiDemo\src\com\baidu\mapapi
3、在一个工程中同时包含了百度地图和高德地图的sdk,编译时报错“Found duplicate file for APK: assets/lineDashTexture.png”。
这是因为百度和高德的sdk,其jar包存在同名文件“assets/lineDashTexture.png”,所以无法通过编译。即百度sdk与高德sdk是互斥的,不能同时存在于同个工程中,必须分开来使用。
显示地图和定位
对于一个地图SDK来说,首先要显示地图,然后定位到当前城市。
这方面百度地图和高德地图的处理代码差不多,下面是两种地图sdk显示并定位的代码例子:
百度地图
// 以下主要是定位用到的代码
private MapView mMapView;
private BaiduMap mMapLayer;
private LocationClient mLocClient;
private boolean isFirstLoc = true;// 是否首次定位
private void initLocation() {
mMapView = (MapView) findViewById(R.id.bmapView);
// 先隐藏地图,待定位到当前城市时再显示
mMapView.setVisibility(View.INVISIBLE);
mMapLayer = mMapView.getMap();
mMapLayer.setOnMapClickListener(this);
// 开启定位图层
mMapLayer.setMyLocationEnabled(true);
mLocClient = new LocationClient(this);
// 设置定位监听器
mLocClient.registerLocationListener(new MyLocationListenner());
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);// 打开gps
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(1000);
option.setIsNeedAddress(true); // 设置true才能获得详细的地址信息
// 设置定位参数
mLocClient.setLocOption(option);
// 开始定位
mLocClient.start();
//获取最近一次的位置
// mLocClient.getLastKnownLocation();
}
public class MyLocationListenner implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null || mMapView == null) {
Log.d(TAG, "location is null or mMapView is null");
return;
}
m_latitude = location.getLatitude();
m_longitude = location.getLongitude();
String position = String.format("当前位置:%s|%s|%s|%s|%s|%s|%s",
location.getProvince(), location.getCity(),
location.getDistrict(), location.getStreet(),
location.getStreetNumber(), location.getAddrStr(),
location.getTime());
loc_position.setText(position);
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(m_latitude)
.longitude(m_longitude).build();
mMapLayer.setMyLocationData(locData);
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(m_latitude, m_longitude);
MapStatusUpdate update = MapStatusUpdateFactory.newLatLngZoom(ll, 14);
mMapLayer.animateMapStatus(update);
// 定位到当前城市时再显示图层
mMapView.setVisibility(View.VISIBLE);
}
}
public void onReceivePoi(BDLocation poiLocation) {
}
}
高德地图
// 以下主要是定位用到的代码
private MapView mMapView;
private AMap mMapLayer;
private AMapLocationClient mLocClient;
private boolean isFirstLoc = true;// 是否首次定位
private void initLocation(Bundle savedInstanceState) {
mMapView = (MapView) findViewById(R.id.amapView);
mMapView.onCreate(savedInstanceState);
// 先隐藏地图,待定位到当前城市时再显示
mMapView.setVisibility(View.INVISIBLE);
if (mMapLayer == null) {
mMapLayer = mMapView.getMap();
}
mMapLayer.setOnMapClickListener(this);
// 开启定位图层
mMapLayer.setMyLocationEnabled(true);
mMapLayer.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
mLocClient = new AMapLocationClient(this.getApplicationContext());
// 设置定位监听器
mLocClient.setLocationListener(new MyLocationListenner());
AMapLocationClientOption option = new AMapLocationClientOption();
option.setLocationMode(AMapLocationMode.Battery_Saving);
option.setNeedAddress(true); // 设置true才能获得详细的地址信息
// 设置定位参数
mLocClient.setLocationOption(option);
// 开始定位
mLocClient.startLocation();
//获取最近一次的位置
// mLocClient.getLastKnownLocation();
}
public class MyLocationListenner implements AMapLocationListener {
@Override
public void onLocationChanged(AMapLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null || mMapView == null) {
Log.d(TAG, "location is null or mMapView is null");
return;
}
m_latitude = location.getLatitude();
m_longitude = location.getLongitude();
String position = String.format("当前位置:%s|%s|%s|%s|%s|%s|%s",
location.getProvince(), location.getCity(),
location.getDistrict(), location.getStreet(),
location.getAdCode(), location.getAddress(),
location.getTime());
loc_position.setText(position);
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(m_latitude, m_longitude);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, 12);
mMapLayer.moveCamera(update);
// 定位到当前城市时再显示图层
mMapView.setVisibility(View.VISIBLE);
}
}
}
POI搜索
POI即地图注点,它是“Point of Interest”的缩写,在地图上标注地点名称、类别、经度、纬度等信息,是一个带位置信息的地图标注。POI搜索是地图sdk的一个重要应用,根据关键字搜索并在地图上显示POI结果,这是智能出行的基础。
下面是使用百度地图搜索POI的截图:
下面是两种地图sdk进行POI搜索的代码例子:
百度地图
// 以下主要是POI搜索用到的代码
private PoiSearch mPoiSearch = null;
private SuggestionSearch mSuggestionSearch = null;
private AutoCompleteTextView mKey = null;
private EditText mScope = null;
private Button btn_search, btn_nextpage, btn_cleardata;
private ArrayAdapter sugAdapter = null;
private int load_Index = 0;
private void initMap() {
mPoiSearch = PoiSearch.newInstance();
mPoiSearch.setOnGetPoiSearchResultListener(this);
mSuggestionSearch = SuggestionSearch.newInstance();
mSuggestionSearch.setOnGetSuggestionResultListener(this);
mScope = (EditText) findViewById(R.id.poi_city);
mKey = (AutoCompleteTextView) findViewById(R.id.poi_searchkey);
btn_search = (Button) findViewById(R.id.search);
btn_nextpage = (Button) findViewById(R.id.map_next_data);
btn_cleardata = (Button) findViewById(R.id.map_clear_data);
btn_search.setOnClickListener(this);
btn_nextpage.setOnClickListener(this);
btn_cleardata.setOnClickListener(this);
sugAdapter = new ArrayAdapter(this, R.layout.spinner_dropdown_item);
mKey.setAdapter(sugAdapter);
// 当输入关键字变化时,动态更新建议列表
mKey.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
}
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3) {
if (cs.length() <= 0) {
return;
}
String city = mScope.getText().toString();
// 使用建议搜索服务获取建议列表,结果在onGetSuggestionResult中更新
mSuggestionSearch
.requestSuggestion((new SuggestionSearchOption())
.keyword(cs.toString()).city(city));
}
});
}
@Override
public void onGetSuggestionResult(SuggestionResult res) {
if (res == null || res.getAllSuggestions() == null) {
return;
} else {
sugAdapter.clear();
for (SuggestionResult.SuggestionInfo info : res.getAllSuggestions()) {
if (info.key != null) {
sugAdapter.add(info.key);
}
}
sugAdapter.notifyDataSetChanged();
}
}
// 影响搜索按钮点击事件
public void searchButtonProcess(View v) {
Log.d(TAG, "editCity=" + mScope.getText().toString()
+ ", editSearchKey=" + mKey.getText().toString()
+ ", load_Index=" + load_Index);
String keyword = mKey.getText().toString();
if (search_method == SEARCH_CITY) {
String city = mScope.getText().toString();
mPoiSearch.searchInCity((new PoiCitySearchOption()).city(city)
.keyword(keyword).pageNum(load_Index));
} else if (search_method == SEARCH_NEARBY) {
LatLng position = new LatLng(m_latitude, m_longitude);
int radius = Integer.parseInt(mScope.getText().toString());
mPoiSearch.searchNearby((new PoiNearbySearchOption())
.location(position).keyword(keyword).radius(radius)
.pageNum(load_Index));
}
}
public void goToNextPage(View v) {
load_Index++;
searchButtonProcess(null);
}
public void onGetPoiResult(PoiResult result) {
if (result == null
|| result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
Toast.makeText(this, "未找到结果", Toast.LENGTH_LONG).show();
return;
} else if (result.error == SearchResult.ERRORNO.NO_ERROR) {
mMapLayer.clear();
PoiOverlay overlay = new MyPoiOverlay(mMapLayer);
mMapLayer.setOnMarkerClickListener(overlay);
List poiList = result.getAllPoi();
overlay.setData(result);
overlay.addToMap();
overlay.zoomToSpan();
// for (PoiInfo poi : poiList) {
// String detail = String.format(
// "uid=%s,city=%s,name=%s,phone=%s, address=%s", poi.uid,
// poi.city, poi.name, poi.phoneNum, poi.address);
// Log.d(TAG, detail); // 坐标为poi.location(LatLng结构)
// }
} else if (result.error == SearchResult.ERRORNO.AMBIGUOUS_KEYWORD) {
// 当输入关键字在本市没有找到,但在其他城市找到时,返回包含该关键字信息的城市列表
String strInfo = "在";
for (CityInfo cityInfo : result.getSuggestCityList()) {
strInfo += cityInfo.city + ",";
}
strInfo += "找到结果";
Toast.makeText(this, strInfo, Toast.LENGTH_LONG).show();
}
}
public void onGetPoiDetailResult(PoiDetailResult result) {
if (result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
} else {
Log.d(TAG,
"name=" + result.getName() + ",address="
+ result.getAddress() + ",detail_url="
+ result.getDetailUrl() + ",shop_hours="
+ result.getShopHours() + ",telephone="
+ result.getTelephone() + ",price="
+ result.getPrice() + ",type=" + result.getType()
+ ",tag=" + result.getTag());
Toast.makeText(this, result.getName() + ": " + result.getAddress(),
Toast.LENGTH_SHORT).show();
}
}
private class MyPoiOverlay extends PoiOverlay {
public MyPoiOverlay(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public boolean onPoiClick(int index) {
super.onPoiClick(index);
PoiInfo poi = getPoiResult().getAllPoi().get(index);
mPoiSearch.searchPoiDetail((new PoiDetailSearchOption()).poiUid(poi.uid));
return true;
}
}
高德地图
// 以下主要是POI搜索用到的代码
private PoiSearch mPoiSearch = null;
private AutoCompleteTextView mKey = null;
private EditText mScope = null;
private Button btn_search, btn_nextpage, btn_cleardata;
private ArrayAdapter sugAdapter = null;
private int load_Index = 0;
private void initMap() {
mScope = (EditText) findViewById(R.id.poi_city);
mKey = (AutoCompleteTextView) findViewById(R.id.poi_searchkey);
btn_search = (Button) findViewById(R.id.search);
btn_nextpage = (Button) findViewById(R.id.map_next_data);
btn_cleardata = (Button) findViewById(R.id.map_clear_data);
btn_search.setOnClickListener(this);
btn_nextpage.setOnClickListener(this);
btn_cleardata.setOnClickListener(this);
sugAdapter = new ArrayAdapter(this, R.layout.spinner_dropdown_item);
mKey.setAdapter(sugAdapter);
// 当输入关键字变化时,动态更新建议列表
mKey.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
}
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3) {
if (cs.length() <= 0) {
return;
}
String city = mScope.getText().toString();
// 使用建议搜索服务获取建议列表,结果在onGetInputtips中更新
InputtipsQuery inputquery = new InputtipsQuery(cs.toString(), city);
Inputtips inputTips = new Inputtips(GaodeActivity.this, inputquery);
inputTips.setInputtipsListener(GaodeActivity.this);
inputTips.requestInputtipsAsyn();
}
});
}
@Override
public void onGetInputtips(List tipList, int rCode) {
if (rCode != 1000) {
Toast.makeText(this, "推荐文字错误代码是"+rCode, Toast.LENGTH_LONG).show();
} else {
sugAdapter.clear();
for (Tip info : tipList) {
if (info.getName() != null) {
sugAdapter.add(info.getName());
}
}
sugAdapter.notifyDataSetChanged();
}
}
// 影响搜索按钮点击事件
public void searchButtonProcess(View v) {
Log.d(TAG, "editCity=" + mScope.getText().toString()
+ ", editSearchKey=" + mKey.getText().toString()
+ ", load_Index=" + load_Index);
String keyword = mKey.getText().toString();
if (search_method == SEARCH_CITY) {
String city = mScope.getText().toString();
PoiSearch.Query query = new PoiSearch.Query(keyword, null, city);
query.setPageSize(10);
query.setPageNum(load_Index);
mPoiSearch = new PoiSearch(this, query);
mPoiSearch.setOnPoiSearchListener(this);
mPoiSearch.searchPOIAsyn();
} else if (search_method == SEARCH_NEARBY) {
LatLonPoint position = new LatLonPoint(m_latitude, m_longitude);
int radius = Integer.parseInt(mScope.getText().toString());
PoiSearch.Query query = new PoiSearch.Query(keyword, null, "福州");
query.setPageSize(10);
query.setPageNum(load_Index);
mPoiSearch = new PoiSearch(this, query);
SearchBound bound = new SearchBound(position, radius);
mPoiSearch.setBound(bound);
mPoiSearch.setOnPoiSearchListener(this);
mPoiSearch.searchPOIAsyn();
}
}
public void goToNextPage(View v) {
load_Index++;
searchButtonProcess(null);
}
@Override
public void onPoiSearched(PoiResult result, int rCode) {
if (rCode != 1000) {
Toast.makeText(this, "POI错误代码是"+rCode, Toast.LENGTH_LONG).show();
} else if (result == null || result.getQuery() == null) {
Toast.makeText(this, "未找到结果", Toast.LENGTH_LONG).show();
return;
} else {
mMapLayer.clear();
List poiList = result.getPois();
// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息
List suggestionCities = result.getSearchSuggestionCitys();
if (poiList!=null && poiList.size()>0) {
PoiOverlay poiOverlay = new PoiOverlay(mMapLayer, poiList);
//从地图上移除原POI信息
poiOverlay.removeFromMap();
//往地图添加新POI信息
poiOverlay.addToMap();
poiOverlay.zoomToSpan();
//给POI添加监听器。在点击POI时提示POI信息
mMapLayer.setOnMarkerClickListener(new OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
marker.showInfoWindow();
return true;
}
});
// for (PoiItem poi : poiList) {
// String detail = String.format(
// "uid=%s,city=%s,name=%s,phone=%s, address=%s", poi.getPoiId(),
// poi.getCityName(), poi.getTitle(), poi.getTel(), poi.getAdName());
// Log.d(TAG, detail); // 坐标为poi.location(LatLng结构)
// }
} else if (suggestionCities != null && suggestionCities.size() > 0) {
String infomation = "推荐城市\n";
for (int i = 0; i < suggestionCities.size(); i++) {
SuggestionCity city = suggestionCities.get(i);
infomation += "城市名称:" + city.getCityName() + "城市区号:"
+ city.getCityCode() + "城市编码:"
+ city.getAdCode() + "\n";
}
Toast.makeText(this, infomation, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "结果记录数为0", Toast.LENGTH_LONG).show();
}
return;
}
}
@Override
public void onPoiItemSearched(PoiItem paramPoiItem, int paramInt) {
// TODO Auto-generated method stub
}
测距、测面积
测量距离和测量面积是地图sdk的又一个应用,除了在地图上添加标注之外,就是要用到数学的两个公式。
其中测距用的是勾股定理(又名商高定理):勾股定理是一个基本的几何定理:一个直角三角形,两直角边的平方和等于斜边的平方。如果直角三角形两直角边为a和b,斜边为c,那么a*a+b*b=c*c
测面积用的是海伦公式(又名秦九韶公式):海伦公式是利用三角形的三个边长直接求三角形面积的公式,表达式为:S=√p(p-a)(p-b)(p-c)。基于海伦公式,可以推导出根据多边形各边长求多边形面积的公式,即S = 0.5 * ( (x0*y1-x1*y0) + (x1*y2-x2*y1) + ... + (xn*y0-x0*yn) )
两种地图sdk在测量上的数学原理是一样的,只在添加地图标注上有些小差异,下面是使用高德地图进行测量的截图:
下面是两种地图sdk进行测量的代码例子:
百度地图
// 下面是在地图上添加绘图操作
private static int lineColor = 0x55FF0000;
private static int arcColor = 0xbb00FFFF;
private static int textColor = 0x990000FF;
private static int polygonColor = 0x77FFFF00;
private static int radius = 100;
private ArrayList posArray = new ArrayList();
boolean is_polygon = false;
private void addDot(LatLng pos) {
if (is_polygon == true && posArray.size() > 1
&& MapUtil.isInsidePolygon(pos, posArray) == true) {
Log.d(TAG, "isInsidePolygon");
LatLng centerPos = MapUtil.getCenterPos(posArray);
OverlayOptions ooText = new TextOptions().bgColor(0x00ffffff)
.fontSize(26).fontColor(textColor).text("标题")// .rotate(-30)
.position(centerPos);
mMapLayer.addOverlay(ooText);
return;
}
if (is_polygon == true) {
Log.d(TAG, "is_polygon == true");
posArray.clear();
is_polygon = false;
}
boolean is_first = false;
LatLng thisPos = pos;
if (posArray.size() > 0) {
LatLng firstPos = posArray.get(0);
int distance = (int) Math.round(MapUtil.getShortDistance(
thisPos.longitude, thisPos.latitude, firstPos.longitude,
firstPos.latitude));
//多次点击起点,要忽略之
if (posArray.size()==1 && distance<=0) {
return;
} else if (posArray.size() > 1) {
LatLng lastPos = posArray.get(posArray.size()-1);
int lastDistance = (int) Math.round(MapUtil.getShortDistance(
thisPos.longitude, thisPos.latitude, lastPos.longitude,
lastPos.latitude));
//重复响应当前位置的点击,要忽略之
if (lastDistance <= 0) {
return;
}
}
if (distance < radius * 2) {
thisPos = firstPos;
is_first = true;
}
Log.d(TAG, "distance="+distance+", radius="+radius+", is_first="+is_first);
// 画直线
LatLng lastPos = posArray.get(posArray.size() - 1);
List points = new ArrayList();
points.add(lastPos);
points.add(thisPos);
OverlayOptions ooPolyline = new PolylineOptions().width(2)
.color(lineColor).points(points);
mMapLayer.addOverlay(ooPolyline);
// 下面计算两点之间距离
distance = (int) Math.round(MapUtil.getShortDistance(
thisPos.longitude, thisPos.latitude, lastPos.longitude,
lastPos.latitude));
String disText = "";
if (distance > 1000) {
disText = Math.round(distance * 10 / 1000) / 10d + "公里";
} else {
disText = distance + "米";
}
LatLng llText = new LatLng(
(thisPos.latitude + lastPos.latitude) / 2,
(thisPos.longitude + lastPos.longitude) / 2);
OverlayOptions ooText = new TextOptions().bgColor(0x00ffffff)
.fontSize(24).fontColor(textColor).text(disText)// .rotate(-30)
.position(llText);
mMapLayer.addOverlay(ooText);
}
if (is_first != true) {
// 画圆圈
OverlayOptions ooCircle = new CircleOptions().fillColor(lineColor)
.center(thisPos).stroke(new Stroke(2, 0xAAFF0000)).radius(radius);
mMapLayer.addOverlay(ooCircle);
// 画图片标记
BitmapDescriptor bitmapDesc = BitmapDescriptorFactory
.fromResource(R.drawable.icon_geo);
OverlayOptions ooMarker = new MarkerOptions().draggable(false)
.visible(true).icon(bitmapDesc).position(thisPos);
mMapLayer.addOverlay(ooMarker);
mMapLayer.setOnMarkerClickListener(new OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
LatLng markPos = marker.getPosition();
addDot(markPos);
return true;
}
});
} else {
Log.d(TAG, "posArray.size()="+posArray.size());
//可能存在地图与标记同时响应点击事件的情况
if (posArray.size() < 3) {
posArray.clear();
is_polygon = false;
return;
}
// 画多边形
OverlayOptions ooPolygon = new PolygonOptions().points(posArray)
.stroke(new Stroke(1, 0xFF00FF00))
.fillColor(polygonColor);
mMapLayer.addOverlay(ooPolygon);
is_polygon = true;
// 下面计算多边形的面积
LatLng centerPos = MapUtil.getCenterPos(posArray);
double area = Math.round(MapUtil.getArea(posArray));
String areaText = "";
if (area > 1000000) {
areaText = Math.round(area * 100 / 1000000) / 100d + "平方公里";
} else {
areaText = (int) area + "平方米";
}
OverlayOptions ooText = new TextOptions().bgColor(0x00ffffff)
.fontSize(26).fontColor(textColor).text(areaText)// .rotate(-30)
.position(centerPos);
mMapLayer.addOverlay(ooText);
}
posArray.add(thisPos);
if (posArray.size() >= 3) {
// 画弧线
OverlayOptions ooArc = new ArcOptions()
.color(arcColor)
.width(2)
.points(posArray.get(posArray.size() - 1),
posArray.get(posArray.size() - 2),
posArray.get(posArray.size() - 3));
mMapLayer.addOverlay(ooArc);
}
}
@Override
public void onMapClick(LatLng arg0) {
addDot(arg0);
}
@Override
public boolean onMapPoiClick(MapPoi arg0) {
addDot(arg0.getPosition());
return false;
}
高德地图
// 下面是在地图上添加绘图操作
private static int lineColor = 0x55FF0000;
private static int arcColor = 0xbb00FFFF;
private static int textColor = 0x990000FF;
private static int polygonColor = 0x77FFFF00;
private static int radius = 100;
private ArrayList posArray = new ArrayList();
boolean is_polygon = false;
private void addDot(LatLng pos) {
if (is_polygon == true && posArray.size() > 1
&& MapUtil.isInsidePolygon(pos, posArray) == true) {
Log.d(TAG, "isInsidePolygon");
LatLng centerPos = MapUtil.getCenterPos(posArray);
TextOptions ooText = new TextOptions().backgroundColor(0x00ffffff)
.fontSize(26).fontColor(textColor).text("标题")// .rotate(-30)
.position(centerPos);
mMapLayer.addText(ooText);
return;
}
if (is_polygon == true) {
Log.d(TAG, "is_polygon == true");
posArray.clear();
is_polygon = false;
}
boolean is_first = false;
LatLng thisPos = pos;
if (posArray.size() > 0) {
LatLng firstPos = posArray.get(0);
int distance = (int) Math.round(MapUtil.getShortDistance(
thisPos.longitude, thisPos.latitude, firstPos.longitude,
firstPos.latitude));
//多次点击起点,要忽略之
if (posArray.size()==1 && distance<=0) {
return;
} else if (posArray.size() > 1) {
LatLng lastPos = posArray.get(posArray.size()-1);
int lastDistance = (int) Math.round(MapUtil.getShortDistance(
thisPos.longitude, thisPos.latitude, lastPos.longitude,
lastPos.latitude));
//重复响应当前位置的点击,要忽略之
if (lastDistance <= 0) {
return;
}
}
if (distance < radius * 2) {
thisPos = firstPos;
is_first = true;
}
Log.d(TAG, "distance="+distance+", radius="+radius+", is_first="+is_first);
// 画直线
LatLng lastPos = posArray.get(posArray.size() - 1);
List points = new ArrayList();
points.add(lastPos);
points.add(thisPos);
PolylineOptions ooPolyline = new PolylineOptions().width(2)
.color(lineColor).addAll(points);
mMapLayer.addPolyline(ooPolyline);
// 下面计算两点之间距离
distance = (int) Math.round(MapUtil.getShortDistance(
thisPos.longitude, thisPos.latitude, lastPos.longitude,
lastPos.latitude));
String disText = "";
if (distance > 1000) {
disText = Math.round(distance * 10 / 1000) / 10d + "公里";
} else {
disText = distance + "米";
}
LatLng llText = new LatLng(
(thisPos.latitude + lastPos.latitude) / 2,
(thisPos.longitude + lastPos.longitude) / 2);
TextOptions ooText = new TextOptions().backgroundColor(0x00ffffff)
.fontSize(24).fontColor(textColor).text(disText)// .rotate(-30)
.position(llText);
mMapLayer.addText(ooText);
}
if (is_first != true) {
// 画圆圈
CircleOptions ooCircle = new CircleOptions().fillColor(lineColor)
.center(thisPos).strokeWidth(2).strokeColor(0xAAFF0000).radius(radius);
mMapLayer.addCircle(ooCircle);
// 画图片标记
BitmapDescriptor bitmapDesc = BitmapDescriptorFactory
.fromResource(R.drawable.icon_geo);
MarkerOptions ooMarker = new MarkerOptions().draggable(false)
.visible(true).icon(bitmapDesc).position(thisPos);
mMapLayer.addMarker(ooMarker);
mMapLayer.setOnMarkerClickListener(new OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
LatLng markPos = marker.getPosition();
addDot(markPos);
marker.showInfoWindow();
return true;
}
});
} else {
Log.d(TAG, "posArray.size()="+posArray.size());
//可能存在地图与标记同时响应点击事件的情况
if (posArray.size() < 3) {
posArray.clear();
is_polygon = false;
return;
}
// 画多边形
PolygonOptions ooPolygon = new PolygonOptions().addAll(posArray)
.strokeColor(0xFF00FF00).strokeWidth(1)
.fillColor(polygonColor);
mMapLayer.addPolygon(ooPolygon);
is_polygon = true;
// 下面计算多边形的面积
LatLng centerPos = MapUtil.getCenterPos(posArray);
double area = Math.round(MapUtil.getArea(posArray));
String areaText = "";
if (area > 1000000) {
areaText = Math.round(area * 100 / 1000000) / 100d + "平方公里";
} else {
areaText = (int) area + "平方米";
}
TextOptions ooText = new TextOptions().backgroundColor(0x00ffffff)
.fontSize(26).fontColor(textColor).text(areaText)// .rotate(-30)
.position(centerPos);
mMapLayer.addText(ooText);
}
posArray.add(thisPos);
if (posArray.size() >= 3) {
// 画弧线
ArcOptions ooArc = new ArcOptions()
.strokeColor(arcColor)
.strokeWidth(2)
.point(posArray.get(posArray.size() - 1),
posArray.get(posArray.size() - 2),
posArray.get(posArray.size() - 3));
mMapLayer.addArc(ooArc);
}
}
@Override
public void onMapClick(LatLng arg0) {
addDot(arg0);
}
点此查看Android开发笔记的完整目录