GWT MapWidget from javascript as GMap2 - javascript

I am using GWT for google map application. I use Google's gwt-maps.jar for mapping api.
I can create a map as
private MapWidget mapId;
if (Maps.isBrowserCompatible()) {
mapId = new MapWidget();
mapId.setPixelSize(600, 500);
RootPanel.get("gmap").add(mapId);
mapId.setCurrentMapType(MapType.getHybridMap());
mapId.addControl(new LargeMapControl());
mapId.addControl(new MapTypeControl());
mapId.addControl(new ScaleControl());
mapId.setCenter(LatLng.newInstance(-33.867139, 151.20711), 9);
}
Now I have some legacy javascript code that needed to work on this map object. I want to use something like this:
$wnd.mapId.addOverlay(ovrlay1);
But I cannot get this $wnd.mapId variable. Do you know any way to get GMap2 object from existing map on some element? It will work if I get the GMap2 instance from my "gmap" div.
For the time being I am using JSNI to generate all the map functionalities. Simmilar to:
$wnd.mapId = new $wnd.GMap2($wnd.document.getElementById("gmap"));

Looks like I have to answer this by myself. The MapWidget object can return an handle to javascript object using getPeer() method. So What I need is bind a javascript object by calling getPeer. The following code do this.
private MapWidget mapId;
if (Maps.isBrowserCompatible()) {
mapId = new MapWidget();
nativeExportMapPeer(mapId.getPeer());
...
}
...
// export the native GMap2 object with a JSNI method
private static native void nativeExportMapPeer(JavaScriptObject peer) /*-{
$wnd.mapId = peer;
}-*/;
Thanks Eric Z. Ayers for pointing this.

Related

Android Javascript Engine; Need to replace WebView with Rhino, J2V8, etc

We are trying to replace our webview and html with a layout file and a javascript engine of some sort. There is a TON of javascript that must be called and we have a rather large JavaScriptInterface that will need to be accessable by the JS engine. I have been trying out Rhino and J2V8 but cannot figure out a way to give javascript access to a full class of methods or an annotation that works similarly to how you annotate methods for WebView.
If anyone has any insight, it would be much appreciated!
Thanks,
Jon
AFAIK there is no "out-of-the-box" solution for this for JSV8.
But have a look at following example:
public class V8ConsoleBridge implements JavaVoidCallback {
#Override
public void invoke(V8Object receiver, V8Array parameters) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < parameters.length(); ++i) {
if (i > 0) {
sb.append(", ");
}
Object object = parameters.get(i);
if (object instanceof V8Object) {
V8Object v8Object = (V8Object) object;
sb.append(v8Object.toString());
v8Object.release();
} else {
sb.append(object);
}
}
Log.i("goebl-v8", sb.toString());
}
public static void register(V8 v8) {
V8ConsoleBridge console = new V8ConsoleBridge();
V8Object v8Console = new V8Object(v8);
v8.add("console", v8Console);
v8Console.registerJavaMethod(console, "debug");
v8Console.registerJavaMethod(console, "log");
v8Console.registerJavaMethod(console, "info");
v8Console.registerJavaMethod(console, "warn");
v8Console.registerJavaMethod(console, "error");
v8Console.release();
}
}
This is a hardcoded bridge for a JS console object to access Android logging system.
You could write generic code to
scan a class you want to expose in JavaScript, much like JavaScript-Interface for WebView, even with annotations like #JavascriptInterface to only include certain members
write generic code for the invoke which actually invokes members of the receiver class by using Java reflection.
Of course it would be great if J2V8 had this useful code, because it might be used by many projects. When you have a solid solution, create a pull request so I can use it too :-)
If you don't mind wading deep in source code, you might find it useful to check out NativeScript. They provide a generic way to access all Java classes known at compile time in JavaScript, which is internally done via reflection. Well, I've heard that they do it this way, I actually didn't read the source code of NativeScript. In NativeScript, you don't have to create bridges, it's done magically by the build- and runtime-system. Maybe the source inspires you to port the ideas to J2V8.

DynamicObjects don't register with RegisterJsObject with Chromium / CefSharp

I created a dynamic object and try to register it with RegisterJsObject. However, the javascript code on the client side doesn't recongize the register js object and I can't call any of the functions that are par tof the dynamic object.
Ex.
C# code:
dynamic obj = new ExpandoObject();
obj.FullName = new Action(() =>
{
Console.WriteLine("FullName method called");
});
Cef.Initialize(new CefSettings());
ChromiumWebBrowser browser = new ChromiumWebBrowser("");
browser.RegisterJsObject("pesonObj", obj);
Javascript Code
personObj.fullName();
Even when I examine the javascript object personObj in a developer's console, it doesn't have the fullName function.
If I create a normal class that isn't dynamic, this isn't the case and works as expected.
So the question is, does Chromium support dynamicObject for registering as javascript objects in the embedded browser.
Any advice appreciated,
Thanks,
D

Get JSON WebMap from ArcGIS JavaScript API Map object

