Need to calculate length in km of line in RethinkDB - rethinkdb

I have a Line object in a document inside RethinkDB
I am looking for an easy/efficient way of calculating the real world distance of the line.
My initial strategy was to pull the line out of the database and calculate it inside Node.js but ideally would like a way to do this 'in the box'
I cannot find a way to iterate over the coordinates of the line inside ReQl and use the distance function to calculate.
Any help is greatly appreciated.

Unfortunately, the only way I could find how to do this, as it seems that the points within the r.line object are inaccessible, is to convert the line into GeoJSON, convert to points, and then return the calculation.
Using an object like this:
{
id: 101,
route: r.line([-122.423246,37.779388], [-121.886420,37.329898])
}
Your query would look like this:
r.table('data').get(101)('route').do(function(doc){
var points = doc.toGeojson()("coordinates").map(function(point){
return r.point(point(0), point(1));
});
return {
"distance": points(0).distance(points(1))
}
});
Or, as you probably have a whole bunch of line distances to calculate:
r.table('data').hasFields("route")('route').map(function(doc){
var points = doc.toGeojson()("coordinates").map(function(point){
return r.point(point(0), point(1));
});
return {
line: points(0).distance(points(1))
}
});
I've also submitted a Github issue to see if we can find an improvement!

Related

Access variable hash depth values with square brackets notation

