This question is related to these two:
Cesium how to scale a polygon to match Lat-Lon positions while zoom-in/zoom-out
Cesium - using camera to scale a polygon to match Lat-Lon positions while zoom-in/zoom-out
The sample code I am following to get lat-lon-alt positions from the camera is located in the gold standard that appears to be baked into the existing camera controller. With this code I can retrieve lat-lon-alt positions from the distance of the camera to get values that are almost exact to the original lat-lon position selected and a height above the surface of the earth. Perfect!
All examples and documentation show polygon creation using degrees or points from degrees.
Now what? Maybe I'm missing something but the intent I thought was to be able to create the polygon using specific x, y, z coordinates so the polygon would "stick" to the top of my house on zoom-in, zoom-out, and camera movement. Now that I have those values, what is the secret to drawing the polygon with those values?
FYI, these are the value I currently have:
=========================NEW INFORMATION===========================
The code for the redPolygon works:
var redPolygon = viewer.entities.add({
name : 'Red polygon on surface',
polygon : {
hierarchy : Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0,
-115.0, 32.0,
-102.0, 31.0,
-102.0, 35.0,
-102.0, 35.0]),
material : Cesium.Color.RED
}
});
viewer.flyTo(redPolygon);
The code for the bluePolygon does not work:
var bluePolygon = viewer.entities.add({
name : 'Blue polygon on surface',
polygon : {
//hierarchy: collection.latlonalt,
hierarchy: Cesium.Cartesian3.fromArray(collection.latlonalt),
material : Cesium.Color.BLUE
}
});
viewer.flyTo(bluePolygon);
If I use hierarchy: collection.latlonalt, I receive the following error:
So I changed the code to hierarchy: Cesium.Cartesian3.fromArray(collection.latlonalt), where collection.latlonalt is my Cartesian3 array:
But nothing gets drawn. No errors. This is what I see in the console:
Just for test, I tried adding a z position to the redPolygon and changing .fromDegreesArray to .fromArray like this:
var redPolygon = viewer.entities.add({
name : 'Red polygon on surface',
polygon : {
hierarchy : Cesium.Cartesian3.fromArray([-115.0, 37.0, 10.0,
-115.0, 32.0, 10.0,
-102.0, 31.0, 10.0,
-102.0, 35.0, 10.0,
-102.0, 35.0, 10.0]),
material : Cesium.Color.RED
}
});
viewer.flyTo(redPolygon);
That didn't work either.
Cesium has helper functions like Cartesian3.fromDegreesArray that are used by the Polygon Demo, but, these helper functions are not needed now that you've got your hands on actual Cartesian3 values.
For example, the polygon demo code looks like this:
var redPolygon = viewer.entities.add({
name : 'Red polygon on surface',
polygon : {
hierarchy : Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0,
-115.0, 32.0,
-107.0, 33.0,
-102.0, 31.0,
-102.0, 35.0]),
material : Cesium.Color.RED
}
});
In the above code, fromDegreesArray in this case just takes a list of 5 lot/lan value pairs, and converts them into a JavaScript array of 5 instances of the Cartesian3 class. This array of 5 Cartesian3s is then stored as the value of hierarchy in the polygon definition. If you inspect that definition at runtime, you'll find the original lon/lat values have been discarded, replaced by the actual Cartesian3s, thanks to the helper function.
So in your code, you'll need an array of Cartesian3s that the user has clicked on thus far. This starts as the empty array, and you'll need to gather at least three clicks, converting each click into a Cartesian3 as you've shown works in your question above, and push that value into the array. Once the array has accumulated 3 or more clicks, you can then pass that array as the hierarchy field of the polygon definition.
In this manner, you've avoided calling fromDegreesArray because your click handler is doing the more detailed work of gathering an exact Cartesian position per click. This gathering has to happen at the time of each click, in case the camera is moved between clicks. So, the array "in progress" has to survive between clicks, until all the clicks have been gathered and a polygon can be created.
EDIT: Here's an example of the code structure I'm trying to describe. I don't show the actual click handlers here, since you seem to have Cartesian3 values coming out of your mouse clicks already. Instead, I show three such values being used to create a polygon.
var viewer = new Cesium.Viewer('cesiumContainer');
// Create an empty array of click positions at the start.
var clickPositions = [];
// When the first mouse click is received, convert to Cartesian3, and push it into the array.
var click1 = new Cesium.Cartesian3(-2155350.2, -4622163.4, 3817393.1);
clickPositions.push(click1);
// Later, more mouse clicks are received and pushed into the array.
var click2 = new Cesium.Cartesian3(-2288079.8, -4906803.1, 3360431.4);
clickPositions.push(click2);
var click3 = new Cesium.Cartesian3(-1087466.8, -5116129.4, 3637866.9);
clickPositions.push(click3);
// Finally, draw the polygon.
var redPolygon = viewer.entities.add({
name : 'Red polygon on surface',
polygon : {
hierarchy : clickPositions,
material : Cesium.Color.RED
}
});
Notice nothing happens to clickPositions when it's assigned to hierarchy. The array of Cartesian3 values is already in the form needed by Cesium here.
So I'm very new to THREE JS and I've been trying to figure this out for a few hours now, but how do I determine whether or not a mesh is facing a selected point? Essentially what I have is an RTS style game, where you can select a character and select where he moves to. Currently you can select the character and you can select and where you want it to move to on the map and it will start walking, however I can't figure out how to determine if it is facing the right direction. I don't want to use lookAt because I want the mesh to turn while it walks forward, and not do anything instantaneously.
Ideas?
a simple solution is to select arbitrary look vector
var lookVector = new THREE.Vector3(0,0,1);
and when you need to do some check transform a copy of this vector with mesh matrix (make sure matrix is updated and count in the geometry transformations if you did any)
var direction = lookVector.clone().applyMatrix4(mesh.matrix);
var origin = mesh.boundingSphere.center;
var lookVectorAtThisTime = direction.sub(origin);
then calculate the angle to your point of interest
var vectorToPOI = POI.sub(origin);
var angle = lookVectorAtThisTime.angleTo(vectorToPOI);
if(angle < minAngle)
{
//looking at the point
}
you can also calculate your look vector directly from geometry or some other way origin vector can be something else than the center of the object, but this should get you on the right path..
I have a google map application where i am moving markers on a polyline. I am generating a new destination point(latlng coordinates). I would like to extend the polyline to this new destination point.
Can some one tell me how i can move the end point of a polyline to another point on the map.
I have used polyline[index].getPath() in here i can see all the latlng coordinate pairs that make up the route. How to add to this route to make it longer or shorter?
Simple. If you merely wanted to add an additional point to the existing array of points, this works:
var currentPath = polyline[index].getPath();
var newPoint = new google.maps.LatLng(40.781321,-73.965855);
currentPath.push(newPoint);
polyline[index].setPath(currentPath);
If you wanted however to change where the current last point is at, try this instead:
var currentPath = polyline[index].getPath();
var newPoint = new google.maps.LatLng(40.781321,-73.965855);
currentPath.setAt(currentPath.getLength()-1, newPoint);
polyline[index].setPath(currentPath);
I am getting line latitude & longitude as
LINESTRING(1491215.4689647 6893983.2031826,1494163.0718675 6894785.7919795)
after seeing this solution.
how to get points return from OpenLayers.Control.DrawFeature
Now what I want to do is that I want to display start point & end point on my web page.
So how can I extract latitude & longitude from here so that I can show it in my page.
If your linestring is already in OpenLayers, there is no reason to convert it to WKT. Linestring geometry contains array of Points. You can access components of geometry in several ways, for example:
drawControls[key].events.register('featureadded', drawControls[key], function(f) {
// First point
var firstPointGeom = f.feature.geometry.components[0].clone();
// Last point
var secondPointGeom = f.feature.geometry.components[f.feature.geometry.components.length - 1].clone();
// Now you got geometries, let's create features from them...
var firstPointFeat = new OpenLayers.Feature.Vector(firstPointGeom);
var secondPointGeom = new OpenLayers.Feature.Vector(secondPointGeom);
yourVectorLayer.addFeatures([firstPointFeat, secondPointGeom]);
});
Pay attention - this works with LineStrings. Probably it's not necessary to go into detail about clone(), it's up to particular use case, whether you need it, or you can use just var firstPointGeom = f.feature.geometry.components[0];
Thats WKT format, you're looking at. You'll potentially need to reproject those coordinates to the target projection if they are not in the same projection. After than, you should be able ot ask openlayers for the points of any given geometry using the base geometry functionaily. Get the point array from the linestring instance and iterate over it. Make sure you know the right coordinate order for your projection / data model.
Hope that helps!
I am using VEMap API. I have the latitude and longitude of the top left point and the bottom right point (bounding box) of a map. I want to get the center point. What is an easy way to do that? I couldn't find a solution by searching on Google.
What I was thinking is that if I can define the map using the two points mentioned above, then I can get the center very easily:
// JavaScript code snippet
var center = map.GetCenter();
var lat = center.Latitude;
var lng = center.Longitude;
Is there a way to call the constructor of map object and pass the two coordinates I have?
Thanks.
The simple answer would be add the latitudes and divide by two, and do the same for longitudes. They are straight lines.
Is there any reason you can't use the VEMap.GetCenter method after the map has been constructed? This way regardless of the viewpoint it will be correct. If you're using the default constructor you can pass in your bounding box, and then call getmap after the object is instantiated.
http://msdn.microsoft.com/en-us/library/bb412539.aspx