How to convert Turf.js polygon to WKT - geo

I'm using Turf.js to generate circle geometry from point and radius, using the circle functions. Example:
c = turf.circle([0.0, 0.0], 100, {steps:1000, units:'kilometers'})
The returned result is Feature object, and the only way I managed to represent the geometry is by applying c.geometry.coordinates which returns an array.
However, my goal is to generate a WKT or at least a GeoJSON, but I haven't found a way to do so.
Does anyone know how to do it with turf.js or alternatively know of a way to get a WKT representation of a circle with center and radius as inputs?

To get GeoJSON text of the feature, you can do this
var gjs = JSON.stringify(polygon_object);
(Inverse check) To parse the string gjs and convert it back to object (GeoJSON) again
var ojn = JSON.parse(gjs);
Live code:-
const pgon = turf.polygon(
[
[
[50.848677, 4.338074],
[50.833264, 4.344961],
[50.840809, 4.366227],
[50.852455, 4.367945],
[50.858306, 4.346693],
[50.848677, 4.338074]
]
],
{ name: "pgon1" }
);
const coords0 = pgon.geometry.coordinates[0];
// Create WKT of the polygon
var phead = `POLYGON((`;
var ptail = `))`;
var pbody = "";
var cur_xy = "";
coords0.forEach( function(item, index){
//console.log(item, index);
//lonlat.push([...item]); //OK
cur_xy = item[0].toFixed(4) +" "+ item[1].toFixed(4);
pbody += cur_xy + ",";
}, pbody);
console.log("*WKT*", phead+pbody+cur_xy+ptail);
// Create geojson of the polygon
console.log("*GeoJSON*" + JSON.stringify(pgon));
<script src="https://cdnjs.cloudflare.com/ajax/libs/Turf.js/5.1.5/turf.min.js"></script>
<p>TurfJS uses GeoJSON to represent geometric features. Here a polygon feature is created and its geometry / properties are manipulated.<br/><br/>The result is printed on the console.</p>

Related

Calculate distance between two PFGeopoints in a NSPredicate for a Parse Query

