第3章(第12講)興趣點( POI)搜索功能

来源:http://www.cnblogs.com/rainmj/archive/2016/02/04/5181543.html
-Advertisement-
Play Games

分類:C#、Android、VS2015、百度地圖應用; 創建日期:2016-02-04 一、簡介 POI(Point of Interest),中文可以翻譯為“興趣點”。在地理信息系統中,一個POI可以是一棟房子、一個商鋪、一個郵筒、一個公交站等。 1、POI檢索 百度地圖SDK提供三種類型的PO


分類:C#、Android、VS2015、百度地圖應用; 創建日期:2016-02-04

一、簡介

POI(Point of Interest),中文可以翻譯為“興趣點”。在地理信息系統中,一個POI可以是一棟房子、一個商鋪、一個郵筒、一個公交站等。

1、POI檢索

百度地圖SDK提供三種類型的POI檢索:周邊檢索、區域檢索和城市內檢索。

l 周邊檢索:以某一點為中心,指定距離為半徑,根據用戶輸入的關鍵詞進行POI檢索;

l 區域檢索:在指定矩形區域內、根據關鍵詞進行POI檢索;

l 城市內檢索:在某一城市內,根據用戶輸入的關鍵字進行POI檢索;

自v3.6.1開始,城市poi檢索返回結果新增門址類列表數據。例如:在“北京”搜索“上地十街1號”,除返回包含“上地十街1號”的poi列表以外,還包括地址為“上地十街1號”的明確門址。

具體來說,即PoiSearch類的SearchInCity(PoiCitySearchOption) 發起檢索時返回的結果增加門址類數據。PoiResult中新增了GetAllAddr()獲取門址類列表,當isHasAddrInfo() 返回true時,除了原poi列表外,還包含門址結果。

2、POI詳情信息的檢索

POI詳情檢索是指根據POI的ID信息,檢索該興趣點的詳情。

3、線上建議查詢

線上建議查詢是指根據關鍵詞查詢線上建議詞。為了幫助開發者實現檢索出來的關鍵詞快速定位到地圖上,SDK自3.5.0版本起,開放了檢索結果的經緯度信息及對應POI點的UID信息。

註意:

a. 線上建議檢索的本質是根據部分關鍵是檢索出來可能的完整關鍵詞名稱,如果需要這些關鍵詞對應的POI的具體信息,請使用POI檢索來完成;

b. 線上檢索結果的第一條可能存在沒有經緯度信息的情況,該條結果為文字聯想出來的關鍵詞結果,並不對應任何確切POI點。例如輸入“肯”,第一條結果為“肯德基”,這條結果是一個泛指的名稱,不會帶有經緯度等信息。

二、運行截圖

簡介:介紹關鍵詞查詢、suggestion查詢和查看餐飲類Place詳情頁功能

詳述:

(1)點擊某些關鍵詞查詢後的結果(如“餐廳”)可跳轉到Place詳情頁;

(2)提供suggestion查詢進行聯想查詢,例如輸入“天安門”則會彈出聯想查詢的列表;

本示例運行截圖如下:

image

三、設計步驟

1、添加demo12_poisearch.xml文件

在layout文件夾下添加該文件,然後將代碼改為下麵的內容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="在" >
        </TextView>

        <EditText
            android:id="@+id/city"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="北京" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="市內找" >
        </TextView>

        <AutoCompleteTextView
            android:id="@+id/searchkey"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.88"
            android:text="餐廳" />
    </LinearLayout>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/search"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="12"
            android:background="@drawable/button_style"
            android:padding="10dip"
            android:text="開始" />

        <Button
            android:id="@+id/map_next_data"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="12"
            android:background="@drawable/button_style"
            android:padding="10dip"
            android:text="下一組數據" />
    </LinearLayout>

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.baidu.mapapi.map.TextureMapFragment" />

</LinearLayout>

2、添加OverlayManager.cs文件

