天天看點

Weex地圖元件開發流程及使用(android)

一、元件開發前準備

   首先,建立高德地圖開發者賬号,擷取地圖的key。

   進入自己的高德開發賬号,點選‘建立新應用’  

Weex地圖元件開發流程及使用(android)

建立應用完成點選右上角的添加新key

Weex地圖元件開發流程及使用(android)
Weex地圖元件開發流程及使用(android)

釋出版SHA1以及調試版SHA1擷取:

1、打開android studio 找到Terminal并打開,或者在最下面找到Terminal 如下圖:

Weex地圖元件開發流程及使用(android)

2、 輸入指令  C:    進入c盤;

3、接着 輸入指令   cd Users\Administrator   其中Administrator是自己的使用者名  Administrator檔案下有個.adnroid檔案, 輸入指令   cd  .android,最後就找到了.android,如圖:

Weex地圖元件開發流程及使用(android)

4、輸入指令  keytool -list -v -keystore debug.keystore  其中debug.keystore是studio預設的keystore,按回車,然後輸入秘鑰:android(系統預設)    回車(秘鑰庫密碼是看不到的)如下圖:

Weex地圖元件開發流程及使用(android)

這樣就成功擷取到開發版的SHA1值了

二、擷取釋出版的SHA1:

擷取釋出版的SHA1,跟擷取開發版的SHA1的1、2、3步驟一樣,不一樣的地方就是第4步稍微不同而已。

1、同上;

2、同上;

3、同上;

4、輸入指令  keytool -list -v -keystore 檔案目錄\自己的簽名檔案 比如我的:keytool -list -v -keystore E:\簽名檔案\android.keystore ,接着按回車,然後輸入秘鑰:(我隻知道我的,哈哈)    回車(秘鑰庫密碼是看不到的)如下圖:

Weex地圖元件開發流程及使用(android)

這樣就成功擷取到釋出版的SHA1值了

Weex地圖元件開發流程及使用(android)

在AndroidManifest.xml中添加相應的權限

<!-- 允許程式打開網絡套接字-->

<uses-permission android:name="android.permission.INTERNET" />

 <!-- 允許程式設定内置sd卡的寫權限-->

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 <!-- 允許程式擷取網絡狀 -->

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 允許程式通路WiFi網絡資訊-->

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<!-- 允許程式讀寫手機狀态和身份-->

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<!-- 允許程式通路CellID或WiFi熱點來擷取粗略的位置-->

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

添加高德地圖的apiKey

Weex地圖元件開發流程及使用(android)

在app的build.gradle中添加相關依賴:

Weex地圖元件開發流程及使用(android)
Weex地圖元件開發流程及使用(android)

二、元件開發

1、自定義MapView控件

  建立布局檔案location_layout.xml。布局檔案裡主要放了一個mapView控件。

Weex地圖元件開發流程及使用(android)

  建立WeexMapView繼承LinearLayout類,開發一個自定義的組合元件。

Weex地圖元件開發流程及使用(android)

public void setMapModel(int model){

    switch (model){

        case 1://連續定位、藍點不會移動到地圖中心點,定位點依照裝置方向旋轉,并且藍點會跟随裝置移動。

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);

            break;

        case 2://連續定位、且将視角移動到地圖中心點,定位藍點跟随裝置移動。(1秒1次定位)

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);

            break;

        case 3://連續定位、且将視角移動到地圖中心點,地圖依照裝置方向旋轉,定位點會跟随裝置移動。(1秒1次定位)

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);

            break;

        case 4://連續定位、且将視角移動到地圖中心點,定位點依照裝置方向旋轉,并且會跟随裝置移動。(1秒1次定位)預設執行此種模式。

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);

            break;

    }

    aMap.setMyLocationStyle(myLocationStyle);

}

//設定預設定位按鈕是否顯示,非必需設定。

public void showLocationButton(boolean isShow){

    aMap.getUiSettings().setMyLocationButtonEnabled(isShow);

}

// 設定為true表示啟動顯示定位藍點,false表示隐藏定位藍點并不進行定位,預設是false。

public void showLocationPoint(boolean isShow){

    aMap.setMyLocationEnabled(isShow);

}

public void setMapType(int type){

    switch (type){

        case 1:

            aMap.setMapType(AMap.MAP_TYPE_NORMAL);// 設定普通地圖模式

            break;

        case 2:

            aMap.setMapType(AMap.MAP_TYPE_NAVI);// 設定導航地圖模式

            break;

        case 3:

            aMap.setMapType(AMap.MAP_TYPE_NIGHT);// 設定夜景地圖模式

            break;

        case 4:

            aMap.setMapType(AMap.MAP_TYPE_SATELLITE);// 設定衛星地圖模式

            break;

    }

}

 public void onDestroy(){

    mapView.onDestroy();

 }

 public void onResume(){

     mapView.onResume();

 }

 public void onPause(){

     mapView.onPause();

 }

 public void onCreate(Bundle outState){

     mapView.onCreate(outState);

 }

 public void onSaveInstanceState(Bundle outState){

     mapView.onSaveInstanceState(outState);

 }

