4.4 一个完整的Google Maps应用

这里给出一个完整的应用Google Maps的例子。这个例子展示的是一辆小汽车在地图上行驶的情况。在实际应用中,经常有这样的需求:通过车载GPS来定位车辆的位置,并实时监控车辆的方位。通常的做法是通过GPS与GPRS结合,将经纬度信息传递到服务器的数据库中,再通过服务器端提取出来之后做成图标在Web地图上显示出来。

本例中没有采用真实的车辆经纬度,而是用Delphi程序模拟显示情况,将经纬度信息不间断地写入数据库中,然后通过Ajax获取数据后展现出来。

4.4.1 开发环境配置

本节将以Google Maps API开发逐步剖析一个实例。本例中,Google Maps作为展示平台,从后台数据库中获取数据,然后将数据点展现在地图上。

本例由于使用了Google Maps API,所以需要连接至Internet,否则程序运行会报错。

软件开发配置如表4-33所示。

表4-33 开发配置

数据库

SQL Server 2000

开发平台

.NET 2.0

开发语言

C#

JavaScript

HTML

Web服务器

IIS 5.1

4.4.2 数据库设置

用户可以在SQL Server服务器上使用SQL语句来建立数据表,建表的SQL语句如下:

CREATE TABLE [markers] (

[id] [int] IDENTITY (1, 1) NOT NULL ,

[name] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,

[lat] [varchar] (30) COLLATE Chinese_PRC_CI_AS NULL ,

[lng] [varchar] (30) COLLATE Chinese_PRC_CI_AS NULL ,

[mark] [char] (10) COLLATE Chinese_PRC_CI_AS NULL

) ON [PRIMARY]

GO

表中的内容如图4-78所示。

image094.jpg

图4-78 数据表内容

数据库文件“gmtest_Data.MDF”和“gmtest_Log.LDF”在本例的Data文件夹中,可通过SQL Server的企业管理器进行附加数据库的操作,数据库sa的密码为“123”。读者也可通过另一个Access文件“gmtest.mdb”来导入,同时要修改SQL Server的sa密码,或者修改本例网页端配置文件“Web.config”中的<appSettings>节,修改方法如下:

<appSettings>

<add key="connStr" value="server=127.0.0.1;database=gmtest;uid=sa;pwd=123;"/>

</appSettings>

在上面的代码中,server表示SQL Server安装的位置,通过IP地址或者名称通道来访问,具体要看SQL Server的SqlExpress设置为IP的方式还是名称通道的方式。关于SqlExpress的设置请读者自行参考相关文档,在此不再赘述。

database指连接的是SQL Server数据库服务器中的哪一个数据库,比如为gmtest。请不要随意修改名称,如果需要重命名,请连同本例.NET程序与Delphi模拟器程序中的代码一同修改。

uid与pwd分别指的是登录数据库的用户名和密码(本例数据库sa的密码为“123”)。

4.4.3 代码分析

整个程序规模不大,构成方式上由“GPS经纬度录入模拟器”和Google Maps Web程序组成,而Web端程序在逻辑上简单地分为以下两个部分。

l  文本框: 图4-79 程序结构树数据管理:在程序中名称为“DataMgn”类库,负责与SQL Server相连,并构造各种查询方法及检索,并返回数据结果。其中db.cs文件为主要逻辑代码文件。
l 网页展现:在程序中名称为http://localhost/gmtest,负责展示网页、展示地图、构造客户端脚本、调用并接受服务器端数据。其中Markers_class.cs为自定义的地标类型文件,gm.js为JavaScript脚本文件,Map.aspx为加载Google Maps的网页。本Web程序采用了AJAX同步方式从服务器端获取数据并展现出来,读者也可采用iframe的方式进行无刷新构造。本例中讲解的AJAX版本目的是为第6章讲解Google Maps与AJAX共同开发做铺垫。

整个Web程序的结构树如图4-79所示。

本例将重点讲解js文件夹中的脚本文件“gm.js”及Map页面的服务器端页面与代码“Map.aspx”、“Map.aspx.cs”,下面依次讲解。

