[ASP.net WebForm/Google] 在Google Map上放置多個標記地點(Marker)/API 3版

[ASP.net WebForm/Google] 在Google Map上放置多個標記地點(Marker)/API 3版

這次被指派的任務要快速完成以下功能

image

在Google Map上放置多個Marker,可以的話,那些Marker的樣式圖片還能夠自訂

 

這邊就先利用Google的地理編碼技術,把地址轉成JSON資訊來看看

.aspx.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
/*要引用以下命名空間*/
using System.Net;
using System.IO;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)//Get Method要做的事
        {
            //飛碟電台大樓
            Response.Write(this.convertAddressToLatLng("台北市羅斯福路2段100號"));
        }



    }

    //把地址轉成JSON格式,這樣資訊裡才有緯經度
    //因為使用到地理編碼技術,請注意使用限制:http://code.google.com/intl/zh-TW/apis/maps/documentation/geocoding/#Limits
    private string convertAddressToLatLng(string address)
    {
        var url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=" + Server.UrlEncode(address);

        string result = String.Empty;
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        using (var response = request.GetResponse())
        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
             
            result = sr.ReadToEnd();
        }
        return result;
    
    }
}

執行結果:

確實產生一堆JSON資訊,但是需要的緯經度在哪裡,這時候就需要Online JSON Viewer協助

image

把以上的JSON字串貼到方框裡後按Format

image

之後再切換到Viewer頁籤

image

透過Online JSON Viewer可以很快速地知道「台北市羅斯福路2段100號」這段地址的緯度(lat:25.0267474)、經度(lng:121.5223709)

viewport為檢視區域,那個不理它

知道是哪個值後,就可以透過JSON.net(右方Download解壓>把Bin\Net\Newtonsoft.Json.dll丟到Web Site專案的Bin目錄即馬上加入參考)

抓取我們要的資料


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
/*要引用以下命名空間*/
using System.Net;
using System.IO;
/*Json.NET相關的命名空間*/
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)//Get Method要做的事
        {
            //飛碟電台大樓
            //Response.Write(this.convertAddressToLatLng("台北市羅斯福路2段100號"));

            string str_json = this.convertAddressToLatLng("台北市羅斯福路2段100號");
            JObject jo = JsonConvert.DeserializeObject<JObject>(str_json);


            //從results開始往下找
            JArray ja = (JArray)jo.Property("results").Value;
            jo = ja.Value<JObject>(0);//JArray第0筆
            //得到location的JObject
            jo = (JObject)((JObject)jo.Property("geometry").Value).Property("location").Value;
            //緯度
            double lat = Convert.ToDouble(((JValue)jo.Property("lat").Value).Value);
            //經度
            double lng = Convert.ToDouble(((JValue)jo.Property("lng").Value).Value);

            Response.Write("緯度:" + lat + "<hr/>");
            Response.Write("經度:" + lng + "<hr/>");
        }



    }

    //把地址轉成JSON格式,這樣資訊裡才有緯經度
    //因為使用到地理編碼技術,請注意使用限制:http://code.google.com/intl/zh-TW/apis/maps/documentation/geocoding/#Limits
    private string convertAddressToLatLng(string address)
    {
        var url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=" + Server.UrlEncode(address);

        string result = String.Empty;
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        using (var response = request.GetResponse())
        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        {

            result = sr.ReadToEnd();
        }
        return result;

    }
}

執行結果:

image

確認這樣取得的緯度和經度無誤後,接下來要透過jQuery Ajax把座標Mark到Google Map上

先把剛剛寫的Code都搬移到泛型處理常式 .ashx


<%@ WebHandler Language="C#" Class="getSpot" %>

