Hand-Generated TopoJSON not Parsing - topojson

I wrote a simple function to parse a the results of d3.geom.voronoi into topoJSON format, which you can see here:
http://bl.ocks.org/emeeks/9908143
As far as I can tell, it matches up with the topoJSON generated in http://bl.ocks.org/mbostock/5249328 except that it doesn't use translate or scale (though I've generated it with a translate of (0,0) and a scale of (1) and received the same error). When I try to parse the features with topojson, I receive this error:
TypeError: Cannot read property 'length' of undefined
at arc (topojson.js:172:54)
at line (topojson.js:187:52)
at ring (topojson.js:193:20)
at Array.map (native)
at polygon (topojson.js:199:19)
at Object.geometryType.Polygon (topojson.js:214:37)
at geometry (topojson.js:205:71)
at object (topojson.js:218:12)
at feature (topojson.js:160:17)
at topojson.js:151:55
The Polygon example I based this on has an array of arrays for arcs, whereas the Linestring example I've compared it to has an array of arcs, so my assumption is that the Polygon by default is a multipolygon and I've followed the array of arrays for this example, but if I just make an array of arcs, it gives me the error "cannot call slice of undefined".
I'm pretty sure my vorToPoly function is mapping arcs correctly, but if someone could take a look at my object topoCollection (I've echoed it to the console) and tell me how it's not matching up with what topojson expects, I'd appreciate it.

Mike Bostock pointed out that the error occurred because my topojson collection was referring to an arc that didn't exist because it started counting the arcs at 1 instead of 0. The problem occurred in this part of my vorToPoly code:
topoArcs.push([[Math.floor(vorPolys[x][y][0]),Math.floor(vorPolys[x][y][1])],[Math.floor(vorPolys[x][nextVal][0]),Math.floor(vorPolys[x][nextVal][1])]]);
arcHash[hashVal] = topoArcs.length;
It should have been flipped:
arcHash[hashVal] = topoArcs.length;
topoArcs.push([[Math.floor(vorPolys[x][y][0]),Math.floor(vorPolys[x][y][1])],[Math.floor(vorPolys[x][nextVal][0]),Math.floor(vorPolys[x][nextVal][1])]]);
That way the hash is starting at 0 instead of 1. Flipping this makes everything work just fine.

Related

Passing a geopandas data frame to `folium.Choropleth` (map renders gray)

I'm trying to make a Choropleth map from a GeoPandas data frame, rather than from a geojson file containing only geometry plus a pandas dataframe containing statistical data. Specifically, I would like to adapt this example, merging the shapefiles for US states with another dataset containing their respective unemployment numbers into a single GeoPandas data frame (merged), and then rendering it with folium.Choropleth.
The folium documentation says that the geo_data parameter can be a geopandas object. When I pass the geopandas_data_frame.geometry to it, the map renders. However, when I pass merged["Unemployment"] to the data parameter, each state renders in blue, despite the fact that the numbers vary.
m = folium.Map(location=[48, -102], zoom_start=3)
folium.Choropleth(
geo_data=merged,
name='choropleth',
data=merged["Unemployment"],
fill_color='YlGn',
fill_opacity=0.7,
line_opacity=1,
legend_name='Unemployment Rate (%)'
).add_to(m)
folium.LayerControl().add_to(m)
m
I have tried changing the data type of merged["Unemployment"] from float to int to str, as per this question.
Folium uses GeoJSON objects to plot the geometries (the geo_data param). You can use the geopandas but you'll have to convert it in the function call.
folium.Choropleth(geo_data=merged.to_json(),
name='choropleth',
data=merged,
columns=["id", "Unemployment"],
fill_color='YlGn',
fill_opacity=0.7,
line_opacity=1,
key_on="feature.properties.id",
legend_name='Unemployment Rate (%)').add_to(m)
The key_on parameter is the tricky one, it has to match the structure of the merged.to_json() file, just print it and check.

Projection of a SpatialPixelsDataFrame objects

I have created SpatialPixelsDataFrame objects from Raster files. But I cannot work it along with my SpatialPintsDataFrame object. I got this error message:
Error in count.points(GPSLocs, Grass) : different proj4string in w and xy
which means the SpatialPixelsDataFrame objects do not have a projection defined.
GPSLocs= SpatialPointsDataFrame object
Grass= SpatialPixelsDataFrame object
Any suggestions of how to fix this issue?
The message "different proj4string in w and xy" suggest that the coordinate reference systems are different (it may be that one of them is undefined). For others to be able to help you, should always show some code or data. For example what you get when you do:
library(raster)
w
xy
# or
crs(w)
crs(xy)