首先看Map.aspx页面代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Map.aspx.cs" Inherits= "Map_cs" %>

<!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>

<!--Google Maps API Key注册脚本-->

<script src="http://maps.google.com/maps?file=api&amp;

v=2&amp;sensor=true_or_ false&amp;key= …… " type="text/javascript">

</script>

<!--脚本引用-->

<script type="text/javascript" language="javascript" src="js/gm.js"></script>

</head>

<body οnlοad="load();">

<form id="form1" runat="server">

<!--GMap对象容器-->

<div id="map" style="width: 360px; height: 280px"></div>

<!--开始运行按钮-->

<input id="btn_run" type="button" value=" 开始 " οnclick="javascript:getNew PositionFromServer();" />

</form>

</body>

</html>

注意该页面的类名为“Map_cs”,这个类名将在页面服务器端中被AJAX注册,注册代码如下:

protected void Page_Load(object sender, EventArgs e)

{

Utility.RegisterTypeForAjax(typeof(Map_cs));

}

在页面的<body>节中的load函数的代码在gm.js脚本文件中:

function load()

{

if (GBrowserIsCompatible()) {

map = new GMap2(document.getElementById("map"));

map.setCenter(new GLatLng(25.020551,121.525849), 14);

map.addControl(new GLargeMapControl());

}

}

地图首先定位在台北市,缩放级别为14,并且在地图上加入了一个地图控件。对照图4-80,页面上主要有两个可见元素:作为GMap容器的div和【开始】按钮,单击按钮之后触发getNewPositionFromServer()函数,该函数位于gm.js脚本文件内:

function getNewPositionFromServer()

{

MarkerObj = new MarkerCls();

setInterval("Map_cs.getNewRecord(getNewPositionCallBack)",800);

setInterval("refreshMap()",500);

}

function getNewPositionCallBack(res)

{

MarkerObj = res.value;

}

上面的代码包含两个定时器,第一个定时器每0.8秒触发一次“Map_cs.getNewRecord()”服务器端的AJAX方法,而getNewPositionCallBack方法是回调函数,意思为执行过AJAX方法后,再执行该回调函数。回调函数的参数res为调用服务器端AJAX函数后的返回值,如果要取得返回值,则需要调用res.value来得到。如图4-81所示为res.value的返回值。

image096.jpg         image097.jpg

图4-80 页面地图                      图4-81 同步调用的AJAX脚本端返回值

之所以res.value的返回值包括5个值,是因为在页面服务器端AJAX方法中,返回值是自定义的Markers_class类型,该类的定义代码如下:

public class Markers_Class

{

//构造函数

public Markers_Class()

{

m_id = 0;

m_lat ="";

m_lng = "";

m_name = "";

m_mark = "";

}

//私有变量

private int m_id;

private string m_lat;

private string m_lng;

private string m_name;

private string m_mark;

//公共属性

public int Id

{

get { return m_id; }

set { m_id = value; }

}

public string Lat

{

get { return m_lat; }

set { m_lat = value; }

}

public string Lng

{

get { return m_lng; }

set { m_lng = value; }

}

public string Name

{

get { return m_name; }

set { m_name = value; }

}

public string Mark

{

get { return m_mark; }

set { m_mark = value; }

}

} //结束定义类型

Markers_Class一共定义了5个属性,没有定义方法,这5个属性与数据表gmtest的字段定义相同,目的是为了在获取SQL查询结果之后,将DataSet转换成较为简单的Markers_Class再传递回客户端,在操作大量数据的时候,这样可以节省时间。下面再讲解负责SQL查询的AJAX服务器端代码:

[AjaxPro.AjaxMethod]

public Markers_Class getNewRecord()

