Virtual Earth VEShapeLayer Will Not Render - javascript

The goal: Allow user to turn on and off different layers of data; and to dynamically pull the data for the current extent from a database on map move event.
This works fine and good if you hard code your VEShapeLayers as done here.
My list of layers is coming from a database, I have everything working the way I want except that when I add shapes to my VEShapeLayer none are rendered on my map. Calling VEShapeLayer.GetShapeCount() returns the expected number... so the layer has the data..
Here are the important bits of the code:
var assets = [];
if (WebServiceResult.length > 0) {
for (var i = 0; i < WebServiceResult.length; i++) {
var ix = FindLayerIndex(WebServiceResult[0].AssetMapLayer);
var velatlong = new VELatLong();
velatlong.Latitude = WebServiceResult[i].Latitude;
velatlong.Longitude = WebServiceResult[i].Longitude;
newShape = new VEShape(VEShapeType.Pushpin, velatlong);
assets.push(newShape);
}
// ix is defined above and is vaild and correct
map.GetShapeLayerByIndex(ix).AddShape(assets);
}
// a call here to map.GetShapeLayerByIndex(ix).GetShapeCount()
// returns the expected number of shapes

I feel dumb; I had not added the stylesheet to my page's header, and my custom icon was rendering transparent as a result of the stylesheet not being available.

Related

Photoshop scripting with JSX in for loop to change fill color of each layer

So, I am tinkering with changing fill colors of layers in a PSD file using JSX. I ultimately want to loop all layers, turning off visibility for all but one, edit the fill color of that layer, save as PNG, and then repeat for all layers and all colors in JSON file. I'm starting small as this is my first attempt, but if your solution can help preempt my downfalls with other tasks then it would be greatly appreciated. Here is what I have (alert properly prompts, but line 5 receives error 1302: no such element referencing line 5):
var layerNum = app.activeDocument.layers.length
alert(layerNum);
var i;
for (i=0;i<layerNum;i++){
var currentLayer = app.activeDocument.layers.index(i)
var myColor = new SolidColor();
//var RGB = HEXtoRGB(Y);
myColor.rgb.red = RGB[255];
myColor.rgb.green = RGB[0];
myColor.rgb.blue = RGB[0];
currentLayer.fill.color = myColor;
}
Is this because the collection of layers does not start at 0? Should I start with layers.index(layerNum) and use i-- to move down the collection? Any insight would be helpful. Thanks in advance to this always helpful community.
This var currentLayer = app.activeDocument.layers.index(i)
should be this: var currentLayer = app.activeDocument.layers[i]
Layers collections are pretty much the same as arrays, starting from 0, so you did it right
As KienT points out you need to use square brackets for layers.
Also it's useful to create a variable that's the app.activeDocument, so you don't have to type that out each time. Looping over the layers backwards (or up) is easy - just remember to take 1 off the layers length. You can adjust also make it ignore the background by making the loop start at 1 instead of 0. You can also adjust the layers visibility from true to false (on and off) as you go.
// call the source document
var srcDoc = app.activeDocument;
var layerNum = srcDoc.layers.length;
// alert(layerNum);
for (var i = layerNum -1; i >= 0; i--)
{
var currentLayer = srcDoc.layers[i];
var myColor = new SolidColor;
// Select the layers as you go
srcDoc.activeLayer = srcDoc.artLayers[i];
// switch layer visibility to on
srcDoc.visible = true;
myColor.rgb.red = 255;
myColor.rgb.green = 0;
myColor.rgb.blue = 0;
app.activeDocument.selection.fill(myColor, ColorBlendMode.NORMAL, 100, false);
}

After Effects Script - Expression Controller Coordinates

Writing a script for After Effects 2015. Trying to copy coordinate data from a point expression controller to a layer's position data. I can't seem to find a way to point to the Expression Controller values.
for (i = 1; i <= app.project.activeItem.selectedLayers[0].property("Effects").numProperties; i++) {
app.project.items[2].layer(i).property("position").setValue(app.project.activeItem.selectedLayers[0].property("Effects").property(i).value);
}
I've also tried this:
for (i = 1; i <= app.project.activeItem.selectedLayers[0].property("Effects").numProperties; i++) {
app.project.items[2].layer(i).property("position").setValue(app.project.activeItem.selectedLayers[0].property("Effects").property(i).property("Point").value);
}
Any help would be appreciated. I'm hoping I didn't make any typos...
This should get you going. You need a layer with an expression point controler and it needs to be selected. I'm using here the match names of the effects. You can use the names from interface as well. I suggest getting the rd_GimmePropPath script from redefinery.com. Helps me every time.
function main() {
app.beginUndoGroup("XXX");
var curComp = app.project.activeItem; // get the current comp
if (!curComp || !(curComp instanceof CompItem)) {
// doulble check
alert("noComp");
return;
};
var layerwithpointcontroller = curComp.selectedLayers[0]; // the first selected layer
// get the value of the expression controler
var pointvalue = layerwithpointcontroller.property("ADBE Effect Parade")
.property("ADBE Point Control")
.property("ADBE Point Control-0001")
.value;
$.writeln(pointvalue); // take a look at it
var nullobject = curComp.layers.addNull();// add a null
nullobject.position.setValue(pointvalue);// set its position
app.endUndoGroup();
}
main();