2、開發WXMapComponent元件

   建立WXMapComponent繼承 WXComponent<WeexMapView>

   WXMapComponent.java代碼如下:

   public class WXMapComponent extends WXComponent<WeexMapView> {

    WeexMapView mapView;

    WXSDKInstance wxInstance; //weex執行個體對象,用于獲得上下文

    boolean clicked=false;

    //兩個不同參數的構造方法

    public WXMapComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) {

        super(instance, dom, parent);

        wxInstance = instance;

    }

    public WXMapComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, int type) {

        super(instance, dom, parent, type);

        wxInstance = instance;

    }

    @Override

    protected WeexMapView initComponentHostView(@NonNull Context context) {

        //獲得WeexMapView的對象

        this.mapView = new WeexMapView(context);

        return this.mapView;

    }

    @Override

    protected void onCreate() {

        super.onCreate();

    }

    @Override

    public void onActivityDestroy() {

        super.onActivityDestroy();

    }

    @WXComponentProp(name = "model")

    public void setMapModel(int model) {

       mapView.setMapModel(model);

    }

    //設定預設定位按鈕是否顯示,非必需設定。

    @WXComponentProp(name = "showLocationButton")

    public void showLocationButton(boolean isShow){

        mapView.showLocationButton(isShow);

    }

    // 設定為true表示啟動顯示定位藍點,false表示隐藏定位藍點并不進行定位,預設是false。

    @WXComponentProp(name = "showLocationPoint")

    public void showLocationPoint(boolean isShow)

    {

        mapView.showLocationPoint(isShow);

    }

    @WXComponentProp(name = "mapType")

    public void setMapType(int type){

        mapView.setMapType(type);

    }

    @JSMethod(uiThread = true)

    public void addMarker(float lnt, float lat, String title, String content,

                          boolean draggable, boolean setFlat, boolean isAnimation, long duration,

                          JSCallback clickCallback,JSCallback dragCallback) {

        LatLng latLng = new LatLng(lnt,lat);

        MarkerOptions markerOption = new MarkerOptions();

        markerOption.position(latLng);

        markerOption.title(title).snippet(content);

        markerOption.draggable(draggable);//設定Marker可拖動

        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory

                .decodeResource(wxInstance.getContext().getResources(), R.drawable.cercle)));

        // 将Marker設定為貼地顯示,可以雙指下拉地圖檢視效果

        markerOption.setFlat(setFlat);//設定marker平貼地圖效果

        Marker marker=mapView.getaMap().addMarker(markerOption);

        if(isAnimation){

            Animation animation = new RotateAnimation(marker.getRotateAngle(),marker.getRotateAngle()+180,0,0,0);

            animation.setDuration(duration);

            animation.setInterpolator(new LinearInterpolator());

            marker.setAnimation(animation);

            marker.startAnimation();

        }

        mapView.getaMap().setOnMarkerClickListener(new AMap.OnMarkerClickListener() {

            @Override

            public boolean onMarkerClick(Marker marker) {

                marker.showInfoWindow();

                return true;

            }

        });

        mapView.getaMap().setOnMarkerDragListener(new AMap.OnMarkerDragListener() {

            @Override

            public void onMarkerDragStart(Marker marker) {

            }

            @Override

            public void onMarkerDrag(Marker marker) {

            }

            @Override

            public void onMarkerDragEnd(Marker marker) {

            }

        });

    }

    @JSMethod(uiThread = true)

    public void addCircle(float lat,float lng,int radius,int strokeWidth){

     LatLng latLng=new LatLng(lat,lng);

     mapView.getaMap().addCircle(new CircleOptions().

             center(latLng).radius(radius).fillColor(Color.BLUE).

             strokeColor(Color.RED).strokeWidth(strokeWidth));

    }

    @JSMethod(uiThread = true)

    public void addLine(ArrayList list) throws JSONException {

        ArrayList<LatLng> latLngList=new ArrayList<LatLng>();

        for(int i=0;i<list.size();i++){

            com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);

            BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");

            BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");

            float lat=bigLat.floatValue();

            float lng=bigLng.floatValue();

//            Log.d(lat+"-"+lng,"經緯度");

            LatLng latLng=new LatLng(lat,lng);

            latLngList.add(latLng);

        }

        mapView.getaMap().addPolyline(new PolylineOptions().addAll(latLngList).width(10).color(Color.BLUE));

    }

    @JSMethod(uiThread = true)

    public void addTileOverlay(ArrayList list){

        ArrayList<LatLng> latLngList=new ArrayList<LatLng>();

        for(int i=0;i<list.size();i++){

            com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);

            BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");

            BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");

            float lat=bigLat.floatValue();

            float lng=bigLng.floatValue();

//            Log.d(lat+"-"+lng,"經緯度");

            LatLng latLng=new LatLng(lat,lng);

            latLngList.add(latLng);

        }

        // 建構熱力圖 HeatmapTileProvider

        HeatmapTileProvider.Builder builder = new HeatmapTileProvider.Builder();

        builder.data(latLngList); // 設定熱力圖繪制的資料

