65.9K
CodeProject 正在变化。 阅读更多。
Home

如何扩展 TextBox 以使用 Google Maps

2010年1月7日

CPOL

2分钟阅读

viewsIcon

40518

downloadIcon

851

如何扩展 TextBox 以使用 Google 地图获取/设置经度和纬度。

引言

您是否需要存储地址的经度/纬度坐标,或者显示一个小输入框来选择 Google 地图中的一个点? 这里有一个小解决方案:扩展 TextBox 以与 Google 地图交互!

背景

要创建这个简单的控件,您只需要了解一些 C#,MooTools JavaScript 框架,并拥有一个 Google Maps 密钥。

Using the Code

我们将从代码开始。 首先,您需要创建一个空的 ASCX 文件,其中包含以下示例代码

<%@Control  Language="C#" AutoEventWireup="false"  src="gmapinput.cs"  %>

然后,创建一个新的 C# 类文件,该文件扩展一个普通的文本框 (System.Web.UI.WebControls.TextBox)

[DefaultProperty("Text")]
  [ToolboxData("<{0}:Input  runat=server></{0}:Input>")]
  public class GoogleMapInput : TextBox
  {
  ...
  }

首先,我们需要一个基本的属性(Google Maps 密钥); 在这种情况下,我假设有一个 *web.config* 设置,其值为 googleMapsKey

public string GoogleMapKey 
{ 
  get 
  { 
      object o = ViewState["GoogleMapKey"]; 
      if (o == null) {
        if(System.Configuration.ConfigurationSettings.
                 AppSettings["googleMapsKey"]!=null)
            return System.Configuration.ConfigurationSettings.
                          AppSettings["googleMapsKey"];            
        else 
            return string.Empty;
      }else return o.ToString(); 
  } 
  Set { ViewState["GoogleMapKey"] = value; } 
}

现在,我们需要检查一些特性

  • 检查 (如果没有包含) *Mootools.js*
  • 包含特定的 JavaScript 代码(mootools 类)以创建 gmap 输入
  • 包含特定的 CSS 样式表
System.Web.UI.HtmlControls.HtmlHead myhead = this.Page.Header;

string embedobjecturl = 
  "/template/plugins/GoogleMapInput/GoogleMapInput.js";
string cssembedobjecturl = 
  "/template/plugins/GoogleMapInput/GoogleMapInput.css";

