How can I associate multiple rectangles to the entity in Cesiumjs? - javascript

In documentation I see entity seem's be able to have associated different shapes with it (point, polygon, polyline, rectangle, billboard etc.). But how can I add e.g multiple rectangles or polygons with different color, shape etc. ?

You need to create separate entities. A single entity has a lot of graphics options (point, label, polygon, etc) but only one of each per entity. So if you want three separate labels, you need three entities. They can all be in the same position if need be, with different label pixel offsets.
Updating my answer to include some "Primitive" code, in response to a comment below.
var rectangle = viewer.scene.primitives.add(new Cesium.RectanglePrimitive({
rectangle : Cesium.Rectangle.fromDegrees(-120.0, 20.0, -60.0, 40.0)
}));

Related

Triangulating contours into 2d mesh with color data intact

I am using a Javascript library 'Tess2' to triangulate a series of contours.
https://github.com/memononen/tess2.js/blob/master/src/tess2.js
It generates a perfect 2d mesh of any shape consisting of multiple contours:
A contour consists of a series of points (in a negative winding order for solid fills, in a positive winding order for holes)
However, the resulting triangles output by the algorithm are no longer tied to a contour and its fill color.
How would I alter Tess2 (or any other javascript library that tesselates contours) to allow for the retention of color data in the resulting triangles?
I've tried looking everywhere and I cannot find a solution.
From what I've seen in the source code, the tessalation function contains a vertex indices in an returned object:
Tess2.tesselate = function(opts) {
...
return {
vertices: tess.vertices,
vertexIndices: tess.vertexIndices,
vertexCount: tess.vertexCount,
elements: tess.elements,
elementCount: tess.elementCount,
mesh: debug ? tess.mesh : undefined
};
You can create a new array with the colors for each vertex, and then use vertexIndices from the object to get a color of the vertex.
If you would like to have a color per face, you would just need to generate an array like above, which means putting the same vertex color for each vertex in a array. You would also like to wrap all of this data in some kind of convienent object or class.
[EDIT]
It turns out that the tesselation algorithm merges vertices in the same position, meaning that it reorganizes vertex array completely. There are a solution to explicitly not merge different contours with overlapping vertices:
Tess2.tesselate({ contours: yourContours, elementType: Tess2.BOUNDARY_CONTOURS });
That should preserve the original vertices, however not in an original order, use vertexIndices to get the original position of these.
After many failed attempts I finally got there.
I've been trying all this time to try and process a huge amount of contours all at once with a single tessellation pass.
I tried editing the tessellation library to make each half edge retain it original contour ID. I had several eureka moments when it finally seemed to work, only to be disappointed when I stress tested it and found it to be less than perfect.
But it turns out I've been incredibly daft...
All I had to do was group each contour with a particular fill, and then tesselate each group independently.
I didn't understand that for every interior contour fill, there would always be an opposite contour that effectively enclosed the outer contour loop.
For instance, to represent a red box with a blue box inside there would be 2 red contours and 1 blue. I thought it could be represented with only 1 blue contour and 1 red, where the blue would also represent the red contour's hole, and so processing each colour group of contours independently didn't make sense to me.
When I finally realised this, I figured it out.
I've published a solution on github but I'm not sure how much use it is to anyone:
https://github.com/hedgehog90/triangulate-contours-colour-example
I've included a pretty comprehensive exporter script for converting contours (including curves) into polygonal paths for Adobe Flash/Animate which might be useful for someone.
I will be writing an OBJ exporter on top of this shortly, so I can represent vector graphics in a 3D engine.

d3js v5 + Topojson v3 Map with border rendering

I come back for a problem. I'm still learning d3js for 5 days and I have a problem about the border rendering.
Why I have that ?
The problem occurs when I add region borders.
svgMap.append("path")
.attr("class", "reg_contour")
.datum(topojson.mesh(fr[0], fr[0].objects.reg_GEN_WGS84_UTF8, function(a, b) { return a !== b; }))
.attr("d", path);
Here is my code : https://plnkr.co/edit/mD1PzxtedWGrZd5ave28?p=preview
Just for the record, the json file combines two layers (departments and regions) created with the same shp and compiled by QGIS for geojson output. After I convert this to topojson by mapshapper.
The error lies in your topojson - the two different feature types, departments and regions do not share the same coordinates along their common boundaries.
First, in this sort of situation it is desirable to check to make sure there is no layering issue (often other features are drawn ontop of others, hiding them or portions of them), we can do this by just showing the regional boundaries:
(plunkr)
So the problem can't be layering, if we look at a particular feature in the topojson, say the department of Creuse:
{"arcs":[[-29,-28,-27,-26,202,-297,-296,205,-295,-410,419]],"type":"Polygon","properties":{"codgeo":"23","pop":120581,"libgeo":"Creuse","libgeo_m":"CREUSE","codreg":"75","libreg":"Nouvelle Aquitaine"}}
We see that the department is drawn using 11 arcs representing each portion of the boundary based on shared boundaries between multiple features so that shared boundaries are only represented once in the data.
If we zoom in on Creuse we can see those 11 arc segments shared between either other departments, regions, or with nothing at all:
The thick portions of the boundary correspond to the thick white boundaries in the image in the question, I've only changed the styling and zoom from the original plunkr
This looks problematic, the department should only have 6 arcs:
Why are there additional arcs? Because the boundaries of the departments are not aligned properly - the shared boundaries between departments do not always share the same arcs in your topojson. Chances are the departments might use a different scale than the regions, a different precision or projection, or were made somehow differently. This has resulted in minute nearly imperceptible differences that have resulted in boundaries that share coordinates in reality not sharing the same coordinates in the data, and thus the shared arcs are going unrecognized.
Since you are generating the mesh like this:
topojson.mesh(fr[0], fr[0].objects.reg_GEN_WGS84_UTF8, function(a, b) { return a !== b; })
Only shared boundaries are drawn, which explains the gaps.
We can rectify this a few ways, the easiest way would be to remove the regions altogether. The departments record which region they are in, we can check to see if a boundary should be drawn if the departments on each side of that boundary are in different regions:
.datum(topojson.mesh(fr[0], fr[0].objects.dep_GEN_WGS84_UTF8, function(a, b) { return a.properties.libreg !== b.properties.libreg; }))
Which gives us:
(plunkr)
Alternatively, we can re-habilitate the regional boundaries by importing them into a GIS platform such as ArcGIS and repairing the geometry. We could also import the departments and make a new layer based on region properties in a dissolve. Using the repair geometry tool in Arc, I get a nice boundary (when shown with the same code as the first image here):
There are other methods, such as including a tolerance in aligning arcs, but these might be more difficult than the above.

Getting intersection between existing layer and drawn shape

EDIT I now get the right layer from map, so the question now sums up to knowing if a layer A which contains curves, intersectects layer B which contains a surface which can be a circle or a polygon that was just drawn. I tried turf library's turf.intersect but I get "cyclic object reference" from that library.
And I am already looping through the curves seperaterly, to the question is now "Does a curve intersect with a shape.
Also tried: ol.extent.getIntersection(...) but it work only with extents wich are rectangle and therefore give very imprecise results.
I have a map and a layer that is built and added through
var layer = new ol.layer.Vector{(...)};
map.addLayer(layer);
And I add a layer through interaction, as shown in this example: http://openlayers.org/en/v3.6.0/examples/draw-features.html?q=draw
(We use the Circle selection.)
I would like to get he intersection between the lines in the fist layer and the shape (surface) drawn through interaction.
So far, I know that I can catch the event:
var draw = new ol.interaction.Draw{(...)};
draw.on('drawend', function(event){(...)};
But so far I have no clue on what information I can get from the event and how to match it with the layer.

Draw Polygons on a map using WebGL's drawArrays

I am trying to draw polygons on a map, using OSM data downloaded. I have written a query that returns a list of polygons from the planet_osm_polygon table. It resturns the list as JSON objects. I am using gl.drawArrays(gl.LINESTRIP, 0, json_data_length) to draw the polygons. I have done the same for points- I have a list of points returned and I have been able to plot them using gl.POINTS.
The problem is, I want each of the polygons to be drawn separately, but I guess using LINE_STRIP is connecting one ending point of one polygon to the starting point of another polygon.
For example, I want civic center plaza and buchanan street in SFO to be separate polygons. But the polygons, after being drawn, are still connected to each other through one point. I want these two to be drawn as separate polygons. How do I do it?
I do not want to use any libraries. Just basic WebGL. My JavaScript code takes the lat-long coordinates from my osm database and converts into pixel coordinates to help plotting- see link: WebGL shader code (http://psousa.net/demos/webgl/) I am using this example and extending it.
If i understood correctly you want to draw 'borders' of multiple polygons not the filled polygon itself.
In order to draw seperate lines in a single draw call you should use gl.LINES mode instead of gl.LINESTRIP.
Lets say you have a quad which has points A,B,C,D and a triangle which has points X Y Z. If you want to use glDrawArrays command with GL_LINES mode , your vertex data should be submitted as
{A,B, B,C, C,D, D,A, X,Y, Y,Z, Z,X}
Following lines are drawn with this vertex data
Line from A to B
Line from B to C
Line from C to D
Line from D to A
Line from X to Y
Line from Y to Z
Line from Z to X
In order to eliminate duplicate vertex data you can also use glDrawElements with a proper index .

javascript polygon intersection

I have used the code in the following :
http://www.amphibian.com/blogstuff/collision.html. in the html test file I have changed the the first triangle to
triangle1.addPoint({"x":-20, "y":-20});
triangle1.addPoint({"x":-20, "y":20});
triangle1.addPoint({"x":20, "y":20});
triangle1.addPoint({"x":20, "y":10});
triangle1.addPoint({"x":10, "y":10});
triangle1.addPoint({"x":10, "y":-20});
now when I move the other triangle with inside this shape before crossing it gives me wrongly intersection. Any idea where could be the problem?
All right, I set up a fiddle for anyone else wanting to play with this. Here are the results:
The script makes use of the Separating Axis Theorem or (as Wikipedia calls it) Hyperplane separation theorem, as explained in the source of polygon.js:
/*
* To detect intersection with another Polygon object, this
* function uses the Separating Axis Theorem. It returns false
* if there is no intersection, or an object if there is. The object
* contains 2 fields, overlap and axis. Moving the polygon by overlap
* on axis will get the polygons out of intersection.
*/
Polygon.prototype.intersectsWith = function(other) {
This theorem only applies to convex polygons. Your shape is not convex as it has a "dent" in it. That's why the script incorrectly reports that the shapes are intersecting. If you need to make it work with concave shapes, you'll have to make it first split the concave shape up in separate convex parts and then apply the theorem to all individual parts. Obviously, this makes the script more complex as you need to iterate over the cross product of the concave parts of two shapes.
Here is my not too complicated implementation of finding the intersection polygon of two polygons.
It works for convex and concave polygons, but not for complex (self-intersecting) polygons.
Algorithm is fairly similar to the one presented in Margalit & Knott.
Its complexity is about 4*n1*n2, where n1 and n2 are numbers of vertices in polygons whose intersection is being calculated.
It is a single standalone .js file. A 'Polygon' is regarded any javascript array of 2D Points. A 'Point' is any javascript object with x and y numeric properties.
Implementing the Union functionality on top of existing one should not be a problem and I will do it probably soon.
Intersection of 2D polygons

Categories