I'm trying to get a WebMap object (as JSON) from a JavaScript Map object in the ArcGIS JavaScript API. Is there any way to do this within the API, without using ArcGIS.com? Ideally something like:
webMapAsJSON = map.toWebMap();
From the "Export Web Map Task" documentation in the REST API, there's this line that suggests it should exist:
"The ArcGIS web APIs (for JavaScript, Flex, Silverlight, etc.) allow developers to easily get this JSON string from the map."
However, I don't see anything in the Map object or elsewhere in the API that would do this.
You can't. At least not officially. The steps outlined below are not recommended. They use part of the ArcGIS JS library that is not part of the public API and therefore this behavior may not work in the next version of the API or they may back-patch a previous version of the API and this could stop working even on something that previously did work.
That said, sometimes you need some "future" functionality right now and this is actually a pretty straightforward way of getting what you want using the common proxy pattern
Use the undocumented "private" function _getPrintDefinition
var proxy_getPrintDefinition = printTask._getPrintDefinition;
printTask._getPrintDefinition = function() {
var getPrintDefResult = proxy_getPrintDefinition.apply(this, arguments);
//Now you can do what you want with getPrintDefResults
//which should contain the Web_Map_as_JSON
console.log(Json.stringify(getPrintDefResult));
//make sure you return the result or you'll break this print task.
return getPrintDefResult;
}
_getPrintDefinition takes the map as the first argument and a PrintParameters object as the second.
so you'll have to create a PrintTask, redefine the _getPrintDefinition function on the newly created print task as outlined above, create a PrintParameters and then run:
myPrintTask._getPrintDefinition(myMap,myPrintParameters);
The results of this on my little test are:
{"mapOptions":{"showAttribution":false,"extent":{"xmin":-7967955.990468411,"ymin":5162705.099750506,"xmax":-7931266.216891576,"ymax":5184470.54355468,
"spatialReference":{"wkid":102100,"latestWkid":3857}},"spatialReference":{"wkid":102100,"latestWkid":3857}},
"operationalLayers":[
{"id":"layer0","title":"layer0","opacity":1,"minScale":591657527.591555,"maxScale":70.5310735,"url":"http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"},
{"id":"XXX-Redacted-XXX","title":"serviceTitle","opacity":1,"minScale":0,"maxScale":0,"token":"XXX-Redacted-XXX","url":"http://XXX-Redacted-XXX/arcgis/rest/services/TestService/MapServer"},
{"id":"XXX-Redacted-XXX","opacity":1,"minScale":0,"maxScale":0,"featureCollection":{"layers":[]}},
{"id":"featureGraphics","opacity":1,"minScale":0,"maxScale":0,"featureCollection":{"layers":[]}},
{"id":"map_graphics","opacity":1,"minScale":0,"maxScale":0,"featureCollection":{"layers":[]}}
]}
if you don't need to do any operations on the web map json and just need the output then you don't even need to use the proxy pattern.
#Suttikeat Witchayakul's answer above should work if your goal is to print the map using a print service.
However, if you are trying to export the map to the web map JSON spec so that you can save it to ArcGIS Online/Portal, or re-instantiate a map object from it later, you may have some problems. This is because the web map specification is not the same as the export web map specification, which what the print task generates and sends to printing services.
Unfortunately, the ArcGIS API for JavaScript does not provide any methods to export a map object to web map JSON. This is supposed to be coming in version 4... at some point. Until then, you can use the all but abandoned cereal library. However, if your map uses layer types that are not fully supported by cereal, it may not work for you as is and you would have to extend it.
If you want to use "esri/tasks/PrintTask" to export your map, you must use "esri/tasks/PrintParameters" for execute the printTask. Just set your map object directly to printParameter.
require([
"esri/map", "esri/tasks/PrintTemplate", "esri/tasks/PrintParameters", ...
], function(Map, PrintTemplate, PrintParameters, ... ) {
var map = new Map( ... );
var template = new PrintTemplate();
template.exportOptions = {
width: 500,
height: 400,
dpi: 96
};
template.format = "PDF";
template.layout = "MAP_ONLY";
template.preserveScale = false;
var params = new PrintParameters();
params.map = map;
params.template = template;
printTask.execute(params, printResult);
});

add namespace to your javascript

I have worked on google map api few years ago and wrote a little reusable utility. At that time adding google map api reference does add all the api classses in your page's global namespace. As this is working sample
<script src="http://maps.google.com/maps?SOMEPARAMETERS">
<script>
var map= new GMap2(document.getElementById("map_canvas"));
var point= new LatLng(31,75);
var line= new Polyline(OPTIONS);
</script>
In v3, all Google Maps JavaScript API code is stored in the google.maps.* namespace instead of the global namespace. Most objects have also been renamed as part of this process and some more changes are done.
Now you have to write the above code as follows
<script src="APIURL">
<script>
var map= new google.map.Map(document.getElementById("map_canvas"));
var point= new google.mapLatLng(31,75);
var line= new google.map.Polyline(OPTIONS);
</script>
ISSUE
I wrote a library back in Google v2 API time and used in number of projects and was working great. But now I am working on a new project and using Google V3 API and want to reuse that old v2 library. But adding v3 library doesn't add the API classes in global namespace and my library doesn't work. Is there any way we can add namespace to our JavaScript file like we did in C# on top and it allows us to write the classes without appending the namespace
You might be able to just use references:
(function() { // A scoping function to avoid creating glboals
var GMap2 = google.map.Map;
var LatLng = google.map.LatLng;
var Polyline = googlemap.Polyline;
// ...your code using the above here...
})();
This assumes, though, that the arguments haven't changed.
Alternately, you could use the Facade pattern:
function GMap2(/*...relevant args...*/)
return new google.map.Map(/*...relevant args here, possibly modified...*/);
}
(And similar for others.)
(That works even if you use new with GMap2 because the result of the new expression will be the object you return from the constructor function if you return an object.)

Get Map Object in Javascript after using CodeIgniter Google Maps API

I'm using the codeigniter library for the google maps api. I load the map using the library located on the CI Wiki: http://www.phpinsider.com/php/code/GoogleMapAPI/
I want to then use javascript on the map object after loading the page. How can I get the map object in javascript? Can I use GMap2 on the same div? Won't that recreate the map?
The reason I want to do this is to bind an event to the map.
Thanks!
Hope this works:
var myMap;
function getMap()
{
if(myMap == null)
myMap = new GMap2(document.getElementById("map"));
return myMap;
}
and then refer to this function to get reference to the GMap2 object.

Categories

Resources