Introduction
This post is about a custom ZK component (Gdirection) that let ZK Gmaps works with Google Direction Service.
Warm Up
To understand this post well, you may reed the articles below first:
ZK Quick Start
ZK Component Development Tutorial: Getting Started
The Program
Let's skipp some files, only take a look at Gdirection.java, Gdirection.js and test zul file here
Gdirection.java
package org.zkoss.gmaps.extended.components;
import org.zkoss.gmaps.Gmaps;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zul.Div;
import org.zkoss.zul.impl.XulElement;
public class Gdirection extends XulElement {
private String _panelId;
private Div _panel;
private String _mapId;
private Gmaps _map;
private String _start;
private String _end;
private String[] _direction;
/**
* Set panel to google direction display,
* note you should make sure the panel is already attached to page before call this function
* because the uuid will be changed when attache to page
* @param panel
*/
public void setPanel (Div panel) {
_panel = panel;
setPanelId(panel.getUuid());
}
/**
* set panel id directly
* @param panelId
*/
public void setPanelId (String panelId) {
_panelId = panelId;
smartUpdate("panelId", _panelId);
}
/**
* get panel id
* @return
*/
public String getPanelId () {
return _panelId;
}
/**
* Set map to google direction display,
* note you should make sure the map is already attached to page before call this function
* because the uuid will be changed when attache to page
* @param map
*/
public void setMap (Gmaps map) {
_map = map;
setMapId(map.getUuid());
}
/**
* set map id directly
* @param mapId
*/
public void setMapId (String mapId) {
_mapId = mapId;
smartUpdate("mapId", _mapId);
}
/**
* get map id
* @return
*/
public String getMapId () {
return _mapId;
}
/**
* Sets the start point of direction
* @param start
*/
public void setStart (String start) {
_start = start;
setDirection (_start, _end);
}
/**
* Sets the end point of direction
* @param end
*/
public void setEnd (String end) {
_end = end;
setDirection (_start, _end);
}
/**
* set direction to route
* @param start the start point
* @param end the end point
*/
public void setDirection (String start, String end) {
if (start != null && end != null) {
_direction = new String[] {start, end};
smartUpdate("direction", _direction);
} else {
_direction = null;
}
}
/**
* set direction to route
* @param direction the String array [start, end]
*/
public void setDirection (String[] direction) {
if (direction.length != 2)
throw new WrongValueException ("the direction should exactly contains [start point, end point]");
_direction = direction;
smartUpdate("direction", _direction);
}
public String[] getDirection () {
return _direction;
}
public String getZclass() {
return _zclass == null ? "z-gdirection" : _zclass;
}
//-- ComponentCtrl --//
protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer)
throws java.io.IOException {
super.renderProperties(renderer);
if (_mapId != null)
render(renderer, "mapId", _mapId);
if (_panelId != null)
render(renderer, "panelId", _panelId);
if (_direction != null)
render(renderer, "direction", _direction);
}
}
It will render start point, end point and the id of gmap and panel div to client side.
Gdirection.js
gmaps.extended.Gdirection = zk.$extends(zul.Widget, {
$define: {
/**
* sets the mapId of the map for direction display
* @param v
*/
mapId: function (v) {
var map,
service,
direction;
map = this._map = zk.Widget.$('#' + v);
if (service = this._directionsService) {
// do route if ready
if (direction = this._direction)
this.setDirection(direction, {force: true});
} else
this._init();
},
/**
* sets the panelId of the panel for direction display
* @param v
*/
panelId: function (v) {
var panel,
service,
direction;
panel = this._panel = jq('#' + v)[0];
if (service = this._directionsService) {
// do route if ready
if (direction = this._direction)
this.setDirection(direction, {force: true});
} else
this._init();
},
/**
* sets the direction to route
* @param v
*/
direction: function (v) {
var display = this._directionsDisplay;
if (display = this._directionsDisplay) {
var s = v? $eval(v) : null,
service;
// wrong arguments or not binded
if (s.length != 2 || !(service = this._directionsService)) return;
var start = s[0],
end = s[1],
request = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
service.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
display.setDirections(response);
}
});
}
}
},
bind_: function () {
this.$supers(gmaps.extended.Gdirection, 'bind_', arguments);
this._tryBind();
},
_tryBind: function () {
var mapId, panelId;
// init if google api, mapId and panelId are ready
if (window.google && window.google.maps
&& (mapId = this._mapId)
&& (panelId = this._panelId))
this._init();
else if ((mapId = this._mapId)
&& (panelId = this._panelId)) {
// retry if the info for init is ready
var wgt = this;
setTimeout (function () {wgt._tryBind()}, 100);
}
},
_init: function () {
var mapId = this._mapId,
panelId = this._panelId,
map,
panel,
direction,
directionsDisplay;
if (!(map = this._map))
map = this._map = zk.Widget.$('#' + mapId);
if (!(panel = this._panel))
panel = this._panel = jq('#' + panelId)[0];
// prevent multiple init
if (directionsDisplay = this._directionsDisplay)
return;
// while map and panel are ready
if (map && map._gmaps && panel) {
this._directionsService = new google.maps.DirectionsService();
this._directionsDisplay = directionsDisplay = new google.maps.DirectionsRenderer();
if ((map = this._map)
&& (map = map._gmaps))
directionsDisplay.setMap(map);
if (panel = this._panel)
directionsDisplay.setPanel(panel);
if (map
&& panel
&& (direction = this._direction))
this.setDirection(direction, {force: true});
} else if (mapId
&& panelId) {
// retry if the info for routing is ready
var wgt = this,
timer;
if (timer = this._initTimer) clearTimeout(timer);
this._initTimer = setTimeout (function () {wgt._init()}, 100);
}
},
getZclass: function () {
return 'z-gdirection';
}
});
This will contunuously trying initiate Google Direction objects if the informations (map/panel id) are ready, and then call route API to show the result if has directions.
google_direction_test.zul
<zk xmlns:w="client">
<combobox id="cbxOne" value="Chicago">
<comboitem label="Chicago" />
<comboitem label="Hammond" />
<comboitem label="Joliet" />
<comboitem label="Kankakee" />
<comboitem label="St Louis" />
<comboitem label="Peoria" />
<attribute name="onChange">
gdirection.setDirection(self.getValue(), cbxTwo.getValue());
</attribute>
</combobox>
to
<combobox id="cbxTwo" value="St Louis">
<comboitem label="Chicago" />
<comboitem label="Hammond" />
<comboitem label="Joliet" />
<comboitem label="Kankakee" />
<comboitem label="St Louis" />
<comboitem label="Peoria" />
<attribute name="onChange">
gdirection.setDirection(cbxOne.getValue(), self.getValue());
</attribute>
</combobox>
<hbox id="hbox">
<gmaps id="gmaps" width="500px" height="500px" />
<div id="panel" width="300px" height="500px" style="overflow: auto;" />
</hbox>
<gdirection id="gdirection" start="chicago" end="st louis"
onCreate='self.setMap(gmaps); self.setPanel(panel);' />
</zk>
The Result
Demo flash on line
http://screencast.com/t/2cpHVkMlGC
Reference
https://google-developers.appspot.com/maps/documentation/javascript/examples/directions-simple
Download
Full project
https://github.com/benbai123/ZK_Practice/tree/master/Components/projects/Addon_Practice/GmapsPractice
gmapsextended.jar
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Addon_Practice/GmapsPractice/target/gmapsextended.jar
demo swf
https://github.com/benbai123/ZK_Practice/blob/master/Components/demos/addon/GmapsWithGoogleDirectionService.swf
No comments:
Post a Comment