Google Map API v2的定位

昨天刚开始看LBS相关的东西,搜了下发现几个问题:一个是时效性的问题,很多发表时间还算近的 内容写的却是V1的,很容易让我们这些菜鸟走更多的弯路;另一个是知识面的,发现有太多太多相同的文章 都在写一个基础内容——Hello World,写接下来的就有点少了,也不多说了,毕竟也是很多情况导致的,也只有接受了,等自己能写高大上的文章才有资格说别人。
========================================正文分隔线==============================================

GOOGLE MAP API V2

新版本的GoogleMap可以使用MapFragment显示地图,Activity也不必再继承MapService。
新版本帮我们做了一些东西:
  • 连接到Google Maps Service。
  • 下载地图资源
  • 在手机屏幕上显示地图
  • 显示控制按钮,例如平移及缩放。

MapFragment

MapFragment是Fragment的子类,是放置地图的容器。对于支持MapFragment的Google Maps Android API的要求:Android 3.1(API level 12)或更高版本。而低版本的API需要通过SupportMapFragment来达到相同的功能效果。

      MapView

MapView同样是地图的容器,但是需要继承MapActivity才可以使用。V2版本可以继承Activity实现既定的地图功能,因此MapView不适合在此直接使用。

    API V2版本中获取地图组件

 GoogleMap mMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();

其中map是布局文件中所定义的地图组件的id.

地图的类型

地图一共有5种类型:
  • Normal:典型的地图,此种地图类型是平常使用最多、最广的类型。
  • Hybrid:混合卫星图及道路地图,该种地图类型除了显示卫星图外,还标记了地名。
  • Satellite:卫星照片。
  • Terrain:地形图。
  • None:什么都没有。

    改变地图的类型

使用 setMapType 可以改变地图的类型(下面会有xml上设置的案例):
 mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
标记(Marker)

用来标记地图上的某一个地点,可以自定义标记的颜色或图示。标记可以定义click事件,如果将draggable属性射程true,即可以使得使用者在长按此标记后移动它。

建立标记的方法是使用MarkerOptions类,使用LatLng类可以用于设置标记的经纬度,代码如下:

MarkerOptions markerOpt = new MarkerOptions();
markerOpt.position(new LatLng(纬度值, 经度值));
markerOpt.title("标记地点");
markerOpt.draggable(true);
mMap.addMarker(markerOpt);

也可以根据需要自定义标记的属性:

* Position(必要):使用 LatLng 类來设定位置,该属性是唯一的必须要设定的属性。

* Title:当用户点击标记时显示的标记的标题信息。

* Snippet:额外的文字,显示在标题信息的下方。

Draggable:是否可以允许用户移动标记,true:可移动;false:不可移动。

* Visible:是否显示标记,true:显示;false:隐藏。

Anchor:图片上的一个点,用来定位到经纬度坐标,默认为图片底边的中间位置。取值范围为:左上角(0.0, 0.0)到右下角(1.0, 1.0)

  * Icon:图示,被放置在原标记的相同位置,只有第一次建立标记时可以使用图示,一旦使用之后不能任意更换  

初始化地图状态信息

地图信息的初始化可以设置以下参数类型:
  • 摄影机的位置,即当前可观看到的地图位置:包含 location(位置), zoom(缩放), bearing(轴承) 及 tilt(倾斜),更改地图视角的详细资料请参考:https://developers.google.com/maps/documentation/android/views?hl=zh-CN。
  • 地图的类型。
  • 是否显示缩放按钮(zoom)以及是否在屏幕上显示罗盘。
  • 使用者可以使用哪些哪些手势来操作地图。
  • 觉得这篇博文写的对这块写的还是很好的http://blog.csdn.net/forrest_ch/article/details/8736684

做下面实例之前还需要看下另一个教程 调用位置服务

接下来给出一个例子: 以下是两者结合的实例,博主还没开始做,等做了会做修改
对于Google Map V2 API Key的申请请参见:http://blog.sina.com.cn/s/blog_9864ddb70101ak4s.html
首先新建Android项目:GoogleMapTest,包名为com.example.googlemaptest。

googlemap.xml

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/mapView"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.MapFragment"
  map:cameraBearing="45"
  map:cameraTargetLat="25.033611"
  map:cameraTargetLng="121.565000"
  map:cameraTilt="0"
  map:cameraZoom="13"
  map:uiCompass="true"
  map:mapType="normal"
  map:uiRotateGestures="true"
  map:uiScrollGestures="true"
  map:uiTiltGestures="true"
  map:uiZoomControls="false"
  map:uiZoomGestures="true" />

该XML文件中“class”以下的语句是对地图的一些属性的设置。这些设置必须要有命名空间 xmlns:map="http://schemas.android.com/apk/res-auto",否则会报错,而且需要注意的是该XML文件中只有这一个fragment标签时才能使用,否则会报错,如果加入了其他的组件,就需要把初始化的这几行语句删除,不妨碍地图的显示。
如果想保留这些设置,又想添加别的界面组件就需要使用include标签,将该XML文件作为另一个XML文件的一部分:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/mapContainer"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >
  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical" >
      <TextView
          android:id="@+id/textView1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_margin="10dp"
          android:text="定位"
          android:textSize="15sp" />
      <LinearLayout
          android:id="@+id/location"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:gravity="center_horizontal"
          android:orientation="horizontal" >
          <!-- 定义输入经度值的文本框 -->
          <EditText
              android:id="@+id/edt_lng"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:ems="6"
              android:hint="经度"
              android:textSize="20sp" />
          <!-- 定义输入纬度值的文本框 -->
          <EditText
              android:id="@+id/edt_lat"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginLeft="5dp"
              android:ems="6"
              android:hint="纬度"
              android:textSize="20sp" />
          <Button
              android:id="@+id/btn_loc"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginLeft="5dp"
              android:text="定位"
              android:textSize="15sp" />
      </LinearLayout>
      <LinearLayout
          android:id="@+id/mapsChoice"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" >
          <!-- 定义选择地图类型的单选按钮 -->
          <RadioGroup
              android:id="@+id/rg_mapType"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_weight="1"
              android:orientation="horizontal" >
              <RadioButton
                  android:id="@+id/rb_nomal"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:checked="true"
                  android:text="普通视图" />
              <RadioButton
                  android:id="@+id/rb_satellite"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="卫星视图" />
          </RadioGroup>
      </LinearLayout>
  </LinearLayout>
  <include android:id="@+id/googleMap"
            layout="@layout/googlemap" />