{

DataMgn.ConnDB dbmgn = new DataMgn.ConnDB();

Markers_Class tmp = new Markers_Class();

//执行SQL语句,返回DataSet

DataSet newLatLng = dbmgn.ReturnDataSet(

"SELECT * FROM markers WHERE (id IN (SELECT MAX(id) FROM markers))");

//Markers_Class对象tmp赋值

tmp.Id = (int)newLatLng.Tables[0].Rows[0]["id"];

tmp.Lat = (string)newLatLng.Tables[0].Rows[0]["lat"];

tmp.Lng = (string)newLatLng.Tables[0].Rows[0]["lng"];

tmp.Name = (string)newLatLng.Tables[0].Rows[0]["name"];

tmp.Mark = (string)newLatLng.Tables[0].Rows[0]["mark"];

dbmgn.Close();

//最后整个方法的返回值类型为Markers_Class

return tmp;

}

当页面端的JS脚本调用被AjaxPro注册过的方法时,服务器端的AJAX方法被执行,此时系统会自行判断该调用过程是否为异步调用。如果客户端同步调用,则客户端调用程序会停止在调用点直到取得返回值为止。本例中为同步调用,前面已经提到,要实现网页无刷新显示操作的方式方法很多,AJAX精髓在于异步调用,本例中同步调用采取AJAX方式也是对第6章内容的一个补充与铺垫。

在前面的图4-80中,车上的GPS经纬度信息连续不断地被上传到服务器的数据库中,当有新的数据添加到数据表之时,可通过编写SQL Server触发器来“通知”Web程序,从而触发页面刷新,这个例子仅仅为示例所用。采取的另一种方法:定时获取数据表的最后一条记录,并将其传递到客户端。

这个获取数据的过程由页面脚本控制,在取得数据之后,脚本开始操作GMap对象,将经纬度信息构造出GIcon对象(图标为一辆黄色的小汽车),并加载到地图上,同时清空以前的GOverLay对象。如此一来终端用户看到的则是地图上的一辆小车不断地在地图上以无刷新的方式行驶。而且要不断地移动地图,以小车为地图中心,确保小车不会跑出地图当前视野范围之外。

脚本端实现以上逻辑的代码如下:

function refreshMap()

{

//创建GIcon对象

var v_icon = new GIcon();

v_icon.image = "img/car.ico";

v_icon.iconSize = new GSize(32, 32);

v_icon.iconAnchor = new GPoint(16, 16);

if (MarkerObj != null)

if ((MarkerObj.Lat!== 0) && (MarkerObj.Lng !== 0))

{

var tmpMarker = new GMarker(new GLatLng(MarkerObj.Lat,MarkerObj.Lng),

{icon:v_icon,title:MarkerObj.mark});

//清空地图上的所有GoverLay对象

map.clearOverlays();

//以小车的经纬度为中心,移动地图

map.panTo(new GLatLng(MarkerObj.Lat,MarkerObj.Lng));

map.addOverlay(tmpMarker);

}

}

这里有两个实用的技巧。对于控制小车保持在当前地图视野范围之内,一般可以采用本例中的方法,但是这种方法的缺点是地图的移动过于频繁,而且如果地图中出现多辆汽车就无法根据其中的某一辆进行定位了;还有一种方法是对于小车的经纬度与地图边界进行判断,直到小车快跑出地图边界的时候才移动并缩放地图。

第二种方法是对于绘制点而言的,一般绘制点的方式有以下两种:

l 使用VML绘制。
l 采用Google Maps API进行绘制。

使用VML绘制的优点是快捷、灵活,可以解决某些Google Maps API提供的功能无法实现的需求。但是缺点是VML的边界较难掌控在地图图框的显示范围内,而且对开发者而言也增加了学习VML的负担。当然在网页上绘制点、线、面还有很多其他的方法,本例中采用的仅仅是Google Maps API提供的方法。

本例在执行时,需要同时打开GPS数据模拟器,小车会自动往东北方向前进,如图4-82和图4-84所示。

image098.gifimage099.gifimage100.jpg              image101.jpg

图4-82 前一时刻车辆位置                        图4-83 后一时刻车辆位置

转载于:https://www.cnblogs.com/shanghaif/archive/2010/07/20/1781678.html

