How to determine SVG path neighbours? - javascript

I've been working with the great JVectorMap library. When the user selects a particular country on the map, I'd like to be able to determine which countries are neighbouring or sharing a border.
My searches for calculating distances between SVG paths hasn't gotten me anywhere. Can anyone suggest a good solution to determine which countries are neighbours and which aren't?
Thanks!

I think the best approach would be an array that lists a country and its bordering country names. Then use the array to filter your results. Creating the array would not be difficult since the following site lists bordering countries in a table:
Land borders
This could take a few hours, but I'm sure others would appreciate your work:)

Supposing that Country shapes are svg path elements you could check those Countries (paths) have coinciding vertices or with a distance within a given threshold.

There isn't a functionality to do this directly in jvectormaps. But what you can do is apply a and incrementing value on each horizontal or vertical strip of regions (call it something like data-adj), and you can do something like:
for( i in regions ){
if (Math.abs(this.data-adj - region[i].data-adj) <= 1){
//is adjacent so do something
}
}
This would really only work if you're looking for adjacency and not something like how many regions over a region is.

I needed to find out the same thing, so i made this: https://github.com/FnTm/country-neighbors
It mainly contains a single json file, that describes land-based neighbors for most of the world.
For most cases, it should do what you need to do.

Related

Displaying crossover only in d3.js Slankey (Dynamic, Interactive)

