Mapbox - Switch between between data fields in shape file - gis

I'm new to using Mapbox. I've been able to import a shapefile containing multiple polygon data sets. I'd like to be able to create a map which allows the user to switch between different datasets. The issue is the initial import creates a single layer and I'm not sure how to create a different layer or object for each new field I'd like the user to be able to switch between. As an example here's the simple TileMill code block that imports the shape file and accesses the first data object
#COPrecincts {
line-color:black;
line-width:0.5;
}
#COPrecincts {
[P_08 > 0.5] {polygon-fill: lighten(blue,40%);}
[P_08 > 0.6] {polygon-fill: lighten(blue,30%);}
[P_08 > 0.7] {polygon-fill: lighten(blue,20%);}
[P_08 > 0.8] {polygon-fill: lighten(blue,10%);}
[P_08 > 0.9] {polygon-fill: blue;}
[P_08 = 0.5] {polygon-fill: lighten(blue,50%);}
[P_08 < 0.5] {polygon-fill: lighten(red,40%);}
[P_08 < 0.4] {polygon-fill: lighten(red,30%);}
[P_08 < 0.3] {polygon-fill: lighten(red,20%);}
[P_08 < 0.2] {polygon-fill: lighten(red,10%);}
[P_08 < 0.1] {polygon-fill: red;}
}

To do this, you are going to need to create multiple TileMill projects so that you can export multiple map layers to switch between. Whether you use JavaScript or some other presentation, having multiple map layers is how you will let the user choose the one in view. You won't be able to hide portions of a single map layer.
One project that will likely be useful to you in creating multiple similar TileMill projects is ProjectMill:
https://github.com/mapbox/projectmill
But also consider stepping back a moment and possibly drawing the data client-side in JavaScript instead of TileMill projects. If you look at this: https://www.mapbox.com/mapbox.js/example/v1.0.0/polyline/ and other vector overlay examples with MapBox.js, you might find something that will work better for your project and not require so much upfront processing and rendering.

Related

Get primitive from AABB tree intersection

This code contains an AABB Tree which is build using a Polyhedron_3 mesh. It is possible to verify if an intersection occures but not what primitive the intersection hit. How can I retrieve the primitive?
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
const Polyhedron& mesh;
tree(faces(_mesh).first, faces(_mesh).second, _mesh);
boost::optional<Primitive_id> intersection = tree.first_intersected_primitive(ray);
if(intersection)
{
//how to get the primitive?
}
Edit:
faces(mesh, tree);
faces(*mesh, tree);
faces(hit, tree);
faces(*hit, tree);
Does not work too.
Edit2:
CGAL::internal::In_place_list_iterator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > > >, std::allocator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > > > > > it = *hit;
CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > >::Halfedge_around_facet_circulator ipfacet = it->facet_begin();
Gets you an iterrator and I_Polyhedron_facet.
Cgal is realy missing some documentation.
Here is the solution: Get the iterator around the face verticess primitive_id->facet_begin(); . And then do this.
Ray_intersection hit = tree.first_intersection(rays[this->transformCoordinates(y,x)]);
if(hit)
{
const Point& point = boost::get<Point>(hit->first);
const Primitive_id& primitive_id = boost::get<Primitive_id>(hit->second);
Polyhedron::Halfedge_around_facet_circulator facerunner = primitive_id->facet_begin();
Point p1;
Point p2;
Point p3;
p1 = facerunner->vertex()->point();
facerunner++;
p2 = facerunner->vertex()->point();
facerunner++;
p3 = facerunner->vertex()->point();
Vector v1(p1,p2);
Vector v2(p1,p3);
Vector n = CGAL::cross_product(v1,v2);
n = n/ std::sqrt(n.squared_length());
}
Answer from the cgal mailinglist:
what are you looking for that is not available here:
https://doc.cgal.org/latest/AABB_tree/index.html#title6
Also note that from here:
https://doc.cgal.org/latest/AABB_tree/classCGAL_1_1AABB__face__graph__triangle__primitive.html
you have:
typedef boost::graph_traits< FaceGraph >::face_descriptor Id
From that same page, you see that the graph type is model of FaceGraph:
https://doc.cgal.org/latest/BGL/classFaceGraph.html
Depending on the type of graph chosen, you have access to the precise
documentation of what face_descriptor corresponds to:
https://doc.cgal.org/latest/BGL/group__PkgBGLTraits.html
Then you can refer to the documentation of the class to know how to
iterate over the vertex of the face.
There is even a generic helper function to do it:
for ( boost::graph_traits<Graph>::vertex_descriptor v :
CGAL::vertices_around_face(halfedge(f, g), g))
{
Point_3 p = get(boost::vertex_index, v, g);
}
I'm not saying it is easy to get but reading the doc gives you the
information required. It's not like reading vtk doc where you have
to guess or read the source code to understand things.
Anyway, we are always looking to improve our doc and we'll be soon
having some cross-packages tutorials and one about manipulation of
surface meshes in CGAL will surely be added.
if intersection is not null, then *intersection should be the Primitive_id of the primitive you are looking for.