How to use DBSCAN algorithm for a list of points in python

I am new to image processing and python coding.
I have detected a number of features in an image and have their respective pixel locations placed in a list format.
My_list = [(x1,y1),(x2,y2),......,(xn,yn)]
I would like to use DBSCAN algorithm to form clusters from the following points.
Currently using sklearn.cluster to import the build in DBSCAN function for python.
If the current format for the points is not compatible would like to know which is?
Error currently facing with the current format:
C:\Python\python.exe "F:/opencv_files/dbscan.py"
**Traceback (most recent call last):**
**File "**F:/opencv_files/dbscan.py**", line 83, in <module>
db = DBSCAN(eps=0.5, min_samples=5).fit(X) # metric=X)**
**File "**C:\Python\lib\site-packages\sklearn\cluster\dbscan_.py**", line 282, in fit
X = check_array(X, accept_sparse='csr')
File "**C:\Python\lib\site-packages\sklearn\utils\validation.py**", line 441, in check_array
"if it contains a single sample.".format(array))
ValueError: Expected 2D array, got 1D array instead:
array=[].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.**
Your data is a list of tuple. There is nothing in this structure that prevents you from doing crazy things with that, such as having different lengths in there. Plus, this is a very slow and memory inefficient way of keeping the data because everything is boxed as a Python object.
Just call data = numpy.array(data) to convert your data into an efficient multidimensional numeric array. This array will then have a shape.

Cannot use scatterplot in Octave

I was learning how to do machine learning on mldata.org and I was watching a video on Youtube on how to use the data (https://www.youtube.com/watch?v=zY0UhXPy8fM) (2:50). Using the same data, I tried to follow exactly what he did and create a scatterplot of the dataset. However when he used the scatterplot command, it worked perfectly on his side, but I cannot do it on myside.
Can anyone explain what's wrong and what I should do?
octave:2> load banana_data.octave
octave:3> pkg load communications
octave:4> whos
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
data 2x5300 84800 double
label 1x5300 42400 double
Total is 15900 elements using 127200 bytes
octave:5> scatterplot(data, label)
error: scatterplot: real X must be a vector or a 2-column matrix
error: called from:
error: /home/anthony/octave/communications-1.2.0/scatterplot.m at line 69, column 7
The error message says it all. Your data is a 2-row matrix, and not a 2-column matrix as it should be. Just transpose it with .'.
scatterplot(data.')
I dropped the label argument since it is not compatible with the communications toolbox, either in matlab or in octave.
Update:
According to news('communications'),
The plotting functions eyediagram' andscatterplot' have improved Matlab compatibility
This may be why the behaviour is different. Be ready to find other glitches, as the octave 3.2.4 used in this course is about 5 years old.
In order to use the label, you should rather use the standard octave scatter function.
Colors could be changed by choosing another colormap.
colormap(cool(256))
scatter(data(1,:), data(2,:), 6, label, "filled")

Loading OBJ file in three.js

I was trying to visualize a simple 3D model of the cylinder on the browser by importing OBJ file in three.js. I started with running simple example of three.js's OBJ loader:
https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_obj.html
which works fine locally.
I tried just by replacing the path of OBJ file with that of mine, but it failed to load. I double check the Path and it is correct.
On checking errors on the console on Firefox (Crtl + Shift + k), it says: Syntax Error and throws following error:
[22:59:30.865] Error: WebGL: DrawElements: bound vertex attribute buffers do not have sufficient size for given indices from the bound element array # http://localhost/~harmanpreet/three.js/build/three.min.js:455
The OBJ file is converted from model made in BRL-CAD (.g to .obj conversion). Link to OBJ file: http://devplace.in/~harman/cyl1_bot_dump.obj
Can anybody figure out what is the problem?
Thank you
Your .obj file looks correct according to specs, but I would advise you to use a non-minified three.js version and then look at the code surrounding the error message.
Also what you could try is replacing the "g" in the obj file at start with an "o" (g = group, o = object) - I'm not sure how three.js handles this internally or if it makes a difference, but I guess it won't hurt to try.
Other than that the error seems to be saying something like "I encountered an array index which is out of bounds", meaning a face (f in the .obj file) uses an index which is higher than the highest defined index, but that doesn't seem to be the case with your file (.obj indexes start at 1, so everything should be fine).

Resources