I am aiming to create a d3.js visualisation dashboard that shows the flow of mutual connections based on a selection for 'a', that provides a statistic for 'b', shaped like a Sankey/Parallel Set. For instance, if 'a' is the user selection, where they select 3 of 11 characteristics of people, then b would be a count of how many people in our sample have all three characteristics.
Think of this like a Sankey/Parallel Set diagram where on the left we see the characteristics (Happy, Loyal, Calm), flowing into one container (200/1000 (with characteristics selected/total population).
I am wondering if anyone knows a pre-established way to JUST displays the crossover that the user defines in a navbar pre-selection.
Thanks.
Data:
![It's a boolean array, with totals. It's like a permutations and combinations spreadsheet
]1
try this for a variety of sankey's,
https://observablehq.com/search?query=sankey
So if you're looking to make a crossover slankey like me, I recommend modelling here:
http://sankeymatic.com/build/
Once you get into it, it's very easy to label what the final node should be, and encourage output to flow to that node.
Hope this helps!

Firebase/Angular2 - Find lat/long in database that is closest to users lat/long

I have a table called locations with a set of places and their lat/long's.
I'm also using geolocation to get the users lat/long.
What I would like to do is get the location that is closest to the user, and check if they are within 5 miles of that place.
I'm not too concerned right now about if the user is within 5 miles, I found an algorithm that seems to do that for me..
But what I am curious about is how I should loop through the firebase table and check if the lat/long is the closest.. Is there a way with firebase to sort based off of closest to a variable?
The table looks like this (ignore the index, I will change this later with unique ids):
as well as in javascript:
user.Lat = 35.90491
user.Long = -79.04691
Any help for matching the user lat/long with the location lat/long
I have about 30-40 locations so far in the table.. Planning on adding more.
Thanks!
If you talking about small numbers of records (not millions). You can create temporary table or temporary column with following formula:
for each location p -> (user.lat-p.lat)^2+(user.lon-p.lon)^2
Then sort it by calculated field - smallest number is closest points.
Keep in mind, that it will work on relatively short distances, but may be wrong when location is too far or close to poles (because of projections).

How to traverse an array of latitude and longitude in JavaScript in an order?

I have an array of point like
aa = [ [1,2], [1,2],[2,1], [2,2], [3,1], [3,2] ]
How can I traverse through those point in an order. Fiddle here:
jsFiddle Link
I took some idea from Sort latitude and longitude coordinates into clockwise ordered quadrilateral but didn't work out
update: I think it would make sense if we add more description like traverse from A to F, with east to west direction, like shown in fig below. With this case I think we could sort the following way (noted in fig)
If you read the answer carefully, they admit that it's not an optimal path. It's simply following an arc from the selected point, and selecting in order anything that lies between the arc and the point. So imagine a pendulum swinging, and anything the bar of the pendulum touches is selected in that order.
This is not a quadrilateral path.
To make a quadrilateral path it may work if instead of calling the method from point A to all other points, you call it recursively selecting only the first point.
Basically, if instead of going from point A to all points, you use the algorithm in recursion, and after the first point is selected, you call it again with the new point. So each point is the clockwise most away from the previous point. Then after every call, you remove the selected points from the list of available points.
However, that will only work if the problem is simple. Meaning you won't have to indent your shape to select all points. So if you have points that is within the interior of a shape of outermost points, the solution will be drastically more complex.
It would require picking a point of indent, and then reversing the algorithm. Then doing that recursively.
I'd recommend ordering the points first.
Take the smallest as a point of reference then use the distance from the reference to sort.
var upper = upperLeft(points);
points.sort(function (point) {
return -point.distance(upper);
});
console.log(points);
This will invert them in sequence.
Remove the - sign to start from F to A

Split weakly-simple-polygon to true simple polygon or polygons

I want to divide weakly-simple polygons into simple polygons.
Background
The use case is to simplify polygons that are Simplified (Unioned) using Javascript Clipper. Javascript Clipper's as well as original Clipper's SimplifyPolygon() function removes self-intersections and combines common edges, but it cannot produce true simple polygons. The output is used in three.js, which has TriangulateShapes() which needs polygons to be simple. Three.js accepts polygon structures that have one contour and zero or multiple holes.
Input, weakly-simple polygons
Weakly-simple polygons cannot have sequential-duplicate-vertices (true duplicate points), nor holes (islands) nor self-intersections (edge crossing over other edge), but there can be non-sequential-multiple-vertices (vertices that have exactly the same coordinate but not as sequential). The input polygon can have either CW or CCW winding order, which means that CW input is outer polygon and CCW is a hole. The input is either CW or CCW polygon.
The input is an array of polygon points eg.:
// This is a true example of weakly-simple polygon:
var input = [{"X":270,"Y":520},{"X":130,"Y":490},{"X":210,"Y":250},{"X":60,"Y":170},{"X":130,"Y":490},{"X":20,"Y":410},{"X":60,"Y":300},{"X":60,"Y":20},{"X":780,"Y":40}, {"X":680,"Y":180},{"X":460,"Y":130},{"X":210,"Y":250},{"X":320,"Y":100},{"X":220,"Y":80}, {"X":210,"Y":250},{"X":520,"Y":250},{"X":680,"Y":180},{"X":770,"Y":480},{"X":540,"Y":470}, {"X":520,"Y":250},{"X":380,"Y":280},{"X":430,"Y":390},{"X":540,"Y":470},{"X":270,"Y":520},{"X":330,"Y":350},{"X":210,"Y":250}];
This is the above input polygon as an image:
And here are the points numbered, where you can easily see what points are duplicates:
As you see, the above polygon can be divided in multiple ways, eg.:
- One outer polygon with five holes
- five outer polygons of which one has one hole
Output, simple polygons as a exPolygon structure
Simple polygon is a polygon that have no self-intersections, no duplicate coordinates whether they were sequential or non-sequential, no holes. The output's simple polygon can have CW or CCW winding order. CW means outer and CCW holes.
The output can have (and in many times there will be) holes, but in certain cases the output has no holes. The output has always at least one outer polygon, but there can be also multiple outer polygons that have zero or more holes.
The output should be an array of exPolygon objects that have properties "outer" and "holes". "outer" is an array of point objects, "holes" is an array of arrays of point objects. If "holes" is populated, the holes in it have to be holes of "outer" polygon in the exPolygon object.
The example of output:
// This is an example of output, but the points are random:
[ { "outer": [{"X":54,"Y":4},{"X":2,"Y":50},{"X":30,"Y":5},{"X":10,"Y":50}],
"holes": [ [{"X":0,"Y":8},{"X":60,"Y":13},{"X":21,"Y":2},{"X":3,"Y":1}],
[{"X":21,"Y":2},{"X":50,"Y":2},{"X":6,"Y":1}] ] },
{ "outer": [{"X":54,"Y":4},{"X":2,"Y":50},{"X":30,"Y":5},{"X":10,"Y":50}],
"holes": [ [{"X":0,"Y":8},{"X":60,"Y":13},{"X":21,"Y":2},{"X":3,"Y":1}],
[{"X":21,"Y":2},{"X":50,"Y":2},{"X":6,"Y":1}] ] },
{ "outer": [{"X":54,"Y":4},{"X":2,"Y":50},{"X":30,"Y":5},{"X":10,"Y":50}],
"holes": [] }
];
Output's "outer" polygons are CW, and "holes" are CCW.
There is no limit for counts of points in polygons, count of exPolygons objects nor count of holes.
Here are other examples of weakly simple polygons:
Example of division
Here is an example of input polygon:
Here is how it could be divided:
Some other polygons can have multiple possible alternatives of ouput depending where are the pseudo-duplicate-points.
My question
How the polygons can be divided this way and the desired output structure achieved? I'm not asking full code (but if you have some spare time and want to show that it is possible). Thoughts of possible algorithms are also welcome.
I have searched hours a solution and tried to find an algorithm.
In case you want to try a solution, I have here a code which I have used to find the duplicates: http://jsbin.com/unuyev/7/edit. It shows the polygon in SVG and shows the points as red circles and an array index of each point (after pressing button "Run with JS").
Here is the same, but with 12 example polygons (change pindex in Javascript window to change the polygon):
http://jsbin.com/unuyev/4/edit
EDIT: Javascript Clipper 6 is available now and there is support for StrictlySimple. But according to the documentation "There's currently no guarantee that polygons will be strictly simple since 'simplifying' is still a work in progress". I have tested StrictlySimple and it fails in certain cases: Orientation problems and lack of rotation invariance. We hope these are fixed soon and StrictlySimple works as expected.
There may be something that I'm missing, but this looks like a classic problem of finding the articulation vertex of a graph. Essentially you're trying to find the weakest point in a graph such that when you cut the graph at that point, you end up with two separate graphs. So in your example, if you cut the polygon at that vertex, you end up with multiple polygons. You can represent your polygons quite easy as a graph, with each vertex representing a graph vertex, and the polygon edges as graph edges.
If I had to solve the problem, this is the approach that I would take. You can check out the following resources:
Articulation vertices from the Algorithm Design Manual - This is your best bet. He explains the algorithm in simple terms and also gives you C code that you can easily translate into JavaScript. If I had to start writing an algorithm, this is where I would start.
Biconnected component
Detection of Articulation Points (search for "articulation")
UPDATE
I'll try and give you a brief overview of the problem and the solution to point you in the right direction. An implementation of this algorithm using graphs will necessarily go into graph-algorithm terminologies, so if you are not familiar with graphs, you might want to read up on them.
The brute-force approach in your case would be to traverse the graph, temporarily delete each vetex and then see if the graph is connected when doing a DFS/BFS traversal on the modified graph. This is not very efficient and will run in quadratic time O(n(m + n)). But there is a linear-time algorithm that is based on classifying the edges of the resultant DFS tree that is formed from a DFS traversal.
In a DFS tree that doesn't contain any back-edges (edges connecting a "lower" node to a node "higher" in the tree [assuming "higher" nodes are those closer to the root]) leaf nodes are not articulation nodes, since deleting any one of them will still leave the graph connected. However, deleting any of the internal nodes will disconnect any nodes that follow it from the root.
Deleting the root of the tree depends on whether it has one or more children. If it has just one child, then it's more-or-less a leaf and so deleting it will have no effect. However, deleting a root node that has more than one child will disconnect the graph.
But in a general graph, you can have back-edges and so deleting any of the nodes in between will not disconnect the graph. So figuring out the articulation vertices boils down to figuring out which sections of the tree are linked to ancestor nodes by back edges (i.e., figuring out the "reachable ancestor" of a vertex).
In the page I linked to from the Algorithm Design Manual, Skiena describes three cases where a vertex can be an articulation vertex (root, bridge, and parent cut-nodes). Using the algorithm he describes, you can figure out if the vertex you are processing, meets any of those conditions. If it does, it is an articulation node.
Hopefully this helps you get started!

Find in Multidiamentional Array

I have an multi dimensional array as
[
{"EventDate":"20110421221932","LONGITUDE":"-75.61481666666670","LATITUDE":"38.35916666666670","BothConnectionsDown":false},
{"EventDate":"20110421222228","LONGITUDE":"-75.61456666666670","LATITUDE":"38.35946666666670","BothConnectionsDown":false}
]
Is there any plugin available to search for combination of LONGITUDE,LATITUDE?
Thanks in advance
for (var i in VehCommLost) {
var item = VehCommLost[i];
if (item.LONGITUDE == 1 && item.LATITUDE == 2) {
//gotcha
break;
}
}
this is json string..which programming language u r using with js??
by the way try with parseJSON
Are the latitudes and longitudes completely random? or are they points along a path, so there is some notion of sequence?
If there is some ordering of the points in the array, perhaps a search algorithm could be faster.
For example:
if the inner array is up to 10,000 elements, test item 5000
if that value is too high, focus on 1-4999;
if too low, focus on 5001-10000, else 5000 is the right anwser
repeat until the range shrinks to the vicinity, making a straight loop through the remaining values quick enough.
After sleeping on it, it seems to me most likely that the solution to your problem lies in recasting the problem.
Since it is a requirement of the system that you are able to find a point quickly, I'd suggest that a large array is the wrong data structure to support that requirement. It maybe necessary to have an array, but perhaps there could also be another mechanism to make the search rapid.
As I understand it you are trying to locate points near a known lat-long.
What if, in addition to the array, you had a hash keyed on lat-long, with the value being an array of indexes into the huge array?
Latitude and Longitude can be expressed at different degrees of precision, such as 141.438754 or 141.4
The precision relates to the size of the grid square.
With some knowledge of the business domain, it should be possible to select a reasonably-sized grid such that several points fit inside but not too many to search.
So the hash is keyed on lat-long coords such as '141.4#23.2' with the value being a smaller array of indexes [3456,3478,4579,6344] using the indexes we can easily access the items in the large array.
Suppose we need to find 141.438754#23.2i7643 : we can reduce the precision to '141.4#23.2' and see if there is an array for that grid square.
If not, widen the search to the (3*3-1=) 8 adjacent grids (plus or minus one unit).
If not, widen to the (=5*5-9) 16 grid squares one unit away. And so on...
Depending on how the original data is stored and processed, it may be possible to generate the hash server-side, which would be preferable. If you needed to generate the hash client-side, it might be worth doing if you reused it for many searches, but would be kind of pointless if you used the data only once.
Could you comment on the possibility of recasting the problem in a different way, perhaps along these lines?

Categories

Resources