package com.partynetwork.iparty.map;
import java.util.List;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.view.animation.Interpolator;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SlidingDrawer;
import android.widget.TextView;
import android.widget.SlidingDrawer.OnDrawerCloseListener;
import android.widget.SlidingDrawer.OnDrawerOpenListener;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.LocationManagerProxy;
import com.amap.api.location.LocationProviderProxy;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMap.InfoWindowAdapter;
import com.amap.api.maps.AMap.OnInfoWindowClickListener;
import com.amap.api.maps.AMap.OnMapLongClickListener;
import com.amap.api.maps.AMap.OnMarkerClickListener;
import com.amap.api.maps.AMap.OnMarkerDragListener;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.Projection;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
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.maps.overlay.PoiOverlay;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.core.SuggestionCity;
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.amap.api.services.poisearch.Cinema;
import com.amap.api.services.poisearch.Dining;
import com.amap.api.services.poisearch.Hotel;
import com.amap.api.services.poisearch.PoiItemDetail;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.poisearch.Scenic;
import com.amap.api.services.poisearch.PoiSearch.OnPoiSearchListener;
import com.amap.api.services.poisearch.PoiSearch.SearchBound;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.lidroid.xutils.view.annotation.event.OnClick;
import com.partynetwork.dataprovider.util.AMapUtil;
import com.partynetwork.dataprovider.util.Util;
import com.partynetwork.iparty.R;
import com.partynetwork.iparty.find.FindItemAdapter;
/**
* AMapV2地图中介绍如何使用mapview显示地图
*/
public class BasicMapActivity extends Activity implements LocationSource,
AMapLocationListener, OnMarkerDragListener, OnMarkerClickListener,
OnPoiSearchListener, InfoWindowAdapter, OnMapLongClickListener,
OnInfoWindowClickListener, OnDrawerCloseListener, OnDrawerOpenListener,
OnGeocodeSearchListener, OnItemClickListener {
public static final int MAP_CODE = 80;
public static final String ADDRESS = "address";
public static final String LATITUDE = "latitude";
public static final String LONGITUDE = "longitude";
private AMap aMap;
/**
* 地图视图
*/
@ViewInject(R.id.map)
private MapView mapView;
/**
* 显示餐馆信息的listview
*/
@ViewInject(R.id.find_content_lv)
private ListView mListView;
/**
* 输入的文本
*/
@ViewInject(R.id.find_search_et)
private EditText keyEdit;
/**
* 抽屉
*/
@ViewInject(R.id.slidingdrawer)
private SlidingDrawer slidingDrawer;
/**
* SlidingDrawer 的 三角箭头
*/
@ViewInject(R.id.handle_icon)
private ImageView handleIcon;
/**
* 完成
*/
@ViewInject(R.id.menu_head_right_tv)
private TextView submit;
/**
* 地址布局
*/
@ViewInject(R.id.address_rl)
private RelativeLayout addressRl;
/**
* 地址文本
*/
@ViewInject(R.id.address_tv)
private TextView addressTv;
/** listview适配器 */
public FindItemAdapter mFindItemAdapter;
/** 定位监听 */
private OnLocationChangedListener mListener;
/** 位置管理 */
private LocationManagerProxy mAMapLocationManager;
/** 地图控件是否显示 */
private UiSettings mUiSettings;
/** 搜索时进度条 */
private ProgressDialog progDialog = null;
/** Poi查询条件类 */
private PoiSearch.Query query;
/** Poi搜索对象 */
private PoiSearch poiSearch;
/** 显示Marker的详情 */
private Marker detailMarker;
/** poi返回的结果 */
private PoiResult poiResult;
/** poi数据 */
private List<PoiItem> poiItems;
/** poi图层 */
private PoiOverlay poiOverlay;
/** 标识 */
private MarkerOptions markerOption;
/** 长按时的标识 */
private Marker longMarker;
/** 跳跃的坐标 */
private LatLng latLng;
/** 点击的位置名称 */
private String addressTitle;
/** 点击的位置 */
private String addressSnippet;
/** poi搜索关键字 */
private String keyWord = "餐厅";
/** 城市名称 */
private String cityName;
/** 最后确定的点 */
private PoiItem mPoiItem;
/** 我的位置 */
private AMapLocation myAMapLocation;
/** 逆地理编码对象 */
private GeocodeSearch geocoderSearch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// R 需要引用包import com.amapv2.apis.R;
setContentView(R.layout.find);
ViewUtils.inject(this);
mapView.onCreate(savedInstanceState);// 必须要写
init();
}
/**
* 初始化AMap对象
*/
private void init() {
if (aMap == null) {
aMap = mapView.getMap();
setUpMap();
}
slidingDrawer.setOnDrawerCloseListener(this);
slidingDrawer.setOnDrawerOpenListener(this);
setListener();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
PoiItem poiItem = poiItems.get(position);
mPoiItem = poiItem;
String str = poiItem.getTitle() + poiItem.getSnippet();
addressRl.setVisibility(View.VISIBLE);
addressTv.setText(str);
submit.setTextColor(getResources().getColor(R.color.blue_text));
LatLonPoint latLonPoint = poiItem.getLatLonPoint();
aMap.animateCamera(CameraUpdateFactory.changeLatLng(AMapUtil
.convertToLatLng(latLonPoint)));
List<Marker> markers = aMap.getMapScreenMarkers();
if (position >= markers.size()) {
addressTitle = poiItem.getTitle();
addressSnippet = poiItem.getSnippet();
drawMarkers(AMapUtil.convertToLatLng(latLonPoint));
} else {
markers.get(position).showInfoWindow();
}
}
/**
* 设置监听
*/
private void setListener() {
mListView.setOnItemClickListener(this);
}
/**
* 显示我的位置
*/
private void setUpMap() {
// 自定义系统定位小蓝点
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationIcon(BitmapDescriptorFactory
.fromResource(R.drawable.map_icon));// 设置小蓝点的图标
myLocationStyle.strokeColor(Color.BLUE);// 设置圆形的边框颜色
// myLocationStyle.radiusFillColor(color)//设置圆形的填充颜色
// myLocationStyle.anchor(int,int)//设置小蓝点的锚点
myLocationStyle.strokeWidth(0.01f);// 设置圆形的边框粗细
aMap.setMyLocationStyle(myLocationStyle);
aMap.setMyLocationRotateAngle(180);
aMap.setLocationSource(this);// 设置定位监听
aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
aMap.setOnMarkerDragListener(this);// 设置marker可拖拽事件监听器
aMap.setOnMarkerClickListener(this);// 设置点击marker事件监听器
aMap.setInfoWindowAdapter(this);// 添加显示infowindow监听事件
aMap.setOnInfoWindowClickListener(this);// 设置点击infoWindow事件监听器
aMap.setOnMapLongClickListener(this);// 对amap添加长按地图事件监听器
mUiSettings = aMap.getUiSettings();
/**
* 设置地图默认的缩放按钮是否显示
*/
mUiSettings.setZoomControlsEnabled(false);
/**
* 设置地图默认的定位按钮是否显示
*/
mUiSettings.setMyLocationButtonEnabled(false);
geocoderSearch = new GeocodeSearch(this);
geocoderSearch.setOnGeocodeSearchListener(this);
initData();
}
private void initData() {
markerOption = new MarkerOptions();
}
/**
* 事件监听
*
* @param view
*/
@OnClick({ R.id.menu_head_left, R.id.find_more_iv, R.id.menu_head_right })
public void onClick(View view) {
switch (view.getId()) {
case R.id.menu_head_left:
// 关闭
finish();
break;
case R.id.find_more_iv:
// 搜索
String text = keyEdit.getText().toString();
if (text.equals("")) {
} else {
keyWord = text;
doSearchQuery(null);
keyEdit.setText("");
}
break;
case R.id.menu_head_right:
// 完成
Intent intent = new Intent();
intent.putExtra(ADDRESS,
mPoiItem.getTitle() + mPoiItem.getSnippet());
intent.putExtra(LATITUDE, mPoiItem.getLatLonPoint().getLatitude());
intent.putExtra(LONGITUDE, mPoiItem.getLatLonPoint().getLongitude());
setResult(MAP_CODE, intent);
finish();
break;
default:
break;
}
}
/**
* 方法必须重写
*/
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
/**
* 方法必须重写
*/
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
/**
* 方法必须重写
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
/**
* 方法必须重写
*/
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
/******************************************************************************** 方法 */
/**
* 开始进行poi搜索
*/
protected void doSearchQuery(LatLonPoint lp) {
showProgressDialog();// 显示进度框
query = new PoiSearch.Query(keyWord, "", cityName);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国)
query.setPageSize(30);// 设置每页最多返回多少条poiitem
query.setPageNum(0);// 设置查第一页
query.setLimitDiscount(false);
query.setLimitGroupbuy(false);
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
if (lp != null) {
poiSearch.setBound(new SearchBound(lp, 5000, true));//
} else {
poiSearch
.setBound(new SearchBound(new LatLonPoint(myAMapLocation
.getLatitude(), myAMapLocation.getLongitude()),
10000, true));//
}
poiSearch.searchPOIAsyn();// 异步搜索
}
/**
* 显示进度框
*/
private void showProgressDialog() {
if (progDialog == null)
progDialog = new ProgressDialog(this);
progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progDialog.setIndeterminate(false);
progDialog.setCancelable(false);
progDialog.setMessage("正在搜索中");
try {
progDialog.show();
} catch (Exception e) {
}
}
/**
* 绘制系统默认的1种marker背景图片
*/
public void drawMarkers(LatLng latlng) {
aMap.clear();// 清理之前的图标
markerOption.title(addressTitle);
if (addressSnippet.length() > 20) {
addressSnippet = addressSnippet.substring(0, 20) + "\n"
+ addressSnippet.substring(20);
}
markerOption.snippet(addressSnippet);
markerOption.position(latlng);
markerOption.perspective(true);
markerOption.draggable(true);
markerOption.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
longMarker = aMap.addMarker(markerOption);
longMarker.showInfoWindow();// 设置默认显示一个infowinfow
}
/**
* marker点击时跳动一下
*/
public void jumpPoint(final Marker marker) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = aMap.getProjection();
Point startPoint = proj.toScreenLocation(latLng);
startPoint.offset(0, -100);
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = 1500;
final Interpolator interpolator = new BounceInterpolator();
handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed
/ duration);
double lng = t * latLng.longitude + (1 - t)
* startLatLng.longitude;
double lat = t * latLng.latitude + (1 - t)
* startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
handler.postDelayed(this, 16);
}
}
});
}
/**
* 隐藏进度框
*/
private void dissmissProgressDialog() {
if (progDialog != null) {
progDialog.dismiss();
}
}
/**
* POI深度信息获取
*/
private StringBuffer getDeepInfo(PoiItemDetail result,
StringBuffer sbuBuffer) {
switch (result.getDeepType()) {
// 餐饮深度信息
case DINING:
if (result.getDining() != null) {
Dining dining = result.getDining();
sbuBuffer
.append("\n菜系:" + dining.getTag() + "\n特色:"
+ dining.getRecommend() + "\n来源:"
+ dining.getDeepsrc());
}
break;
// 酒店深度信息
case HOTEL:
if (result.getHotel() != null) {
Hotel hotel = result.getHotel();
sbuBuffer.append("\n价位:" + hotel.getLowestPrice() + "\n卫生:"
+ hotel.getHealthRating() + "\n来源:"
+ hotel.getDeepsrc());
}
break;
// 景区深度信息
case SCENIC:
if (result.getScenic() != null) {
Scenic scenic = result.getScenic();
sbuBuffer
.append("\n价钱:" + scenic.getPrice() + "\n推荐:"
+ scenic.getRecommend() + "\n来源:"
+ scenic.getDeepsrc());
}
break;
// 影院深度信息
case CINEMA:
if (result.getCinema() != null) {
Cinema cinema = result.getCinema();
sbuBuffer.append("\n停车:" + cinema.getParking() + "\n简介:"
+ cinema.getIntro() + "\n来源:" + cinema.getDeepsrc());
}
break;
default:
break;
}
return sbuBuffer;
}
/**
* 查单个poi详情
*
* @param poiId
*/
public void doSearchPoiDetail(String poiId) {
if (poiSearch != null && poiId != null) {
poiSearch.searchPOIDetailAsyn(poiId);
}
}
/**
* poi没有搜索到数据,返回一些推荐城市的信息
*/
private void showSuggestCity(List<SuggestionCity> cities) {
}
/**
* 响应逆地理编码
*/
public void getAddress(final LatLonPoint latLonPoint) {
RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200,
GeocodeSearch.AMAP);// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求
}
/******************************************************************************** 监听 */
/**
* 激活定位
*/
@Override
public void activate(OnLocationChangedListener listener) {
mListener = listener;
if (mAMapLocationManager == null) {
mAMapLocationManager = LocationManagerProxy.getInstance(this);
/*
* mAMapLocManager.setGpsEnable(false);
* 1.0.2版本新增方法,设置true表示混合定位中包含gps定位,false表示纯网络定位,默认是true Location
* API定位采用GPS和网络混合定位方式
* ,第一个参数是定位provider,第二个参数时间最短是5000毫秒,第三个参数距离间隔单位是米,第四个参数是定位监听者
*/
mAMapLocationManager.requestLocationUpdates(
LocationProviderProxy.AMapNetwork, 5000, 10, this);
}
}
/**
* 停止定位
*/
@Override
public void deactivate() {
mListener = null;
if (mAMapLocationManager != null) {
mAMapLocationManager.removeUpdates(this);
mAMapLocationManager.destory();
}
mAMapLocationManager = null;
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
/**
* 定位成功后回调函数
*/
@Override
public void onLocationChanged(AMapLocation aLocation) {
if (mListener != null && aLocation != null) {
myAMapLocation = aLocation;
mListener.onLocationChanged(aLocation);// 显示系统小蓝点
float bearing = aMap.getCameraPosition().bearing;
aMap.setMyLocationRotateAngle(bearing);// 设置小蓝点旋转角度
deactivate();
doSearchQuery(new LatLonPoint(aLocation.getLatitude(),
aLocation.getLongitude()));
cityName = aLocation.getCity();
}
}
/**
* 监听拖动marker时事件回调
*/
@Override
public void onMarkerDrag(Marker arg0) {
}
/**
* 监听拖动marker结束事件回调
*/
@Override
public void onMarkerDragEnd(Marker arg0) {
latLng = arg0.getPosition();
}
/**
* 监听开始拖动marker事件回调
*/
@Override
public void onMarkerDragStart(Marker arg0) {
}
/**
* 对marker标注点点击响应事件
*/
@Override
public boolean onMarkerClick(Marker marker) {
if (aMap != null) {
if (marker.getPosition().equals(latLng)) {
jumpPoint(marker);
} else if (poiOverlay != null && poiItems != null
&& poiItems.size() > 0) {
detailMarker = marker;
doSearchPoiDetail(poiItems.get(poiOverlay.getPoiIndex(marker))
.getPoiId());
}
}
return false;
}
/**
* POI详情回调
*/
@Override
public void onPoiItemDetailSearched(PoiItemDetail result, int rCode) {
dissmissProgressDialog();// 隐藏对话框
if (rCode == 0) {
if (result != null) {// 搜索poi的结果
if (detailMarker != null) {
StringBuffer sb = new StringBuffer(result.getSnippet());
if ((result.getGroupbuys() != null && result.getGroupbuys()
.size() > 0)
|| (result.getDiscounts() != null && result
.getDiscounts().size() > 0)) {
if (result.getGroupbuys() != null
&& result.getGroupbuys().size() > 0) {// 取第一条团购信息
sb.append("\n团购:"
+ result.getGroupbuys().get(0).getDetail());
}
if (result.getDiscounts() != null
&& result.getDiscounts().size() > 0) {// 取第一条优惠信息
sb.append("\n优惠:"
+ result.getDiscounts().get(0).getDetail());
}
int i = 0;
int index = 0;
while (index < sb.length()) {// 描述太长,分割显示
if (sb.charAt(index) == '\n') {// 已经有换行,重新计算
i = 0;
}
index++;
i++;
if (i % 25 == 0) {
sb.insert(index, '\n');
}
}
} else {
sb = new StringBuffer("地址:" + result.getSnippet()
+ "\n电话:" + result.getTel() + "\n类型:"
+ result.getTypeDes());
}
sb = getDeepInfo(result, sb);// 加入poi搜索深度信息
detailMarker.setSnippet(sb.toString());
}
} else {
}
} else if (rCode == 27) {
Util.showMsg(this, R.string.error_network);
} else if (rCode == 32) {
Util.showMsg(this, R.string.error_key);
} else {
Util.showMsg(this, R.string.error_other);
}
}
/**
* POI搜索回调
*/
@Override
public void onPoiSearched(PoiResult result, int rCode) {
dissmissProgressDialog();// 隐藏对话框
if (rCode == 0) {
if (result != null && result.getQuery() != null) {// 搜索poi的结果
if (result.getQuery().equals(query)) {// 是否是同一条
poiResult = result;
poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始
List<SuggestionCity> suggestionCities = poiResult
.getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息
if (poiItems != null && poiItems.size() > 0) {
// 添加到适配器
mFindItemAdapter = new FindItemAdapter(this, poiItems);
mListView.setAdapter(mFindItemAdapter);
/**
* 打开抽屉
*/
slidingDrawer.animateOpen();
aMap.clear();// 清理之前的图标
poiOverlay = new PoiOverlay(aMap, poiItems);
poiOverlay.removeFromMap();
poiOverlay.addToMap();
poiOverlay.zoomToSpan();
} else if (suggestionCities != null
&& suggestionCities.size() > 0) {
showSuggestCity(suggestionCities);
} else {
Util.showMsg(this, R.string.no_result);
}
}
} else {
Util.showMsg(this, R.string.no_result);
}
} else if (rCode == 27) {
Util.showMsg(this, R.string.error_network);
} else if (rCode == 32) {
Util.showMsg(this, R.string.error_key);
} else {
Util.showMsg(this, R.string.error_other);
}
}
@Override
public View getInfoContents(Marker arg0) {
return null;
}
@Override
public View getInfoWindow(Marker arg0) {
return null;
}
/**
* 对长按地图事件回调
*/
@Override
public void onMapLongClick(LatLng arg0) {
latLng = arg0;
getAddress(new LatLonPoint(arg0.latitude, arg0.longitude));
}
@Override
public void onInfoWindowClick(Marker arg0) {
String str = arg0.getSnippet() + arg0.getTitle();
addressRl.setVisibility(View.VISIBLE);
addressTv.setText(str);
submit.setTextColor(getResources().getColor(R.color.blue_text));
PoiItem poi = new PoiItem("1", new LatLonPoint(
arg0.getPosition().latitude, arg0.getPosition().longitude),
arg0.getTitle(), arg0.getSnippet());
mPoiItem = poi;
}
@Override
public void onDrawerOpened() {
handleIcon.setImageResource(R.drawable.map_handle_down);
}
@Override
public void onDrawerClosed() {
handleIcon.setImageResource(R.drawable.map_handle_up);
}
/**
* 地理编码查询回调
*/
@Override
public void onGeocodeSearched(GeocodeResult arg0, int arg1) {
}
/**
* 逆地理编码回调
*/
@Override
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
if (rCode == 0) {
if (result != null && result.getRegeocodeAddress() != null
&& result.getRegeocodeAddress().getFormatAddress() != null) {
addressTitle = result.getRegeocodeAddress().getBuilding();
addressSnippet = result.getRegeocodeAddress()
.getFormatAddress();
aMap.animateCamera(CameraUpdateFactory.changeLatLng(AMapUtil
.convertToLatLng(new LatLonPoint(latLng.latitude,
latLng.longitude))));
drawMarkers(latLng);
} else {
Util.showMsg(this, R.string.no_result);
}
} else if (rCode == 27) {
Util.showMsg(this, R.string.error_network);
} else if (rCode == 32) {
Util.showMsg(this, R.string.error_key);
} else {
Util.showMsg(this, R.string.error_other);
}
}
}