I have an svg element composed of many different path objects, each of which represents one U.S state.
http://jsfiddle.net/jGjZ2/
I would like to merge the east territory (gold) into a single path object with no visible divisions.
The end result should look like this (ignore the inaccuracies):
I am using D3.
There is no GeoJSON or TopoJSON data - the map is svg directly embedded in html (see jsfiddle).
Thanks a lot!
Assuming you can ignore the stated restriction of manipulating an existing SVG image (which seems like an arbitrary restriction given the ready availability of cartographic boundaries in more easy-to-manipulate formats…), you can use topojson.mesh to merge multiple polygons. Though, note this approach has a few limitations as described in this example:
Another simple approach is to just draw the highlighted polygons twice: once with a thick black stroke and no fill, and a second time on top with orange fill and no stroke. This achieves the same effect without any need for topological manipulation:
I suppose if you really had to, you could reach into the SVG element and do the same thing by extracting the vector data, but it will be easier if you start from clean data.
Related
I am working on a data set of coordinate points(many dots in area) either (x,y) or (lat,lon) which fall into multiple categories. What I am trying to do is get polygons of areas from those points which are called concave or non-convex as far as I know, but also those polygons have to be next to each other with no gaps between them.
These are the initial points(example)
This is the approximate result I am aiming for
Real life example would be European geopolitical map, if you had all of the addresses of all countries and wanted to get area of each country as a polygon and end up with a map.
I have come across many questions related to getting polygons from set of points, but were unable to use it in my scenario. If you need any more information please let me know. Thank you for your help.
You could use a Voronoi tesselation of the input space. Instead of having point you have sets of points though. Basically, you take each point in space, and look at the closest point to it. It then gets the same "class" as that point. For smoother outputs you could look at a k majority out of N nearest points. It would mean working with a bitmap image rather than 2D coordinates, but you'd get something workable. You could then use simpler image manipulation tricks (edge detection, binary set operations etc to get just the edges, and then perhaps superimpose those on the image).
As an alternative, you could run a convex hull algorithm on each data set, and then try to fix the overlap areas.
What is the neatest (code design) and most per-formant way of getting an array of points for an arc (polyline), for the purpose of animating using Cesium's timer/clock.
Variable inputs include (start/end location), height (highest point) from earth's surface and number of points for drawing.
I'm currently using a polyline collection, so the answer should describe how to generate the points for existing polylines or convert to a different approach.
I would also need the arc (color) to fadeIn or fadeOut to opacity 0.
Multiple arcs may be added or removed from the collection per second. Each arc will have different start and end points
The start and end location should have height 0 (touching the earth).
(For Cesium version b26)
Just to be sure I understand your question, you have a bunch of polylines on a map and you want to get a bunch of data points along the line for use in animating the something along the path. I'll also assume you want geodesic lines/arcs for the polylines rather than the straight lines that are normally drawn on Mercator maps as geodesic lines actually follow the spatially accurate path of the polyline i.e. the same path a plane would take. If this is the case then take a look at this blog post: http://alastaira.wordpress.com/2011/06/27/geodesics-on-bing-maps-v7/ This post describes how to calculate data points along the geodesic path of a polyline.
CesiumJS includes several spline functions that can be used. One of the easier ones to use that an accomplish what you want with just three points is the Catmull-Rom Spline:
http://cesiumjs.org/Cesium/Build/Documentation/CatmullRomSpline.html
You will need to produce a middle point. To do this you can take a mean of the lat/lon coordinates and add a large height. Because of the spline used and the low number of points, it does end up looking a little egg shaped. The benefit to this is that you can ask the spline object for an arbitrary number of points, so the arc can be as smooth as you want. Just don't forget to add the first and last points to the array returned by the spline as those are omitted.
There are other types of splines, but I found the Catmull-Rom spline the easiest to use. You can search the CesiumJS documentation for some of the other included splines.
I've been looking into the same thing (minus the time aspect) and I found Cesium.EllipsoidGeodesic(start, end, ellipsoid), which allows you to get points at fractions of the path. It seems to me that you can choose the fraction based on the distance and calculate regular points using the result.
https://cesiumjs.org/Cesium/Build/Documentation/EllipsoidGeodesic.html
I haven't tried it yet, but it's on my list of things to do.
I am wondering if anyone has heard of some javascript which can take a simple SVG path that took maybe 30 seconds to create in illustrator or something and convert it into something that looks 3d. There is an extrude function in illustrator which does this. It is also called polling in sketchUp.
I am using Raphael.js now, but am open to other suggestions. A simple solution would be to make a copy of the path and move it a couple pixels down and to the right and give it a darker color behind the original path, but I am looking for something that might have a little more shading.
Thanks!
There is always a possibility to use three.js for extruding the path for use in webGL in browser:
http://alteredqualia.com/three/examples/webgl_text.html#D81F0A21010#23a
(More samples here:http://stemkoski.github.io/Three.js/)
It uses js-fonts and parses the path commands on them, extrudes the paths and renders the scene. In the same way it should be possible to take an SVG path and extrude it. Raphael has Raphael.parsePathString() which gives you the path segments as an array of individual segments. If you first convert the path commands to cubic curves using Raphael.path2curve() and Raphael._pathToabsolute(), you have only only one segment type so you can use three.js:s BEZIER_CURVE_TO command. If you have transformations applied on the path (which is usually the case in Illustrator export) you can flatten them using function from here: https://stackoverflow.com/a/13102801/1691517.
One possible starting point is here (click the fiddle of the answer):
Extruding multiple polygons with multiple holes and texturing the combined shape
Three.js supports few path commands, but have not tested all of them (
http://threejsdoc.appspot.com/doc/three.js/src.source/extras/core/Path.js.html, see below).
THREE.PathActions = {
MOVE_TO: 'moveTo',
LINE_TO: 'lineTo',
QUADRATIC_CURVE_TO: 'quadraticCurveTo', // Bezier quadratic curve
BEZIER_CURVE_TO: 'bezierCurveTo', // Bezier cubic curve
CSPLINE_THRU: 'splineThru', // Catmull-rom spline
ARC: 'arc' // Circle
};
I have used a custom rather complex function to polygonize SVG path, so was no need to rely to other commands than moveto and lineto.
The downside is of course rather low support level for webGL, 31-53%: http://caniuse.com/webgl
Other more cross-browser solution is this SVG3d library if lesser quality and slowness is not an issue:
http://debeissat.nicolas.free.fr/svg3d.php
https://code.google.com/p/svg3d/
I think this resource could be helpful to you, he uses d3 to generate 2D visualization and then uses d3-threeD to extrude.
Sounds like you want to use svg filters. Webplatform.org has a pretty good tutorial about that. Scroll down a bit and you'll find some lighting filters that looks like 3d.
Raphaël doesn't support filters though, so either you'll need to extend it, or just use svg directly.
I have a large set of rectangles that are drawn on html5 canvas.
I would like to be able to interact with this image using mouse tracking (I cannot use SVG because it does not scale to 10-100k rectangles). Is there any data structure/algo that, given the mouse x,y coordinates would be able to tell you which box the mouse was over (using the computed locations of the rectangles)? I was thinking something like a k-d tree but was not sure.
If your data is always of the form shown I think you should be able to do better than a spatial tree data structure.
Since the data is structured in y you should be able to calculate which 'strip' of rectangles the points is in based on offsets in O(1) time.
If you store the individual rectangles within each 'strip' in sorted order (using xmax say) you should then be able to locate the specific rectangle within the strip using a binary search (in O(log(n))).
Hope this helps.
The naive solution would be to iterate over all rectangles and check if you are in it. Checking for a single rectangle is easy (if you want I will write it down explicitly).
If you have many rectangles and care about performance, you can easily speed things up by putting the rectangles in a data structure which is faster to look in. Looking at the image you sent, one obvious property of your data is that there is a limited amount of vertical positions ("rows"). This means that if you check which row you are on, you then only need to check rectangles within that row. Finally, to select which row you are on or within a row select which rectangle, keep a sorted data structure (e.g. some search tree).
So your data structure could be something like a search tree for row, where each node holds a search tree of rectangles along the row.
R-tree is suitable for providing spatial access of this kind
But some questions:
Is your rectangle set static or dynamic?
How many point queries do you expect for rectangle set?
Edit:
Because rectangle set is static:
There is method, used in traditional graphics with bitmaps (don't know is it applicable to html5 canvas or not):
Make additional bitmap with the same size as main picture. Draw every rectangle with the same coordinates, but fill it with unique color (for example, color = rectangle index). Then check color under mouse point => get rectangle index in O(1)
I am currently trying to create a blue, circular, pie-chart-esque image for my website. The circle will be split into 6 different segments.
What I want to happen is that when the user hovers over a particular segment, this segment will turn orange, and some text will appear beside the circle corresponding to that segment.
I have found some resources online which achieve nearly the effect I need using CSS image maps. http://www.noobcube.com/tutorials/html-css/css-image-maps-a-beginners-guide-/ However, these techniques split up an image using rectangles. If I were splitting up a circular object I would prefer to split up the area based on particular arcs.
I assume this is beyond the reach of pure HTML and CSS. I do not have a great deal of experience with web languages, although I have had passing experience with JQuery. What are the techniques I need to solve my problem and what technology would be best to implement it?
you can create image maps that are not rectangular, but use polygon shapes.
this useful tool http://www.image-maps.com/ will let you achieve what you are looking for, without having to write your own polygon mapping!
A few options:
HTML image map
It's simple to create an HTML image map that comes very close to the shape of each slice of the circle, but there are limitations to HTML images maps. For instance, you can't nest content inside each slice of the image map (as an easy way to implement a hover pop-up). If an HTML image map is adequate for you, it's the simplest solution.
CSS image map
To define circle-slice shapes, a CSS image map is impractical, unless you only need a very-rough approximation of the hotspots for each circle slice. But if you could live with that, you'd have a lot more flexibility as far as the functionality.
onmousemove
You could also get the mouse coordinates with an onmousemove event handler for the entire circle, and then do your own calculations to determine which circle slice the mouse is in. This allows you to accurately define the hotspots for each circle slice, and you'd have more flexibility than with an HTML image map. But the calculations may take a little work.
I have a solution for this using mainly HTML and CSS with a tiny bit of jQuery to handle the showing of the text by the side of the circle.
It does however use some CSS properties that are not very widely supported such as pointer-events
JSFiddle Demo