This is an old revision of the document!
Table of Contents
Google Maps Sample
This sample application fully embeds Google Maps. This is example of how complex external components can be integrated with SOLoist code. You can browse map just as you would on original application. By choosing house from suggestbox map view will be centered on location based on the saved coordinates. You can unlock marker and set different location for that house, all data will be automatically saved. You could also type in address manually and perform geocoding, exact coordinates will be provided by Google Maps.
Live example
UML Model
Business Logic Code
None.
GUI Code
package rs.sol.sampleapps.gmaps; import rs.sol.sampleapps.House; import rs.sol.soloist.server.builtindomains.builtindatatypes.Text; 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.GUICollectionInput; import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIElementComponent; import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUISuggestWidget; import rs.sol.soloist.server.guiconfiguration.layout.TableLayoutData; import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUIFindAllInstancesSAPComponent; import rs.sol.soloist.server.uml.concepts.runtime.ISlot; public class GoogleMapsFragment { private ISlot<Text> house; private GUIPanelComponent rootPanel; public GoogleMapsFragment(GUIPanelComponent rootPanel) { this.rootPanel = rootPanel; this.house = rootPanel.input; init(); } private void init() { houseLocationDetails(); GUIElementComponent coordinates = GUIElementComponent.createSlotEditor(rootPanel, House.PROPERTIES.coordinates, house); coordinates.styleName.set(Text.fromString("#coordinatesH")); GUIHTMLComponent.create(rootPanel, "<div id=\"map_canvasH\"></div>"); GUIHTMLComponent html1 = GUIHTMLComponent.create(rootPanel, ""); html1.styleName.set(Text.fromString("#tab1886H")); GUIComponentBinding.create(house, html1.html); } private void houseLocationDetails() { GUIPanelComponent table = GUIPanelComponent.createTable(rootPanel); table.styleName.set(Text.fromString("form")); int row = 0, col = 0; GUILabelComponent.create(table, "House", row, col++).styleName.set(Text.fromString("formLabel")); GUILabelComponent.create(table, "Address", row, col++).styleName.set(Text.fromString("formLabel")); GUILabelComponent.create(table, "City", row, col++).styleName.set(Text.fromString("formLabel")); GUILabelComponent.create(table, "Country", row, col++).styleName.set(Text.fromString("formLabel")); GUIFindAllInstancesSAPComponent allHouses = GUIFindAllInstancesSAPComponent.create(rootPanel, House.FQ_TYPE_NAME); GUIElementComponent suggestBox = GUIElementComponent.createInput(table, new GUISuggestWidget(), new GUICollectionInput()); GUIComponentBinding.create(allHouses.value, GUICollectionInput.get(suggestBox).collection); GUIElementComponent seAddress = GUIElementComponent.createSlotEditor(table, House.PROPERTIES.address, house); seAddress.styleName.set(Text.fromString("#addressH")); GUIElementComponent seCity = GUIElementComponent.createSlotEditor(table, House.PROPERTIES.city, house); seCity.styleName.set(Text.fromString("#cityH")); GUIElementComponent seCountry = GUIElementComponent.createSlotEditor(table, House.PROPERTIES.country, house); seCountry.styleName.set(Text.fromString("#countryH")); row++; col = 0; TableLayoutData.setRowColumn(suggestBox, row, col++); TableLayoutData.setRowColumn(seAddress, row, col++); TableLayoutData.setRowColumn(seCity, row, col++); TableLayoutData.setRowColumn(seCountry, row, col++); GUIComponentBinding.create(suggestBox.value, rootPanel.input); } }
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.builtindomains.builtindatatypes.Text; 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.name.set(Text.fromString("GMapsSample")); SoloistServiceServlet.registerApplication(application); application.context.set(createContextAndStyles()); GUIPanelComponent root = GUIPanelComponent.createFlow(application); GUILabelComponent title = GUILabelComponent.create(root, "Google Maps"); title.styleName.set(Text.fromString("titleStyle")); GUIPanelComponent topPanel = GUIPanelComponent.createFlow(root); topPanel.styleName.set(Text.fromString("topPanel")); new GoogleMapsFragment(topPanel); } private GUIContext createContextAndStyles() { GUIContext context = new GUIContext(); context.supercontext.set(DefaultContextInit.getRoot()); GUIObjectSetting person = GUIObjectSetting.create(context, House.CLASSIFIER); GUITextFeature.createName(person, House.PROPERTIES.code); return context; } }
- 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); } } }