Why does D3.js not display my geoJSON file ? - javascript

I want to draw the outline of Berlin (germany) with D3.js.
The geoJSON file for Berlin i use is this (there Berlin-"bundesländer"):
http://opendatalab.de/projects/geojson-utilities/
But it just doesn't work with my .json file. I cant spot the difference to this .json file for us-states that works just fine with exactly the same code:
http://examples.oreilly.com/0636920026938/chapter_12/us-states.json
I also tried to completely copy the us-states file, delete all "features" entries except one and then only replace the coordinates-array of the one left with the coordinates-array of my file. But firebug tells me that the path's element has no "d" attribute at all.
I really appreciate any hint. Thank you in advance!
/*
I use the default albersUsa projection.
If I define path as : d3.geo.path().projection(null) some path-element is added.
But if that's the solution how can i translate that path ?
*/
var path = d3.geo.path();
d3.json("data/berlinBundeslaender_simplify2000.json",function(geoJson){
var color1 = d3.scale.category20();
mainSVG.selectAll("path")
.data(geoJson.features)
.enter()
.append("path")
.attr("d",path)
.attr("fill",function(d,i){return color1(i);});
});

The albersUSA projection will clip anything that's not within the lower 48 US states, Hawaii or Alaska. That is, anything else simply won't be displayed. Use a different projection for different parts of the world.

Related

D3 V6 and JavaScript - GeoJSON fill is "spilling" outside of path [duplicate]

