Differences

This shows you the differences between two versions of the page.

Link to this comparison view

google_maps [2012/03/31 21:48]
srdjan.lukovic created
google_maps [2012/07/09 10:56] (current)
srdjan.lukovic [GUI Code]
Line 1: Line 1:
-====== Google Maps Sample ====== +====== Interactive Maps ====== 
-...+ 
 +**Interactive Maps** is a [[SOLoist Sample Applications|SOLoist sample application]] that fully embeds [[http://maps.google.com/ | Google Maps]] that interact with the enclosing application by exhanging geo-coordinates. This example demonstrates how complex external components can be integrated with SOLoist code in order to interchange the data and keep them in sync.  
 + 
 +The user can browse the map. By selecting an object of //House// in the suggest box, the map view will be positioned on the location based on the coordinates stored in the object's //coordinates// attribute.  
 + 
 +When the marker is unlocked by unchecking the checkbox, and a different location is selected in the map, all the data from Google Maps will be automatically saved to the selected object's attributes.  
 + 
 +The user can also type in an address in the text input field, when Google Maps provides the coordinates. 
 + 
 +This way, the geo-coordinates from Google Maps and the values of attributes from SOLoist objects are kept in sync
  
 ==== Live example ==== ==== Live example ====
  
-[[http://soloistdemo.org/SampleApplications/googlemaps.html]]\\+[[http://soloistdemo.org/SampleApplications/gmaps.html]]\\
 [[http://soloistdemo.org/SampleApplications/oql?q=SELECT+h%2C+h.code%2C+h.address%2C+h.city%2C+h.country%2C+h.coordinates%0D%0AFROM+House+h&f=html | OQL Query: Houses]] [[http://soloistdemo.org/SampleApplications/oql?q=SELECT+h%2C+h.code%2C+h.address%2C+h.city%2C+h.country%2C+h.coordinates%0D%0AFROM+House+h&f=html | OQL Query: Houses]]
 +|{{screen:googlemaps.png?300}}|
  
 ===== UML Model ===== ===== UML Model =====
Line 11: Line 21:
  
 ===== Business Logic Code ===== ===== Business Logic Code =====
 +None.
 +
 +===== GUI Code =====
 <code java> <code java>
-//...+package rs.sol.sampleapps.gmaps; 
 + 
 +import rs.sol.sampleapps.House; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUIHTMLComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUILabelComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUIPanelComponent; 
 +import rs.sol.soloist.server.guiconfiguration.construction.GUIComponentBinding; 
 +import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIEdit; 
 +import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIInput; 
 +import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUIFindAllInstancesSAPComponent; 
 +import rs.sol.soloist.server.uml.concepts.runtime.ISlot; 
 + 
 +public class GoogleMapsFragment { 
 + 
 + private ISlot<?> house; 
 + private GUIPanelComponent rootPanel; 
 + 
 + public GoogleMapsFragment(GUIPanelComponent rootPanel) { 
 + this.rootPanel = rootPanel; 
 + this.house = rootPanel.opRelay1(); 
 + init(); 
 +
 + 
 + private void init() { 
 + houseLocationDetails(); 
 +  
 + GUIEdit coordinates = GUIEdit.createField(rootPanel, House.PROPERTIES.coordinates); 
 + GUIComponentBinding.create(house, coordinates.ipElement()); 
 + coordinates.setStyle("#coordinatesH"); 
 + GUIHTMLComponent.create(rootPanel, "<div id=\"map_canvasH\"></div>"); 
 + 
 + GUIHTMLComponent html1 = GUIHTMLComponent.create(rootPanel, ""); 
 + html1.setStyle("#tab1886H"); 
 +  
 + GUIComponentBinding.create(house, html1.ipHTML()); 
 +
 + 
 + private void houseLocationDetails() { 
 + GUIPanelComponent table = GUIPanelComponent.createTable(rootPanel); 
 + table.setStyle("form"); 
 +  
 + int row = 0, col = 0; 
 + GUILabelComponent.create(table, "House", row, col++).setStyle("formLabel"); 
 + GUILabelComponent.create(table, "Address", row, col++).setStyle("formLabel"); 
 + GUILabelComponent.create(table, "City", row, col++).setStyle("formLabel"); 
 + GUILabelComponent.create(table, "Country", row, col++).setStyle("formLabel"); 
 +  
 + GUIFindAllInstancesSAPComponent allHouses = GUIFindAllInstancesSAPComponent.create(rootPanel, House.CLASSIFIER); 
 + GUIInput suggestBox = GUIInput.createSuggest(table); 
 + GUIComponentBinding.create(allHouses.opValue(), suggestBox.ipCollection()); 
 +  
 + GUIEdit seAddress = GUIEdit.createField(table, House.PROPERTIES.address); 
 + GUIComponentBinding.create(house, seAddress.ipElement()); 
 + seAddress.setStyle("#addressH"); 
 +  
 + GUIEdit seCity = GUIEdit.createField(table, House.PROPERTIES.city); 
 + GUIComponentBinding.create(house, seCity.ipElement()); 
 + seCity.setStyle("#cityH"); 
 + 
 + GUIEdit seCountry = GUIEdit.createField(table, House.PROPERTIES.country); 
 + GUIComponentBinding.create(house, seCountry.ipElement()); 
 + seCountry.setStyle("#countryH"); 
 +  
 + row++; col = 0; 
 + suggestBox.setRowColumn(row, col++); 
 + seAddress.setRowColumn(row, col++); 
 + seCity.setRowColumn(row, col++); 
 + seCountry.setRowColumn(row, col++); 
 +  
 + GUIComponentBinding.create(suggestBox.opValue(), rootPanel.ipRelay1()); 
 +
 +  
 +}
 </code> </code>
  
-===== GUI Code ===== 
 <code java> <code java>
-...+package rs.sol.sampleapps.gmaps; 
 + 
 +import rs.sol.sampleapps.House; 
 +import rs.sol.soloist.helpers.init.DefaultContextInit; 
 +import rs.sol.soloist.helpers.init.Initializer; 
 +import rs.sol.soloist.helpers.init.InitializerFailedException; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUIApplicationComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUILabelComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUIPanelComponent; 
 +import rs.sol.soloist.server.guiconfiguration.style.GUIContext; 
 +import rs.sol.soloist.server.guiconfiguration.style.GUIObjectSetting; 
 +import rs.sol.soloist.server.guiconfiguration.style.GUITextFeature; 
 +import rs.sol.soloist.server.server.SoloistServiceServlet; 
 + 
 +public enum GMaps implements Initializer { 
 + 
 + INSTANCE; 
 + 
 + @Override 
 + public void init() throws InitializerFailedException { 
 + GUIApplicationComponent application = new GUIApplicationComponent(); 
 + application.setName("GMapsSample"); 
 + SoloistServiceServlet.registerApplication(application); 
 + application.setContext(createContextAndStyles()); 
 +  
 + GUIPanelComponent root = GUIPanelComponent.createFlow(application); 
 +  
 + GUILabelComponent title = GUILabelComponent.create(root, "Google Maps"); 
 + title.setStyle("titleStyle"); 
 +  
 + GUIPanelComponent topPanel = GUIPanelComponent.createFlow(root); 
 + topPanel.setStyle("topPanel"); 
 + 
 + new GoogleMapsFragment(topPanel); 
 +    } 
 +  
 + private GUIContext createContextAndStyles() { 
 + GUIContext context = new GUIContext(); 
 + DefaultContextInit.getRoot().addContext(context); 
 + 
 + GUIObjectSetting person = GUIObjectSetting.create(context, House.CLASSIFIER); 
 + GUITextFeature.createName(person, House.PROPERTIES.code); 
 + 
 + return context; 
 +
 + 
 +
 +</code> 
 + 
 +<code javascript extension.js> 
 +/** 
 + * Javascript that controls behavior of external components. 
 + */ 
 + 
 +var mapH, markerH, positionH; 
 +var geocoder; 
 +var timeout = 100; 
 +var lock = true; 
 +var first = true; 
 + 
 +var solHQ = new google.maps.LatLng(44.813209013839284, 20.464512819311494); 
 +var lockText = 'Lock marker'; 
 +var coorText = 'Coordinates'; 
 +var buttonText = 'Geocode'; 
 + 
 +function initialize() { 
 + 
 + geocoder = new google.maps.Geocoder(); 
 + markerH = new google.maps.Marker(); 
 + 
 + var myOptions = { 
 + zoom : 14, 
 + center : solHQ, 
 + scaleControl : true, 
 + mapTypeId : google.maps.MapTypeId.ROADMAP 
 + }; 
 + 
 + var canvasId = "map_canvasH"; 
 + var coorId = "coordinatesH"; 
 + 
 + mapH = new google.maps.Map(document.getElementById(canvasId), myOptions); 
 + positionH = coordinatesControl(mapH); 
 + 
 + geocode(mapH); 
 + lockMarkerControl(mapH); 
 + 
 + google.maps.event.addListener(mapH, 'click', function(event) { 
 + if (!lock) { 
 + var coor = document.getElementById(coorId); 
 + markerH.setPosition(event.latLng); 
 + markerH.setMap(mapH); 
 + coor.value = event.latLng; 
 + positionH.innerHTML = parseLatLng(event.latLng); 
 + var address = document.getElementById("addressH"); 
 + var city = document.getElementById("cityH"); 
 + var country = document.getElementById("countryH"); 
 + codeLatLng(event.latLng, address, city, country); 
 + coor.focus(); 
 + coor.blur(); 
 +
 + }); 
 + 
 + drawMap(); 
 + 
 +
 + 
 +function codeLatLng(latlng, address, city, country) { 
 + geocoder.geocode({ 
 + 'latLng' : latlng 
 + }, function(results, status) { 
 + if (status == google.maps.GeocoderStatus.OK) { 
 + if (results[0]) { 
 + var ac = results[0].address_components; 
 + var str = "", num = "", cty = "", cnt = ""; 
 + for ( var i in ac) { 
 + if (ac[i].types[0] == "street_number") 
 + num = ac[i].long_name; 
 + if (ac[i].types[0] == "street_address" || ac[i].types[0] == "route" || ac[i].types[0] == "intersection") 
 + str = ac[i].long_name; 
 + if (ac[i].types[0] == "locality") 
 + cty = ac[i].long_name; 
 + if (ac[i].types[0] == "country") 
 + cnt = ac[i].long_name; 
 +
 + address.value = str + " " + num; 
 + city.value = cty; 
 + country.value = cnt; 
 + address.focus(); 
 + address.blur(); 
 + city.focus(); 
 + city.blur(); 
 + country.focus(); 
 + country.blur(); 
 +
 + } else { 
 + alert("Geocoder failed due to: " + status); 
 +
 + }); 
 +
 + 
 +function codeAddress(address, coor) { 
 + geocoder.geocode({ 
 + 'address' : address 
 + }, function(results, status) { 
 + if (status == google.maps.GeocoderStatus.OK) { 
 + coor.value = results[0].geometry.location; 
 + coor.focus(); 
 + coor.blur(); 
 + drawMap(); 
 +
 + }); 
 +
 + 
 +function parseLatLng(latLng) { 
 + if (latLng === "") 
 + return coorText + " ( - )"; 
 + 
 + var dec = 1000000; 
 + var ll = new Array(); 
 + ll = latLng.toString().substring(1, latLng.toString().length - 1).split(', '); 
 + return coorText + " (" + (Math.round(parseFloat(ll[0]) * dec) / dec) + ", " 
 + + (Math.round(parseFloat(ll[1]) * dec) / dec) + ")"; 
 +
 + 
 +function coordinatesControl(map) { 
 + var controlDiv = document.createElement('DIV'); 
 + controlDiv.id = 'mapsCoor'; 
 + map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(controlDiv); 
 + return controlDiv; 
 +
 + 
 +function geocode(map) { 
 + var button = document.createElement('button'); 
 + button.id = 'geocodeButton'; 
 + button.innerHTML = buttonText; 
 + 
 + map.controls[google.maps.ControlPosition.TOP_RIGHT].push(button); 
 + 
 + var address = document.getElementById("addressH"); 
 + var city = document.getElementById("cityH"); 
 + var country = document.getElementById("countryH"); 
 + 
 + google.maps.event.addDomListener(button, 'click', function() { 
 + var fullAddress = address.value + ' ' + city.value + ' ' + country.value; 
 + var coor = document.getElementById("coordinatesH"); 
 + codeAddress(fullAddress, coor); 
 + }); 
 +
 + 
 +function lockMarkerControl(map) { 
 + var controlDiv = document.createElement('DIV'); 
 + controlDiv.id = 'mapsCheckbox'; 
 + var cb = document.createElement('input'); 
 + cb.type = 'checkbox'; 
 + cb.checked = lock; 
 + controlDiv.innerHTML = '<div id=\'text\'>' + lockText + '</div>'; 
 + controlDiv.appendChild(cb); 
 + 
 + map.controls[google.maps.ControlPosition.TOP_RIGHT].push(controlDiv); 
 + 
 + google.maps.event.addDomListener(cb, 'click', function() { 
 + lock = cb.checked; 
 + }); 
 +
 + 
 +function drawMap() { 
 + 
 + var coor = document.getElementById("coordinatesH"); 
 + if (coor != null && coor.value !== "") { 
 + var latLng = new Array(); 
 + latLng = coor.value.substring(1, coor.value.length - 1).split(', '); 
 + position = new google.maps.LatLng(latLng[0], latLng[1]); 
 + markerH.setMap(mapH); 
 + markerH.setPosition(position); 
 + mapH.setCenter(position); 
 + positionH.innerHTML = parseLatLng(position); 
 + } else { 
 + mapH.setCenter(solHQ); 
 + markerH.setMap(null); 
 + positionH.innerHTML = parseLatLng(""); 
 +
 +
 + 
 +function htmlComponentChanged(id) { 
 + 
 + if (id == "tab1886H") { 
 + if (first) { 
 + setTimeout(function() { 
 + initialize(); 
 + }, timeout); 
 + first = false; 
 + } else { 
 + setTimeout(function() { 
 + drawMap(); 
 + }, timeout); 
 +
 +
 +}
 </code> </code>
Print/export