using System;
using System.Web;
/*要引用以下的命名空間*/
using System.Data;
using System.Data.SqlClient;
using System.Net;
using System.IO;
/*Json.NET相關的命名空間*/
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class getSpot : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        //取得DataTable
        DataTable dt = this.queryDataTable();
        //將DataTable轉成JSON字串
        string str_json = JsonConvert.SerializeObject(dt, Formatting.Indented);
        context.Response.Write(str_json);
    }
 
    /// <summary>
    /// 從DB撈出DataTable
    /// </summary>
    /// <returns></returns>
     private DataTable queryDataTable()
    {
         
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("緯度",typeof(double)));
        dt.Columns.Add(new DataColumn("經度",typeof(double)));
        dt.Columns.Add(new DataColumn("名稱",typeof(string)));

        DataRow dr = dt.NewRow();
        string str_json = this.convertAddressToJSONString("台北市羅斯福路2段100號");
        double[] latLng = this.getLatLng(str_json);
        dr["緯度"] = latLng[0];
        dr["經度"] = latLng[1];
        dr["名稱"] = "飛碟電台大樓";
        dt.Rows.Add(dr);

        dr = dt.NewRow();
        str_json = this.convertAddressToJSONString("台北市和平東路一段162號");
        latLng = this.getLatLng(str_json);
        dr["緯度"] = latLng[0];
        dr["經度"] = latLng[1];
        dr["名稱"] = "台灣師範大學行政部";
        dt.Rows.Add(dr);

        dr = dt.NewRow();
        str_json = this.convertAddressToJSONString("台北市中正區羅斯福路2段164-1號");
        latLng = this.getLatLng(str_json);
        dr["緯度"] = latLng[0];
        dr["經度"] = latLng[1];
        dr["名稱"] = "捷運古亭站";
        dt.Rows.Add(dr);

        return dt;
    }


    /// <summary>
    /// 傳入JSON字串,取得緯經度
    /// </summary>
    /// <param name="json"></param>
    /// <returns></returns>
     private double[] getLatLng(string json)
     {
         JObject jo = JsonConvert.DeserializeObject<JObject>(json);

         //從results開始往下找
         JArray ja = (JArray)jo.Property("results").Value;
         jo = ja.Value<JObject>(0);//JArray第0筆
         //得到location的JObject
         jo = (JObject)((JObject)jo.Property("geometry").Value).Property("location").Value;
         
         //緯度
         double lat = Convert.ToDouble(((JValue)jo.Property("lat").Value).Value);
         //經度
         double lng = Convert.ToDouble(((JValue)jo.Property("lng").Value).Value);
         
         double[] latLng= {lat,lng};

         return latLng;
     
     } 
     //把地址轉成JSON格式,這樣資訊裡才有緯經度
     //因為使用到地理編碼技術,請注意使用限制:http://code.google.com/intl/zh-TW/apis/maps/documentation/geocoding/#Limits
     private string convertAddressToJSONString(string address)
     {
         var url = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=" + HttpContext.Current.Server.UrlEncode(address);

         string result = String.Empty;
         HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
         using (var response = request.GetResponse())
         using (StreamReader sr = new StreamReader(response.GetResponseStream()))
         {

             result = sr.ReadToEnd();
         }
         return result;

     }
 
    
    
    public bool IsReusable {
        get {
            return false;
        }
    }

}

再把.cs檔 Code-Behind的代碼都清空


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;


public partial class _Default : System.Web.UI.Page
{
     

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)//Get Method要做的事
        {
            
        }

    }

}

.aspx的設計畫面


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"
    Debug="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>
    <!--要玩Google Map 就一定要引用此js-->
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript">
        $(document).ready(init);

        //網頁上所有的DOM都載入後
        function init() {
            addMarker();
        }
        //加入標記點
        function addMarker() {
            $.ajax(
            {
                url: 'getSpot.ashx',
                type: 'post',
                async: false,
                data: {},
                dataType: 'json',
                success: function (data) {


                    var first = true;
                    var map;
                    for (var index in data) {

                        if (first == true) {//第一次執行迴圈
                            /*以哪個緯經度中心來產生地圖*/
                            var latlng = new google.maps.LatLng(data[index].緯度, data[index].經度);
                            var myOptions = {
                                zoom: 14,
                                center: latlng,
                                mapTypeId: google.maps.MapTypeId.ROADMAP
                            };
                            /*產生地圖*/
                            map = new google.maps.Map($("#div_showMap")[0], myOptions);

                            first = false;
                        } //End if (first == true) 


                        //建立緯經度座標
                        var myLatlng = new google.maps.LatLng(data[index].緯度, data[index].經度);
                        //加一個Marker到map中
                        var marker = new google.maps.Marker({
                            position: myLatlng,
                            map: map,
                            title: data[index].名稱
                        });
                    } //End for (var index in data) 
                }     //End success: function (data) 
            });       //End jQuery Ajax
        }             //End function addMarker() 

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="div_showMap" style="width: 800px; height: 600px">
    </div>
    </form>
</body>
</html>

執行.aspx的結果:

image

確實出現三個標記點

因為時間不早了,等早上再來研究如何更改標記點圖示和加入對話框

研究包

下一篇:[ASP.net WebForm/Google] Google Map標記點(Marker)更改圖示、加入對話框/API 3版

其他參考資料:(官方) Google Maps Javascript API V3 Examples

(官方)反向地理編碼 (地址查閱)

MSDN討論:怎么使用google maps api?(经纬度转地址)

取得用戶端的地理位置

其他衍伸閱讀文章:

GoogleMap 結合資料庫在地圖上加入地標

筆記-地址轉換經緯度 C#及Javascript版本

Google Maps API地址轉換 黑暗執行緒