I have a special case when I want to do something like
let predicate = NSPredicate(format:"
DISTANCE(\(UserLocation),photoLocation) <= visibleRadius AND
DISTANCE(\(UserLocation),photoLocation" <= 10)"
var query = PFQuery(className:"Photo", predicate:predicate)
Basically, I want to get all photos that are taken within 10km around my current location if my current location is also within the photo's visible radius
Also, photoLocation and visibleRadius are two columns in the database, I will supply UserLocation as a PFGeoPoint.
Is it possible to achieve this? In my opinion, I don't think that I may call, for example, photoLocation.latitude to get a specific coordinate value. May I?
I'll appreciate you a lot if this can be achieved!!
I found this at the pares.com docs here is the link
let swOfSF = PFGeoPoint(latitude:37.708813, longitude:-122.526398)
let neOfSF = PFGeoPoint(latitude:37.822802, longitude:-122.373962)
var query = PFQuery(className:"PizzaPlaceObject")
query.whereKey("location", withinGeoBoxFromSouthwest:swOfSF, toNortheast:neOfSF)
var pizzaPlacesInSF = query.findObjects()
This code fetch you all the objects that are in a rectangle area defined by the swOfSF & neOfSF objectc, where seOfSF is in the south-west corner and neOfSF is in the north-east corner.
You can make some alterations to the code and get all the objects in rectangle area that your object is in middle
i would recommend that you don't use a radius, because it will take a lot of calculations. Instead use a rectangle area (like in the code i gave you).
just calculate what is the max/min longitude & max/min latitude from your position and fetch all the objects that are in between. you can read about how to fine the min/max longitude & latitude here Link
I managed to solve it using Parse Cloud Code, here is the quick tutorial
Parse.Cloud.define("latestPosts", function(request, response) {
var limit = 20;
var query = new Parse.Query("Post");
var userLocation = request.params.userLocation;
var searchScope = request.params.searchScope;
var afterDate = request.params.afterDate;
var senderUserName = request.params.senderUserName;
query.withinKilometers("Location", userLocation, searchScope);
query.greaterThan("createdAt", afterDate);
query.notEqualTo("senderUserName",senderUserName);
query.ascending("createdAt");
query.find({
success: function(results) {
var finalResults = results.filter(function(el) {
var visibleRadius = el.get("VisibleRadius");
var postLocation = el.get("Location");
return postLocation.kilometersTo(userLocation) <= visibleRadius;
});
if (finalResults.length > limit) {
var slicedFinalResults = results.slice(0, 20);
response.success(slicedFinalResults);
} else {
response.success(finalResults);
}
},
error: function() {
response.error("no new post");
}
});
});
The code above illustrate a basic example of how to use Cloud Code. Except, I have to make sure that all the returned image are in the union of user's search scope and photo's visible circle. There are more techniques such as Promises. But for my purpose, the code above should just suffice.

issue with different type of axes for storyboard example of dimplejs

I'm trying to create a storyboard very similar to the one in dimpleJS examples. My data looks like below.
[{"Date":"2014-05-05T19:03:23Z","Liters":0.23,"Soda":"Coke","Day":"2014-05-05","Time of Day":"15:03","Day-Time":"2014-05-05 15:03"},{"Date":"2014-05-05T19:37:27Z","Liters":0.35,"Soda":"Coke","Day":"2014-05-05","Time of Day":"15:37","Day-Time":"2014-05-05 15:37"},{"Date":"2014-05-05T20:33:33Z","Liters":0.21,"Soda":"Coke","Day":"2014-05-05","Time of Day":"16:33","Day-Time":"2014-05-05 16:33"},{"Date":"2014-05-05T21:11:37Z","Liters":0.21,"Soda":"Coke","Day":"2014-05-05","Time of Day":"17:11","Day-Time":"2014-05-05 17:11"},{"Date":"2014-05-06T13:55:09Z","Liters":0.22,"Soda":"Coke","Day":"2014-05-06","Time of Day":"9:55","Day-Time":"2014-05-06 9:55"},{"Date":"2014-05-06T14:27:13Z","Liters":0.27,"Soda":"Coke","Day":"2014-05-06","Time of Day":"10:27","Day-Time":"2014-05-06 10:27"},{"Date":"2014-05-06T15:42:21Z","Liters":0.14,"Soda":"Coke","Day":"2014-05-06","Time of Day":"11:42","Day-Time":"2014-05-06 11:42"},{"Date":"2014-05-06T16:16:24Z","Liters":0.24,"Soda":"Coke","Day":"2014-05-06","Time of Day":"12:16","Day-Time":"2014-05-06 12:16"},{"Date":"2014-05-05T19:13:24Z","Liters":0.59,"Soda":"Diet Coke","Day":"2014-05-05","Time of Day":"15:13","Day-Time":"2014-05-05 15:13"},{"Date":"2014-05-05T20:33:33Z","Liters":0.01,"Soda":"Diet Coke","Day":"2014-05-05","Time of Day":"16:33","Day-Time":"2014-05-05 16:33"},{"Date":"2014-05-05T21:04:36Z","Liters":0.39,"Soda":"Diet Coke","Day":"2014-05-05","Time of Day":"17:04","Day-Time":"2014-05-05 17:04"},{"Date":"2014-05-05T21:11:37Z","Liters":0.21,"Soda":"Diet Coke","Day":"2014-05-05","Time of Day":"17:11","Day-Time":"2014-05-05 17:11"},{"Date":"2014-05-05T21:57:42Z","Liters":0.17,"Soda":"Diet Coke","Day":"2014-05-05","Time of Day":"17:57"},{"Date":"2014-05-06T11:11:53Z","Liters":0.42,"Soda":"Diet Coke"},{"Date":"2014-05-06T12:54:03Z","Liters":0.49,"Soda":"Diet Coke"},{"Date":"2014-05-06T12:55:03Z","Liters":0.48,"Soda":"Diet Coke"},{"Date":"2014-05-06T13:07:04Z","Liters":0.27,"Soda":"Diet Coke"},{"Date":"2014-05-06T13:34:07Z","Liters":0.41,"Soda":"Diet Coke"},{"Date":"2014-05-06T13:55:09Z","Liters":0.19,"Soda":"Diet Coke"},{"Date":"2014-05-06T14:27:13Z","Liters":0.01,"Soda":"Diet Coke"},{"Date":"2014-05-06T15:42:21Z","Liters":0.02,"Soda":"Diet Coke"},{"Date":"2014-05-06T16:01:23Z","Liters":0.45,"Soda":"Diet Coke"},{"Date":"2014-05-06T16:05:23Z","Liters":0.52,"Soda":"Diet Coke"},{"Date":"2014-05-06T16:35:27Z","Liters":0.65,"Soda":"Diet Coke"},{"Date":"2014-05-06T16:49:28Z","Liters":0.4,"Soda":"Diet Coke"},{"Date":"2014-05-06T16:50:29Z","Liters":0.14,"Soda":"Diet Coke"},{"Date":"2014-05-05T18:10:18Z","Liters":0.24,"Soda":"Powerade"},{"Date":"2014-05-05T19:03:23Z","Liters":0.01,"Soda":"Powerade"},{"Date":"2014-05-05T19:37:27Z","Liters":0.01,"Soda":"Powerade"},{"Date":"2014-05-05T20:39:34Z","Liters":0.39,"Soda":"Powerade"},{"Date":"2014-05-05T21:04:36Z","Liters":0.01,"Soda":"Powerade"},{"Date":"2014-05-06T10:32:49Z","Liters":0.18,"Soda":"Powerade"},{"Date":"2014-05-06T11:11:53Z","Liters":0.01,"Soda":"Powerade"},{"Date":"2014-05-06T12:54:03Z","Liters":0.01,"Soda":"Powerade"},{"Date":"2014-05-06T14:27:13Z","Liters":0.02,"Soda":"Powerade"},{"Date":"2014-05-06T15:42:21Z","Liters":0.02,"Soda":"Powerade"},{"Date":"2014-05-06T16:01:23Z","Liters":0.03,"Soda":"Powerade"},{"Date":"2014-05-06T16:05:23Z","Liters":0.03,"Soda":"Powerade"},{"Date":"2014-05-06T16:23:25Z","Liters":0.12,"Soda":"Powerade"},{"Date":"2014-05-06T16:50:29Z","Liters":0.01,"Soda":"Powerade"}]
I've category and time axes. The problem is that the bubbles do not show up at the correct y(time) axis. My code looks like below and it also shows too many 0 values although there is no 0 value in dataset.
var series, charts, lastDate = null, sodas = dimple.getUniqueValues(data, "Soda");
charts = [new dimple.chart(svg, null)],
charts.push(myChart);
charts.forEach(function (chart, i) {
var x, y, z;
chart.setBounds(this.attributes.left, this.attributes.top, this.attributes.width - 225, this.attributes.height - 225);
x = chart.addCategoryAxis("x", "Soda");
x.overrideMax = 3;
x.hidden = (i === 0);
y = chart.addTimeAxis("y", "Day-Time", "%Y-%m-%d %H:%M", "%d-%m %H:%M");
// y.overrideMax = "17:00";
y.hidden = (i === 0);
z = chart.addMeasureAxis("z", "Liters");
z.overrideMax = 1;
// Ensure the same colors for every owner in both charts
// differing by opacity
sodas.forEach(function (soda, k) {
chart.assignColor(
soda,
charts[0].defaultColors[k].fill,
"white",
(i === 0 ? 0.3 : 1));
}, this);
}, this);
charts[1].addLegend(850, 100, 60, 300, "Right");
charts[1].setStoryboard("Time of Day", function (d) {
// Use the last date variable to manage the previous tick's data
if (lastDate !== null) {
// Pull the previous data
var lastData = dimple.filterData(data, "Time of Day", lastDate);
// Add a series to the background chart to display old position
var lastSeries = charts[0].addSeries("Soda", dimple.plot.bubble);
// Average suits these measures better
lastSeries.aggregate = dimple.aggregateMethod.avg;
// Give each series its own data at different periods
lastSeries.data = lastData;
// Draw the background chart
charts[0].draw();
// Class all shapes as .historic
lastSeries.shapes.attr("class", "historic");
// Reduce all opacity and remove once opacity drops below 5%
d3.selectAll(".historic").each(function () {
var shape = d3.select(this),
opacity = shape.style("opacity") - 0.02;
// shape.style("opacity", opacity);
if (opacity < 0.1) {
shape.remove();
} else {
shape.style("opacity", opacity);
}
});
}
lastDate = d;
});
series = charts[1].addSeries("Soda", dimple.plot.bubble)
series.aggregate = dimple.aggregateMethod.avg;
// Draw the main chart
charts[1].draw();
Here is the screenshot.
Thanks for adding the fiddles. If you remove the x.hidden = (i === 0); and y.hidden = (i === 0); lines (so that the back chart's axes are displayed) you can see the issue. Unlike measure axes where you can fix the max and min to make sure that the charts are identically proportioned, category axes will only draw for the elements in the data, so a frame with a single category will only draw a single point in the centre of the axis. Also the ordering will change by default.
To get your case working you need to fix ordering for the x axis.
x.addOrderRule(["Coke", "Diet Coke", "Powerade"]);
Define a max and min value for the y axis:
y.overrideMin = d3.time.format("%Y-%m-%d").parse("2014-05-05");
y.overrideMax = d3.time.format("%Y-%m-%d").parse("2014-05-07");
And stick some dummy rows in for any missing categories.
lastData = lastData.concat([
{
"Date": "2014-05-06T00:00:00Z",
"Liters": 0,
"Soda": "Coke"
},
{
"Date": "2014-05-06T00:00:00Z",
"Liters": 0,
"Soda": "Diet Coke"
},
{
"Date": "2014-05-06T00:00:00Z",
"Liters": 0,
"Soda": "Powerade"
}
]);
This results in this output: http://jsfiddle.net/4qBqJ/9/

Adobe Edge Animate—how do I get the current label?

In Adobe Edge Animate, how do I get the name of the label that corresponds to a given time? I've seen that I can get the current time as an integer using
sym.getPosition()
but if there's a label at that position, how do I get the label as a string?
function getLabel() {
var stage = sym.getComposition().getStage();
var labels = stage.timelines['Default Timeline'].labels;
var currentLabel;
var currentPosition = stage.getPosition();
$.each( labels, function( label, position ){
if (position <= currentPosition) currentLabel = label;
});
return currentLabel;
}
console.log( getLabel() );
this will return the label on (or next previous to) the current position.
For those of us here looking for a Adobe Animate 2019 solution (like I was), it's similar, but slightly different:
function getLabel(_this) {
var currentLabel;
var currentPosition = _this.currentFrame;
_this.labels.forEach(function( label, index ){
if (label.position <= currentPosition) currentLabel = label.label;
});
return currentLabel;
}
Your position on the timeline is easier to get, and the labels object is organized differently. (Also jQuery is unavailable.)

Three.js Ray Casting for Collision Detection

I'm trying to draw a line using ray casting. Basically I want to set up some lines coming from my "player" object out in all directions.
(like so: https://gamedev.stackexchange.com/questions/35013/how-to-handle-3d-collisions-using-raycasting-with-a-reflection-vector)
I want this so I can then use I can see my collision detection visually.
I know I can use different ways to do collision detection, but i'm using this way as a learning detection.
My issue is the code below draws a line but it seems to randomly change length and not always point at the same angle.
var ray = new THREE.Ray( player.model.objects.position, new THREE.Vector3(1, 1, 1));
var geometry = new THREE.Geometry();
// my issue is here. I don't think this is the right way use a ray to workout the second vector?
// EDIT: Realized this should be set at player position and outwards.
//var newx = 300 * ray.direction.x;
//var newz = 300 * ray.direction.z;
// EDIT CODE UPDATE
var newx = (player.model.objects.position.x) + (60 * ray.direction.x);
var newz = (player.model.objects.position.z) + (60 * ray.direction.z);
// THREE.Vector3 {x: 1310.1526178356803, y: 0, z: 1290.8237947033065}
console.log(player.model.objects.position);
geometry.vertices.push( player.model.objects.position);
geometry.vertices.push( new THREE.Vector3(newx, player.model.objects.position.y, newz));
var line = new THREE.Line(geometry, material);
scene.add(line);
Any help appreciated.
I was trying to do the same thing after seeing that model.. Since I tried to do it the same way and couldn't figure it out, I'll offer an alternative.
var line;
function update() {
// Z- DIRECTION
raycaster.ray.direction.set(0, 0, -1);
var geometry = new THREE.Geometry();
intersections = raycaster.intersectObjects( objects );
if ( intersections.length > 0 ) {
var geometry = new THREE.Geometry();
// POSITION OF MESH TO SHOOT RAYS OUT OF
geometry.vertices.push( obj.position );
geometry.vertices.push( intersections[0].point );
scene.remove(line);
line = new THREE.Line(geometry, new THREE.LineBasicMaterial({color: 0x990000}));
scene.add(line);
}
}
So now you have a line shooting out of your mesh into whatever the closest intersect is.
https://dl.dropbox.com/u/42766757/guy.png

Adding x axis labels when using dojox.charting.DataSeries

I'm creating a Dojo line chart from a dojo.data.ItemFileReadStore using a dojox.charting.DataSeries. I'm using the third parameter (value) of the constructor of DataSeries to specify a method which will generate the points on the chart. e.g.
function formatLineGraphItem(store,item)
{
var o = {
x: graphIndex++,
y: store.getValue(item, "fileSize"),
};
return o;
}
The graphIndex is an integer which is incremented for every fileSize value. This gives me a line chart with the fileSize shown against a numeric count. This works fine.
What I'd like is to be able to specify the x axis label to use instead of the value of graphIndex i.e. the under lying data will still be 1,2,3,4 but the label will show text (in this case the time at which the file size was captured).
I can do this by passing in an array of labels into the x asis when I call chart.addAxis() but this requires me to know the the values before I iterate through the data. e.g.
var dataSeriesConfig = {query: {id: "*"}};
var xAxisLabels = [{text:"2011-11-20",value:1},{text:"2011-11-21",value:2},{text:"2011-11-22",value:3}];
var chart1 = new dojox.charting.Chart("chart1");
chart1.addPlot("default", {type: "Lines", tension: "4"});
chart1.addAxis("x", {labels: xAxisLabels});
chart1.addAxis("y", {vertical: true});
chart1.addSeries("Values", new dojox.charting.DataSeries(dataStore, dataSeriesConfig, formatLineGraphItem));
chart1.render();
The xAxisLabels array can be created by preparsing the dataSeries but it's not a very nice work around.
Does anyone have any ideas how the formatLineGraphItem method could be extended to provide the x axis labels. Or does anyone have any documentation on what values the object o can contain?
Thanks in advance!
This will take a unix timestamp, multiply the value by 1000 (so that it has microseconds for JavaScript, and then pass the value to dojo date to format it).
You shouldn't have any problems editing this to the format you need.
You provided examples that your dates are like "1", "2", "3", which is clearly wrong. Those aren't dates.. so this is the best you can do unless you edit your question.
chart1.addAxis("x",{
labelFunc: function(n){
if(isNaN(dojo.number.parse(n)) || dojo.number.parse(n) % 1 != 0){
return " ";
}
else {
// I am assuming that your timestamp needs to be multiplied by 1000.
var date = new Date(dojo.number.parse(n) * 1000);
return dojo.date.locale.format(date, {
selector: "date",
datePattern: "dd MMMM",
locale: "en"
});
}
},
maxLabelSize: 100
}