新建一個SrcOverlayUtil文件夾,在該文件夾下添加該文件。

說明:SrcOverlayUtil文件夾下的文件用於自定義一些基於基礎覆蓋而組合而成的高級覆蓋物,包括用於顯示poi數據,規劃路線,公交詳情路線的覆蓋物等。

using Com.Baidu.Mapapi.Map;
using Com.Baidu.Mapapi.Model;
using System.Collections.Generic;
namespace BdMapV371Demos.SrcOverlayUtil
{
    /// <summary>
    /// 提供一個能夠顯示和管理多個Overlay的基類。
    /// 將覆蓋物點擊事件傳遞給OverlayManager後,OverlayManager才能響應點擊事件。
    /// 在MarkerClick事件中處理Marker點擊事件。
    /// </summary>
    public abstract class OverlayManager : Java.Lang.Object, BaiduMap.IOnMarkerClickListener, BaiduMap.IOnPolylineClickListener
    {
        BaiduMap mBaiduMap = null;
        private List<OverlayOptions> mOverlayOptionList = null;

        protected List<Overlay> mOverlayList = null;

        public OverlayManager(BaiduMap baiduMap)
        {
            mBaiduMap = baiduMap;
            mBaiduMap.SetOnMarkerClickListener(this);
            if (mOverlayOptionList == null)
            {
                mOverlayOptionList = new List<OverlayOptions>();
            }
            if (mOverlayList == null)
            {
                mOverlayList = new List<Overlay>();
            }
        }

        /// <summary>
        /// 重寫此方法設置要管理的Overlay列表
        /// </summary>
        /// <returns></returns>
        public abstract List<OverlayOptions> GetOverlayOptions();

        /// <summary>
        /// 將所有Overlay 添加到地圖上
        /// </summary>
        public void AddToMap()
        {
            if (mBaiduMap == null)
            {
                return;
            }
            RemoveFromMap();
            List<OverlayOptions> overlayOptions = GetOverlayOptions();
            if (overlayOptions != null)
            {
                mOverlayOptionList.AddRange(GetOverlayOptions());
            }

            foreach (OverlayOptions option in mOverlayOptionList)
            {
                mOverlayList.Add(mBaiduMap.AddOverlay(option));
            }
        }

        /// <summary>
        /// 將所有Overlay從地圖上消除
        /// </summary>
        public void RemoveFromMap()
        {
            if (mBaiduMap == null)
            {
                return;
            }
            foreach (Overlay marker in mOverlayList)
            {
                marker.Remove();
            }
            mOverlayOptionList.Clear();
            mOverlayList.Clear();
        }

        /// <summary>
        /// 縮放地圖,使所有Overlay都在合適的視野內
        /// 註: 該方法只對Marker類型的overlay有效
        /// </summary>
        public void ZoomToSpan()
        {
            if (mBaiduMap == null)
            {
                return;
            }
            if (mOverlayList.Count > 0)
            {
                LatLngBounds.Builder builder = new LatLngBounds.Builder();
                foreach (Overlay overlay in mOverlayList)
                {
                    // polyline 中的點可能太多,只按marker縮放
                    if (overlay is Marker)
                    {
                        builder.Include(((Marker)overlay).Position);
                    }
                }
                mBaiduMap.SetMapStatus(MapStatusUpdateFactory
                        .NewLatLngBounds(builder.Build()));
            }
        }

        public virtual bool OnMarkerClick(Marker marker)
        {
            return false;
        }

        public virtual bool OnPolylineClick(Polyline polyline)
        {
            return false;
        }
    }
}

3、添加PoiOverlay.cs文件

在SrcOverlayUtil文件夾下添加該文件。

using Android.OS;
using Android.Widget;
using Com.Baidu.Mapapi;
using Com.Baidu.Mapapi.Map;
using Com.Baidu.Mapapi.Search.Poi;
using System.Collections.Generic;

