Google Earth defaults to the "Borders and Labels" (i.e, showing country outlines) on. I have KMZ/KML files where I want the borders turned off. I've searched documents describing the KML and can't find anything related to layers.
I also tried saving KMZ files with and without the borders turned on, and they are identical.
Anyone know how to access the layers through the KML API?
You can't yet turn on/off layers in Google Earth directly via KML. Currently it's a manual action done by user of Google Earth.
However, there is currently a directive to turn on/off historical imagery, streetview, and sun light modes.
https://developers.google.com/kml/documentation/kmlreference#gxvieweroptions
But you can turn the layers on/off easily via the GE API:
To enable a specific layer:
ge.getLayerRoot().enableLayerById(ge.LAYER_NAME, true)
To disable a layer:
ge.getLayerRoot().enableLayerById(ge.LAYER_NAME, false);
Reference: https://developers.google.com/earth/documentation/layers#layers
The API doesn't have constants defined for the individual layers within ge.LAYER_BORDERS but if you look in the KML file, each "Folder" node has an ID, so, as JasonM1 says, you can use enableLayerById for each one you want to switch off, having switched on the top containing node (ge.LAYER_BORDERS in this case).
Here's the code i used to clean up the "Borders and Labels" layer via the API:
ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
ge.getLayerRoot().enableLayerById("530286de-c7b3-11dc-938c-dd553d8c9902", false); // internation borders
ge.getLayerRoot().enableLayerById("cfdff130-394a-11e0-98fa-dd5743f1dfd8", false); // coastline
ge.getLayerRoot().enableLayerById("533444c6-c7b3-11dc-b02e-dd553d8c9902", false); // 1st level borders too
ge.getLayerRoot().enableLayerById("534ab67a-c7b3-11dc-a2a7-dd553d8c9902", false); // 2nd level borders too
ge.getLayerRoot().enableLayerById("e2334aaa-e853-11df-9192-77880e18aa7d", false); // geographic features
p.s. I can't seem to find where i got the "borders and labels.kml" file now, but it was probably here somewhere, will continue looking...
Related
I want to rotate out/toggle two images within my Chrome Cast's Ambient Mode (via Google Photo Album).
Possible routes that I see:
Delete image 1 and add image 2 of an album one day, the next delete image 2 and add image 1.
Each day, switch the selected Album within the Ambient Mode settings.
Methods I see:
https://developers.google.com/cast/, however there doesn't seem to be any mention of settings or ambient mode. I suspect these methods are not public.
ifttt, sadly I don't see anything even remotely along these lines already out there.
Is this possible, where could I look?
The Ambient mode content is managed by the Cast platform based on the selected content you have provided. There isn't an API to be able to control what content is selected to be displayed.
I was wondering if there is a good way to draw icons (markers) in the middle of polygons, using kml in google earth plugin.
Currently I solve this by calculating the middle, and for every polygon adding a placemark with the icon in the calculated center.
But then i have to make sure that when I remove the polygom I remove the marker also.
Is there a way to make them connected and not seperate like that?
Thank you!
You could encapsulate the placemark and polygon objects into a single object, allowing you to create custom "PlacemarkPolygons" passing in any options you require. So you would have.
function PlacemarkPolygons(options) {
// your set up...
}
To see what I mean take a look at this "CustomOverlay" example that wraps a groundOverlay and a polygon to provide click events for the groundOverlay.
http://jsfiddle.net/2bUXQ/
Although the Google Earth API objects are different from yours, the principal would be exactly the same. You would define a custom object that wraps the two API objects that you want to associate together, along with any methods that help you to use it.
In the past I've used the Image Field Module to require a user to provide an image of specific dimensions and it's worked great. I like the new Media Library Picker Field and it's integration with the Image Editor module to allow for cropping and re-sizing.
What I'd like to do is use the Media Library Picker Field but require the user to crop and/or re-size the image to specific dimensions. Is there any way to configure it that way? So far, the best I've come up with is to provide some help text to the user suggesting that they re-size the image to desired dimensions.
Should I just stick with the Image Field if I must have the image meet specific dimensions or is there a better way with the Media Library Picker Field?
You can't enforce that the image is supplied with specific dimensions using the Orchard 1.7+ media processing features, however you can ensure that it is displayed with correct dimensions.
Orchard 1.7 introduces the concept of media profiles, which effectively allow you to create a bunch of image transformations, name them, and then use them arbitrarily throughout your site.
On a recent project I was given a load of customer profile pictures for a testimonial page on an Orchard site. They were supplied in a variety of different sizes, and I knew I needed at least 2 different sizes (one for the main testimonial page, and a smaller one for testimonial widgets shown on other pages).
In the Admin Dashboard, I went to Media -> Profiles and created a new Media Profile called Customer_Profile_Regular, then added a Resize filter to scale it down to 100x100px (the resize filter is quite flexible, and you can create your own filters easily by implementing the IImageFilterProvider interface).
I did the same for a second profile, Customer_Profile_Small, scaling down to 50x50.
Then, using Shape Tracing, I overrode the existing Media Library Picker field display shape, and replaced it with this:
#{
var imagesField = Model.ContentItem.Testimonial.CustomerProfile;
}
#if(imagesField.MediaParts.Any()) {
<div class="customer-profile-image">
#Display.MediaUrl(Profile: "Customer_Profile_Regular", Path: imagesField.MediaParts.First().MediaUrl)
</div>
}
For the testimonial widget, it was simply a case of creating a similar shape override, supplying the other profile name.
Now I can upload any image to my media library, and use it as a customer profile image on a testimonial. Orchard will automatically resize (or perform other operations on) the image based on the profile I tell it to use, the result of which is stored in the site's Media folder so that it is only regenerated when necessary.
I have many large KML data-sets, which are served using a hierarchy of region-based network-links; as described in the KML reference:
Using Regions in conjunction with NetworkLinks, you can create a hierarchy of pointers, each of which points to a specific sub-Region. The <viewRefreshMode>, as shown in the following KML file, has an onRegion option, which specifies to load the Region data only when the Region is active. If you provide nested Regions with multiple levels of detail, larger amounts of data are loaded only when the user's viewpoint triggers the next load.
This works nicely when loaded in Google Earth.
I now wish to load these in an application using the Google Earth plug-in. And I need to access the loaded content via the Google Earth API; (i.e. attach click events, alter styles) to integrate the content into the application.
The issue is, I haven't found any reference to an 'on-load' event for network links. In my mind, the way this would work is:
Load top-level network link via the API, attaching a call-back function which will be invoked when the network-link is loaded.
In the call-back function, parse the KML returned by network link. For intermediate levels in the regionation hierarchy, this KML will contain only network links to the next regionation level. Load these into the plug-in via the API, again specifying the same call-back function, which will be invoked when these are loaded (i.e. when their region becomes visible).
Eventually, the KML returned will contain the actual 'content'. At this stage we load the actual content (i.e. placemarks) into the plug-in, after performing any desired modifications (e.g. attaching event-listeners, setting styles, etc).
I'm thinking the javascript would look something like the following.
Please note: this is just a rough sketch to perhaps aid in understanding my question. I am NOT asking why this code doesn't work.
//create network link
var networkLink = ge.createNetworkLink("");
networkLink.setName("Regionated hierarchy root");
// create a Link object
//the network-links contained in the kml that will be returned in this file
//are region-based; they will only be loaded when the user zooms into the relevant
//region.
var link = ge.createLink("");
link.setHref("http://foo.com/regionatedRoot.kml");
// attach the Link to the NetworkLink
networkLink.setLink(link);
//specify the callback function to be invoked when the network link is loaded
//this is is the part that doesn't actually exist; pure fiction...
networkLink.onLoad = networkLinkLoaded;
// add the NetworkLink feature to Earth
ge.getFeatures().appendChild(networkLink);
// function which will be invoked when a network-link is loaded
// i.e. when its region becomes active
function networkLinkLoaded(kml) {
//parse the kml returned for child network links,
//this will create the network link KmlObject, with a
//region specified on it.
for (childNetworkLink in parseNetworkLinks(kml)) {
//and append them, again hooking up the call-back
childNetworkLink.onLoad = networkLinkLoaded;
ge.getFeatures().appendChild(childNetworkLink);
}
//if the user has zoomed in far enough, then the kml returned will
//contain the actual content (i.e. placemarks).
//parse the kml returned for content (in this case placemarks)
for (placemark in parsePlacemarks(kml)) {
//here we would attach event-listeners to the placemark
ge.getFeatures().appendChild(placemark);
}
}
Is this possible?
Have I taken a wrong turn in my thinking? I believe I have followed recommended practices for managing large KML datasets, but I am unsure how to use these via the API.
Addendum:
As an example of the type of problem I am trying to solve:
Imagine you are building a web application using the Google Earth Plugin, and you want to display a placemark for every set of traffic-lights in the world. The placemarks should only display at an appropriate level-of-detail (e.g. when the camera is at 5km altitude). When a user clicks on a placemark, we want the web app to load statistics for that set of traffic-lights, and display them in a sidebar.
How would you engineer this?
You wouldn't need access to the object data directly to provide the functionality you require. You would handle the data load exactly like you have done, using a hierarchy of region-based network-links.
Then if your usage scenario is like the one you set out in your addendum then you would simply use the target data from the click event to load your statistical data based on the placemarks as required.
For example, you could simply set up a generic mousedown event handler on the window object and then test to see if the target is a placemark. You can add this generic listener before you load any data and it will still be fired when you click on your dynamically loaded placemarks. There is no need to attach individual event-listeners to the placemarks at all.
e.g.
window.google.earth.addEventListener(ge.getWindow(), 'mousedown', onWindowMouseDown);
var onWindowMouseDown = function(event) {
if (event.getTarget().getType() == 'KmlPlacemark') {
// get the placemark that was clicked
var placemark = event.getTarget();
// do something with it, or one of its relative objects...
var document = placemark.getOwnerDocument();
var parent = placemark.getParentNode();
// etc...
}
}
Not sure if this is quite what you want but there is a kmltree api that will:
build out the kml tree for you based on the kml given
allow you to have a 'kmlloaded' event handler
http://code.google.com/p/kmltree/
function initCB(instance){
ge = instance;
ge.getWindow().setVisibility(true);
var gex = gex = new GEarthExtensions(ge);
var tree = kmltree({
url: 'http://foo.com/regionatedRoot.kml',
gex: gex,
mapElement: $('#map3d'),
element: $('#tree'),
});
$(tree).bind('kmlLoaded', function(event, kmlObject){ //do something here });
tree.load();
}
it does require you to bring in another js api but it works pretty good and gives you some good built in functionality.
So far I haven't found anything just from the plug-in that will fire an event when the kml is loaded...
you might be able to try using fetchKml() especially if you are hardcoding that url for the link in there?
google.earth.fetchKml(ge, 'http://foo.com/regionatedRoot.kml', function(kmlObject){
//do logic here
});
I used Apple's AVEdit-Demo, tweaked it a little and was able to add CALayers with animations and images to the video-composition. So far, this works fine.
It uses AVVideoComposition and AVPlayer/AVPlayerItem to merge videos (and show them - the export rendering is a little different).
I added a layer with a png with some transparent areas, sort of like a mask, that hides parts of the video. Now I need to move the video-layer, so I can adjust the hidden parts (a.k.a. the visible part). The Mask covers the whole screen (in a CALayer), so moving the Mask-Layer isn't an option.
I didn't find any properties or methods, to adjust the position of the video-layer...
Any Ideas?
Found it...
I had to access the AVMutableCompositionTrack in the AVMutableVideoComposition and set the preferredTransform there (CGAffineTransformTranslate).
However - the Docs state, that this should be possible in a AVMutableComposition as well (AVAssetTrack setPreferredTransform).
I couldn't get this to work, though.