Snapping to closest Marker Method always returning false

hopefully you can help me with this problem :)
Here is my situation:
Recently I have been working with the Google Maps API. And with that I created a map, with markers representing a recomendation on a travel route on it. The data of each of these markers are stored in my DB, so that everytime I start my Webapplication I can represent them on the map. The markers however can be moved to another place on the map by the user, and so a new travel route is stored.
Other than the recommended trip, I also store other locations of the same country in my DB. This is due to the abilty of the user to move the other markers around to personalize his/her trip.
Here is my Problem:
With Javascript I listen to the Drop Event of the user and afterwards I get the new Location of that marker(location where it was dropped) and pass it on to another method:
//point1: contains marker which was dropped with its new location
//location: String containing the name of the place where the marker was dropped
arePointsNear: function (point1, location) {
//result: Obj I pass on to method: trip.getHotels in order to get a List containing
//all Hotels in the region 'location'
var result = { 'markerLat': point1.position.lat(), 'markerLng': point1.position.lng(), 'loc': location };
Trip.getHotels(result, function (hotels) {
var found = false;
//i: used as index of the hotels Array(res)
var i = 0
while (!found) {
//sw: SouthWest, ne: NorthEast
var sw = new google.maps.LatLng(hotels[i].lat - 1, hotels[i].lng - 1);
var ne = new google.maps.LatLng(hotels[i].lat + 1, hotels[i].lng + 1);
var bounds = new google.maps.LatLngBounds(sw, ne);
found = $.contains(bounds, point1);
if (found) { break; }
i++;
}
});
}
I am basically trying now to snapp the dropped marker to the closest hotel in my array. The Code above doesnt give out any error but the var found is always 'false', even though I am pretty shure that the location of the dropped marker is within the boundaries of one of the hotels.
Link to Related question: Snap to nearest marker
Here my questions ...
Why is found always false? Could it be that I am missing something?
Does the problem lie with the jquery contains method, or with the following line:
var sw = new google.maps.LatLng(hotels[i].lat - 1, hotels[i].lng - 1);
I would be glad to hear your answers and I thank you in advance
Edit!
After getting my question answered I tried it with '.contains'. This for some reason still wouldnt work, so I have written a pretty simple method myself to detect the closest point or marker to another point or marker on the map. This I want to share with everyone who may be looking for just that:
//marker: Point to which you want to find the closest Point to
arePointsClose: function (marker) {
//Trip: This is my Object and getHotels a method within my Object trip
//With getHotels I get a List of Hotels from the Controller using AJAX
//I pass a function to getHotels (For more information research: Callback)
Trip.getHotels(function (hotels) {
var closestPoint = undefined;
var closestHotel = 0;
//Here I start looping through my array of hotels
for (var i = 0; i < hotels.length ; i++) {
// Here I maka an if in one line and if the number resulting should be negative I multiply by -1 to evit that
var x = ((marker.position.lat() - hotels[i].lat) < 0) ? (marker.position.lat() - hotels[i].lat) * (-1) : (marker.position.lat() - hotels[i].lat);
var y = ((marker.position.lng() - hotels[i].lng) < 0) ? (marker.position.lng() - hotels[i].lng) * (-1) : (marker.position.lng() - hotels[i].lng);
var point = x + y;
//The point var is overwritten for the purpose of checking later in the if, if it is actually smaller than the actual closestPoint
if (closestPoint == undefined || point <= closestPoint) {
closestPoint = point;
closestHotel = hotels[i];
}
}
//Now closestPoint contains just what you wanted. Pass it on to another function now to maybe redraw the markers (and) their path
//Trip.yourFunction
});
}
The jQuery contains function is mean to work with DOM elements, e.g. does this div contain that span:
$.contains('#thisDiv', '#thatSpan')`;
Not if a Google Maps LatLngBounds object contains a specific point.
For that, you need to do use the LatLngBounds' own contains function, e.g.:
var bounds = new google.maps.LatLngBounds(sw, ne);
found = bounds.contains(point1);

Loop through parallel Layers

i have a problem with a recursive function. I´ll try to explain as good as possible:
I have a photoshop-document containing various smart-objects all named: Smart_Objectname.
The Smarts may also contain other Smarts.
I now try to write a function that runs trough the whole document and opens a smart(searches with regex for "Smart"), if it contains another it will open the next one and so on. If the last is reached it starts saving each layer inside the smart named with "Layername.png" as png and closes it again. Then it saves the layers of the Smart before until reaching the root document again.
The "going deeper into smarts part" is already working. But if i have two Smart-objects in the same hierarchy it won´t work and set the wrong Layer as active when going deeper into the first one. I simply can´t find the error, but something seems to be wrong with my code.
Any help or easier way to do this would be great :)
Here my code so far...maybe a bit complicated:
findSmart(app.activeDocument.layerSets); //call it
function findSmart(layerNode) {
for (var i=0; i<layerNode.length; i++) {
var res = /Smart/;// a reg exp
var mat = collectNamesAM(res);// get array of matching layer indexes
for( var y = 0; y < mat.length; y++ ){
makeActiveByIndex( mat[y], false );
// do something with layer
var activeLayer = app.activeDocument.activeLayer;
//Open smart
//=======================================================
var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );
var desc45 = new ActionDescriptor();
executeAction( idplacedLayerEditContents, desc45, DialogModes.NO );
}//next Smart match if any
//Go deeper
findSmart(layerNode[i].layerSets);
var len = app.activeDocument.layers.length;
for (var i = 0; i < len; i++) {
var layer = app.activeDocument.layers[i];
//search for all .png Layers to save
var id = ".png";
var exist = layer.name.slice(-id.length) == id; // true
app.activeDocument.activeLayer = layer;
var activeLayer = app.activeDocument.activeLayer;
//save pic if .png
if(exist){
saveAll(); //just opens each layer in another doc and saves it as png then closes the documents without saving
}//end if
}//end for
// Close the Smart Object and move to next one
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}//first smart
}//end function
I found the solution. it was just a little mistake with the call of the recursive part(i did it too early) and an if that checks for a smart inside a smart. so the last bit of the code right after the if(exist) thing should be:
if(y == 0){
findSmart(layerNode[y].layerSets);
}
//Close the Smart Object and move to next one
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}//next smart if any
}//end for
}//end function

Javascript - Connect two lines

In the following picture:
alt text http://rookery9.aviary.com.s3.amazonaws.com/4478500/4478952_3e06_625x625.jpg
I want to connect the boxes in the above with below, Let us call the bottom edge of the top boxes as A and top edge of the below boxes as B
Now, I have two arrays containing the points in the line A and B say
A = [ {Ax1, Ay1},{Ax2, Ay2},.... ] and B = [ {Bx1, By1},{Bx2, By2},.... ]
In real world it can be like A = [ {100, 100},{120, 100},{140, 100},{160, 100}] and B=[ {120, 200},{140, 200},{160, 200},{180, 200},{200, 200},]
Please look at the black dots in the picture above
How can I get the connectiong points as shown in the pictures? Connecting point must be as close to the center of the line as possible.
Here is what I'm trying to get, but below functions draw line between the two matching points from the starting from the left of the both lines, Any suggessions
drawConnection : function(componentOut, componentIn, connectionKey) {
var outDim = $(componentOut).data('dim');
var inDim = $(componentIn).data('dim');
var outPorts = $(componentOut).data('ports');
var inPorts = $(componentIn).data('ports');
var abovePorts = {};
var belowPorts = {};
var i = 0;
if(outDim.bottomLeft.y < inDim.topLeft.y){
// Now proceed only if they can be connect with a single line
if(outDim.bottomLeft.x < inDim.topRight.x && outDim.bottomRight.x>inDim.topLeft.x) {
// Now get a proper connecting point
abovePorts = outPorts.bottom;
belowPorts = inPorts.top;
for(i=0; i<abovePorts.length; i++) {
for(j=0; j<belowPorts.length; j++) {
if(!abovePorts[i].inUse && !belowPorts[j].inUse && (abovePorts[i].x == belowPorts[j].x)){
console.debug("Drawing vertical lines between points ("+abovePorts[i].x+","+abovePorts[i].y+") and ("+abovePorts[i].x+","+belowPorts[j].y+")");
return true;
}
}
}
}
}
return false;
},
-- Update
I'm exactly trying to get something similar to this http://raphaeljs.com/graffle.html, but the connections should be made with straight lines as shown below
alt text http://rookery9.aviary.com.s3.amazonaws.com/4480500/4480527_1e77_625x625.jpg
Have you tried Raphael.js : http://raphaeljs.com/ ?
Another approach is to use the HTML+CSS engine of the browser, instead of using JS.
You can use a table.
One cell row for each box and a 2 cells row for the connector.
You color one of the border for the connector and use margin, float and width styles, to position the boxes.
I've already used this technique to draw org charts a long time ago... when IE6 was considered the best browser!
Another worth looking at is Processing.js if you want a bit more power. I've used Raphael.js before and that was pretty easy to pickup and use. Just be aware that both utilize the Canvas element which to my knowledge isn't supported in all browsers yet.

Categories