</LinearLayout>

MainActivity.java

package com.example.googlemaptest;

import java.util.List;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;

public class MainActivity extends Activity {
  //定义界面上的可视化组件
  private Button btn_loc, btn_nav;
  private EditText edt_lng, edt_lat;
  private RadioGroup rg_mapType;
  GoogleMap mMap;
  private CameraPosition cameraPosition;
  private MarkerOptions markerOpt;
  //定义LocationManager对象
  private LocationManager locManager;
  private Location location;
  private String bestProvider;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//获取用户界面的组件
findViews();
//创建LocationManager对象,并获取Provider
initProvider();
//取得地图组件
mMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.mapView)).getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
updateToNewLocation(location);
//给按钮添加监听器
btn_loc.setOnClickListener(new MapClickedListener());
//为RadioGroup的选中状态改变添加监听器
rg_mapType.setOnCheckedChangeListener(new ChangeMapTypeListener());
// 设置监听器,自动更新的最小时间为间隔N秒(1秒为1*1000,这样写主要为了方便)或最小位移变化超过N
locManager.requestLocationUpdates(bestProvider,  3 * 1000, 8, new LocationListener() {
  //当Provider的状态改变时
  @Override
  public void onStatusChanged(String provider, int status, Bundle extras) {
  }
  @Override
  public void onProviderEnabled(String provider) {
// 当GPS LocationProvider可用时,更新位置
location = locManager.getLastKnownLocation(provider);
  }
  @Override
  public void onProviderDisabled(String provider) {
updateToNewLocation(null);
  }
  @Override
  public void onLocationChanged(Location location) {
// 当GPS定位信息发生改变时,更新位置
updateToNewLocation(location);
  }
  });
}
private void initProvider() {
  //创建LocationManager对象
  locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  // List all providers:
  List<String> providers = locManager.getAllProviders();
  Criteria criteria = new Criteria();
  bestProvider = locManager.getBestProvider(criteria, false);
  location = locManager.getLastKnownLocation(bestProvider);
  System.out.println("经度:"+location.getLatitude()+"  纬度:" + location.getLongitude());
}
//点击事件监听器
private class MapClickedListener implements OnClickListener{
  @Override
  public void onClick(View v) {
//根据用户输入经纬度定位
//获取用户输入的经纬度
String lng = edt_lng.getText().toString().trim();
String lat = edt_lat.getEditableText().toString().trim();
if(lng.equals("") || lat.equals("")){
  Toast.makeText(getApplicationContext(), "请输入有效的经纬度信息!"
, Toast.LENGTH_LONG).show();
  location = locManager.getLastKnownLocation(bestProvider);
  updateToNewLocation(location);
}
else{
  location.setLongitude(Double.parseDouble(lng));
  location.setLatitude(Double.parseDouble(lat));
  //调用方法更新地图定位信息
  updateToNewLocation(location);
}
  }
}
private class ChangeMapTypeListener implements OnCheckedChangeListener{
  @Override
  public void onCheckedChanged(RadioGroup group, int checkedId) {
switch(checkedId){
case R.id.rb_nomal://如果勾选的是"正常视图"的单选按钮
  mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
  break;
case R.id.rb_satellite://如果勾选的是"卫星视图"的单选按钮
  mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
  break;
    }
  }
}
//获取用户界面组件
private void findViews() {
  //获取界面上的两个按钮
  btn_loc = (Button) findViewById(R.id.btn_loc);
  //获取界面上的两个文本框
  edt_lng = (EditText) findViewById(R.id.edt_lng);
  edt_lat = (EditText) findViewById(R.id.edt_lat);
  //获得RadioGroup
  rg_mapType = (RadioGroup) findViewById(R.id.rg_mapType);
}
private void updateToNewLocation(Location location){
  mMap.clear();
  markerOpt = new MarkerOptions();
  //定位石家庄
  double dLong = 114.51500;
  double dLat = 38.042000;
  if(location != null){
//获取经度
dLong = location.getLongitude();
//获取纬度
dLat = location.getLatitude();
  }
  markerOpt.position(new LatLng(dLat, dLong));
  markerOpt.draggable(false);
  markerOpt.visible(true);
  markerOpt.anchor(0.5f, 0.5f);//设为图片中心
  markerOpt.icon(BitmapDescriptorFactory
.fromResource(android.R.drawable.ic_menu_mylocation));
  mMap.addMarker(markerOpt);
  //将摄影机移动到指定的地理位置
  cameraPosition = new CameraPosition.Builder()
    .target(new LatLng(dLat, dLong))              // Sets the center of the map to ZINTUN
    .zoom(17)                  // 缩放比例
    .bearing(0)                // Sets the orientation of the camera to east
    .tilt(30)                  // Sets the tilt of the camera to 30 degrees
    .build();                  // Creates a CameraPosition from the builder
    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
  }
}



转自:http://blog.csdn.net/hujiameihuxu/article/details/9907041


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值