Given this hash:
hash1= { node1: { node2: { node3: { node4: { node5: 1 } } } } }
We access inside nodes with square brackets like this:
hash1[:node1][:node2][:node3][:node4]
Now I have a hash that I know will always be nested as it is an XML response from a SOAP webservice, but neither the depth of the hash nor the names of the nodes stay the same. So it would be nice if I could ask the user of my application for the hash depth and store it in a variable. And then be able to do hash1[:hash_depth] and achieve the same result as above.
I have accomplished what I want by the following code:
str = 'node1,node2,node3,node4'
str_a = str.split(',')
hash_copy = hash1
str_a.each { |s| hash_copy = hash_copy.[](s.to_sym) }
hash_copy
=> {:node5=>1}
hash1[:node1][:node2][:node3][:node4]
=> {:node5=>1}
that is asking the user to enter the hash depth separated by commas, store it in a string, split it, make an array, clone the original hash, go down each level and modify the hash till I get to the desired node. Is there a way to do it with the square brackets notation and using a variable to store the depth without modifying the hash or needing to clone it?
Edit:
someone answered with the following (can't see his post anymore???)
hash_depth="[:node1][:node2][:node3][:node4]"
eval "hash1#{hash_depth}"
Although eval does everything you need, there is another approach, since you already have the working code for comma-separated list:
hash_depth="[:node1][:node2][:node3][:node4]"
csh = hash_depth.gsub(/\A\[:|\]\[:|\]\Z/, { '][:' => ',' })
#⇒ "node1,node2,node3,node4"
And now you are free to apply your existing function to csh.
If this is a webapp, I think you should prepare a list of short textareas, which starts with a single text item, and the user can keep adding a new item to the list by clicking on a button. The areas will be filled by the user, and will be sent.
Then, you will probably receive this through some serialized form. You decode this to get an array of strings:
str_a = ["node1", "node2", "node3", "node4"]
and you can reach the inner element by doing:
str_a.inject(hash1){|h, s| h[s.to_sym]} #=> {:node5 => 1}

zingchart setseriesdata visibility issue

Pretty straight forward question, as soon as i use setseries data the visibility my pie chart is no longer visible. I have checked the plot object and the series were updated correctly, however since I do not find a visibility attribute anywhere in the plot object, i am at a loss.
The lack of zingcharts documentation and proper examples does not aid either. Im fairly certain this is a simple scenario to solve, but I've been unable to do so.
zingchart.exec('organismplot', 'setseriesdata', {
"data": [
{
"values":data_update.organisms,
"text":"active",
"background-color":"#2d4962",
"border-width":"1px",
"shadow":0,
"visible":1
},
{
"values":(data_update.totalorganism-data_update.organisms),
"text":"passive",
"background-color":"#2d4962",
"border-width":"1px",
"shadow":0,
"visible":0
}]
I'm a member of the ZingChart team, and I'm happy to help you out!
What is the type of data_update.organisms and data_update.totalorganism-data_update.organisms? Make sure that you are passing a single element array, or if those are simply single values, wrap the variables in brackets to create a single value array for the "values" attribute. E.G.:
"data": [
{
"values":[data_update.organisms], // If data_update.organisms is a single value.
"text":"active",
"background-color":"#2d4962",
"border-width":"1px",
"shadow":0,
"visible":1
},
{
"values":[data_update.totalorganism-data_update.organisms], // Again, single value array.
"text":"passive",
"background-color":"#2d4962",
"border-width":"1px",
"shadow":0,
"visible":0
}
]
I've created a demo using your exact method call, except I've changed the "values" attributes to use a single value array, which are needed for pie charts. Check out the demo here.
I hope that helps. Let me know if you need some more help!

Time scale won't convert dates to numbers

I am having trouble with using the time scale. I have dates in the format 'YYYYMMDD', I parse these with:
parseDate = d3.time.format("%Y%m%d").parse
I set the domain to static dates using the same above function. I can see the dates in correct format in the console. But when applying the scale function x, it returns 'NaN' WAT?
It's probably something small I'm not seeing, it's driving me mad...
Code can be found here: http://bl.ocks.org/pberden/5668581
I think the problem is in the way you call d3.nest. According to the spec
The key function will be invoked for each element in the input array, and must return a string identifier that is used to assign the element to its group.
You convert the Day in your csv file to a Date but then, as you are building a map from the array using d3.nest(), the invocation of the key function turns this Date to a String by doing an implicit conversion.
To fix this I think you could try to force your line generator to turn a String into Date like so
var line = d3.svg.line()
.x(function(d) { return x(new Date(d.key)); })
.y(function(d) { return y(d.values.Value); });

mustache/hogan i18n and taking word-order into account

Found a couple of questions (and answers) on this: How is internationalization configured for Hogan.js?
,etc.
but non in particular that take word order into account. I need the ability to:
step 1. given a key -> lookup a sentence in a particular language.
step 2. this sentence may contain {{var}} , which need to be
substituted by json-values.
step 2. alone is general mustache-templating.
step 1. alone could be done with several techniques, but I prefer techniques that don't involve any specialized code outside of the Mustache/Hogan engine (in combination with a i18n-resource bundle of course) . Hogan seems to support this with something like: (from url above)
var template = "{{#i18n}}Name{{/i18n}}: {{username}}",
context = {
username: "Jean Luc",
i18n: function (i18nKey) {return translatedStrings[i18nKey];}
};
However to combine 1. and 2. in this example I would want translatedStrings[i18nKey] to return a string which potentially contains {{<some expansion>}} as well.
Someone knows of an elegant way to do this?
Rationale:
Often languages differ a lot in word order, etc. which makes for complex templates without this ability.
The latest version of Hogan.js will handle Mustache tags inside the result returned from a lambda. One minor change to the code in your question however, is that the result of the lambda should be a function in order to modify the string:
var translatedStrings = { name: "Nom {{rank}}" };
var template = "{{#i18n}}name{{/i18n}}: {{username}}",
context = {
username: "Jean Luc",
rank: 'Captain',
i18n: function() {
return function (i18nKey) {return translatedStrings[i18nKey];};
}
};
document.write(Hogan.compile(template).render(context));​ // Nom Captain: Jean Luc
I created a jsfiddle that demonstrates this with the latest version.

Codeigniter: URI segments

How do I create an if statement saying something like this?
Basically, how do you use the URI class to determine if there is a value in any segment?
$segment = value_of_any_segment;
if($segment == 1{
do stuff
}
I know this is pretty elementary, but I don't totally understand the URI class...
Your question is a little unclear to me, but I'll try to help. Are you wondering how to determine if a particular segment exists or if it contains a specific value?
As you are probably aware, you can use the URI class to access the specific URI segments. Using yoursite.com/blog/article/123 as an example, blog is the 1st segment, article is the 2nd segment, and 123 is the 3rd segment. You access each using $this->uri->segment(n)
You then can construct if statements like this:
// if segment 2 exists ("articles" in the above example), do stuff
if ($this->uri->segment(2)) {
// do stuff
}
// if segment 3 ("123" in the above example) is equal to some value, do stuff
if ($this->uri->segment(3) == $myValue) {
// do stuff
}
Hope that helps! Let me know if not and I can elaborate or provide additional information.
Edit:
If you need to determine if a particular string appears in any segment of the URI, you can do something like this:
// get the entire URI (using our example above, this is "/blog/article/123")
$myURI = $this->uri->uri_string()
// the string we want to check the URI for
$myString = "article";
// use strpos() to search the entire URI for $myString
// also, notice we're using the "!==" operator here; see note below
if (strpos($myURI, $myString) !== FALSE) {
// "article" exists in the URI
} else {
// "article" does not exist in the URI
}
A note regarding strpos() (from the PHP documentation):
This function may return Boolean
FALSE, but may also return a
non-Boolean value which evaluates to
FALSE, such as 0 or "". Please read
the section on Booleans for more
information. Use the === operator for
testing the return value of this
function.
I hope my edit helps. Let me know if I can elaborate.

Resources