//                .gradient(A); // 設定熱力圖漸變,有預設值 DEFAULT_GRADIENT,可不設定該接口

// Gradient 的設定可見參考手冊

// 構造熱力圖對象

        HeatmapTileProvider heatmapTileProvider = builder.build();

        // 初始化 TileOverlayOptions

        TileOverlayOptions tileOverlayOptions = new TileOverlayOptions();

        tileOverlayOptions.tileProvider(heatmapTileProvider); // 設定瓦片圖層的提供者

// 向地圖上添加 TileOverlayOptions 類對象

        mapView.getaMap().addTileOverlay(tileOverlayOptions);

    }

    @JSMethod(uiThread = true)

    public void setInfoWindowAdapter(){

      mapView.getaMap().setInfoWindowAdapter(new AMap.InfoWindowAdapter() {

          @Override

          public View getInfoWindow(Marker marker) {

              return null;

          }

          View infoWindow = null;

          @Override

          public View getInfoContents(Marker marker) {

              if(infoWindow == null) {

                  infoWindow = LayoutInflater.from(wxInstance.getContext()).inflate(

                          R.layout.custom_info_window, null);

              }

//              render(marker, infoWindow);

              return infoWindow;

           //加載custom_info_window.xml布局檔案作為InfoWindow的樣式

          }

      });

      mapView.getaMap().setOnInfoWindowClickListener(new AMap.OnInfoWindowClickListener() {

          @Override

          public void onInfoWindowClick(Marker marker) {

             String content=marker.getSnippet().toString();

              Toast.makeText(wxInstance.getContext(),content,Toast.LENGTH_LONG).show();

          }

      });

    }

}

   值得注意的一點是在H5界面的json數組通過元件的接口傳到原生需要用ArrayList接收,在把ArrayList中的每一個元素轉換成com.alibaba.fastjson.JSONObject。通過JSONObject的get("JsonName"),可以獲得存在json中的值。

        for(int i=0;i<list.size();i++){

            com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);

            BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");

            BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");

            float lat=bigLat.floatValue();

            float lng=bigLng.floatValue();

//            Log.d(lat+"-"+lng,"經緯度");

            LatLng latLng=new LatLng(lat,lng);

            latLngList.add(latLng);

        }

