Using Google Maps v3 DrawingManager from GWT - gwt

I am working on a project that uses GWT 2.4 and gwt-maps.jar to create a MapWidget and place it in a panel with various controls. This all works fine.
I would like to give my users the ability to draw a polyline on the map and use the getLength method in Polyline to determine the length of the drawn polyline. I have done this before in ActionScript and it was a bit of a pain in the neck (the rubber-banding between the last clicked point and the mouse in particular) and I was hoping not to have to do that again.
The drawing manager looks like it might be a good fit (for the drawing part at least) but it is in v3 of the API and the gwt-maps.jar code only is at v2. So I thought I might write some JavaScript and call out from GWT using JSNI, something along the lines of (in wibble.html - my top-level HTML file):
var dM = new google.maps.drawing.DrawingManager( ...
function showDM(map) {
dM.setMap(map);
dM.setOptions({
drawingControl: true
});
And then (in Wobble.java):
private MapWidget map = new MapWidget( ...
private native void showIt(final MapWidget map) /*-{
$wnd.showDM(map);
}-*/;
I have tried passing the MapWidget and its peer but in both cases I get an invalid value error when calling setMap.
Has anybody tried (and succeeded) in doing this or am I barkig up the wrong tree?
Thanks,
SO

First of all, I only have experience with GWT and GWT-JS communication. Not Google APIs.
Now:
Looks like you are passing a GWT object (compiled javscript object) to DrawingManager. The problem is the DrawingManager API receives "nice javascript objects" (not objects with obfuscated methods).
If you want to pass an HTML Element is ok (but then, you must pass widget.getElement() that really is a <div> object (by example).
Solution
Indeed GMaps API docs says you must pass a Map object from the GMap API. You create that map with an element that will be the canvas.
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
If you want to use your MapWidget as the map canvas then you can use its HTML Element.
In GWT:
private native void showIt(final MapWidget map) /*-{
$wnd.showDM(map.getElement()); // use mapwidget's element as canvas
}-*/;
In javascript:
function showDM(canvasToUse) {
// TODO: define myOptions :)
var map = new google.maps.Map(canvasToUse, myOptions);
dM.setMap(map);
dM.setOptions({
drawingControl: true
});
Disclaimer
It's only based on my experience with GWT and JSNI. I didn't try it nor have experience with GMaps or DrawingManager. You should check what I say and tell me if I had luck :)
Hope it helps!

Related

Changing jasper report parameters in runtime

I know, but we really need it.
We have a clear division of labor.
They create templates, I fill them in runtime according to some rules.
Can't teach my business to insert something like this and be sure they really did it ok(so can't move any logic to templates):
$P{risk_types}.get($F{risk_type}) ?: "UNDEFINED"
Also can not fill from files hardcoded in some adapter hadwritten by god-knows-who and unchangeable in runtime. It's a web app. Best option is to find a way to replace that file source from adapter to a ByteArrayStream.
SO:
Need to substitute contents of parameters(also default ones) at runtime.
example:
need to set JSON_INPUT_STREAM
Like this unsolved thread.
https://community.jaspersoft.com/questions/516611/changing-parameter-scriptlet
Really hope not to work on xml level, but xml also can't solve my problem as far as I tried.
Thank you!
The easiest and cleanest way we did this(bypassing usage of tons of deprecated documentation and unfinished bugged undocumented static antipatterned new features):
Create context with repository extension
SimpleJasperReportsContext jasperReportsContext = new SimpleJasperReportsContext();
jasperReportsContext.setExtensions(RepositoryService.class, Collections.singletonList(new MyRepositoryService(jasperReportsContext, yourOptionalParams)));
Fill this way(after compile and other usual actions)
JasperPrint print = JasperFillManager.getInstance(jasperReportsContext).fill(compiled, new HashMap<>());
Now your repository must extend default one to be hack-injected(cause of hodgie coded "isAssignableFrom") successfully
public class PrintFormsRepositoryService extends DefaultRepositoryService {
#Override
public InputStream getInputStream(RepositoryContext context, String uri) {
// return here your own good simple poj inputStream even from memory if you found source
// or pass to another repository service(default one probably)
return null;
}
}

syncfusion ej grid javascript method

I am very new to syncfusion controls for mvc. While exploring how to set dynamic datasource to grid, I came across this line of javascript code which I cannot understand. I have been through the javascript api docs for ej grid but couldn't find the meaning.
var obj = $("#Grid").ejGrid("instance");
If someone can explain the meaning and point out some reference documentation, I will be highly grateful.
The example I came across
https://help.syncfusion.com/aspnetmvc/grid/how-to
The javascript api I have been through
https://help.syncfusion.com/api/js/ejgrid#members:datasource
P.s: I know from a comment I came across that this has something to do with current instance of ej grid but I would like a solid understanding via a reference so I can understand.
From my little experience with Syncfusion controls the documentation explaining how to perform tasks is not well stated. If you have a license you can ask questions in their forum but I can tell you what little I learned perusing their forum.
In their JS 1 version
var obj = $("#Grid").ejGrid("instance");
and in their JS 2 version
var obj = document.getElementById('Grid').ej2_instances[0];
The variable obj appears to get an object reference to the grid identified by the id Grid. I am not sure what the instance value refers to other than the examples in the documentation show it and it works when it is used.
Not sure if I was much help.
In the Below code example Grid – Grid ID and you can take the Grid instance using the above code example. From the instance you can get the details regarding the column, dataSource, filterSettings, sortSettings etc currently applied to ejGrid. We have given support to customize the Grid using several public method. You can call those method by taking the Grid instance.
#(Html.EJ().Grid<EJGrid.Models.Order>("Grid")
.Datasource((IEnumerable<object>)ViewBag.datasource)
.AllowPaging()
.Columns(col =>
{ col.Field("OrderID").HeaderText("Order ID").TextAlign(TextAlign.Right).Width(75).Add();
col.Field("EmployeeID").HeaderText("Employee ID").TextAlign(TextAlign.Right).Width(90).Add();
col.Field("Freight").HeaderText("Freight").Format("{0:c}").TextAlign(TextAlign.Right).Width(90).Add();
col.Field("ShipCity").HeaderText("Ship City").Width(90).Add();
col.Field("Child.Test").HeaderText("TEst").Format("{0:c}").Width(90).Add();
col.Field("ShipCountry").HeaderText("Ship Country").Width(90).Add();
})
)
<script>
var obj = $("#Grid").ejGrid("instance");
var value = $("#colValue").val();
//Add custom parameter to the server
var query = new ej.Query().addParams("EmployeeID", value);
//Creating ejDataManager with UrlAdaptor
var dataManager = ej.DataManager({ url: "/Home/GetData", adaptor: new ej.UrlAdaptor() });
var promise = dataManager.executeQuery(query); promise.done(function (e) {
//Assign the result to the grid dataSource using "dataSource" method.
obj.dataSource(e.result);
</script>
To update the Grid, you can use dataSource() method. To call that method you need to take the Grid instance and call that method.
Refer the below API documentation for your reference
https://help.syncfusion.com/api/js/ejgrid#methods:datasource - used to update the Grid dataSource dynamically
https://help.syncfusion.com/api/js/ejgrid#members:datasource - returns the Grid dataSource.
Please get back to us if you have further queries.

Balloon flyto Google Earth API

In my KML I have an aggregate of placemarks in a table format. When you click the placemark you can see all the placemarks currently being loaded. Each of the placemarks have an id like below
<Placemark id="Location1">
When I add the following below I am able to fly to that balloon and it will open. However in the API this function does not work. It tries to do the following http://www.something.com#ballooonFlyTo is there a way to allow the balloon fly to method in the API?
<a href="#Location1;balloonFlyto>Location 1</a>
Not directly no, but it would be easy to modify your links to call a custom function that will support the behavior you require.
Also, if you are loading your features via kml rather than creating them programmatically then you would need to supply the full path to the kmlFeature - not just its ID. i.e.
http://somesite.com/my.kml#Location1 rather than just #Location1 - where http://somesite.com/my.kml is the file that defines the feature with the id Location1.
If you have something like the following javascript method it should work as expected. That is it will fly to the view and open a feature balloon. (This is presuming ge is the google earth plugin in your application and that the placemarks have abstract views defined).
// Attempts to find and element by ID,
// fly to its abstract view and open a feature balloon for it.
var flyto = function(id) {
var placemark = ge.getElementByUrl(id);
if(!placemark) {
return false;
}
if (placemark.getAbstractView()) {
ge.getView().setAbstractView(placemark.getAbstractView());
}
var content = placemark.getBalloonHtmlUnsafe(); // or getDescription()
var balloon = ge.createHtmlStringBalloon('');
balloon.setFeature(placemark);
balloon.setContentString(content);
ge.setBalloon(balloon);
return false;
};
Then you can simply modify your links to call the flyto function passing the desired id. e.g.
Location 1
If your placemarks do not have abstract views, then you would have to do something like extracting the point geometry and then create a lookat or camera using the latitude and longitude data to set the view.
EDIT
I decided that this functionality was really cool, so I have put together an example that does not require any special mark up of the links at all. When kml links containing a command are clicked the plugin behaves just like the full Google Earth Client would.
Here is a fully working example.

GWT-OpenLayers and OpenLayers.Format.WMSCapabilities

I am working with the Google Web Toolkit wrapper for OpenLayers. I'm attempting to add a WMS layer to a map, but I need to parse a Capabilities document in order to get the available layer names. I see that a WMSCapabilities class is available in OpenLayers http://dev.openlayers.org/releases/OpenLayers-2.12/doc/apidocs/files/OpenLayers/Format/WMSCapabilities-js.html, but I can't seem to find the implementation in GWT. Is this feature not yet available, or is it hiding, undocumented somewhere? Thanks in advance!
I still don't know if the GWT implementation is available, but it's actually rather easy to wrap native javascript code in Java. Here is my solution:
import com.google.gwt.core.client.JsArrayString;
native JsArrayString getLayerNames(String capDoc) /*-{
var toReturn = [];
var parser = new $wnd.OpenLayers.Format.WMSCapabilities();
var doc = parser.read(capDoc);
for (var i in doc.capability["layers"]) {
toReturn.push(doc.capability["layers"][i].name);
}
return toReturn;
}-*/;
You can then access them using:
JsArrayString layers = getLayerNames(getMyCapabilitiesDocumentAsString());
for (int i = 0; i < layers.length(); i++) {
Window.alert("A layer name is " + layers.get(i));
}
The variable doc is a javascript array containing the entire contents of the capabilities document, so it's possible to access more than just the layer names; simply pull out what you need. Also, it's probably better to create a single parser rather than create a new one each time the method is called, but that's a different exercise ;)

trigger resize Event to Google Maps from GWT 2.5 using "gwt-maps-3.8.0"

Using gwt-maps-3.8.0 lib GWT-Maps and i am not able to trigger a resize.
-> tried using "import com.google.gwt.user.client.Event;" -> Event.trigger(mapWidget,"resize"); "The method trigger(GoogleMap, String) is undefined for the type Event"
(this is the follow up from here: second call of google maps does not show the map in correct size)
That's the best I found so far:
private final native void resizeMap(GoogleMap map) /*-{
$wnd.google.maps.event.trigger(map, 'resize');
}-*/;
If you don't want to use your own nativ JS code you could just use the mapWidget.getMap().triggerResize() method provided by the gwt-maps-3.8.0 library