GoogleMap 結合資料庫在地圖上加入地標
在藍色小舖上滿常看到的一個問題就是,如何從DB中撈取座標資料加在GoogleMap上。
雖然這是一個滿基本的功能,但也滿重要的。如果能自己寫出來,我想對於Ajax跟
Client與Server的觀念都有一定的認知,以後要利用此概念做出其他功能也不是難事了。
這篇文章就用實際的範例,來講解這個功能要怎麼做
本篇範例使用WebForm + 泛型處理常式 + jQuery AJAX + GoogleMap V3 來實作 |
- 新開一個Web Application
-
新增一個項目"泛型處理常式",取名為"GoogleMapHandler.ashx"
預設新增之後裡面會有一個屬性一個方法
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Write("Hello World"); } public bool IsReusable { get { return false; } }
IsReusable指定IHttpHandler可否重用,通常都是false
ProcessRequest是我們主要要處理的對象
- 測試案例假設需從前端接收一個Key,然後用此Key去資料去中撈出資料(經度、緯度以及地標名稱),再將撈出的資料以JSON格式傳回前端
在ProcessRequest中加入
//傳進來的參數,可用這個去查詢資料庫
var key = context.Request["key"];
DataTable table = GetMapInfo(key);
拿到名稱為key的參數後,用GetMapInfo方法去資料庫撈取資料。
GetMapInfo可另外抽到別的檔案去實作,但此案例就在原檔案中作假資料
/// <summary>
/// 進資料庫查詢經緯度資料,並傳回DataTable
/// </summary>
private DataTable GetMapInfo(string key)
{
//如果需要用到key去資料庫查資料,請注意SQL Injection的問題
//這邊的範例我就直接建假資料
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("經度"));
table.Columns.Add(new DataColumn("緯度"));
table.Columns.Add(new DataColumn("Title"));
DataRow dr = null;
dr = table.NewRow();
dr["經度"] = "121.517322";
dr["緯度"] = "25.045831";
dr["Title"] = "台北車站";
table.Rows.Add(dr);
dr = table.NewRow();
dr["經度"] = "121.536076";
dr["緯度"] = "25.030511";
dr["Title"] = "大安森林公園";
table.Rows.Add(dr);
dr = table.NewRow();
dr["經度"] = "121.564357";
dr["緯度"] = "25.033506";
dr["Title"] = "台北101";
table.Rows.Add(dr);
return table;
}
以上Code做了三筆假資料,並回傳一個DataTable。
利用此DataTable的資料,組成JSON的格式回傳
/*
JSON 格式
[{ key : value },{ key : value },{ key : value }]
*/
int i = 0;
StringBuilder sb = new StringBuilder();
sb.Append("[");
foreach (DataRow item in table.Rows)
{
i++;
sb.Append("{");
sb.AppendFormat("\"Title\": \"{0}\", \"Lng\": \"{1}\",\"Lat\": \"{2}\"",
item["Title"].ToString(),
item["經度"].ToString(),
item["緯度"].ToString()
);
sb.Append("}");
if (i < table.Rows.Count)
sb.Append(",");
}
sb.Append("]");
context.Response.ContentType = "text/plain";
//將此JSON格式的資料回傳
context.Response.Write(sb.ToString());
到此,Server端程式就已經寫完了。
接著來寫Client端利用jQuery AJAX 呼叫泛型處理常式
1. 寫一個function來去呼叫GoogleMapHandler.ashx,並把座標加入Map中
//參數map為地圖的實體
function AddMark(map) {
//用jQuery的Ajax,向GoogleMapHandler.ashx要求座標資料
//更多用法請看jQuery API
$.ajax({
url: '/GoogleMapHandler.ashx',
type: 'GET',
data: { key: $('#map_key').val() },
dataType: 'json',
success: function (data, textStatus) {
for (var item in data) {
//建立經緯度座標
var myLatlng = new google.maps.LatLng(data[item].Lat, data[item].Lng);
//加一個Marker到map中
//更多用法可看Google Map API V3
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data[item].Title
});
}
}
});
}
url:指定泛型處理常式的路徑
type:使用GET
data:名稱為key,值是ID為map_key的Textbox
dataType:json
succcess:當dataType為json時,此callback的function第一個參數data會使用JSON.parse()
來做轉換,假設我們回傳的json格式是 { 'Name' : 'CodingRoad' }的話 ,則用data.Name就可以取到值。
2. 在Windows onload的時候,加入地圖,並去呼叫GoogleMapHandler.ashx查到經緯度,
建立Marker加到Map之中
function initialize() {
var latlng = new google.maps.LatLng(25.030, 121.536);
var myOptions = {
zoom: 14,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
AddMark(map);
}
//Window Onload的時候加入地圖
google.maps.event.addDomListener(window, 'load', initialize);
做出後的效果為:
貼上完整的Code
GoogleMapHandler.ashx
/// <summary>
///GoogleMapHandler 的摘要描述
/// </summary>
public class GoogleMapHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//傳進來的參數,可用這個去查詢資料庫
var key = context.Request["key"];
DataTable table = GetMapInfo(key);
/*
JSON 格式
[{ key : value },{ key : value },{ key : value }]
*/
int i = 0;
StringBuilder sb = new StringBuilder();
sb.Append("[");
foreach (DataRow item in table.Rows)
{
i++;
sb.Append("{");
sb.AppendFormat("\"Title\": \"{0}\", \"Lng\": \"{1}\",\"Lat\": \"{2}\"",
item["Title"].ToString(),
item["經度"].ToString(),
item["緯度"].ToString()
);
sb.Append("}");
if (i < table.Rows.Count)
sb.Append(",");
}
sb.Append("]");
context.Response.ContentType = "text/plain";
//將此JSON格式的資料回傳
context.Response.Write(sb.ToString());
}
/// <summary>
/// 進資料庫查詢經緯度資料,並傳回DataTable
/// </summary>
private DataTable GetMapInfo(string key)
{
//如果需要用到key去資料庫查資料,請注意SQL Injection的問題
//這邊的範例我就直接建假資料
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("經度"));
table.Columns.Add(new DataColumn("緯度"));
table.Columns.Add(new DataColumn("Title"));
DataRow dr = null;
dr = table.NewRow();
dr["經度"] = "121.517322";
dr["緯度"] = "25.045831";
dr["Title"] = "台北車站";
table.Rows.Add(dr);
dr = table.NewRow();
dr["經度"] = "121.536076";
dr["緯度"] = "25.030511";
dr["Title"] = "大安森林公園";
table.Rows.Add(dr);
dr = table.NewRow();
dr["經度"] = "121.564357";
dr["緯度"] = "25.033506";
dr["Title"] = "台北101";
table.Rows.Add(dr);
return table;
}
public bool IsReusable
{
get
{
return false;
}
}
}
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!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 runat="server">
<title></title>
<script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
//參數map為地圖的實體
function AddMark(map) {
//用jQuery的Ajax,向GoogleMapHandler.ashx要求座標資料
//更多用法請看jQuery API
$.ajax({
url: '/GoogleMapHandler.ashx',
type: 'GET',
data: { key: $('#map_key').val() },
dataType: 'json',
success: function (data, textStatus) {
for (var item in data) {
//建立經緯度座標
var myLatlng = new google.maps.LatLng(data[item].Lat, data[item].Lng);
//加一個Marker到map中
//更多用法可看Google Map API V3
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data[item].Title
});
}
}
});
}
function initialize() {
var latlng = new google.maps.LatLng(25.030, 121.536);
var myOptions = {
zoom: 14,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
AddMark(map);
}
//Window Onload的時候加入地圖
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<form id="form1" runat="server">
地圖參數:<input type="text" id="map_key" value="1" />
<div id="map_canvas" style="width: 800px; height: 600px"></div>
</form>
</body>
</html>
這是一個很基本的功能,但包含了一些基本功。
希望有幫助到問此問題的人。
!! 如果頁面有使用DOCTYPE的話!! 則GoogleMap的容器大小不能用 style=”width:100%;height:100%;”這樣的方式指定; |