The GMapController gives a simple way to display a map provided by google according to coordinates or address. This is a FieldController that means that it can be linked to the databinding service.
The control org.adichatz.engine.widgets.GMap was developped by Adichatz.
GMap is a composite control which contains a browser. A http request is send to google and map result is displayed.
In this example, field coordinates is stored in the database as a string with following syntax
<lat : lng> where latitude and longitude
use format ##.## (in this example value is <45.75 : 4.85>).
Two controllers are linked to the model field coordinates:
Both controls are databound: If value changes in a control, modification is reported to the other control or anywhere in the application. That is a standard behavior.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <includeTree xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance" coreClassName="org.adichatz.engine.core.ASectionCore" entityURI="adi:/entityURI="adi://org.mycompany.myproject/model.gmap/GmapMM" generationType="DETAIL" xsi:noNamespaceSchemaLocation="http://www.adichatz.org/xsd/v0.8.4/generator/includeTree.xsd"> <section text="#MSG(gmap, detailContainerText)" style="Section.TWISTIE | Section.TITLE_BAR | Section.EXPANDED" id="detailContainer"> <layout layoutConstraints="wrap 2" columnConstraints="[fill]25[fill,grow]" rowConstraints="[fill,grow]"/> <composite> <layout layoutConstraints="wrap 2" columnConstraints="[fill, align right]10[fill,grow]" rowConstraints="20[]20[][]"/> <formattedText editPattern="######" format="Integer" property="id" enabled="false" id="id"/> <text property="coordinates" id="coordinates"/> </composite> <gMap coordPattern="##.##" mapTypeId="roadmap" mapDataType="COORDINATES" toolBarStyle="AdiSWT.EXPANDABLE" zoom="10" property="coordinates" noLabel="true" id="map"> <convertModelToTarget>import adichatzJboss7E4.GeometryUtil; import com.vividsolutions.jts.geom.Point; import org.adichatz.engine.widgets.supplement.LatLng; Point point = (Point) GeometryUtil.getGeometryFromInputStream(value); return new LatLng(point.getX(), point.getY(), getControl().getPattern());</convertModelToTarget> </gMap> </section> </includeTree>
coordPattern: | Coordinates pattern here is <lat : lng> using ##.## format. |
---|---|
mapTypeId: | Choose between roadmap, satellite, hybrid, terrain. |
mapDataType: | Choose between COORDINATES ( value is a point) and ADDRESS (value is a postal address). |
mapTypeControl:true | Add control for choosing Map Type (roadmap, satellite…) in the map . |
noLabel: | No label are affected to control map. By default, when a field control is linked to a model field (here property=“coordinates”), a label control is automatically created. |
toolBarStyle: | AdiSWT.EDITABLE: Coordinates control is editable. |
zoom: | Give a value between 0 and 20 (default is 12). |
<convertTargetToModel>: | Value from target is a LatLng type and must be converted to a Point. |
In this example, fields latitude and longitude are stored in the database as floats.
So control map cannot be link to the database because one control cannot be databound to 2 model fields. So programming must be used.
Synchronization of map control following to database fields is done in displayMap function (lines 6 and 9-19). This function is called thru 3 listeners of detailContainer controller:
In the other hand, changes made thru GMap control are broadcast to latitude and longitude controllers.
This way to manage synchronization between controllers is compatible with databinding service: Changes are synchronized in other editors if needed.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <includeTree xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance" coreClassName="org.adichatz.engine.core.ASectionCore" entityURI="adi:/entityURI="adi://org.mycompany.myproject/model.gmap/GmapMM" generationType="DETAIL" xsi:noNamespaceSchemaLocation="http://www.adichatz.org/xsd/v0.8.4/generator/includeTree.xsd"> <section text="#MSG(gmap, detailContainerText)" style="Section.TWISTIE | Section.TITLE_BAR | Section.EXPANDED" id="detailContainer"> <listeners> <listener listenerTypes="AFTER_SYNCHRONIZE | AFTER_PROPERTY_CHANGE | POST_REFRESH"> <code>displayGMap();</code> </listener> </listeners> <additionalCode>import org.adichatz.engine.widgets.GMap; private boolean doit = true; private void displayGMap() { if (doit) { doit = false; GMap gmapControl = #CONTROL(map); Gmap gmap = #BEAN(); gmapControl.setValue(gmap.getLatitude() + " : " + gmap.getLongitude()); doit = true; } }</additionalCode> <layout layoutConstraints="wrap 2" columnConstraints="[fill]25[fill,grow]" rowConstraints="[fill,grow]"/> <composite layoutData="wmin 200"> <layout layoutConstraints="wrap 2" columnConstraints="[fill, align right]10[grow,fill]" rowConstraints="20[]20[][]"/> <formattedText editPattern="######" format="Integer" property="id" enabled="false" id="id"/> <formattedText editPattern="##.##" format="Float" property="latitude" id="latitude"/> <formattedText editPattern="##.##" format="Float" property="longitude" id="longitude"/> </composite> <gMap coordPattern="##.##" toolBarStyle="AdiSWT.COORDINATES | AdiSWT.EDITABLE | AdiSWT.EXPANDABLE" zoom="14" id="map"> <listeners> <listener listenerTypes="MODIFY_TEXT"> <code>if (doit) { doit = false; #CONTROLLER(latitude).broadCastedSetValue(gmap.getCenter().getLatitude()); #CONTROLLER(longitude).broadCastedSetValue(gmap.getCenter().getLongitude()); doit = true; }</code> </listener> </listeners> </gMap> </section> </includeTree>
doit: | Allows to avoid tha change done by programming . |
---|---|
#BEAN(): | The bean of the current entity. |
#CONTROLLER(latitude): | Reference to the controller containing a FormattedText control and bound to latitude model field of bean Gmap. |
<controller>.broadCastedSetValue(…): | Sets a value in the control of ther controller and launches the databinding mecchanism. |
Two controllers are linked to the model field address:
Both controls are databound: If value changes in a control, modification is reported to the other control or anywhere in the application. That is a standard behavior.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <includeTree xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance" coreClassName="org.adichatz.engine.core.ASectionCore" entityURI="adi:/entityURI="adi://org.mycompany.myproject/model.gmap/GmapMM" generationType="DETAIL" xsi:noNamespaceSchemaLocation="http://www.adichatz.org/xsd/v0.8.4/generator/includeTree.xsd"> <section text="#MSG(gmap, detailContainerText)" style="Section.TWISTIE | Section.TITLE_BAR | Section.EXPANDED" id="detailContainer"> <layout layoutConstraints="wrap 2" columnConstraints="[fill]25[fill,grow]" rowConstraints="[fill,grow]"/> <composite> <layout layoutConstraints="wrap 2" columnConstraints="[fill, align right]10[fill,grow]" rowConstraints="20[]20[][]"/> <formattedText editPattern="######" format="Integer" property="id" enabled="false" id="id"/> <text textLimit="255" property="address" id="address"/> </composite> <gMap mapType="Terrain" noLabel="true" toolBarStyle="AdiSWT.ADDRESS | AdiSWT.EDITABLE | AdiSWT.EXPANDABLE" zoom="10" property="address" id="map"/> </section> </includeTree>
mapType: | Terrainis selected. |
---|---|
toolBarStyle | AdiSWT.ADDRESS: Use Adress text control, AdiSWT.EDITABLE: Address control is editable. |
noLabel: | No label are affected to control map. |