随便写着玩玩.不要太认真哦^^
这里说一下googlemap第三版和第二版的区别在于第三版能够在移动设备上运行得更快更好.而且第三版取消了key,无需为不同域名注册不用的key了.
为什么要是用第3方的library?如果不用,就需要在gwt项目中自己编写许多js代码来访问谷歌地图.使用后,就可以直接写java代码来访问啦^^.
gwt官方的google map api library还停留在第2版的基础上,还好.有个牛人把第三版的所有类都平移到了java上,并且发布成了gwt的插件.而且,此library在MVP下也能相当容易的被添加进来.
这个项目网址是 http://code.google.com/p/gwt-google-maps-v3/
有兴趣的朋友可以透过这个网址查询更多有用的信息.附件里面提供了google-map-v3的jar包下载.
开始前,没有google map js版基础的还是需要先看看官方的js版介绍.
网址是 http://code.google.com/apis/maps/documentation/javascript/
因为那个牛人是把js类,方法一字不差(目前还没发现有类名有区别的)的平移到gwt上的,所以熟悉js中的一些基本类还是有必要的.
PS:由于我能力有限..就没法把实现原理和大家分享了..
好了,废话不多说了,开始改造项目吧..^^
首先把jar包添加进来.然后在GoogleMapV3.gwt.xml中添加以下内容
我们要实现的基本功能是在地图上显示几个停车场的车位情况,这些情况都是从后台数据库中获取的.
第二个功能是使用者可以选择自己所在地址,然后通过"寻路"功能,在地图上显示出来从所选位置如何驾车到指定的停车场的路径.
有几个资源图片,我放在附件中了,其中有几个不同颜色的停车场图标,用于区分剩余车位情况.剩的少的,就用红色,黄色,剩的多的就用绿色,蓝色等.
拿到这借个图片后,想将他们拷贝到war下即可.
先简单的修改一下实体:ParkData.java,在这个bean里面存储一些显示用信息,这个bean将从后台传递到前台供显示.除了上次所说的需要将其序列化外,还需要让他继承com.extjs.gxt.ui.client.data.BaseModel.因为我们页面会用到一个gxt组件--下拉框.在这里不得不啰嗦一下,如果你需要将一个自己定义的实体放到gxt的组件中,基本上都要继承BaseModel.在gxt中的"bean"和java常规的bean是有一定区别的.java中使用get(),set(XXX)方法获取属性,而gxt bean则使用get("pname"),set("pname",object)方法设置和获取属性.以这个项目为例,我们要把ParkData中的parkName放到下拉框中显示,那么就需要将setParkName改造一下,如下
然后前台的下拉框设置需要显示的字段如下:
这样,下拉框就能显示了.当然,这是只是gxt中显示实体中字段的一种方式,通过继承不同的父类,具体的编码方式又会有所改变.比如继承BeanModel,有些gxt组件就不需要显式的set这些
property,但ComboBox是必须要有这个set("pname",object)的方法的.
然后在GreetingService.java中添加方法
保存后你会发现这个类说有错误.这个时候转到GreetingServiceAsync.java,点击红色错误,选择第一个Generat method...........即可自动生成出对于的方法.继续保存,然后你会发现GreetingServiceImpl.java又有错误了..原因是没有实现方法getParks(),好吧,就实现它吧
然后,修改GoogleMapV3.java,添加地图代码进去
吼吼,最后修改html即可
在html中加入
[img]http://dl.iteye.com/upload/attachment/543417/9f11afe6-9bdf-3f94-b27e-7bc56da75b43.jpg[/img]
注意sensor=false,如果你在移动设备上运行,就可以改成true,那么就会启用gps等定位系统了,这个参数是必须有的!还有个language参数,你可以设置不同的语言.不依赖浏览器语言设置.
OK.OVER.
[url]http://www.nptpark.com[/url]
这里说一下googlemap第三版和第二版的区别在于第三版能够在移动设备上运行得更快更好.而且第三版取消了key,无需为不同域名注册不用的key了.
为什么要是用第3方的library?如果不用,就需要在gwt项目中自己编写许多js代码来访问谷歌地图.使用后,就可以直接写java代码来访问啦^^.
gwt官方的google map api library还停留在第2版的基础上,还好.有个牛人把第三版的所有类都平移到了java上,并且发布成了gwt的插件.而且,此library在MVP下也能相当容易的被添加进来.
这个项目网址是 http://code.google.com/p/gwt-google-maps-v3/
有兴趣的朋友可以透过这个网址查询更多有用的信息.附件里面提供了google-map-v3的jar包下载.
开始前,没有google map js版基础的还是需要先看看官方的js版介绍.
网址是 http://code.google.com/apis/maps/documentation/javascript/
因为那个牛人是把js类,方法一字不差(目前还没发现有类名有区别的)的平移到gwt上的,所以熟悉js中的一些基本类还是有必要的.
PS:由于我能力有限..就没法把实现原理和大家分享了..
好了,废话不多说了,开始改造项目吧..^^
首先把jar包添加进来.然后在GoogleMapV3.gwt.xml中添加以下内容
<inherits name='com.google.gwt.maps.Maps' />
我们要实现的基本功能是在地图上显示几个停车场的车位情况,这些情况都是从后台数据库中获取的.
第二个功能是使用者可以选择自己所在地址,然后通过"寻路"功能,在地图上显示出来从所选位置如何驾车到指定的停车场的路径.
有几个资源图片,我放在附件中了,其中有几个不同颜色的停车场图标,用于区分剩余车位情况.剩的少的,就用红色,黄色,剩的多的就用绿色,蓝色等.
拿到这借个图片后,想将他们拷贝到war下即可.
先简单的修改一下实体:ParkData.java,在这个bean里面存储一些显示用信息,这个bean将从后台传递到前台供显示.除了上次所说的需要将其序列化外,还需要让他继承com.extjs.gxt.ui.client.data.BaseModel.因为我们页面会用到一个gxt组件--下拉框.在这里不得不啰嗦一下,如果你需要将一个自己定义的实体放到gxt的组件中,基本上都要继承BaseModel.在gxt中的"bean"和java常规的bean是有一定区别的.java中使用get(),set(XXX)方法获取属性,而gxt bean则使用get("pname"),set("pname",object)方法设置和获取属性.以这个项目为例,我们要把ParkData中的parkName放到下拉框中显示,那么就需要将setParkName改造一下,如下
public void setParkName(String parkName) {
this.parkName = parkName;
set("name",parkName);
}
然后前台的下拉框设置需要显示的字段如下:
combox.setDisplayField("name");
这样,下拉框就能显示了.当然,这是只是gxt中显示实体中字段的一种方式,通过继承不同的父类,具体的编码方式又会有所改变.比如继承BeanModel,有些gxt组件就不需要显式的set这些
property,但ComboBox是必须要有这个set("pname",object)的方法的.
然后在GreetingService.java中添加方法
List<ParkData> getParks();
保存后你会发现这个类说有错误.这个时候转到GreetingServiceAsync.java,点击红色错误,选择第一个Generat method...........即可自动生成出对于的方法.继续保存,然后你会发现GreetingServiceImpl.java又有错误了..原因是没有实现方法getParks(),好吧,就实现它吧
@Override
public List<ParkData> getParks() {
//如果你数据库中有数据
// return parkDataManager.getAll();
List<ParkData> datas = new ArrayList<ParkData>();
ParkData data = new ParkData();
data.setAllNum("150");
data.setLastNum("88");
data.setIcon("parking_green.png");
data.setId(1);
data.setLat(22.57604477669078);
data.setLng(113.95060540771487);
data.setParkName("石鼓山公园停车场");
data.setTel("18675511111");
data.setDescs("每小时2元");
data.setUpdateTime("2011-08-18 17:55:24");
data.setAddress("石鼓山路1号");
datas.add(data);
ParkData data2 = new ParkData();
data2.setAllNum("80");
data2.setLastNum("0");
data2.setIcon("parking_red.png");
data2.setId(2);
data2.setLat(22.58099803468149);
data2.setLng(113.95493985748294);
data2.setParkName("西丽天虹购物中心停车场");
data2.setTel("0755-23336868");
data2.setDescs("每小时5元");
data2.setUpdateTime("2011-08-18 17:56:27");
data2.setAddress("沙河西路2345号");
datas.add(data2);
ParkData data3 = new ParkData();
data3.setAllNum("120");
data3.setLastNum("50");
data3.setIcon("parking_blue.png");
data3.setId(2);
data3.setLat(22.581047566362173);
data3.setLng(113.9514744434357);
data3.setParkName("西丽医院停车场");
data3.setTel("0755-86655555");
data3.setDescs("每小时3元");
data3.setUpdateTime("2011-08-18 16:02:20");
data3.setAddress("留仙大道54号");
datas.add(data3);
return datas;
}
然后,修改GoogleMapV3.java,添加地图代码进去
import java.util.List;
import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.Theme;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.maps.client.HasMapOptions;
import com.google.gwt.maps.client.MapOptions;
import com.google.gwt.maps.client.MapTypeId;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.base.HasInfoWindow;
import com.google.gwt.maps.client.base.HasInfoWindowOptions;
import com.google.gwt.maps.client.base.HasLatLng;
import com.google.gwt.maps.client.base.InfoWindow;
import com.google.gwt.maps.client.base.InfoWindowOptions;
import com.google.gwt.maps.client.base.LatLng;
import com.google.gwt.maps.client.directions.DirectionsCallback;
import com.google.gwt.maps.client.directions.DirectionsRenderer;
import com.google.gwt.maps.client.directions.DirectionsRequest;
import com.google.gwt.maps.client.directions.DirectionsService;
import com.google.gwt.maps.client.directions.DirectionsStatus;
import com.google.gwt.maps.client.directions.DirectionsTravelMode;
import com.google.gwt.maps.client.directions.HasDirectionsRenderer;
import com.google.gwt.maps.client.directions.HasDirectionsRequest;
import com.google.gwt.maps.client.directions.HasDirectionsResult;
import com.google.gwt.maps.client.directions.HasDirectionsService;
import com.google.gwt.maps.client.event.Event;
import com.google.gwt.maps.client.event.EventCallback;
import com.google.gwt.maps.client.event.HasMouseEvent;
import com.google.gwt.maps.client.event.MouseEventCallback;
import com.google.gwt.maps.client.overlay.HasMarker;
import com.google.gwt.maps.client.overlay.HasMarkerOptions;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerImage;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.RootPanel;
import com.yx.map.client.bean.ParkData;
public class GoogleMapV3 implements EntryPoint {
public static final String Greeting_SERVICE = "/greetingService.gwt";
private final GreetingServiceAsync greetingService = GWT
.create(GreetingService.class);
private MapWidget mapWidget;
private TextField<String> myLatLng = new TextField<String>();
private HasInfoWindow lastInfoWindow = null;
private HasMarker hasMarker = null;
private ComboBox<ParkData> combox = new ComboBox<ParkData>();
private ListStore<ParkData> stroe = new ListStore<ParkData>();
private HasDirectionsService directionsService = new DirectionsService();
private HasDirectionsRenderer directionsDisplay = new DirectionsRenderer();
public void onModuleLoad() {
ServiceDefTarget endpoint = (ServiceDefTarget) greetingService;
String moduleRelativeURL = Greeting_SERVICE;
endpoint.setServiceEntryPoint(moduleRelativeURL);
Registry.register(Greeting_SERVICE, greetingService);
// 设置样式
GXT.setDefaultTheme(Theme.GRAY, true);
//这个MapOptions对于js版本中的
// var myOptions = {
// zoom: 8,
// center: latlng,
// mapTypeId: google.maps.MapTypeId.ROADMAP
// };
final HasMapOptions options = new MapOptions();
// 设置缩放级别
options.setZoom(14);
// 设置地图中心位置
// 22.57604477669078, 113.95060540771487
options.setCenter(new LatLng(22.57604477669078, 113.95060540771487));
// 设置地图样式.
options.setMapTypeId(new MapTypeId().getRoadmap());
// 启用拖动地图
options.setDraggable(true);
// 启用地图导航控件.其实就是左边的那个
options.setNavigationControl(true);
// 启用地图类型选择控制器.用于选择是卫星视图.还是普通的视图.
options.setMapTypeControl(true);
// 启用鼠标滚轮缩放
options.setScrollwheel(true);
//MapWidget是一个map容器,并不是真正的map对象,如果你要拿到map,需要mapWidget.getMap()
mapWidget = new MapWidget(options);
mapWidget.setSize("2000px", "2000px");
directionsDisplay.setMap(mapWidget.getMap());
Event.addListener(options, "click", new MouseEventCallback() {
@Override
public void callback(HasMouseEvent event) {
myLatLng.setValue(event.getLatLng().getLatitude() + ","
+ event.getLatLng().getLongitude());
if (hasMarker != null) {
hasMarker.setVisible(false);
}
HasMarkerOptions mymarkerOptions = new MarkerOptions();
mymarkerOptions.setTitle("我的位置");
mymarkerOptions.setPosition(event.getLatLng());
mymarkerOptions.setClickable(true);
mymarkerOptions.setMap(mapWidget.getMap());
HasMarker mark = new Marker(mymarkerOptions);
mark.setVisible(true);
hasMarker = mark;
}
});
greetingService.getParks(new AsyncCallback<List<ParkData>>() {
@Override
public void onSuccess(List<ParkData> result) {
//把结果添加到stroe中用于给下拉列表做选择
stroe.add(result);
//循环结果,在地图上构建marker
for (ParkData parkData : result) {
MarkerImage.Builder builder = new MarkerImage.Builder(
parkData.getIcon());
HasMarkerOptions mymarkerOptions = new MarkerOptions();
mymarkerOptions.setTitle(parkData.getParkName());
mymarkerOptions.setPosition(new LatLng(parkData.getLat(),
parkData.getLng()));
mymarkerOptions.setClickable(true);
mymarkerOptions.setIcon(builder.build());
mymarkerOptions.setMap(mapWidget.getMap());
final HasMarker mark = new Marker(mymarkerOptions);
mark.setVisible(true);
//构建对话框
HasInfoWindowOptions infoWindowOptions = new InfoWindowOptions();
infoWindowOptions.setContent("<h4>"
+ parkData.getParkName() + "</h4><br/>"
+ parkData.getAddress() + "<br/>" + "总车位: <b>"
+ parkData.getAllNum() + "</b><br/>"
+ "空车位: <b>" + parkData.getLastNum()
+ "</b><br/>" + "费用简介:" + parkData.getDescs()
+ "<br/>" + "电话:" + parkData.getTel() + "<br/>"
+ "更新时间:" + parkData.getUpdateTime() + "<br/>");
final HasInfoWindow infoWindow = new InfoWindow(
infoWindowOptions);
//添加marker的点击事件
Event.addListener(mark, "click", new EventCallback() {
@Override
public void callback() {
if (null != lastInfoWindow) {
lastInfoWindow.close();
}
infoWindow.open(mapWidget.getMap(), mark);
lastInfoWindow = infoWindow;
}
});
}
createMap();
GXT.hideLoadingPanel("loading");
}
@Override
public void onFailure(Throwable caught) {
}
});
}
private void createMap() {
Viewport viewport = new Viewport();
viewport.setLayout(new BorderLayout());
ContentPanel panel2 = new ContentPanel();
panel2.setSize(500, 500);
panel2.setScrollMode(Scroll.NONE);
panel2.setLayout(new FitLayout());
panel2.add(mapWidget);
Button button = new Button("查 询");
button.addSelectionListener(new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
// 获取目的地址
HasLatLng desclan = new LatLng(combox.getValue().getLat(),
combox.getValue().getLng());
HasDirectionsRequest request = new DirectionsRequest();
// request.setTravelMode("DRIVING");
// Walking代表走路过去的路线,Driving代表驾车路线..一般驾车路线会比较绕......要遵守交通规则 哈哈.
// request.setTravelMode(new DirectionsTravelMode().Walking());
request.setTravelMode(new DirectionsTravelMode().Driving());
request.setDestinationLatLng(desclan);
//设置起始地址
request.setOriginLatLng(hasMarker.getPosition());
request.setProvideRouteAlternatives(false);
//这段代码很重要,如果不加入,那么无法导航.
//至于为什么要删除__gwt_ObjectId作者也没详说,只给出了这个解决方法.
if (!GWT.isScript()) {
removeGwtObjectId(request.getJso());
}
directionsService.route(request, new DirectionsCallback() {
@Override
public void callback(HasDirectionsResult response,
String status) {
if (status.equals(new DirectionsStatus().Ok())) {
directionsDisplay.setDirections(response);
if (hasMarker != null) {
hasMarker.setVisible(false);
}
}
}
});
}
});
ToolBar toolBar = new ToolBar();
combox.setStore(stroe);
combox.setTriggerAction(TriggerAction.ALL);
//设置显示属性
combox.setDisplayField("name");
combox.setValue(stroe.getAt(0));
toolBar.add(combox);
toolBar.add(button);
panel2.setTopComponent(toolBar);
viewport.add(panel2, new BorderLayoutData(LayoutRegion.CENTER));
viewport.add(myLatLng, new BorderLayoutData(LayoutRegion.NORTH, 50, 50,
50));
RootPanel.get().add(viewport);
}
private native void removeGwtObjectId(JavaScriptObject jso) /*-{
delete jso['__gwt_ObjectId'];
}-*/;
}
吼吼,最后修改html即可
在html中加入
<head>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<head>
<body>
<div id="loading">正在加载停车场车位数据...</div>
</body>
[img]http://dl.iteye.com/upload/attachment/543417/9f11afe6-9bdf-3f94-b27e-7bc56da75b43.jpg[/img]
注意sensor=false,如果你在移动设备上运行,就可以改成true,那么就会启用gps等定位系统了,这个参数是必须有的!还有个language参数,你可以设置不同的语言.不依赖浏览器语言设置.
OK.OVER.
[url]http://www.nptpark.com[/url]