This question already has answers here:
D3.js Drawing geojson incorrectly
(2 answers)
Closed 2 years ago.
Creating a map using D3 V6, showing educational attainment by county. I have a counties.topojson and csvData.csv which are loaded:
var promises = [];
promises.push(d3.csv("data/csvData.csv")); //load attributes from csv
promises.push(d3.json("data/counties.topojson")); //load background spatial data
Promise.all(promises).then(callback);
and in a callback function assigned to variables csvData and counties. The counties are then translated using:
miCounties = topojson.feature(counties, counties.objects.collection).features;
The csvData is joined to the county data, and the join is confirmed in console.log(joinedCounties), within the callback function setEnumerationUnits() is called (where colorScale is quantile scale based on an array created from the csvData and map is the SVG element:
function setEnumerationUnits(joinedCounties,map,path,colorScale){
var counties = map.selectAll(".counties")
.data(joinedCounties)
.enter()
.append("path")
.attr("class", function(d){
return "counties " + d.properties.NAME;
})
.attr("d", path)
.style("fill", function(d) {
return choropleth(d.properties, colorScale);
})
I should also mention adding "fill" to the .counties class in CSS also creates the "spilling". I have checked the topojson in QGIS and Pro, which both appear normal. I have also tried a second source of data with the same results.
Here is the result:
Here is what is looks like without styling, no fill, just stroke defined in CSS:
I receive no errors in the console. I appreciate any help anyone can give! Thanks!
Thank you! The turf.rewind worked!!
here's what I added to make it work (after installing turf library):
miCounties.forEach(function(feature){
feature.geometry = turf.rewind(feature.geometry, {reverse:true});
One or more of your GeoJSON entries are the wrong way around. The values are correct, but they are in the wrong order. d3-geo generally expects GeoJSON features to be clockwise:
Spherical polygons also require a winding order convention to determine which side of the polygon is the inside: the exterior ring for polygons smaller than a hemisphere must be clockwise, while the exterior ring for polygons larger than a hemisphere must be anticlockwise.
You can fix the winding of your data using a plugin or tool like turf, which you can use to "rewind" your shapes - though you should use the reverse: true option.

Not able to get the Zoom/Pan and States name appear in India Map - D3?

I am new to D3.js. However after being practiced the examples of this site, I tried to play ahead with Mr.John Coogan's map given here. The output that I found in his site is as under
But when I am trying to do the same thing by placing his .js,css,.json and index.html in plunker it is coming as
Problems
a) No States are getting displayed
b) Zoom and Pan is not working
In another word, at this point of time I am looking only for the Indian map to work exactly as the example shown by Mr. Coogan.
What needs to be done for this?
Here's the working plunk: http://plnkr.co/1EqpIFecwJmkbvypTyQD?p=preview
You needed to uncomment this line:
.call(d3.behavior.zoom().on("zoom", redraw))
on line 40 of the index.html in your plunk, and then zoom and pan will work.
The state colors (based on wealth) are not showing because of various, more complex errors. The error shown in the console (svg is not defined referencing line 78) is just the start (you need to replace svg with india, which is defined).
In fact the whole original gist your example is based on is really just a work in progress, but most of the answers for how to fix it can be found in this thread from the google group, from Mike Bostock himself.
Essentially, the json data loads asynchronously, so need to be loaded in series.
// load the two JSON files in series
d3.json("states.json", function(states) {
d3.json("wealth.json", function(wealthdata) {
...
});
});
Then you can just apend the relevant colorbrewer CSS class when you first create each path:
india.selectAll("path")
.data(states.features)
.enter().append("path")
.attr("d", path)
.attr("class", function(d) {
return "q" + quantize(wealthdata[d.id]) + "-9";
})
.attr("d", path);
But you also need to define the quantize scale, range...:
var quantize = d3.scale.quantize()
.range(d3.range(9));
... and domain (which you can only do once the data has been loaded:
quantize.domain([0, d3.max(d3.values(wealthdata))]);

Visualising a custom map with QGIS and D3.js is harmed by the projection

These are 4 polygons I have: http://imgur.com/vsVjxE1 in QGIS. I now wanted to use them with D3.js. I already tried out the things in QGIS generated shapefile malformed when converted to topojson by mapshaper. That was working well on the old json file. But when I was creating a new one, it was bugging in the vertical middle. That's the example http://jsfiddle.net/kwoxer/kpL1uyy2/5/:
var projection = d3.geo.projection(function(x, y) { return [x, y];})
.precision(0).scale(1).translate([0, 0]);
var path = d3.geo.path().projection(projection);
I also tried:
var path = d3.geo.path().projection(null);
but then the whole map was mirrored in the middle.
I think I don't use that system correctly I must assume. The json is fine on mapshaper, too. So do you have some tips, so that I just draw anything I want however big it is and then d3.js is able to draw it as it is. =)
Maybe by
normalizing lan/lng
disabling KBS
I really don't know why creating an own map is not straithforward.
Edit1: found nearly my issue here https://gis.stackexchange.com/questions/54373/either-geojson-to-topojson-conversion-problem-or-projection-issue-with-d3-js but I got:
C:\Program Files\GDAL>ogr2ogr.exe -f "GeoJSON" -s_srs region.prj -t_srs EPSG:432
6 asdas.json region.shp
ERROR 4: Failed to create GeoJSON datasource: asdas.json.
GeoJSON driver failed to create asdas.json
Edit2: already found this interesting answer: https://gis.stackexchange.com/questions/14731/how-do-i-specify-a-crs-for-a-fictional-game-map-in-qgis
But I used such a projection like he used, but still failing with d3.js.
I'm just using an own projection now:
+proj=eqc +a=1790493.11 +lat_ts=0 +lon_0=0 +rf=800 +units=m +no_defs
With that projection all is fine.

D3js draws only one feature within geoJSON FeatureCollection

although being pretty new to D3js I already get most of the things up and running. However, what is not yet working, is the display of a geoJSON-based map of inner-city boundaries (data: http://ddj.haim.it/data/muenchen.geojson).
Here's what I have been trying lately:
var nWidth = 800, nHeight = 600,
oMap = d3.select('body').append('svg').attr('width', nWidth).attr('height', nHeight),
oProjection = d3.geo.mercator().center([ 11.591, 48.139 ]).scale(50000).translate([nWidth / 2, nHeight / 2]),
oPath = d3.geo.path().projection(oProjection);
d3.json('data/muenchen.geojson', function(_mError, _oCollection) {
oMap.append('g')
.selectAll('path')
.data(_oCollection.features)
.enter()
.append('path')
.attr('class', 'entity')
.attr('d', oPath);
});
What do I get? A map where only the last featue is drawn correctly and another one is drawn as one huge rectangle (well, in the source, it's not a rect, it's a path).
Any help greatly appreciated.
Thanks a bunch,
Mario
Not sure whether I get your point, Lars. I can see the last polygon from the geoJSON, however, only the last one. Here's the current output: http://ddj.haim.it/d3.html
EDIT: Okay, I got your point. Sorry and thanks a lot for the answer.
The key thing is to "fill" the paths (in the CSS) with transparency.

SVG to HTML map and area

I have been trying to convert map in SVG to HTML area map for three days. I`am trying to do that with this SVG.
I've tried to convert this SVG with several methods and programs, but all of them failed.
e.g.: inkscape, inkscapeMap, Adobe Illustrator, Polygonator, SVGtoHTML and more.
So I wrote my own PHP script to do the job. Its works fine, but it converts only polygons. But there are two paths in SVG which need to be convert to polygon as well. I've tried to convert these paths into polygons in Illustrator and Inkscape, but apparently there is no way how to force these programs to convert path into polygons. (SVG editors probably decide alone, if they do the conversion or not). I find this topic on SO. But I'am not able to get the JS work - I dont know what the param sample is, and more - browser said that function createElementNS is unknown.
The best result I'am able to reach is this HTML, but there is still two region missing (because they are in SVG in paths)
I would be pleased for any clue.
QUESTIONS
1) How to transform SVG paths into polygons? Is that possible?
2) Is there any software which converts SVG into HTML area maps?
3) Could you show my example parametrs, in this JS function (function written Phrogz):
function polygonSampledFromPath(path,samples){
var doc = path.ownerDocument;
var poly = doc.createElementNS('http://www.w3.org/2000/svg','polygon');
var points = [];
var len = path.getTotalLength();
var step = step=len/samples;
for (var i=0;i<=len;i+=step){
var p = path.getPointAtLength(i);
points.push( p.x+','+p.y );
}
poly.setAttribute('points',points.join(' '));
return poly;
}
3ad) Why is function createElementNS unknown?
PS: I hope you understand my English :)

Categories

Resources