Bing Maps Layers - Finding information on segment

I have a large object, full of WKT information from a GIS system. I'm looping over the data and mapping it into layers, then pushing those layers onto the map. This is working fine and I'm getting the right data showing up.
for (var j = 0; j < 10; j++) {
var dataLayer = new Microsoft.Maps.Layer($scope.thing);
for (var i = 0; i < bArray.length; i++) {
if (bArray[i].count == $scope.thing) {
dataLayer.add(new Microsoft.Maps.WellKnownText.read(bArray[i].wkt);
dataLayer.item = bArray[i].count;
}
}
Microsoft.Maps.Events.addHandler(dataLayer, "click", polylineClicked);
$scope.map.layers.insert(dataLayer);
$scope.map.layers[j].setVisible(false);
$scope.thing++;
}
The data in each layer breaks down into different categories, stored in the field "item", and I show those categories in a side legend.
My question is how do I find "item" for each segment on the map? When I view the map object I can see the layers, when I go into the layers I can see the primitives, but when I enter the primitive, they all have the same category in "item", instead of what they should have.
How do I find "item" for each segment?
Thanks
Docmur
First off, use the metadata property of the layer to store custom info, otherwise you risk overwriting one of the internal properties of the layer class. For example: dataLayer.metadata = { item: "custom data" };
That said, your item property is on the dataLayer, not on the individual primitives. It also looks like you are adding the same value to it over an over again on the inner loop so you will end up with a lot of values that are the same. Can you provide more details on what you want to achieve as there likely is a much cleaner way to do this.

What's visible in a ScrollViewer?

I have a GridView. I am using the nested ScrollViewer's SnapPoints to snap each record into view. Because this is only a visual change, and not a data change, how can I determine which record(s) is currently visible? Something like SelectedItem, but a visual query. I could check every record, but it seems inefficient. Ideas?
In your case you could use the VisualTreeHelperExtensions from WinRT XAML Toolkit and do something like this
gridView
.GetDescendantsOfType<GridViewItem>()
.Select(gvi => gridView.ItemFromContainer(gvi));
It does a somewhat intensive visual tree search, but might be OK for your scenario if your GridView uses virtualization since the items returned are in or near the view port. If you want to be more precise you can test for bounding rect intersections. Something like this might be enough:
static class RectExtensions
{
public static bool ContainsPartOf(this Rect bigRect, Rect smallRect)
{
// this is a very targeted test for horizontally scrollable smallRects inside of a bigRect
return bigRect.Left < smallRect.Left && bigRect.Right > smallRect.Left ||
bigRect.Left < smallRect.Right && bigRect.Right > smallRect.Right;
}
}
var sv = gridView.GetFirstDescendantOfType<ScrollViewer>();
var bigRect = new Rect(0, 0, sv.ActualWidth, sv.ActualHeight);
gridView
.GetDescendantsOfType<GridViewItem>()
.Where(gvi => bigRect.ContainsPartOf(gvi.GetBoundingRect(sv)))
.Select(gvi => gridView.ItemFromContainer(gvi));

D3 reusable multi-line chart with JSON data

I'm trying to do some re-factoring on my charts to make them re-usable using this as a guide: http://bost.ocks.org/mike/chart/
I'm having problems drawing the lines in my multi-line graph though - specifically passing the data to the x and y values. If I hard code the element names it works, but if I try to use the xValue and yValue objects this does not work. I'm assuming that this is because I'm trying to call a function within the parameter of an other object, but I'm not sure how to get around this. In the exmaple Mike uses d[0] and d[1], but this won't work with JSON data (or I'm not sure how to make it work).
I've posted this JSFiddle so you can see the code. The problem lines are 125 to 131 which in turn is being called from line 165.
var main_line = d3.svg.line()
.interpolate("cardinal")
// Hard coding the elements works
//.x(function(d) { return main_x(d.date); })
//.y(function(d) { return main_y(d.buildFixTime); });
// Passing xValue and yValue does not work
.x(function(d) { return main_x(xValue); })
.y(function(d) { return main_y(yValue); });
http://jsfiddle.net/goodspeedj/fDyLY/
Thank you in advance.
You need to redefine your accessor method within .x() and .y(). The accessor method defines the way that a datum is pulled out of the data that is bound to the selection that you call the line generator on.
Suppose you have a relatively flat data structure such as the following.
data = [{x : 1, y : 2}, {x:1, y:3}, {x:4, y:5}];
You then bind the data to a selection with the following statement
d3.select("body").datum(data).append("path").attr("d",lineGenerator);
Quite a bit is going on underneath this statement. I'll give you a bit more of a walkthrough after showing you a commonly used example.
The important aspect to understand is that similarly to other calls in d3 such as
var exampleRectangles = d3.select("body")
.data(data).enter()
.append("rect")
.attr("width",2)
.attr("height", 3)
.attr("x",function(datum){return datum.x}) // pay attention to this line
.attr("y",0);
d3 is implicitly iterating over each element in your data. For each datum in your data array, in this case there is a total of three datum, you are going to add a rectangle to the dom.
In the line that I tell you to pay attention to you notice that you're defining an anonymous (unnamed) function. What is that datum parameter coming from? It's implicitly being passed to your anonymous function.
So each rectangle has it's own corresponding datum {x : 1, y : 2}, {x:1, y:3}, {x:4, y:5} respectively. Each rectangle's x coordinate is defined by the respective datum.x attribute. Under the sheets, d3 is implicitly looping over the data array that you've defined. A similar approach to the example d3 code could be written as above.
for (var i = 0; i < data.length; i++)
{
d3.select("body").append("rect")
.attr("width",2)
.attr("height", 3)
.attr("x",data[i].x)
.attr("y",0);
}
This follows from the notion of data driven documents (d3). For each item added (a rectangle in the above example a piece of data is tied to it. In the above example you see that there is something kind of similar to your .x() and .y() accessor functions :
.attr("x",function(datum){return datum.x})
This function is telling d3 how to filter over the total datum that's being passed to the .attr() accessor method.
So, you need to determine which data you need to get a hold of to make your .attr("d", lineGenerator)call make sense. The difference between your.datum(data)call and the typical.data(data)call is that instead of parceling the data that's being passed to.data(data)`, the whole array is given as a single piece of data to the line generator function (similar to main_line(data), wherein it will again implicitly loop over the points to construct your path.
So, what you need to do is determine what a single datum will be defined as for your function to operate on.
I'm not going to define that as I don't seem to know quite which information you are operating on, but I would hazard a guess at something like.
.x(xAccessor)
.y(yAccessor)
function xAccessor(datum)
{
return xScale(datum._id.month);
}
function yAccessor(datum)
{
return yScale(datum.buildFixTime);
}
The way you have it set up, xValue and yValue are functions; you have to actually execute them on something to get a value back.
.x(function(d) { return main_x( xValue(d) ); })
.y(function(d) { return main_y( yValue(d) ); });
If you weren't using a scale, you could use
.x(xValue)
.y(yValue);
but only because if you pass in a function d3 executes it for you with the data as a parameter. And that only works for d3 methods that expect functions as possible input -- the scale functions expect data values as input.
I wrote a long piece work for another user last week that you may find useful, explaining methods that accept functions as parameters.

Force-directed graphing

I'm trying to write a force-directed or force-atlas code base for a graphing application I'm building for myself. Here is an example of what I'm attempting: http://sawamuland.com/flash/graph.html
I managed to find some pseudo code to accomplish what I'd like on the Wiki Force-atlas article. I've converted this into ActionScript 3.0 code since it's a Flash application. Here is my source:
var timestep:int = 0;
var damping:int = 0;
var total_kinetic_engery:int = 0;
for (var node in list) {
var net_force:int = 0;
for (var other_node in list) {
net_force += coulombRepulsion(node, other_node, nodeList);
}
for (var spring in list[node].relations) {
net_force += hookeAttraction(node, spring, nodeList);
}
list[node].velocity += (timestep * net_force) * damping;
list[node].position += timestep * list[node].velocity;
total_kinetic_engery += list[node].mass * (list[node].velocity) ^ 2;
}
The problem now is finding pseudo code or a function to perform the the coulomb repulsion and hooke attraction code. I'm not exactly sure how to accomplish this.
Does anyone know of a good reference I can look at...understand and implement quickly?
Best.
There are links to these in the same article. Hooke's is the spring force between end-nodes of a link, while Coulomb's force repels nearby nodes away.
The question is not really the expressions, but the constants applied inside them. I would read the original article, google for "Fruchterman, T. M. J., & Reingold, E. M. (1991). Graph Drawing by Force-Directed Placement. Software: Practice and Experience, 21(11)." and read through the pdf to see what the authors suggest.
Btw, your vars may have to be floats, not integers.
have you looked at flare? there is a demo with a force-directed graph.