namespace BdMapV371Demos.SrcOverlayUtil
{
    /// <summary>
    /// 顯示一條公交詳情結果的Overlay,繼承自該類的子類可顯示其他類型的Overlay
    /// </summary>
    public class PoiOverlay : OverlayManager
    {
        private static readonly int MaxPoiSize = 10;
        private PoiResult mPoiResult = null;

        public PoiOverlay(BaiduMap baiduMap) : base(baiduMap)
        {

        }

        /// <summary>
        /// 設置POI數據
        /// </summary>
        /// <param name="poiResult">POI結果數據</param>
        public void SetData(PoiResult poiResult)
        {
            this.mPoiResult = poiResult;
        }

        public override List<OverlayOptions> GetOverlayOptions()
        {

            if (mPoiResult == null || mPoiResult.AllPoi == null)
            {
                return null;
            }
            List<OverlayOptions> markerList = new List<OverlayOptions>();
            int markerSize = 0;
            for (int i = 0; i < mPoiResult.AllPoi.Count && markerSize < MaxPoiSize; i++)
            {
                if (mPoiResult.AllPoi[i].Location == null)
                {
                    continue;
                }
                markerSize++;
                Bundle bundle = new Bundle();
                bundle.PutInt("index", i);
                markerList.Add(new MarkerOptions()
                    .InvokeIcon(BitmapDescriptorFactory.FromAssetWithDpi("Icon_mark"
                            + markerSize + ".png")).InvokeExtraInfo(bundle)
                    .InvokePosition(mPoiResult.AllPoi[i].Location));
            }
            return markerList;
        }

        /// <summary>
        /// 獲取該 PoiOverlay 的 poi數據
        /// </summary>
        public PoiResult GetPoiResult()
        {
            return mPoiResult;
        }

        /// <summary>
        /// 重寫此方法可改變預設點擊行為
        /// </summary>
        /// <param name="i">被點擊的poi在PoiResult.AllPoi中的索引</param>
        /// <returns></returns>
        public virtual bool OnPoiClick(int i)
        {
            if (mPoiResult.AllPoi != null && mPoiResult.AllPoi[i] != null)
            {
                Toast.MakeText(BMapManager.Context,
                        mPoiResult.AllPoi[i].Name, ToastLength.Long).Show();
            }
            return false;
        }

        public override bool OnMarkerClick(Marker marker)
        {
            if (!mOverlayList.Contains(marker))
            {
                return false;
            }
            if (marker.ExtraInfo != null)
            {
                return OnPoiClick(marker.ExtraInfo.GetInt("index"));
            }
            return false;
        }

        public override bool OnPolylineClick(Polyline polyline)
        {
            return false;
        }
    }
}

4、添加Demo12PoiSearch.cs文件

在SrcSdkDemos文件夾下添加該文件,然後將代碼改為下麵的內容:

using Android.App;
using Android.Content.PM;
using Android.OS;
using Android.Support.V4.App;
using Android.Widget;
using BdMapV371Demos.SrcOverlayUtil;
using Com.Baidu.Mapapi.Map;
using Com.Baidu.Mapapi.Search.Core;
using Com.Baidu.Mapapi.Search.Poi;
using Com.Baidu.Mapapi.Search.Sug;

namespace BdMapV371Demos.SrcSdkDemos
{
    /// <summary>
    /// 演示poi搜索功能
    /// </summary>
    [Activity(Label = "@string/demo_name_poi",
        ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
         ScreenOrientation = ScreenOrientation.Sensor)]
    public class Demo12PoiSearch : FragmentActivity
    {
        private PoiSearch mPoiSearch = null;
        private SuggestionSearch mSuggestionSearch = null;
        private BaiduMap mBaiduMap = null;
        // 搜索關鍵字輸入視窗
         private AutoCompleteTextView keyWorldsView = null;
        private ArrayAdapter<string> sugAdapter = null;
        private int load_Index = 0;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.demo12_poisearch);

