I have a geojson object defining Neighborhoods in Los Angeles using lon/lat polygons. In my web application, the client has to process a live stream of spatial events, basically a list of lon/lat coordinates. How can I classify these coordinates into neighborhoods using Javascript on the client (in the browser)?
I am willing to assume neighborhoods are exclusive. So once a coordinate as been classified as neighborhood X, there is no need to further test it for other neighborhoods.
There's a great set of answers here on how to solve the general problem of determining whether a point is contained by a polygon. The two options there that sound the most interesting in your case:
As #Bubbles mentioned, do a bounding box check first. This is very fast, and I believe should work fine with either projected or unprotected coordinates. If you have SVG paths for the neighborhoods, you can use the native .getBBox() method to quickly get the bounding box.
the next thing I'd try for complex polygons, especially if you can use D3 v3, is rendering to an off-screen canvas and checking pixel color. D3 v3 offers a geo path helper that can produce canvas paths as well as SVG paths, and I suspect if you can pre-render the neighborhoods this could be very fast indeed.
Update: I thought this was an interesting problem, so I came up with a generalized raster-based plugin here: http://bl.ocks.org/4246925
This works with D3 and a canvas element to do raster-based geocoding. Once the features are drawn to the canvas, the actual geocoding is O(1), so it should be very fast - a quick in-browser test could geocode 1000 points in ~0.5 sec. If you were using this in practice, you'd need to deal with edge-cases better than I do here.
If you're not working in a browser, you may still be able to do this with node-canvas.
I've seen a few libraries out there that do this, but most of them are canvas libraries that may rely on approximations more than you'd want, and might be hard to adapt to a project which has no direct need to rely on them for intersections.
The only other half-decent option I can think of is implementing ray casting in javascript. This algorithm isn't technically perfect since it's for Euclidean geometry and lat/long coordinates are not (as they denote points on a curved surface), but for areas as small as a neighbourhood in a city I doubt this will matter.
Here's a google maps extension that essentially does this algorithm. You'd have to adapt it a bit, but the principles are quite similar. The big thing is you'd have to preprocess your coordinates into paths of just two coordinates, but that should be doable.*
This is by no means cheap - for every point you have to classify, you must test every line segment in the neighborhood polygons. If you expect a user to be reusing the same coordinates over and over between sessions, I'd be tempted to store their neighborhood as part of it's data. Otherwise, if you are testing against many, many neighborhoods, there are a few simple timesavers you can implement. For example, you can preprocess every neighborhoods extreme coordinates (get their northmost, eastmost, southmost, and westmost points), and use these to define a rectangle that inscribes the town. Then, you can first check the points for candidate neighborhoods by checking if it lies inside the rectangle, then run the full ray casting algorithm.
*If you decide to go this route and have any trouble adapting this code, I'd be happy to help
Related
The problem here is I don't really know the right question to ask, but essentially I want to generate a pattern of ngons that all fit perfectly together, kinda like the picture.
Is there an algorithm or anything that can do this?
FYI I'm attempting this in JavaScript
The algorithm you want is a Voronoi Diagram. The essential description of the algorithm is such:
Generate a list of random points on a plane (or get the points as input from somewhere).
Create a geometric map of n-gons that represent all the space in the plane closest to each point.
The resulting graph will look something like this (stylized and colored):
The look and shape of the n-gons depend on the spacing of the points. You can play with different point distributions or generation methods to get a Voronoi Diagram with particular characteristics. You can also play with the n-gons themselves, for example you can treat the boundaries as fuzzy approximations, blending or leaving gaps between adjacent n-gons:
There are a ton of cool things you can do with a Voronoi Diagram, and pretty much every programming language has libraries that can compute one very quickly. For example, one of the interactive examples for Paper.js is a dynamically generated Voronoi Diagram where one of the points is the location of the cursor. Here's another example where someone uses Voronoi Diagrams as one of the steps for procedural terrain generation. Yet another example is a Voronoi Diagram using the locations of all the airports in the world, which you could use to find the closest airport to any location on the planet.
One such library in Javascript is d3-voronoi, though like I said, there are quite a few libraries out there, not to mention a gazillion tutorial articles on how to implement it yourself should you decide to go that route.
I have a use case where I need to render a significant amount (~50,000 glyphs) of crisp, scalable text strings on a canvas element. The best solution I've tried so far involves triangulating text drawn on a canvas element (Text was drawn using fillText method), uploading matrix uniforms and the Float32Array of triangles representing that string to the GPU via WebGL. Using this method, I was able to render 100,000 glyphs at about 30fps. Glyphs become blocky at very high zoom levels, but that is fine for my use case.
However, this method has overhead of about ~250ms per string, since I first draw the string to a canvas element in memory, read pixel data, turn the bitmap image into a vector and then triangulate the vector data. Searching the web for solutions, I came across two interesting open-source projects:
OpenType.js: https://opentype.js.org/
Earcut: https://github.com/mapbox/earcut
So now I want to re-write my initial proof of concept to use OpenType and Earcut. OpenType for feeding curve data into Earcut, and Earcut for triangulating that data and returning an array representing the point for each triangle.
My problem is, I can't figure out how to get the data OpenType provides and convert it into the format that Earcut accepts. Can anyone provide assistance for this?
More Info:
This StackOverflow question had some great information, but lacks some of the implementation details: Better Quality Text in WebGL. I suppose what I am trying to accomplish is the "Font as Geometry" approach described in the first answer.
You can create a path using Font.getPath. Path consists of move-to, line-to, curve-to, quad-to and close instructions, accessed via path.commands. You will need to convert bezier curve instructions into small segments first, of course.
Once you have a set of closed paths, you need to determine which ones are holes. Inner outlines will be oriented in an opposite direction to outer ones, and you can assign them to the smallest outer outline containing them. Once you have groups of <outer outline and a set of holes> you should be able to feed it to earcut library.
This is a simple implementation that assumes there are no intersections. For me it worked very well for most fonts, except for very few "fancy" fonts that have intersecting paths.
Here's a working example: https://jsbin.com/gecakub/edit?html,js,output
Instead of creating meshes for each string, you could also create them for individual characters, and then position them yourself using kerning data from the library.
Edit: this solution will only work for TTF fonts, though it can be easily adjusted for CCF (.otf) by ignoring path orientation and using a better "path A is inside path B" check, unless the font has intersecting paths.
We are developing a web-based game. The map has a fixed size and is procedually generated.
At the moment, all these polygons are stored in one array and checked whether they should be drawn or not. This requires a lot of performance. Which is the best rendering / buffering solution for big maps?
What I've tried:
Quadtrees. Problem: Performance still not as great because there are so many polygons.
Drawing sections of the map to offscreen-canvases. A test run: http://norizon.ch/repo/buffered-map-rendering/ Problem: The browser crashes when trying to buffer that much data and such big images (maybe 2000x2000) still seem to perform badly on a canvas.
(posting comments as an answer for convenience)
One idea could be, when the user is translating the map, to re-use the part that will still be in view, and to draw only the stripe(s) that are no longer corrects.
I believe (do you confirm ?) that the most costly operation is the drawing, not to find which polygon to draw.
If so, you should use your QuadTree to find the polygons that are within the strips. Notice that, given Javascript's overhead, a simple 2D bucket that contains the polygons that are within a given (x,y) tile might be faster to use (if the cost of the quadtree is too high).
Now i have a doubt about the precise way you should do that, i'm afraid you'll have to experiment / benchmark, and maybe choose a prefered browser.
Problems :
• Copying a canvas on itself can be very slow depending on devices/Browsers. (might require to do 2 copy, in fact)
• Using an offscreen canvas can be very slow depending on devices/Browsers. (might not use hardware acceleration when off-screen).
If you are drawing things on top of the map, you can either use a secondary canvas on top of the map canvas, or you'll be forced to use an off-screen canvas that you'll copy on each frame.
I have tried a lot of things and this solution turned out to be the best for us.
Because our map has a fixed size, it is calculated server-side.
One big image atlas with all the required tiles will be loaded at the beginning of the game. For each image on the atlas, a seperate canvas is created. The client loads the whole map data into one two-dimensional array. The values determine, which tile has to be loaded. Maybe it would be even better if the map was drawn on a seperate canvas, so that only the stripes have to be painted. But the performance is really good, so we won't change that.
Three conclusions:
Images are fast. GetImageData is not!
JavaScript has not yet great support for multi threading, so we don't calculate the map client-side in game-time.
Quadtrees are fast. Arrays are faster.
I´m searching for a (or more) best practice(s) for the following problem. I´ll try to describe it as abstract as possible, so the solution can be applied to scenarios i have not yet thought of.
Data available: Voxels (Volumetric Pixels), forming a cube, with coordinates x,y,z and a color attached.
Goal: Use OpenGL to display this data, as you move through it from different sides.
Question: Whats the best practice to render those voxels, depending on the viewpoint? How (which type of Object) can store the data?
Consider the following:
The cube of data can be considered as z layers of x y data. It should
be possible to view, in-between-layers, then the displayed color
should be interpolated from the closest matching voxels.
For my application, i have data sets of (x,y,z)=(512,512,128) and
more, containing medical data (scans of hearts, brains, ...).
What i´ve tried so far:
Evaluated different frameworks (PIXI.js, three.js) and worked through a few WebGL tutorials.
If something is not yet clear enough, please ask.
There are 2 major ways to represent / render 3D datasets. Rasterization and Ray-tracing.
One fair rasterization approach is a surface reconstruction technique by the use of algorithms such as Marching Cubes, Dual Contouring or Dual Marching Cubes.
Three.js have a Marching Cubes implementation in the examples section. You basically create polygons from your voxels for classical rasterization. It may be faster than it seems. Depending the level of detail you want to reach, the process can be fast enough to be done more than 60 times per second, for thousands of vertices.
Although, unless you want to simply represent cubes (I doubt) instead of a surface, you will also need more info associated to each of your voxels rather than only voxel positions and colors.
The other way is raycasting. Unless you find a really efficient raycasting algorithm, you will have serious performance hit with a naive implementation.
You can try to cast rays from your camera position through your data structure, find / stop marching through when you reach a surface and project your intersection point back to screen space with the desired color.
You may draw the resulting pixel in a texture buffer to map it on a full-screen quad with a simple shader.
In both cases, you need more information than just colors and cubes. For example, you need at least density values at each corners of your voxels for Marching cubes or intersection normals along voxels edges (hermite data) for Dual Contouring.
The same for ray-casting, you need at least some density information to figure out where the surface lies or not.
One of the keys is also in how you organize the data in your structure specially for out-of-core accesses.
I have a B-Spline curve. I have all the knots, and the x,y coordinates of the Control Points.
I need to convert the B-Spline curve into Bezier curves.
My end goal is to be able to draw the shape on an html5 canvas element. The B-Spline is coming from a dxf file which doesn't support Beziers, while a canvas only supports Beziers.
I've found several articles which attempt to explain the process, however they are quite a bit over my head and really seem to be very theory intensive. I really need an example or step by step help.
Here's what I've found:
(Explains B-Splines),(Converting to Beziers),(Javascript Example)
The last link is nice because it contains actual code, however it doesn't seem to take into account the weight assigned by the nodes. I think this is kind of important as it seems to influence whether the curve passes through a control point.
I can share my Nodes or Control Points if that would be useful. If someone would point me to a step-by-step procedure or help me with some psuedo(or actual)code, I would be so grateful.
I wrote a simple Javascript implementation of Boehm's algorithm for cubic B-Splines a while back. It's a fairly straightforward implementation involving polar values, described here in section 6.3: Computer Aided Geometric Design- Sederberg
If you're just interested in the implementation, I've linked the classes I wrote here: bsplines.js
This could be helpful - https://github.com/Tagussan/BSpline
My project has moved on and I no longer need it, but this seems to be a pretty useful way to feed control points and have a curve drawn.