(void)longPress:(UIGestureRecognizer*)gestureRecognizer {
創(chuàng)新互聯(lián)主要從事做網(wǎng)站、網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)聶拉木,10多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):18980820575
if (gestureRecognizer.state == UIGestureRecognizerStateBegan){ //這個(gè)狀態(tài)判斷很重要
//坐標(biāo)轉(zhuǎn)換
CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView];
CLLocationCoordinate2D touchMapCoordinate =
[self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];
//這里的touchMapCoordinate.latitude和touchMapCoordinate.longitude就是想要的經(jīng)緯度,
NSLog(@"%f",touchMapCoordinate.latitude);
NSLog(@"%f",touchMapCoordinate.longitude);
//30.264998 120.122538 30.285012 120.117989
LocationObject *aLocationObject = [[LocationObject alloc]initWithTitle:@"hello" latitue:touchMapCoordinate.latitude longitude:touchMapCoordinate.longitude];
aLocationObject._subTitleString = @"world";
NSMutableArray *_mapAnnotations = [[NSMutableArray alloc]initWithCapacity:1];
[_mapAnnotations addObject:aLocationObject];
[self.mapView addAnnotations:_mapAnnotations ];
[_mapAnnotations release];
[aLocationObject release];
}
}
第一步:申請(qǐng)Key
先申請(qǐng)高德的KEY
1、填寫(xiě)應(yīng)用名稱(chēng)
2、綁定服務(wù)選擇IOS平臺(tái)
3、輸入bundle id:將Xcode切換到General標(biāo)簽,即可查看Bundle Identifier
4、點(diǎn)擊獲取KEY
第二步、新建地圖工程
在xCode里,新建一個(gè)?Single View Application工程,并且進(jìn)行配置。
在高德官網(wǎng)有地圖配置的詳細(xì)說(shuō)明,這里我就不多說(shuō)了。
第三步、添加MKMapView
1、在xCode里選擇Build Phases標(biāo)簽,點(diǎn)開(kāi)Link Binary With Libraries,再點(diǎn)加號(hào)。
2、在彈出來(lái)的搜索框里搜索Mapkit。
3、選擇iOS 8.0--MapKit.framework,最后點(diǎn)擊add即可。
第四步、申請(qǐng)定位權(quán)限
在?info.plist中追加NSLocationAlwaysUsageDescription或者NSLocationAlwaysUsageDescription字段。
NSLocationWhenInUseUsageDescription表示應(yīng)用在前臺(tái)的時(shí)候可以搜到更新的位置信息;NSLocationAlwaysUsageDescription表示應(yīng)用在前臺(tái)和后臺(tái)(suspend或terminated)都可以獲取到更新的位置數(shù)據(jù)。
所以我還是建議NSLocationAlwaysUsageDescription這種方便的模式,哈哈。
1.在工程的Supporting?Files中選擇plist文件
2.點(diǎn)擊+號(hào),輸入字段NSLocationAlwaysUsageDescription
3.按回車(chē),即可完成添加字段
第五步、初始化Mapview
高德的坐標(biāo)系是國(guó)內(nèi)標(biāo)準(zhǔn)坐標(biāo)(GCJ-02,又稱(chēng)火星坐標(biāo)),國(guó)際上一般是采用GPS坐標(biāo)(WGS-84),所以大多數(shù)國(guó)際應(yīng)用在中國(guó)使用時(shí),需要進(jìn)行坐標(biāo)轉(zhuǎn)換。
好在蘋(píng)果的MapKit用的是高德的地圖,showUserLocation= YES,坐標(biāo)已經(jīng)是GCJ-02的啦,可以直接使用~
(PS:不建議使用CLLocationManager定位管理類(lèi),它返回的坐標(biāo)是GPS坐標(biāo),必須進(jìn)行坐標(biāo)轉(zhuǎn)換,很麻煩。)
第六步、初始化AMapSearchAPI
構(gòu)造AMapSearchAPI對(duì)象,設(shè)置搜索結(jié)果語(yǔ)言為英文AMapSearchLanguage_en。
這步非常重要喔!必須要設(shè)置成英文,才能巧妙地讓POI搜索、逆地理編碼和地理編碼、輸入提示等,都變成純英文喔。
第七步、寫(xiě)個(gè)搜索demo來(lái)看看
以一個(gè)普通的POI檢索為例,當(dāng)檢索英文關(guān)鍵詞時(shí),出來(lái)純英文的搜素建議;搜索結(jié)果也用英文來(lái)展示。
/* ?POI 搜索. ?*/
- ?(void)searchPOIWithKey:(NSString *)key adcode:(NSString *)adcode
{
if (key.length == 0)
{
return;
}
//構(gòu)造POI搜索對(duì)象AMapPlaceSearchRequest
AMapPlaceSearchRequest ?*place = [[AMapPlaceSearchRequest alloc] init];
//設(shè)置關(guān)鍵字
place.keywords = key;
place.requireExtension = YES;//設(shè)置成YES,返回信息詳細(xì),較費(fèi)流量
if (adcode.length 0)
{
place.city = @[adcode];
}
//發(fā)起查詢(xún)
[_search ?AMapPlaceSearch:place];
}
//回調(diào)中顯示結(jié)果
- ?(void)onPlaceSearchDone:(AMapPlaceSearchRequest *)request response:(AMapPlaceSearchResponse ?*)respons
{
if (respons.pois.count == 0)
{
return;
}
NSMutableArray ?*poiAnnotations = [NSMutableArray arrayWithCapacity:respons.pois.count];
[respons.pois ?enumerateObjectsUsingBlock:^(AMapPOI *obj, NSUInteger idx, BOOL *stop) {
[poiAnnotations ?addObject:[[POIAnnotation alloc] initWithPOI:obj]];
}];
/* ?將結(jié)果以annotation的形式加載到地圖上. */
[_mapView addAnnotations:poiAnnotations];
/* ?如果只有一個(gè)結(jié)果,設(shè)置其為中心點(diǎn). */
if (poiAnnotations.count == 1)
{
_mapView.centerCoordinate = [poiAnnotations[0] coordinate];
}
/* 如果有多個(gè)結(jié)果, 設(shè)置地圖使所有的annotation都可見(jiàn). */
else
{
[_mapView showAnnotations:poiAnnotations animated:NO];
}
}
效果圖:
1.首先加載出百度地圖
2.在地圖加載成功后的方法里去得到左下角和右上角的坐標(biāo)點(diǎn)的經(jīng)緯度, 需要一個(gè)方法來(lái)實(shí)現(xiàn)屏幕坐標(biāo)點(diǎn)轉(zhuǎn)化成經(jīng)緯度。
3.得到倆個(gè)點(diǎn)的經(jīng)緯度就可以開(kāi)始發(fā)起搜索了。
4.在搜索結(jié)果的代理方法里將搜索到的結(jié)果展示出來(lái)。
5.當(dāng)?shù)貓D區(qū)域發(fā)生改變時(shí),會(huì)觸發(fā)的方法有3個(gè): "正在改變"、"即將改變"、"改變完成"。
很容易就想到,我們需要使用的是"改變完成"的方法,在里面重新請(qǐng)求一次搜索:
**
總結(jié): demo只實(shí)現(xiàn)了一個(gè)很基礎(chǔ)的功能,后期還可以增加更加炫酷的功能,比如改變氣泡的形狀。如果你有更好的想法,歡迎和我交流!
**
demo地址:
首先創(chuàng)建工程,并在工程Build PathConfigure Build Path…libraries 中選擇“Add Externel JARs…”,選定
MapApi.jar,點(diǎn)擊OK,這樣就可以將高德地圖Android API 庫(kù)文件引入。然后在工程Build PathConfigure Build
Path…Order and Export 中將引入的庫(kù)文件MapApi.jar 選中,點(diǎn)擊OK,這樣您就可以在您的程序中使用高德地圖API
了。
二、我們?cè)诓皇煜さ那闆r下、先盡量多的添加此軟件應(yīng)用權(quán)限;所以在mainifest中添加如下代碼;插入的位置在
application的代碼之前。
Java代碼
uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/uses-permission
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/uses-permission
uses-permission android:name="android.permission.INTERNET"/uses-permission
uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/uses-permission
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/uses-permission
uses-permission android:name="android.permission.READ_PHONE_STATE"/uses-permission
uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/uses-permission
uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/uses-permission
三、接著就要在res文件下的layout中添加界面布局了。其代碼如下、你可以完全復(fù)制進(jìn)去。
Java代碼
?xml version="1.0" encoding="utf-8"?
LinearLayout xmlns:android=""
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
!--添加文本輸入框,查找地址--
LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:orientation="horizontal"
xmlns:android=""
android:layout_gravity="center_horizontal"
TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="經(jīng)度"/
EditText android:layout_height="fill_parent"
android:layout_width="100px"
android:id="@+id/longitude"/
TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="緯度"/
EditText android:layout_height="fill_parent"
android:layout_width="100px"
android:id="@+id/latitude"/
Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查找"
android:id="@+id/button"/
/LinearLayout
com.amap.mapapi.map.MapView android:id="@+id/mapView"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:clickable="true"
/
/LinearLayout
四、最后就是軟件的主程序部分了、里面需要的類(lèi)和方法不多,主要以按鈕的監(jiān)聽(tīng)器和地圖的界面實(shí)現(xiàn)為主
Java代碼
public void onCreate(Bundle savedInstanceState) {
// this.setMapMode(MAP_MODE_VECTOR);//設(shè)置地圖為矢量模式
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMapView = (MapView) findViewById(R.id.mapView);
mMapView.setBuiltInZoomControls(true); // 設(shè)置啟用內(nèi)置的縮放控件
mMapController = mMapView.getController(); // 得到mMapView
// 的控制權(quán),可以用它控制和驅(qū)動(dòng)平移和縮放
point = new GeoPoint((int) (39.982378 * 1E6), (int) (116.304923 * 1E6)); // 用給定的經(jīng)緯度構(gòu)造一個(gè)GeoPoint,單位是微度(度*
// 1E6)
// 按鈕添加監(jiān)聽(tīng)器
button_location = (Button) findViewById(R.id.location);
longitude = (EditText) findViewById(R.id.longitude);
latidute = (EditText) findViewById(R.id.latitude);
locationListener = new OnClickListener() {
public void onClick(View e) {
if (e.equals(button_location)) {
// 得到文本輸入框的中經(jīng)緯 度坐標(biāo)值
String latStr = longitude.getText().toString();
// 將得到的字符串轉(zhuǎn)成數(shù)值
double lat = Integer.parseInt(latStr);
String lngStr = latidute.getText().toString();
double lng = Integer.parseInt(lngStr);
//轉(zhuǎn)成經(jīng)緯度坐標(biāo)
lat=lat*1E6;
lng=lng*1E6;
// 用給定的經(jīng)緯度構(gòu)造一個(gè)GeoPoint,單位是微度(度*1E6)
point = new GeoPoint((int) (lat), (int) (lng));
mMapController.setCenter(point); // 設(shè)置地圖中心點(diǎn)
mMapController.setZoom(12); // 設(shè)置地圖zoom 級(jí)別
// 添加地圖覆蓋物
// MyLocationOverlay(this, mMapView);
mylocTest.enableMyLocation(); // 判斷是否發(fā)現(xiàn)位置提供者
mylocTest.enableCompass(); // 打開(kāi)指南針
mMapView.getOverlays().add(mylocTest);// 添加定位覆蓋物
}
}
};
// 按鈕添加監(jiān)聽(tīng)器
button_location.setOnClickListener(locationListener);
mMapController.setCenter(point); // 設(shè)置地圖中心點(diǎn)
mMapController.setZoom(12); // 設(shè)置地圖zoom 級(jí)別
// 添加地圖覆蓋物
mylocTest = new MyLocationOverlay(this, mMapView);
mylocTest.enableMyLocation(); // 判斷是否發(fā)現(xiàn)位置提供者
mylocTest.enableCompass(); // 打開(kāi)指南針
mMapView.getOverlays().add(mylocTest);// 添加定位覆蓋物
}
//另外一個(gè)添加界面覆蓋物的類(lèi):
public class MyLocationOverlayProxy extends com.amap.mapapi.map.MyLocationOverlay{
private Location mLocation;
protected final Paint mPaint = new Paint();
protected final Paint mCirclePaint = new Paint();
private Bitmap gps_marker=null;
private Point mMapCoords = new Point();
private final float gps_marker_CENTER_X;
private final float gps_marker_CENTER_Y;
private final LinkedListRunnable mRunOnFirstFix = new LinkedListRunnable();
public MyLocationOverlayProxy(amap amap, MapView mMapView) {
super(amap, mMapView);
gps_marker = ((BitmapDrawable) amap.getResources().getDrawable(
R.drawable.marker_gpsvalid)).getBitmap();
gps_marker_CENTER_X = gps_marker.getWidth() / 2 - 0.5f;
gps_marker_CENTER_Y= gps_marker.getHeight() / 2 - 0.5f;
}
public boolean runOnFirstFix(final Runnable runnable) {
if (mLocation != null) {
new Thread(runnable).start();
return true;
} else {
mRunOnFirstFix.addLast(runnable);
return false;
}
}
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
mLocation = location;
for(final Runnable runnable : mRunOnFirstFix) {
new Thread(runnable).start();
}
mRunOnFirstFix.clear();
super.onLocationChanged(location);
}
protected void drawMyLocation(Canvas canvas, MapView mapView, final Location mLocation,
GeoPoint point, long time) {
Projection pj=mapView.getProjection();
if (mLocation != null) {
mMapCoords=pj.toPixels(point, null);
final float radius = pj.metersToEquatorPixels(mLocation.getAccuracy());
this.mCirclePaint.setAntiAlias(true);
this.mCirclePaint.setARGB(35, 131, 182, 222);
this.mCirclePaint.setAlpha(50);
this.mCirclePaint.setStyle(Style.FILL);
canvas.drawCircle(mMapCoords.x, mMapCoords.y, radius, this.mCirclePaint);
this.mCirclePaint.setARGB(225, 131, 182, 222);
this.mCirclePaint.setAlpha(150);
this.mCirclePaint.setStyle(Style.STROKE);
canvas.drawCircle(mMapCoords.x, mMapCoords.y, radius, this.mCirclePaint);
canvas.drawBitmap(gps_marker, mMapCoords.x-gps_marker_CENTER_X, mMapCoords.y-gps_marker_CENTER_Y, this.mPaint);
}
}
}
App內(nèi)根據(jù)手機(jī)上裝載的地圖App將其顯示在彈出的選擇框,選擇對(duì)應(yīng)地圖跳轉(zhuǎn)進(jìn)入地圖導(dǎo)航。需要用到- (BOOL)canOpenURL:(NSURL *)url NS_AVAILABLE_IOS(3_0);方法判斷手機(jī)是否已安裝相應(yīng)地圖App。
要進(jìn)行跳轉(zhuǎn)需要先在xcode的plist文件內(nèi)將目標(biāo)App的url Scheme加入白名單(LSApplicationQueriesSchemes)。