4.4 一个完整的Google Maps应用相关推荐

  1. Google Maps和GIS开发资源收集

    Google Maps JQuery Maps google map是怎样工作的 Google Map API基本概念 Google Maps API编程资源大全 google map限制地图缩放级别 ...

  2. Google Maps API编程资源大全

    Google Maps API是Google自己推出编程API,可以让全世界对Google Maps有兴趣的程序设计师自行开发基于Google Maps的服务,建立自己的地图网站.以下是我在Googl ...

  3. Emulator 29.2.12 稳定版发布,启用 Google Maps UI

    Android 模拟器 Emulator 29.2.12 稳定版发布了,它启用了一项新功能 Google Maps UI,这适用于开发与设备位置相关联的应用程序的开发人员.有了 Google Maps ...

  4. Android版Google Maps入门:高级

    1.简介 尽管Google Maps的标准功能非常有用,但有时您还需要做更多的事情. 幸运的是,Google创建了一个开放源代码库,其中包含一组实用程序,Android开发人员可以使用这些实用程序通过 ...

  5. 关于Keyhole和Google Maps(三)

    1.破解 2004 年末,梦工厂的动画师 Paul Rademacher 想在湾区租一套价格合适的房子.他在 Craigslist 上搜了几个月,在地图上标出地点和价格,等周末再去现场看.他花了许多个 ...

  6. 如何在WordPress中添加Google Maps Store Locator

    Do you want to add Google Maps store locator in WordPress? A store locator is a map pointing to your ...

  7. Google Earth Engine APP——一个完整的地图图例APP(美国西部土地利用分类)

    本文是一个完整的关于美国西部的牧场零星覆盖物 1984年至2020年美国西部牧场的部分覆盖率产品,分辨率为30米.通过选择要显示的年份和覆盖成分的组合,以及点击点来检查时间序列来探索数据. 具体的文章 ...

  8. 【转】Google Maps Android API V2的使用及问题解决

    Google Maps Android API V2的使用及问题解决 Google Maps Android API V2使用及问题解决 说明 因为Google Maps的API版本更新,之前的一些教 ...

  9. maps-api-v3_利用Google Maps API发挥创意

    maps-api-v3 您已经设计了一个闪亮的新网站: 仔细选择颜色,版式和照片,以完美反映公司的品牌形象. 然后您的客户要求您添加地图. 当然,您可以使用地图构建"向导",例如每 ...

最新文章

  1. 悬浮按钮app_分享一款网页转App的神器,绝对值得一用
  2. jsp页面之间跳转的数据传递
  3. 曾比海底捞还牛,如今关店1200家!肯德基的猪队友,快被中国人抛弃了?
  4. java io类filereader,39. Java IO: FileReader
  5. IPLAT62--后台返回提示参数
  6. iOS开发编译错误:std::terminate(), referenced from:
  7. iOS【面试】2018年面试题集锦
  8. 真正的焦虑感来自对比
  9. myeclipse(eclipse)IDE配置
  10. 桌面创建html文件夹路径,HTML5+ - DirectoryEntry(文件夹及文件操作)
  11. 高等数学张宇18讲 第十三讲 无穷级数
  12. PID控制原理(全干货)
  13. Nodejs之NestJS之pkg打包
  14. java 众数 中位数_什么是中位数、众数、平均数,今天终于弄明白
  15. 代码的坏味道与重构技术
  16. javascript html 去除,javascript去除html标签
  17. linux 查看发行版本
  18. 软件工程课程周进度报告 第六周
  19. 大一计算机专业考什么证书,计算机专业大一的学生能考什么证书?
  20. 宇宙无敌第一帅的Java笔记

热门文章

  1. 计算机片段教学优秀教案,精彩教学片段100例—导入篇(1)
  2. Android--调用系统照相机拍照与摄像
  3. 谜题39:您好,再见!
  4. SQL Server之游标
  5. JAVA 搭建基于SPRINGBOOT的SSM(SPRING + SPRINGMVC + MYBATIS)的MAVEN项目
  6. 【bzoj1727】[Usaco2006 Open]The Milk Queue 挤奶队列 贪心
  7. iOS 两种易混淆的存储路径
  8. Android类参考---Fragment(五)
  9. SQL Server 中的case when then else 中的结果类型
  10. MSDN Visual系列:在MOSS中创建一个BDC实体