使用两个json在地图上的不准确

时间:2018-05-07 11:53:26

标签: json d3.js

我必须创建一张欧洲地图,能够放大国家和地区。 我发现this question适合我,我试图重现结果。

我下载了这些文件:

我使用mapshaper来简化0.7%阈值的路径,我导出了结果文件。 然后在Qgis我删除了一些我不感兴趣的国家,我出口为Geojson。 我再次将文件上传到mapshaper并将其导出为Topojson。

这些是获得的文件:

这是我创建的代码。

的index.html

<html lang='en'>
<head>
    <meta charset='utf-8'>
    <script src='https://d3js.org/d3.v5.js' charset='utf-8'></script>
    <script src='https://d3js.org/topojson.v2.min.js'></script> 
</head>
<body>
    <div id='map'></div>
    <script src='./map.js'></script>
</body>
</html>

map.js

var countries;
var regions;

var width = 600;
var height = 400;
var dblclick_timer = false;

var projectionCurrent = d3.geoMercator() 
    .scale(1) 
    .translate([width / 2, height / 2]);
var projectionBase = d3.geoMercator()
    .scale(1) 
    .translate([width / 2, height / 2]);

var path = d3.geoPath().projection(projectionCurrent);

var map = d3.select('#map');
var mapSvg = map.append('svg')
    .attr('id', 'map-svg')
    .attr('width', width)
    .attr('height', height);

var files = ['./nuts0.json', './nuts2.json'];
var promises = [];

promises.push(d3.json(files[0]));
promises.push(d3.json(files[1]));

Promise.all(promises)
    .then(makeMap)
    .catch(function(err) {
        throw err;
    });

var mapSvgGCountry = mapSvg.append('g').attr('id', 'nuts0');
var mapSvgGRegion = mapSvg.append('g').attr('id', 'nuts2');

function makeMap(data) {
    var nuts0 = data[0];
    var nuts2 = data[1];

    countries = topojson.feature(nuts0, nuts0.objects.nuts0);
    regions = topojson.feature(nuts2, nuts2.objects.nuts2);

    projectionBase.fitSize([width, height], countries);
    projectionCurrent.fitSize([width, height], countries);

    var mapSvgGCountryPath = mapSvgGCountry.selectAll('path')
        .data(countries.features)
        .enter()
        .append('path');

    mapSvgGCountryPath.attr('class', 'country')
        .attr('fill', 'orange')
        .style('stroke', 'white')
        .style('stroke-width', 1) 
        .attr('d', path)
        .attr('id', function(c) {
            return 'country' + c.properties.nuts_id; // id = countryAT (Austria)
        })
        .on('click', clickOrDoubleCountry);
} 

function clickOrDoubleCountry(d, i) {
    if(dblclick_timer) {
        clearTimeout(dblclick_timer);
        dblclick_timer = false;

        d3.selectAll('.region').remove();

        var features = regions.features.filter(function(feature) { 
            return feature.properties.nuts_id.substring(0, 2) == d.properties.nuts_id;
        });

        mapSvgGRegion.selectAll(null)
            .data(features)
            .enter().append('path')
            .attr('class', 'region')
            .attr('fill', 'tomato')
            .style('stroke', 'white')
            .style('stroke-width', 1) 
            .attr('d', path)
            .attr('id', function(r) {
                return 'region' + r.properties.nuts_id; //  id = regionAT11 (Burgenland)
            })
            .on('click', clickOrDoubleRegion);

        var featureCollection = {'type': 'FeatureCollection', 'features': features};
        var projectionEnd = d3.geoMercator();
        zoomCountries(projectionCurrent, projectionEnd.fitExtent([[50, 50], [width-50, height-50]], featureCollection));    
    } 
    else {
        dblclick_timer = setTimeout(function() {
            dblclick_timer = false;
        }, 250)
    }
} 

function clickOrDoubleRegion(d, i) {
    if(dblclick_timer) {
        clearTimeout(dblclick_timer);
        dblclick_timer = false;
        zoomCountries(projectionCurrent, projectionBase);
        d3.selectAll('.region').remove();
    } 
    else { 
        dblclick_timer = setTimeout(function() {
            dblclick_timer = false;
        }, 250)
    }
} 

function zoomCountries(projectionStart, projectionEnd) {
    d3.selectAll('path')
        .transition()
        .attrTween('d', function(d) {
            var s = d3.interpolate(projectionStart.scale(), projectionEnd.scale());
            var x = d3.interpolate(projectionStart.translate()[0], projectionEnd.translate()[0]);
            var y = d3.interpolate(projectionStart.translate()[1], projectionEnd.translate()[1]);
            return function(t) {
                projectionCurrent.scale(s(t)).translate([x(t), y(t)])
                path.projection(projectionCurrent);
                return path(d);
            }
        })
        .duration(1000);
}

交互有效,但我报告了here完全相同的问题。我承认我并不理解接受的答案。 Andrew Reid推荐的代码我把它放在管理点击并双击某个国家/地区的功能中:

var features = regions.features.filter(function(feature) {
   return feature.properties.nuts_id.substring(0, 2) == d.properties.nuts_id;
});

而不是d.properties.country(请参阅bl.ocks)我使用了d.properties.nuts_id来表示相同的事情,这是该国家/地区的双字母标识符。

我不知道我必须用mapshaper解散哪个文件。我试图解散nuts0.jsonnuts2.json并使用它们,但代码不起作用。 所以我尝试使用不同的组合:

  • nuts0.json已解散且nuts2.json已解散
  • nuts0.json未解散且nuts2.json已解散
  • nuts0.json已解散且nuts2.json未解散
  • nuts0.json未解散且nuts2.json未解散

Here the code

无效。我做错了什么?

如果我发布了一个新问题而不是使用&#34; old&#34;我很抱歉一个但不知道做什么是正确的。

0 个答案:

没有答案