            // 初始化搜索模塊,註冊搜索事件監聽
            mPoiSearch = PoiSearch.NewInstance();
            mPoiSearch.GetPoiResult += (s, e) =>
            {
                var result = e.P0;
                if (result == null
                        || result.Error == SearchResult.ERRORNO.ResultNotFound)
                {
                    return;
                }
                if (result.Error == SearchResult.ERRORNO.NoError)
                {
                    mBaiduMap.Clear();
                    PoiOverlay overlay = new MyPoiOverlay(this, mBaiduMap);
                    mBaiduMap.SetOnMarkerClickListener(overlay);
                    overlay.SetData(result);
                    overlay.AddToMap();
                    overlay.ZoomToSpan();
                    return;
                }
                if (result.Error == SearchResult.ERRORNO.AmbiguousKeyword)
                {

                    // 當輸入關鍵字在本市沒有找到,但在其他城市找到時,返回包含該關鍵字信息的城市列表
                    string strInfo = "";
                    foreach (CityInfo cityInfo in result.SuggestCityList)
                    {
                        strInfo += cityInfo.City;
                        strInfo += ",";
                    }
                    strInfo += "找到結果";
                    Toast.MakeText(this, strInfo, ToastLength.Long)
                            .Show();
                }
            };
            mPoiSearch.GetPoiDetailResult += (s, e) =>
            {
                var result = e.P0;
                if (result.Error != SearchResult.ERRORNO.NoError)
                {
                    Toast.MakeText(this, "抱歉,未找到結果", ToastLength.Short).Show();
                }
                else
                {
                    Toast.MakeText(this, "成功,查看詳情頁面", ToastLength.Short).Show();
                }
            };

            mSuggestionSearch = SuggestionSearch.NewInstance();
            mSuggestionSearch.GetSuggestionResult += (s, e) =>
            {
                var res = e.P0;
                if (res == null || res.AllSuggestions == null) return;
                sugAdapter.Clear();
                foreach (SuggestionResult.SuggestionInfo info in res.AllSuggestions)
                {
                    if (info.Key != null) sugAdapter.Add(info.Key);
                }
                sugAdapter.NotifyDataSetChanged();
            };

            keyWorldsView = FindViewById<AutoCompleteTextView>(Resource.Id.searchkey);
            sugAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleDropDownItem1Line);
            keyWorldsView.Adapter = sugAdapter;
            TextureMapFragment map1 = FragmentManager.FindFragmentById<TextureMapFragment>(Resource.Id.map);
            mBaiduMap = map1.BaiduMap;

            // 當輸入關鍵字變化時,動態更新建議列表
            keyWorldsView.AfterTextChanged += (sender, e) => { };
            keyWorldsView.BeforeTextChanged += (sender, e) => { };
            keyWorldsView.TextChanged += (sender, e) =>
            {
                string s = e.Text.ToString();
                if (s.Length <= 0) return;
                string city = (FindViewById<EditText>(Resource.Id.city)).Text;
                // 使用建議搜索服務獲取建議列表,結果在onSuggestionResult()中更新
                mSuggestionSearch.RequestSuggestion(
                    new SuggestionSearchOption().Keyword(s).City(city));
            };

            Button btnSearch = FindViewById<Button>(Resource.Id.search);
            btnSearch.Click += delegate
            {
                SearchButtonProcess();
            };

            Button btnNext = FindViewById<Button>(Resource.Id.map_next_data);
            btnNext.Click += delegate
            {
                load_Index++;
                SearchButtonProcess();
            };
        }

        protected override void OnPause()
        {
            base.OnPause();
        }

        protected override void OnResume()
        {
            base.OnResume();
        }

        protected override void OnDestroy()
        {
            mPoiSearch.Destroy();
            mSuggestionSearch.Destroy();
            base.OnDestroy();
        }

        protected override void OnSaveInstanceState(Bundle outState)
        {
            base.OnSaveInstanceState(outState);
        }

        protected override void OnRestoreInstanceState(Bundle savedInstanceState)
        {
            base.OnRestoreInstanceState(savedInstanceState);
        }

        public void SearchButtonProcess()
        {
            EditText editCity = FindViewById<EditText>(Resource.Id.city);
            EditText editSearchKey = FindViewById<EditText>(Resource.Id.searchkey);
            mPoiSearch.SearchInCity(new PoiCitySearchOption()
                .City(editCity.Text)
                .Keyword(editSearchKey.Text)
                .PageNum(load_Index));
        }

        private class MyPoiOverlay : PoiOverlay
        {
            Demo12PoiSearch poiSearchDemo;

            public MyPoiOverlay(Demo12PoiSearch poiSearchDemo, BaiduMap baiduMap) :
                base(baiduMap)
            {
                this.poiSearchDemo = poiSearchDemo;
            }

            public override bool OnPoiClick(int index)
            {
                base.OnPoiClick(index);
                PoiInfo poi = GetPoiResult().AllPoi[index];
                if (poi.HasCaterDetails)
                {
                    poiSearchDemo.mPoiSearch.SearchPoiDetail(
                        new PoiDetailSearchOption().PoiUid(poi.Uid));
                }
                return true;
            }
        }
    }
}

 

 

 

 

