JavaScript global variable to store kml model object - kml

I'm developing a webpage to display google earth and a kml object. There will be two frames, one is the earth + kml object, the other is to display kml object's info like altitude, latitude, longitude...
I'm done with load the kml object and display its info on the page. Now, I want to add some events to control the kml object with keyboard, to move it and reflect all the changes in coordination onto the display frame.
In order to do that, I create my own object:
//Constructor for object ModelInfo
function ModelInfo(name) {
var me = this;
me.model = null;
me.name = name;
me.lon = 120.89250214028388;
me.lat = 22.17480037801846;
me.alt = 15.00;
me.heading = 0.0;
me.tilt = 0.0;
me.roll = 0.0;
me.kmlUrl = "";
me.ALTITUDE_MODE = ge.ALTITUDE_RELATIVE_TO_GROUND;
me.scaleX = 0.3;
me.scaleY = 0.3;
me.scaleZ = 0.3;
}
When I fetchKml, I store the kml model into my objectInfo.model:
// Fetch a KML file and show it
function finished(object, objInfo) {
if (!object) {
// wrap alerts in API callbacks and event handlers
// in a setTimeout to prevent deadlock in some browsers
setTimeout(function() {
alert('Bad or null KML.');
}, 0);
return;
}
var modelPlacemark;
walkKmlDom(object, function() {
if (this.getType() == 'KmlPlacemark' && this.getGeometry()
&& this.getGeometry().getType() == 'KmlModel') {
modelPlacemark = this;
}
});
var model = modelPlacemark.getGeometry();
objInfo.model = model;
This is how I call fetchKml
shutter = new ModelInfo("Shutter"); //shutter is global variable
shutter.kmlUrl = 'http://120.125.80.113/kml/student/space_shuttle_23_20110812a/space_shuttle_23_20110812a_SP.kmz';
google.earth.fetchKml(ge, shutter.kmlUrl, function(obj) {
finished(obj, shutter);
});
But the problem is, after fetchKml finishes, I try to access shutter.model, it is always null, but when I access shutter.model from within function finished, it is not null
So my question is how did it happen? Is there anyway to store kml object in a global variable to modify its attribute later?
Thanks,
Hans

After several hrs trying to figure out why, I decided to use Firebug to debug the code and found out the reason. I still don't know why though.
The name I used for my variable "shutter" somehow isn't listed as a member of this page when I debugged using Firebug. When I changed it to flying_obj then everything is ok, I was able to store the kml object inside my flying_obj.model
Anyone knows what's wrong with the name "shutter" please explain it to me. It'd be great!!
Hans

Related

How to get position of clicked icon on cesium map

I am trying to draw circles around an icon that is selected via clicking. My current code is:
this.handler.setInputAction(function(click) {
var pickedObjects = viewer.scene.drillPick(click.Position);
if(Cesium.defined(pickedObjects)) {
if(pickedObjects.length >=1)
{
var cartesian = thisRef.viewer.camera.pickEllipsoid(click.position, thisRef.viewer.scene.globe.ellipsoid);
thisRef.drawCircle(cartesian);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK;
};
If the user is zoomed out quite far, the position won't be accurate. It needs to be based on the selected object, not the users click. However I can't figure out how to do this. I have pickedObjects, but I can't figure out how to get their position from those objects. It doesn't seem to be an entity (even though I think the icon was an entity when it was being created) and so I can't use entity.position. Thank you for your help.
To be able to access the standard Cesium entity, it turns out, you must go in the drillPick objects id. So I modified my code to get the first object in the list of objects and get the id from that, and now I can call the member position of a standard entity.
this.handler.setInputAction(function(click) {
var pickedObjects = viewer.scene.drillPick(click.Position);
if(Cesium.defined(pickedObjects)) {
if(pickedObjects.length >=1)
{
var entity = pickedObjects[0].id;
thisRef.drawCircle(entity.position);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK;
};

C# Revit API, how to create a simple wall using ExternalCommand?

I just wanted to learn Revit API and create a simple wall using ExternalCommand. But I cannot figure it out...
I think my problem is here:
var symbolId = document.GetDefaultFamilyTypeId(new ElementId(BuiltInCategory.OST_Walls));
When I debug it symbolId always -1.
Can you help me what is wrong with this code snippet?
public Autodesk.Revit.UI.Result Execute(
Autodesk.Revit.UI.ExternalCommandData command_data,
ref string message,
Autodesk.Revit.DB.ElementSet elements)
{
var document = command_data.Application.ActiveUIDocument.Document;
var level_id = new ElementId(1526);
// create line
XYZ point_a = new XYZ(-10, 0, 0);
XYZ point_b = new XYZ(10, 10, 10);
Line line = Line.CreateBound(point_a, point_b);
using (var transaction = new Transaction(doc))
{
transaction.Start("create walls");
Wall wall = Wall.Create(doc, line, level_id, false);
var position = new XYZ(0, 0, 0);
var symbolId = document.GetDefaultFamilyTypeId(new ElementId(BuiltInCategory.OST_Walls));
if (symbolId == ElementId.InvalidElementId) {
transaction.RollBack();
return Result.Failed;
}
var symbol = document.GetElement(symbolId) as FamilySymbol;
var level = (Level)document.GetElement(wall.LevelId);
document.Create.NewFamilyInstance(position, symbol, wall, level, StructuralType.NonStructural);
transaction.Commit();
}
return Result.Succeeded;
}
Work through the Revit API getting started material and all will be explained. That will save you and others many further questions and answers.
To address this specific question anyway, GetDefaultFamilyTypeId presumably does not do what you expect it to for wall elements. In the GetDefaultFamilyTypeId method API documentation, it is used for structural columns, a standard loadable family hosted by individual RFA files. Walls are built-in system families and behave differently. Maybe GetDefaultFamilyTypeId only works for non-system families.
To retrieve an arbitrary (not default) wall type, use a filtered element collector to retrieve all WallType elements and pick the first one you find.
Here is a code snippet that picks the first one with a specific name, from The Building Coder discussion on Creating Face Wall and Mass Floor
:
WallType wType = new FilteredElementCollector( doc )
.OfClass( typeof( WallType ) )
.Cast<WallType>().FirstOrDefault( q
=> q.Name == "Generic - 6\" Masonry" );

How do I transfer rich text attachments from one document to another

I have 2 documents which are supposed work in such a way to be able to transfer files between them. However, it doesn't work. The exception I get is Exception occurred calling method NotesDocument.save() Notes error: One or more of the source document's attachment are missing. Run Fixup to delete the document in the source database. This happens after I try to call save() function on the document to which I've just transfered files from the first.
The functions are below:
function transferFiles(docToGetFrom, docToTransferTo, fileFieldFromFirstName, fileFieldFromSecondName)
{
var rit1:NotesRichTextItem = getFirstNotesRichTextItem(docToGetFrom, fileFieldFromFirstName);
docToTransferTo.copyItem(rit1, fileFieldFromSecondName);
deleteAllFilesFromDocument(docToGetFrom, fileFieldFromFirstName);
docToTransferTo.save();
}
function getFirstNotesRichTextItem(documentToGetFrom, fileFieldName)
{
if (documentToGetFrom == null)
{
return(null);
}
if (!documentToGetFrom.hasItem(fileFieldName))
{
return(null);
}
var rit1:NotesRichTextItem = documentToGetFrom.getFirstItem(fileFieldName);
return rit1;
}
function deleteAllFilesFromDocument(documentToDeleteFrom, fileFieldName)
{
var arr = getAllEmbeddedObjects(documentToDeleteFrom, fileFieldName);
for(var i = 0; i < arr.length; i++)
{
arr[i].remove();
}
documentToDeleteFrom.save();
}
function getAllEmbeddedObjects(documentToGetFrom, fileFieldName)
{
var rit1:NotesRichTextItem = getFirstNotesRichTextItem(documentToGetFrom, fileFieldName);
if (rit1 == null)
{
return(null);
}
try
{
var arr=rit1.getEmbeddedObjects();
return arr;
}
catch(e)
{
return(null);
}
}
According to plain logic, I need to do the following in order to make it work:
Get attachments from the document A
Copy them to the document B
Remove attachments from the document A
Call save() on A
Call save() on B
I did exactly the same, but nevertheless get this nasty exception. Also, I've tried to solve the problem by setting OLEDisableFX to 1, but with no luck. I assume that something must be wrong with the method copyItem() (I guess it can only work properly with simple datatypes). What's the problem? Thanks in advance.
You'll probably need to detach the attachment from the source document and attach it to the target document. See the NotesEmbeddedObject class for examples.
Use the CopyItemToDocument method of the NotesItem class. The following is some code I used in a LotusScript agent but the CopyItemToDocument method is also available in Java and SSJS.
If doc.Hasitem("RTF1") Then
Set item = Nothing
Set item = doc.getFirstItem("RTF1")
Call item.Copyitemtodocument(targetdoc, "targetRTF")
Call item.Remove()
End If

Making jslink target specific list

Background
I got a page where I’m showing two list views from two separate lists which both have Custom List as their ListTemplate. They got their separate jslink file cause I don’t want them to look alike.
Problem
The js link file targets both listviews since they use the same Template.
Code
(function () {
var listContext = {};
listContext.Templates = {};
listContext.ListTemplateType = 100;
listContext.Templates.Header = "<div><ul>";
listContext.Templates.Footer = "</ul></div>";
listContext.Templates.Item = LinkTemplate;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(listContext);
})();
Question
Is there any way to make the js only target a specific list?
Ended up going with Paul Hunts solution that he writes about on myfatblog.co.uk. http://www.myfatblog.co.uk/index.php/2013/09/listview-web-part-issues-with-jslink-and-display-templates-a-solution/
The script ended up looking like this and I pasted it into the jslink function where I define what listContext to override.
// Override the RenderListView once the ClientTemplates.JS has been called
ExecuteOrDelayUntilScriptLoaded(function(){
// Copy and override the existing RenderListView
var oldRenderListView = RenderListView;
RenderListView = function(ctx,webPartID)
{
// Check the title and set the BaseViewId
if (ctx.ListTitle == "List")
ctx.BaseViewID = "list";
//now call the original RenderListView
oldRenderListView(ctx,webPartID);
}
},"ClientTemplates.js");

Highlighting or Bolding the Borders of a kml Polygon

Hey after loading a kml file to google earth I was trying to have when a user clicks a certain polygon from the kml, to have that polygon highlighted.
So far I can record the click event, get the event type (KmlPlacemark) and grab its kml markup.
I tried doing something similar to this example where they add a placemark to the getFeatures of the kmlObject but both target and type don't seem to have 'getFeatures'. After looking around the documentation I think I might either want setOutline from Kml Polystyle class or setWidth() from KmlLineStyle class but am not sure. Also when I try something like target.setOutline(true); it doesn't work.
Can anyone tell me if I'm on the right track, hints to what I'm doing wrong, and if there's a better way to do this?
function recordEvent(event) {
var target = event.getTarget();
var type = target.getType();
if(type == "KmlPolygon") {
alert("KMLPolygon ");
}else if(type == "KmlPlacemark") {
// // get the data you want from the target.
var description = target.getDescription();
var balloon = target.getBalloonHtml();
var outputKml = target.getKml();
if ('getFeatures' in event) {
console.log("test");
event.getFeatures().appendChild(placemark);
}
console.log("hello?")
// target.setOutline(true);
console.log(outputKml);
}
};
google.earth.addEventListener(ge.getGlobe(), 'click', recordEvent);
Thanks!
I find the best way to do what you are asking is to:
Detect click events like you currently do
If clicked, create a new Style, then assign it to the target
var newStyle = ge.createStyle('');
// Assign your Style's attributes such as LabelStyle and IconStyle
// eg to set the scale of your label
newStyle.getLabelStyle().setScale(2.5);
// Set the Style
target.setStyleSelector(newStyle);
Edit to add in this link of a Google example showing it more in depth
https://code.google.com/apis/ajax/playground/#styling_placemarks_using_style_maps

Resources