I'm attempting to follow Mike Bostock's process to project to the bounding box of a feature in a topojson file. My topojson file is already projected to Texas State Mapping System (EPSG 3081) from the mand line using geoproject:
d3.geoConicConformal().parallels([34 + 55 / 60, 27 + 25 / 60]).rotate([100, -31 - 10 / 60])
However, copying his code exactly and modifying the relevant bits to match my data set results in the error "Uncaught TypeError: path.bounds is not a function" on this line:
var b = path.bounds(state),
Here is my plete code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JS Mapping Project</title>
<script type="text/javascript" src=".v3.min.js"></script>
<script src=".v1.min.js"></script>
<script src=".v1.min.js"></script>
<script src=".v1.min.js"></script>
<script src=".v2.min.js"></script>
<style type="text/css">
body {
background-color: #eee;
}
svg {
background-color: #fff;
border: 1px solid #000;
}
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 1000;
var h = 850;
var projection = d3.geoProjection( function(x, y) {
return [x, y];
});
// Create a path generator.
var path = d3.geo.path()
.projection();
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Load in GeoJSON data
d3.json("data/topojson/boundary_quantize.json", function(error, json) {
//Add error handling
if (error) throw error;
var states = topojson.feature(json, json.objects.state),
state = states.features.filter(function(d) { return d.properties.NAME === "Texas"; })[0];
projection
.scale(1)
.translate([0, 0]);
// Compute the bounds of a feature of interest, then derive scale & translate.
var b = path.bounds(state),
s = .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h),
t = [(w - s * (b[1][0] + b[0][0])) / 2, (h - s * (b[1][1] + b[0][1])) / 2];
// Update the projection to use puted scale & translate.
projection
.scale(s)
.translate(t);
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "2")
.attr("d", path(topojson.mesh(json, json.objects.national)));
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "1")
.attr("d", path(topojson.mesh(json, json.objects.state)));
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "0.5")
.attr("d", path(topojson.mesh(json, json.objects.county)));
});
</script>
</body>
</html>
A few things that I've discovered manipulating the code:
If I remove the projection by changing var path = d3.geo.path().projection(); to var path = d3.geo.path();, the error goes away (because the call to the broken code goes away) but the svg draw is broken:
If I change the path definition to var path = d3.geoPath();, suddenly the geometry draws correctly:
This won't work (and I don't know why geoPath() works in the first place) because then the rest of my calls to path fail.
As I was typing this, I realized that I forget the call to my projection variable. I changed .projection(); to .projection(projection);. Now my map looks really weird, but there aren't errors on the path.bounds line as before:
It would seem that my projection definition is wrong, despite using the formula from this StackExchange answer.
I changed the code from geoProjection() to geoIdentity() based on Mike Bostock's response to a ment on his Medium article. My map appeared to be projected, scaled, and centered correctly, but the all black and white color scheme didn't help. I added some quick coloring to the various layers and it now looks very broken:
I then thought maybe it was because I didn't add the ", function(a,b) { return a !== b; }" to the topojson.mesh function, but doing that made things more broken:
I double-checked my topojson file again at mapshaper, but my geometry is correct:
At this point I'm stumped. Something is wrong with the way I'm implementing topojson to render my data, but it matches the code I'm seeing in examples.
I'm attempting to follow Mike Bostock's process to project to the bounding box of a feature in a topojson file. My topojson file is already projected to Texas State Mapping System (EPSG 3081) from the mand line using geoproject:
d3.geoConicConformal().parallels([34 + 55 / 60, 27 + 25 / 60]).rotate([100, -31 - 10 / 60])
However, copying his code exactly and modifying the relevant bits to match my data set results in the error "Uncaught TypeError: path.bounds is not a function" on this line:
var b = path.bounds(state),
Here is my plete code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JS Mapping Project</title>
<script type="text/javascript" src="https://d3js/d3.v3.min.js"></script>
<script src="https://d3js/d3-array.v1.min.js"></script>
<script src="https://d3js/d3-geo.v1.min.js"></script>
<script src="https://d3js/d3-geo-projection.v1.min.js"></script>
<script src="https://d3js/topojson.v2.min.js"></script>
<style type="text/css">
body {
background-color: #eee;
}
svg {
background-color: #fff;
border: 1px solid #000;
}
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 1000;
var h = 850;
var projection = d3.geoProjection( function(x, y) {
return [x, y];
});
// Create a path generator.
var path = d3.geo.path()
.projection();
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Load in GeoJSON data
d3.json("data/topojson/boundary_quantize.json", function(error, json) {
//Add error handling
if (error) throw error;
var states = topojson.feature(json, json.objects.state),
state = states.features.filter(function(d) { return d.properties.NAME === "Texas"; })[0];
projection
.scale(1)
.translate([0, 0]);
// Compute the bounds of a feature of interest, then derive scale & translate.
var b = path.bounds(state),
s = .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h),
t = [(w - s * (b[1][0] + b[0][0])) / 2, (h - s * (b[1][1] + b[0][1])) / 2];
// Update the projection to use puted scale & translate.
projection
.scale(s)
.translate(t);
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "2")
.attr("d", path(topojson.mesh(json, json.objects.national)));
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "1")
.attr("d", path(topojson.mesh(json, json.objects.state)));
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "0.5")
.attr("d", path(topojson.mesh(json, json.objects.county)));
});
</script>
</body>
</html>
A few things that I've discovered manipulating the code:
If I remove the projection by changing var path = d3.geo.path().projection(); to var path = d3.geo.path();, the error goes away (because the call to the broken code goes away) but the svg draw is broken:
If I change the path definition to var path = d3.geoPath();, suddenly the geometry draws correctly:
This won't work (and I don't know why geoPath() works in the first place) because then the rest of my calls to path fail.
As I was typing this, I realized that I forget the call to my projection variable. I changed .projection(); to .projection(projection);. Now my map looks really weird, but there aren't errors on the path.bounds line as before:
It would seem that my projection definition is wrong, despite using the formula from this StackExchange answer.
I changed the code from geoProjection() to geoIdentity() based on Mike Bostock's response to a ment on his Medium article. My map appeared to be projected, scaled, and centered correctly, but the all black and white color scheme didn't help. I added some quick coloring to the various layers and it now looks very broken:
I then thought maybe it was because I didn't add the ", function(a,b) { return a !== b; }" to the topojson.mesh function, but doing that made things more broken:
I double-checked my topojson file again at mapshaper, but my geometry is correct:
At this point I'm stumped. Something is wrong with the way I'm implementing topojson to render my data, but it matches the code I'm seeing in examples.
Share Improve this question edited May 23, 2017 at 11:46 CommunityBot 11 silver badge asked Feb 23, 2017 at 16:33 HasecBinUsrHasecBinUsr 1633 silver badges13 bronze badges1 Answer
Reset to default 4Had a breakthrough here. By changing the call to the feature from topojson.mesh to topojson.feature, the problem instantly resolved itself. I don't know why .mesh works in this example, but it definitely didn't work for me.
EDIT: I've identified why .mesh has been used in the example. It is to select only the internal boundaries so the coastline is not rendered, which is a great idea from a cartographic perspective. The thing I realized is to not apply a fill to those paths to prevent the drawing errors I had before.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745376916a4625042.html
评论列表(0条)