3、開發WXMapModule元件

 建立WXLocationModule 繼承WXModule類,其中添加@JSMethod的方法可以在H5界面調用。

   public class WXLocationModule extends WXModule{

    @JSMethod

    public void getLocationInfo(float longitude,float latitude,final JSCallback callback) {

        GeocodeSearch geocoderSearch = new GeocodeSearch(mWXSDKInstance.getContext());//位置搜對象

        LatLonPoint point=new LatLonPoint(longitude,latitude);//坐标

        float range=200;//範圍

        RegeocodeQuery query=new RegeocodeQuery(point,200,GeocodeSearch.AMAP);

        geocoderSearch.getFromLocationAsyn(query);

        geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {

            @Override

            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {//獲得位置資訊的回調方法

                Map<String, Object> map = new HashMap<>();

                map.put("locationInfo", regeocodeResult);

                callback.invokeAndKeepAlive(map);

            }

            @Override

            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

            }

        });

    }

    @JSMethod

    public void getLocationByName(String name,String cityCode,final JSCallback callback){

        GeocodeSearch geocoderSearch = new GeocodeSearch(mWXSDKInstance.getContext());//位置搜對象

        // name表示位址,第二個參數表示查詢城市,中文或者中文全拼,citycode、adcode

        GeocodeQuery query = new GeocodeQuery(name,cityCode);

        geocoderSearch.getFromLocationNameAsyn(query);

        geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {

            @Override

            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {

            }

            @Override

            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

                Map<String, Object> map = new HashMap<>();

                map.put("location", geocodeResult);

                callback.invokeAndKeepAlive(map);

            }

        });

    }

    @JSMethod

    public void getWeatherInfo(String pace,String type){

    //檢索參數為城市和天氣類型,實況天氣為WEATHER_TYPE_LIVE、天氣預報為WEATHER_TYPE_FORECAST

    }

    @JSMethod

    public void getDistance(LatLng latLng1,LatLng latLng2){

        float distance = AMapUtils.calculateLineDistance(latLng1,latLng2);

    }

    @JSMethod

    public void downloadMapOffline(String cityname) throws AMapException {

//構造OfflineMapManager對象

            amapManager = new OfflineMapManager(mWXSDKInstance.getContext(), new OfflineMapManager.OfflineMapDownloadListener() {

            @Override

            public void onDownload(int i, int i1, String s) {

            }

            @Override

            public void onCheckUpdate(boolean b, String s) {

            }

            @Override

            public void onRemove(boolean b, String s, String s1) {

            }

        });

//按照citycode下載下傳

//        amapManager.downloadByCityCode(String citycode);

//按照cityname下載下傳

        amapManager.downloadByCityName(cityname);

//        amapManager.pause();

//        amapManager.stop();

        // 設定應用單獨的地圖存儲目錄

//        MapsInitializer.sdcardDir = "自定義的目錄";

    }

    @JSMethod

    public void updateOfflineCityByName(String cityname) throws AMapException {

        //通過updateOfflineCityByName方法判斷離線地圖資料是否存在更新

        amapManager.updateOfflineCityByName(cityname);

    }

    public void deleteOfflineCityByName(String cityName){

        //删除某一城市的離線地圖包

        amapManager.remove(cityName);

    }

    @JSMethod

    public void getDownloadOfflineMapCityList(){

//        擷取城市清單

        ArrayList<OfflineMapCity> offlineMapCityList = amapManager.getOfflineMapCityList();

//        擷取省清單

        ArrayList<OfflineMapProvince> offlineMapProvinceList = amapManager.getOfflineMapProvinceList();

//        擷取已下載下傳城市清單

        ArrayList<OfflineMapCity> downloadOfflineMapCityList = amapManager.getDownloadOfflineMapCityList();

//        擷取正在或等待下載下傳城市清單

        ArrayList<OfflineMapCity> downloadingCityList = amapManager.getDownloadingCityList();

    }

}

4、注冊Component和Module

在建立myAplication繼承Application,在其onCreate()方法中注冊元件。

Weex地圖元件開發流程及使用(android)

三、元件主要功能及使用方法

1)WXlocationModule使用

  在H5中引入元件:

  var location=weex.requireModule('Location');

1、根據描述和城市編碼獲得坐标資訊

location.getLocationByName('廊坊市廣陽區新奧科技園B座','0316',function (res) {

     self.point=res.location.geocodeAddressList[0].latLonPoint;//獲得坐标資訊

    });

2、根據坐标獲得位置資訊

  location.getLocationInfo(lat,lnt,function (res) {

    var info=res;

   });

3、獲得天氣資訊

  location.getWeatherInfo('北京市','now',function (res) {

    var weatherInfo=res;

  });

4、得到兩個坐标點之間的距離

 location.getDistance(latLng1,latLng2,function (res) {

    var distance=res;

 });

5、離線地圖相關

location.downloadMapOffline(cityname);//下載下傳離線地圖,可設定下載下傳路徑

  location.deleteOfflineCityByName(cityName);//删除離線地圖

  location.getDownloadOfflineMapCityList()//獲得離線地圖清單

2)WXMapComponent使用

   在H5中使用元件:

  <map ref="myMap" style="width: 750px;height: 1300px" showLocationButton="true" model="1" showLocationPoint="true" mapType="1">

</map>

 showLocationButton:是否顯示定位按鈕

    Model:定位方式

    mapType:地圖模式(衛星圖,夜間圖等)

showLocationPoint:是否顯示目前所在點的标示圖

1、顯示地圖上某個坐标處的标示,點選顯示提示資訊

   this.$refs.myMap.addMarker(lat, lnt, '新奧科技園', '新奧科技園B座',

    true, false, true, 1.00,      //參數:經度、緯度、标題、内容、是否可拖動、是否平貼地圖、是否使用動畫、動畫時間

    function (res) {//點選事件

     modal.toast({message:'click'})

    },function (res) {//拖動事件

      modal.toast({message:'drag'})

    });

2、以某個坐标點為圓心,畫一個圓形圖

self.$refs.myMap.addCircle(self.point.latitude,self.point.longitude,1000,20);

     第一個和第二個參數分别為圓心的經度和緯度坐标,第三個參數為半徑,第四個參數為圓形的線的寬度

3、在地圖上繪制線

   self.$refs.myMap.addLine(self.pointList);

   參數是一個坐标點的集合

4、在地圖上繪制熱力圖層

   self.$refs.myMap.addTileOverlay(self.pointList);

    參數是一個坐标的集合

繼續閱讀