5、修改MainActivity.cs

在MainActivity.cs文件的demos欄位定義中,去掉【示例12】下麵的註釋。

運行觀察結果。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本模板為自適應寬度模板,可相容PC,手機等多種環境,適應不同屏幕大小寬度。預覽圖片:進入下載頁:http://hovertree.com/h/bjaf/bnbpkr9p.htm效果預覽http://hovertree.com/texiao/muban/1/ 轉自:http://hovertree.c
  • webpack入門
  • 1.JQuery簡介: JQuery是用js寫的JavaScript庫,是為了簡化js對HTML元素的操作、實現動畫效果並方便為網站提供ajax交互; 2.ready()方法: ready()方法和js的windown.onload()方法類似,都是當頁面的文檔載入完畢後調用該方法;不同的是read
  • 分類:C#、Android、VS2015; 創建日期:2016-02-07 一、簡介 功能描述:用戶單擊按鈕彈出菜單。當用戶選擇一個菜單項,會觸發MenuItemClick事件並讓彈出的菜單消失;如果用戶在菜單外單擊,則直接消失彈出的菜單。當菜單消失時,會引發DismissEvent事件(利用此事件...
  • 首先,手機橫豎長度的懸殊差距,註定了app橫豎屏的表現的差異化。老實說,目前絕大多數android的App在產品設計之初都是在豎屏的基礎上進行設計的(也就是單手操作),並無專門地去考慮切換橫屏後的用戶體驗。這些App若是允許切換橫屏操作,而用戶的手機又設置了允許自動旋轉,那麼用戶在使用這些App的時...
  • Request failed: unacceptable content type: text/plain(AFNetworking) = 在使用AFNetworking遇到如下問題,已解決。。。 Error Domain=com.alamofire.error.serialization.resp
  • 分類:C#、Android、VS2015;創建日期:2016-02-06 第4章 UI設計基礎 第3章雖然通過百度地圖應用展示了你可能感興趣的內容,但是,如果你是一個初學者,一開始就看懂和理解代碼可能會非常費勁。為瞭解決此問題,從這一章開始,本模塊將從最基本的內容講起,帶你逐步進入用C#進行Andr...
  • 實在太忙,靈魂有香氣的女子這個App,斷斷續續開發了1個多月了,前後臺自己獨立完成, 由於接觸swift沒多久,還屬於新手行列,不熟悉,希望大家給出意見, 根據意見,完善後將於近期將考慮開放swift版本的源代碼。 下載方式: 1、靈魂有香氣的女子這個App :https://itunes.appl
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...