How to access generated Javascript (ScriptObject) from Javascript? - javascript

I have a Silverlight application that generates a lot of Google Maps objects on the Silverlight site. For example a Map is created like this:
var map = HtmlPage.Window.CreateInstance(#"google.maps.Map", container, mapOptions);
var center = (ScriptObject)_map.Invoke("getCenter");
Everything works fine. But now I need to access the map object from Javascript directly. I think it could be done by exposing a map property as ScriptableMember and use it from Javascript. But that"s a bit odd because the map object lives already in the browser. But how do I access it?
Update
Just to make clearer what I'm talking about
Let's say I have created my map as shown above. Now I have a loaded Javasript file with this function:
function ReadMapCenter()
{
//Need the map object in Javascript
map.getCenter();
}
How can I access the existing map Object from Javascript?

If you just expose it as type ScriptObject I think the bridge will simply unpack the scripted object rather than create yet another layer of wrapping for it.
Alternative
Don't use CreateInstance
In your javascript at the global leve use:-
var map;
function createMap(container, mapOptions)
{
if (!map)
{
map = new google.maps.Map(container, mapOptions);
}
return map;
}
now your javascript has a map global it can use.
In silverlight use:-
var map = HtmlPage.Window.Invoke("createMap", container, mapOptions);

Related

Microsoft.Maps.SDKMap is undefined, when creating object in BingMaps V8

While creating bingmap instance, SDKMap is undefined. Is there any missing credentials in following code?
function GetBingMap(){
var vcredentials = "<%=this.credentialKey%>" //credential Key
var vzoomLevel = Number("<%=this.zoom%>"); //Zoom Level
// Create the Map instance
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), //div map load
{
credentials: vcredentials, //credential
zoom: vzoomLevel, //zoom level
showZoomButtons: false, // enable Zoom Buttons
showLocateMeButton: false, // show Locate me button
showMapTypeSelector: false,//enable Map type selector
showScalebar: false,//enable scale bar
showTermsLink: false//enable terms link
});
this.map= map;
Make sure that the Bing Maps source code has loaded before calling your GetBingMap function. It sounds like it hasn't fully loaded before your code tries to create a map instance. If you are using async/defer in the script reference in the script tag, remove it.

Leaflet control Joomla issue

I've created a Joomla Component and i have a Leaflet map in the component window.
I've used Leaflet with Omnivore plugin to add GPX and KML to my map and I used the Leaflet controls to allow to add and remove the layers.
I've tested the controls in a clean joomla development installation and the controls are OK, as seen in the first image
enter image description here
When I use the component in my Joomla site che controls are not OK, there are some dirty entry as seen in the second figures
enter image description here
I think this is because of the templates and some script that interfere with Leaflet but I can't fix it.
The joomla versions are the same, the template no, the joomla site use gantry.
This is the function I used to populate the map:
function showRouteTracks(tracce, baseURI, popup=false, enableLayers=true, enableElevation=false){
var layerControl = new Array();
for (var i = 0; i < tracce.length; i++) {
var customLayer = L.geoJson(null, {
style: getStyle(i)
});
if(tracce[i][3]=='GPX'){
var layer = omnivore.gpx(baseURI+tracce[i][2], null, customLayer).on('ready', function() {
elevation(enableElevation,layer);
});
if(popup){
link=''+tracce[i][5]+''
layer.bindPopup(tracce[i][0]+"➝"+tracce[i][1]+"<br/>"+link);
}
lvrtMap.addLayer(layer);
layerControl[tracce[i][0]+"➝"+tracce[i][1]]=layer;
}
if(tracce[i][3]=='KML'){
var layer = omnivore.kml(baseURI+tracce[i][2], null, customLayer).on('ready', function() {
elevation(enableElevation,layer);
});
if(popup){
link=''+tracce[i][5]+''
layer.bindPopup(tracce[i][0]+"➝"+tracce[i][1]+"<br/>"+link);
}
lvrtMap.addLayer(layer);
layerControl[tracce[i][0]+"➝"+tracce[i][1]]=layer;
}
}
if(!enableLayers)
layerControl=null;
if(enableElevation)
L.control.layers(lvrtMapLayers,layerControl,{'position':'bottomright'}).addTo(lvrtMap);
else
L.control.layers(lvrtMapLayers,layerControl).addTo(lvrtMap);
}
Currently you're creating an array to store the title/layer items:
var layerControl = new Array();
But L.Control.Layers takes object literals as baselayer/overlay parameters:
var baseLayers = {
"Mapbox": mapbox,
"OpenStreetMap": osm
};
var overlays = {
"Marker": marker,
"Roads": roadsLayer
};
L.control.layers(baseLayers, overlays).addTo(map);
So you should use an object literal:
var layerControl = {};
You can add items the same way as you did before:
layerControl['MyTitle'] = myLayerInstance;
I'll bet you'll have no problem then. What happening now is that your trying to assign string keys to items in an array, which isn't supported (even supposed to work but that aside). A javascript array can only have numeric keys and nothing else.
That it works for you with a clean install and not in your production setup is that probably in production you have a javascript library/framework loaded which adds methods/properties to javascript's native array prototype and they are enumerable. Thus when the layercontrol instance iterates the array it also finds these extra methods/properties and tries to add them to the layercontrol.
Just use a object literal: {} not an Array, you'll be fine, good luck.
EDIT: Got curious and did some digging. As it turns out this is caused by Mootools and then i ran into this question: Looping through empty javascript array returns array object functions which gives some explanation and some other solutions but it's best if you just use a object literal because at the moment you're kind of abusing Array.

AngularJS Google Map directive map instance

I'm using http://angular-google-maps.org/ it's nice angular google maps library. But i want use map instance which is loaded not in angularjs context by something like this:
$scope.map = {
events: {
tilesloaded: function (map) {
$scope.$apply(function () {
$scope.mapInstance = map;
});
}
}
}
Ok nice i have mapInstance and I CAN use it programmatically. But in application lifecycle this fire to late- so in other words I want to load whole directive (and get map instance) before other code- where I just wan't to use other map events.
In recently looking up ways to get the map instance from the example on the docs page, I came across this instead:
$scope.map.control.getGMap().
Make sure on your google-maps HTML markup, you have the options attribute set as control="map.control" and an empty object set in your $scope.map object.
$scope.map= { control : {}, ...other map options...};
That empty objects is filled when google map is initiated. I hope this helps and isn't too late.
Enjoy Angular!!!

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