for (int i = 0; i < myhead.Controls.Count; i++)
{ 
  if (((LiteralControl)myhead.Controls[i]).Text.
           ToLower().IndexOf("mootools-1.2-core.js") == -1) {
  //include mootools
}

if (((LiteralControl)myhead.Controls[i]).Text.
         ToLower().IndexOf("mootools-1.2-more.js") == -1) {
//include mootools.more
}
//Include the embedObject url and css

现在,我们需要重写 render 属性来编写我们的文本框

protected override void Render(HtmlTextWriter writer)
{
    string thisContainer = this.ClientID + "CC";
    string valore = this.Text;
    string lat = "";
    string log = "";
    //check if the text value is a point and split into  the two part lat/lng
    if (!string.IsNullOrEmpty(valore) && valore.Trim() != "")
    {
        if (valore.IndexOf(',') != -1) {
            lat = valore.Trim().Substring(0, valore.IndexOf(','));
            log = valore.Trim().Substring(valore.IndexOf(',') + 1);
        }
    }
    //prepare the html code :
    writer.Write("<div id=\""+thisContainer+"\" >");
    writer.Write("<div class=\"ginputarea\">");
    writer.Write("<fieldset>");
    writer.Write("<legend>Localit&agrave;</legend>");
    writer.Write("<label for=\""+thisContainer+
                 "_inputAdd\">Localit&agrave;</label>");
    writer.Write("<input type=\"text\"  id=\""+
                 thisContainer+"_inputAdd\" />  ");
    writer.Write("<input type=\"button\"  id=\""+
                 thisContainer+"_btmAdd\" " + 
                 "value=\"update\"  class=\"btmgupd\" />");
    writer.Write("</fieldset>");
    writer.Write("<fieldset class=\"latlong\">");
    writer.Write("<legend>Coordinate</legend>");
    writer.Write("<label for=\""+thisContainer+
                 "_inputLA\">Lat.</label>");
    writer.Write("<input type=\"text\"  id=\""+
                 thisContainer+"_inputLA\" /> ");
    writer.Write("<label for=\""+thisContainer+
                 "_inputLO\">Long.</label>");
    writer.Write("<input type=\"text\"  id=\""+
                 thisContainer+"_inputLO\" />       ");
    writer.Write("<input type=\"button\"  id=\""+thisContainer+
                 "_btmLL\" value=\"update\" " + 
                 "class=\"btmgupd\" />    ");
    writer.Write("</fieldset>");
    writer.Write("</div>");
    writer.Write("<div class=\"gmaparea\">");
    writer.Write("<div id=\"" + thisContainer + 
                 "_maps\"  style=\"width:240px; height:135px;" + 
                 " border:1px solid #333;  \">");
    writer.Write("</div>");
    writer.Write("</div>");
    writer.Write("<input type=\"hidden\"  value=\"" + this.Text + 
                 "\" id=\"" + this.ClientID + 
                 "\"  name=\"" + this.UniqueID + "\" />");
    writer.Write("</div>");
    string gK = this.GoogleMapKey;
    string lato = "";
    //if the text value is a lat/lng value set
    //the start  value for the gmap Input
    if (lat.Trim() != "" &&  log.Trim() != "") {
        lato = ",latitude:'" + lat + 
               "',longitude:'"  +  log + "'";
    }
    // create the mootools class 
    writer.Write("<script language=\"javascript\" defer=\"defer\">\n");
    writer.Write("var " + this.ID + "imoEl = 
                 new  GoogleMapsObj('','','',{panelID:'" + 
                 thisContainer + "',   " + 
                 this.ClientID + "'" + lato + "}); \n");
    // declare a little javascript function to set the  point into the map:
    writer.Write("function mappa(puntoL,puntoG) {\n");
    writer.Write("" + this.ID + "imoEl.setLatLong(puntoL,puntoG);\n");
    writer.Write("}\n");
    writer.Write("</script>\n");
    // end
}

最后,我们来谈谈 mootools 类(假设您了解 MooTools 语法的基本知识,或者您可以查看 http://docs.mootools.net

[*以下是 mootools 类的 JavaScript 代码*:]

var GoogleMapsObj = new Class( {
    options: {
    panelID:'mioEmbeder',
    googlekey: '1',
    dataID : '',
    latitude:'',
    longitude:'',
    currentURL:''
    },

在选项声明之后,我们需要初始化类

initialize: function(address, lat, long, options) {
  this.options.panelID = options.panelID;
  this.options.googlekey = options.googlekey;
  if(options.dataID)
  this.options.dataID = options.dataID;
  if(options.latitude)
  this.options.latitude = options.latitude;
  if(options.longitude)
  this.options.longitude = options.longitude;
  //init leftArea:
  var inpAdd = $(this.options.panelID+'_inputAdd') ;
  var btmAdd = $(this.options.panelID+'_btmAdd')   ;
  var inpLA =  $(this.options.panelID+'_inputLA')  ;
  var inpLO =  $(this.options.panelID+'_inputLO')  ;
  var btmLL =  $(this.options.panelID+'_btmLL')    ;
  var mappa =  $(this.options.panelID+'_maps')     ;
  
  if(this.options.latitude!='') 
      inpLA.value = this.options.latitude;
  if(this.options.latitude!='') 
      inpLO.value = this.options.longitude;

  if(address.toString()!='') 
      inpAdd.value = address;
  if(lat.toString()!='')
      inpLA.value = lat;
  if(long.toString()!='')
      inpLO.value = long;

  var mioFF = this; 

设置所有 DOM 元素和值后,我们需要将事件分配给按钮

if( btmAdd ) {
      btmAdd.addEvent('click',function(e) {
          evt = new Event(e);evt.stop();
          //clear one e 
          var address = $(mioFF.options.panelID+'_inputAdd');
          var _lat = '';
          if(address) _lat = address.value;
          if(_lat=='' ) return;
          mioFF.initGMaps(_lat);
      });
  }
  if( btmLL ) {
      btmLL.addEvent('click',function(e) {
          evt = new Event(e);evt.stop();
          var lat = $(mioFF.options.panelID+'_inputLA');
          var long = $(mioFF.options.panelID+'_inputLO');
          var _lat = '';
          var _long = '';
          if(lat) _lat = lat.value;
          if(long) _long = long.value;
          if(_lat=='' || _long=='') return;
          var objD = $(mioFF.options.dataID);
          if(objD) {
              objD.value = _lat + ','+_long;
          }
          mioFF.initGMaps('');
      });
  }

这是更重要的调用; 使用此函数,我们初始化 Google 地图,其中包含或不包含纬度/经度或地址信息。

    this.initGMaps('');
},

这是初始化 Google 地图的函数

initGMaps : function(address) {
  //get lat e long
  var lat = $(this.options.panelID+'_inputLA');
  var long = $(this.options.panelID+'_inputLO');
  var _lat = '';
  var _long = '';
  if(lat) _lat = lat.value;
  if(long) _long = long.value;
  var urlA = '';
  if(_lat!='') urlA+='&lt=' + _lat;
  if(_long!='') urlA+='&lg=' + _long;
  if(address!='') {
    urlA+='&ad='+escape(address);
  }
  if(this.options.currentURL!=urlA) {
    this.options.currentURL=urlA;
  } else return;
  var eCont = $(this.options.panelID+'_maps');
  eCont.empty();
  eCont.set('html','');
//continue..

这是我展示 Google 地图的简单解决方案:我使用一个 iFrame 来显示地图,设置传递的 URL 或 lat/lng 坐标 (var: urlA),并设置 Google 密钥

if(window.ie) {
    var iframe = '<iframe  src="/template/plugins/GoogleMapInput/testg.aspx?g='+ 
                 this.options.googlekey+urlA+
                 '"  frameborder="0" allowtransparency="true"'+
                 '  height="135" width="240" scrolling="no"  ></iframe>';
         eCont.set('html',iframe);
 } else {
          var ifrm = new Element('iframe');
          ifrm.setProperties({
              id :'googleFrame',
            name: 'googleFrame',
            frameborder:'0',
            allowtransparency:'true',
            height:'135',
            width:'240',
            scrolling:'no'
        });
         ifrm.setProperty('src',
           "/template/plugins/GoogleMapInput/testg.aspx?g="+
           this.options.googlekey+urlA);
        eCont.adopt(ifrm);
  }
//and of the code block started into the previous section...
},

这是另一个有用的函数,用于从 HTML 输入中检索值

setLatLong : function(lat,long) {
      var _lat = $(this.options.panelID+'_inputLA');
      var _long = $(this.options.panelID+'_inputLO');
      if(_lat) _lat.value = lat;
      if(_long) _long.value = long;
      var objD = $(this.options.dataID);
      if(objD) {
          objD.value = lat + ','+long;
      }
    }
 //end of the javascript class
});
//other implementation for this class...
GoogleMapsObj.implement(new Options, new Events);

这是 C# 部分,用于读取 querystring 并设置默认值

<%@ Page Language="c#" ContentType="text/html" ResponseEncoding="utf-8" %>
<script language="c#" runat="server">
    string googleKey="";
    string lat ="";
    string logi ="";
    string addr ="";
    void Page_Load(object o, EventArgs e ) {
        if(Request.Params["g"]==null) 
            googleKey = ""; 
        else 
            googleKey = Request.Params["g"].ToString();
        if(Request.Params["lt"]==null)
            lat = "37.4419"; 
        else 
            lat = Request.Params["lt"].ToString();
        if(Request.Params["lg"]==null)
            logi = "-122.1419"; 
        else 
            logi = Request.Params["lg"].ToString();
        if(Request.Params["ad"]==null) 
            addr = ""; 
        else 
            addr = HttpUtility.UrlDecode(Request.Params["ad"].ToString());
    }
</script>

这是 Google Maps JavaScript 部分

<script src="http://www.google.com/jsapi?key=<%=googleKey%>" 
      type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
    google.load("maps", "2.x"); 
    var map = null;
    var geocoder = null;
    function load() {
        var latitude = <%=lat%>;
        var longitude = <%=logi%>;
        var address = '<%=addr%>';
        if (GBrowserIsCompatible()) {
            map = new google.maps.Map2(document.getElementById("map")); 
            if(!map) return;
            map.setCenter(new google.maps.LatLng(latitude, longitude), 13); 
            var marker = new google.maps.Marker(new GLatLng(latitude, longitude));
            map.addOverlay(marker);
            if(address!='') getLatLong(address);
        }
    }
    function getLatLong(address) { 
        //if the url passed is an address we need to geocode...
        geocoder = new google.maps.ClientGeocoder();
        if (geocoder) {
            geocoder.getLatLng(
                address,
                function(point) {
                    if (!point) {
                        alert(address + " not found");
                        window.parent.mappa('','');
                    } else {
                        map.setCenter(point, 13);
                        window.parent.mappa(point.lat(),point.lng());
                        var marker = new google.maps.Marker(point);
                        map.addOverlay(marker);
                    }
                }
            );
        }
    }
//]]>
</script>

最后,这是完整的 HTML 代码

//[here the c# part]
<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        //[here the google map (javascript) part]
    </head>
    <body style=" margin:0px; padding:0px;" onLoad="load()" onUnload="GUnload()">
        <form runat="server">
            <div id="map" style="width: 240px; height: 135px;"></div>
        </form>
    </body>
</html>

现在我们已经准备好所有文件; 此时,我们有

  • GMapInput.cs
  • GMapInput.ascx
  • GMapInput.js
  • Testg.aspx
  • ..如果你想要 *GMapInput.css*(自定义控件)

您可以使用像这样的标准语法包含您的新 Web 控件

<%@ Register TagPrefix="gmap" 
   TagName="Input" Src="/controls/myown/gmapinput.ascx" %>

并且,这是 HTML 代码

<gmap:Input id="myGmapTextBox" runat="server"/>

关注点

此 Web 控件是由我和我的团队开发的 CMS 系统 Joack joack logo 的一部分。 我们开发了许多有用的控件来集成有用的 API,例如,open social API 和 Facebook API。

历史

这是该控件的第一个版本; 我希望您找到更强大的解决方案并升级它!

© . All rights reserved.