একটি জিওজেএসএন বিষয়বস্তুতে d3 এ মানচিত্রটি কেন্দ্র করুন


140

বর্তমানে ডি 3-এ যদি আপনার কাছে জিওজেএসওন অবজেক্ট থাকে যা আপনি আঁকতে যাচ্ছেন আপনাকে এটি আকার দিতে হবে এবং এটি কেন্দ্রীভূত করার জন্য এটি অনুবাদ করতে হবে যাতে এটি অনুবাদ করতে হয়। এটি পরীক্ষা এবং ত্রুটির একটি অত্যন্ত ক্লান্তিকর কাজ এবং আমি ভাবছিলাম যে এই মানগুলি পাওয়ার জন্য আরও ভাল উপায় যদি কেউ জানত?

উদাহরণস্বরূপ যদি আমি এই কোড আছে

var path, vis, xy;
xy = d3.geo.mercator().scale(8500).translate([0, -1200]);

path = d3.geo.path().projection(xy);

vis = d3.select("#vis").append("svg:svg").attr("width", 960).attr("height", 600);

d3.json("../../data/ireland2.geojson", function(json) {
  return vis.append("svg:g")
    .attr("class", "tracts")
    .selectAll("path")
    .data(json.features).enter()
    .append("svg:path")
    .attr("d", path)
    .attr("fill", "#85C3C0")
    .attr("stroke", "#222");
});

কীভাবে আমি অল্প অল্প করে না গিয়ে স্ক্যাল (8500) এবং ট্রান্সলেট ([0, -1200]) পেতে পারি?


উত্তর:


134

নীচেরগুলি আপনি যা চান তা প্রায় করছে বলে মনে হচ্ছে। স্কেলিংটি ঠিক আছে বলে মনে হচ্ছে। আমার মানচিত্রে এটি প্রয়োগ করার সময় একটি ছোট অফসেট রয়েছে। এই ছোট্ট অফসেটটি সম্ভবত সম্ভবত কারণ হ'ল আমি মানচিত্রটি কেন্দ্র করে অনুবাদ কমান্ডটি ব্যবহার করি, যখন আমার সম্ভবত সেন্টার কমান্ডটি ব্যবহার করা উচিত।

  1. একটি প্রক্ষেপণ এবং d3.geo.path তৈরি করুন
  2. বর্তমান অনুমানের সীমা গণনা করুন
  3. স্কেল এবং অনুবাদ গণনা করতে এই সীমা ব্যবহার করুন
  4. প্রক্ষেপণ পুনরুদ্ধার

কোডে:

  var width  = 300;
  var height = 400;

  var vis = d3.select("#vis").append("svg")
      .attr("width", width).attr("height", height)

  d3.json("nld.json", function(json) {
      // create a first guess for the projection
      var center = d3.geo.centroid(json)
      var scale  = 150;
      var offset = [width/2, height/2];
      var projection = d3.geo.mercator().scale(scale).center(center)
          .translate(offset);

      // create the path
      var path = d3.geo.path().projection(projection);

      // using the path determine the bounds of the current map and use 
      // these to determine better values for the scale and translation
      var bounds  = path.bounds(json);
      var hscale  = scale*width  / (bounds[1][0] - bounds[0][0]);
      var vscale  = scale*height / (bounds[1][1] - bounds[0][1]);
      var scale   = (hscale < vscale) ? hscale : vscale;
      var offset  = [width - (bounds[0][0] + bounds[1][0])/2,
                        height - (bounds[0][1] + bounds[1][1])/2];

      // new projection
      projection = d3.geo.mercator().center(center)
        .scale(scale).translate(offset);
      path = path.projection(projection);

      // add a rectangle to see the bound of the svg
      vis.append("rect").attr('width', width).attr('height', height)
        .style('stroke', 'black').style('fill', 'none');

      vis.selectAll("path").data(json.features).enter().append("path")
        .attr("d", path)
        .style("fill", "red")
        .style("stroke-width", "1")
        .style("stroke", "black")
    });

9
আরে জান ভ্যান ডের লান আমি এই প্রতিক্রিয়ার জন্য আপনাকে কখনও ধন্যবাদ জানাতে পারি নি। আমি যদি আমার অনুগ্রহকে আলাদা করে দিতে পারি তবে এটির পক্ষে সত্যিই ভাল প্রতিক্রিয়া। এর জন্য ধন্যবাদ!
ক্লাইময়েড

আমি এটি প্রয়োগ করলে আমি সীমানা = অসীমতা পেতে পারি। এটি কীভাবে সমাধান করা যায় তার কোনও ধারণা?
সিমকে নিস

@ সিমকেনিজ এখানে সমস্যা হিসাবে একই সমস্যা দেখা দিতে পারে এখানে stackoverflow.com/questions/23953366/… উল্লিখিত সমাধানটি চেষ্টা করে দেখুন।
জান ভ্যান ডের লান

1
হাই জান, আপনার কোডের জন্য আপনাকে ধন্যবাদ। আমি কিছু জিওজেসন ডেটা দিয়ে আপনার উদাহরণটি চেষ্টা করেছি কিন্তু এটি কার্যকর হয়নি। আমি বলতে পারি আমি কী ভুল করছি? :) আমি জিওজেসন ডেটা আপলোড করেছি: onedrive.live.com/…
user2644964

1
ডি 3 ভি 4-তে প্রজেকশন ফিটিং হ'ল বিল্ট-ইন পদ্ধতি: projection.fitSize([width, height], geojson)( এপিআই ডক্স ) - নীচে @dnltsk এর উত্তর দেখুন।
ফ্লোরিয়ান লেদারম্যান

173

আমার উত্তর জান ভ্যান ডার লানের কাছাকাছি, তবে আপনি কিছুটা সহজ করতে পারবেন কারণ আপনার ভৌগলিক সেন্ট্রয়েড গণনা করার প্রয়োজন নেই; আপনার কেবল বাউন্ডিং বক্স দরকার। এবং, একটি অনাবৃত, অপরিবর্তিত ইউনিট প্রক্ষেপণ ব্যবহার করে আপনি গণিতটি সহজ করতে পারেন।

কোডটির গুরুত্বপূর্ণ অংশটি হ'ল:

// Create a unit projection.
var projection = d3.geo.albers()
    .scale(1)
    .translate([0, 0]);

// Create a path generator.
var path = d3.geo.path()
    .projection(projection);

// 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]) / width, (b[1][1] - b[0][1]) / height),
    t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];

// Update the projection to use computed scale & translate.
projection
    .scale(s)
    .translate(t);

ইউনিট প্রজেকশনটিতে বৈশিষ্ট্যের সীমানা বাক্সটি সংযুক্ত করার পরে, আপনি বাউন্ডিং বক্সের অনুপাতের অনুপাত এবং ( এবং ) ক্যানভাসের অনুপাত ( এবং ) এর সাথে তুলনা করে উপযুক্ত স্কেলটি গুণতে পারেন । এই ক্ষেত্রে আমি বাউন্ডিং বাক্সটি 100% এর চেয়ে 95% ক্যানভাসেও বেঁধে রেখেছি, সুতরাং স্ট্রোক এবং পার্শ্ববর্তী বৈশিষ্ট্যগুলি বা প্যাডিংয়ের জন্য প্রান্তগুলিতে কিছুটা অতিরিক্ত জায়গা রয়েছে।b[1][0] - b[0][0]b[1][1] - b[0][1]widthheight

তারপর আপনি গনা করতে অনুবাদ সীমান্ত বক্স (কেন্দ্রে ব্যবহার (b[1][0] + b[0][0]) / 2এবং (b[1][1] + b[0][1]) / 2) এবং ক্যানভাস (কেন্দ্রে width / 2এবং height / 2)। নোট করুন যেহেতু বাউন্ডিং বাক্স ইউনিট প্রজেকশনের স্থানাঙ্কগুলিতে রয়েছে তাই এটি অবশ্যই স্কেল ( s) দ্বারা গুণিত হতে হবে ।

উদাহরণস্বরূপ, bl.ocks.org/4707858 :

বাউন্ডিং বাক্সে প্রকল্প

প্রজেকশন সামঞ্জস্য না করে কোনও সংগ্রহের কোনও নির্দিষ্ট বৈশিষ্ট্যে কীভাবে জুম করা যায় তা সম্পর্কিত একটি প্রশ্ন রয়েছে, অর্থাত্ , জুমকে জুম ইন এবং আউট করার জন্য জ্যামিতিক ট্রান্সফর্মের সাথে প্রজেকশনটিকে একত্রিত করা। এটি উপরের মতো একই নীতিগুলি ব্যবহার করে তবে গণিতটি কিছুটা পৃথক কারণ জ্যামিতিক ট্রান্সফর্ম (এসভিজি "ট্রান্সফর্ম" বৈশিষ্ট্য) ভৌগলিক প্রক্ষেপণের সাথে একত্রিত is

উদাহরণস্বরূপ, bl.ocks.org/4699541 :

বাউন্ডিং বাক্সে জুম করুন


2
আমি উল্লেখ করতে চাই যে উপরের কোডটিতে কয়েকটি ত্রুটি রয়েছে, বিশেষত সীমানার সূচকগুলিতে। এর মতো দেখতে পাওয়া উচিত: s = (0.95 / ম্যাথ.ম্যাক্স ((খ [1] [0] - খ [0] [0]) / প্রস্থ, (খ [1] [1] - খ [0] [0] ) / উচ্চতা)) * 500, টি = [(প্রস্থ - গুলি * (খ [1] [0] + খ [0])) / 2, (উচ্চতা - গুলি * (খ [1] [1] + খ [0] [1])) / 2];
IRos

2
@ আইরিস - দেখে মনে হচ্ছে এটি বাহ্যিক * 500... এছাড়াও, স্কেল গণনায় b[1][1] - b[0][0]হওয়া উচিত b[1][1] - b[0][1]
nrabinowitz


5
সুতরাং:b.s = b[0][1]; b.n = b[1][1]; b.w = b[0][0]; b.e = b[1][0]; b.height = Math.abs(b.n - b.s); b.width = Math.abs(b.e - b.w); s = .9 / Math.max(b.width / width, (b.height / height));
হার্ব কডিল

3
এটি এই জাতীয় সম্প্রদায়ের কারণে যে ডি 3 এর সাথে কাজ করতে এমন আনন্দ হয়। অসাধারণ!
অরুনক্জান

54

ডি 3 ভি 4 বা ভি 5 এর সাথে এর সহজতর উপায়!

var projection = d3.geoMercator().fitSize([width, height], geojson);
var path = d3.geoPath().projection(projection);

এবং পরিশেষে

g.selectAll('path')
  .data(geojson.features)
  .enter()
  .append('path')
  .attr('d', path)
  .style("fill", "red")
  .style("stroke-width", "1")
  .style("stroke", "black");

উপভোগ করুন, চিয়ার্স


2
আমি আশা করি এই উত্তরটি আরও বেশি ভোট পেয়েছে। d3v4কিছুক্ষণের জন্য কাজ করে সবেমাত্র এই পদ্ধতিটি আবিষ্কার করেছি।
চিহ্নিত করুন

2
কোথা gথেকে আসে? এটাই কি এসজিজি ধারক?
তিশাল্লাকা

1
চশল্লাকাকে ট্যাগ করা gউচিত<g></g>
giankotarola

1
লজ্জা এটি এতদূর নিচে এবং 2 মানের উত্তর পরে। এটি এড়ানো সহজ এবং এটি অন্যান্য উত্তরগুলির চেয়ে স্পষ্টতই সহজ।
কর্ট

1
ধন্যবাদ. ভি 5 এও কাজ করে!
চৈতন্য বাঙ্গেরা

53

আমি ডি 3 তে নতুন - আমি কীভাবে এটি বুঝতে পারি তা ব্যাখ্যা করার চেষ্টা করব তবে আমি নিশ্চিত নই যে আমি সবকিছু ঠিকঠাক পেয়েছি।

গোপনীয়তাটি জেনে গেছে যে কার্টেসিয়ান স্পেসে কিছু পদ্ধতি কার্টোগ্রাফিক স্পেস (অক্ষাংশ, দ্রাঘিমাংশ) এবং অন্যদের উপর পরিচালিত করবে (স্ক্রিনে এক্স, ওয়াই)। কার্টোগ্রাফিক স্পেস (আমাদের গ্রহ) হ'ল (প্রায়) গোলাকার, কার্টেসিয়ান স্পেস (স্ক্রিন) সমতল - অন্যটির উপরে একটিকে ম্যাপ করার জন্য আপনার প্রয়োজন একটি অ্যালগরিদম, যা প্রক্ষেপণ বলা হয় । এই স্থানটি অনুমানের মনোমুগ্ধকর বিষয়ের গভীরে এবং কীভাবে তারা গোলাকারকে প্লেনে রূপান্তরিত করার জন্য ভৌগলিক বৈশিষ্ট্যগুলি বিকৃত করে; কিছু অ্যাঙ্গেল সংরক্ষণের জন্য ডিজাইন করা হয়েছে, অন্যরা দূরত্ব সংরক্ষণ করে এবং আরও কিছু - সর্বদা একটি আপস হয় (মাইক বোস্টকের উদাহরণগুলির একটি বিশাল সংগ্রহ রয়েছে )।

এখানে চিত্র বর্ণনা লিখুন

ডি 3-তে, প্রোজেকশন অবজেক্টটির মানক ইউনিটগুলিতে দেওয়া কেন্দ্রের সম্পত্তি / সেটার থাকে:

projection.center ([অবস্থান])

যদি কেন্দ্রটি নির্দিষ্ট করা থাকে, তবে প্রক্ষেপণের কেন্দ্রটিকে নির্দিষ্ট স্থানে সেট করে, দ্রাঘিমাংশ এবং অক্ষাংশের একটি দুই-উপাদান অ্যারে এবং প্রজেকশনটি প্রদান করে। যদি কেন্দ্রটি নির্দিষ্ট না করা থাকে তবে বর্তমান কেন্দ্রটি ফিরে আসে যা ডিফল্ট ⟨0 °, 0 °⟩ হয়⟩

পিক্সেলে দেওয়া অনুবাদও রয়েছে - যেখানে প্রক্ষেপণ কেন্দ্রটি ক্যানভাসের তুলনায় দাঁড়িয়ে আছে:

projection.translate ([বিন্দু])

যদি বিন্দুটি নির্দিষ্ট করা থাকে, তবে প্রজেকশনটির অনুবাদটিকে নির্দিষ্ট দুটি-উপাদান অ্যারে [x, y] এ অফসেট সেট করে এবং প্রজেকশনটি প্রদান করে। যদি পয়েন্টটি নির্দিষ্ট না করা থাকে তবে বর্তমান অনুবাদটি অফসেটটি ফেরত দেয় যা ডিফল্ট [480, 250]। অনুবাদ অফসেট প্রক্ষেপণের কেন্দ্রের পিক্সেল স্থানাঙ্ক নির্ধারণ করে। ডিফল্ট অনুবাদ অফসেটটি 960 × 500 অঞ্চলের কেন্দ্রে ⟨0 °, 0 ° places রাখে।

যখন আমি ক্যানভাসে কোনও বৈশিষ্ট্যটি কেন্দ্র করতে চাই, আমি বৈশিষ্ট্য সীমানা বাক্সের কেন্দ্রে প্রক্ষেপণ কেন্দ্রটি সেট করতে চাই - আমার দেশের (ব্রাজিল) জন্য মেরেটার (ডাব্লুজিএস ৮৪, গুগল মানচিত্রে ব্যবহৃত) ব্যবহার করার সময় এটি আমার পক্ষে কাজ করে, অন্যান্য অনুমান এবং গোলার্ধ ব্যবহার করে কখনও পরীক্ষা করা হয় না। অন্যান্য পরিস্থিতিতে আপনার সামঞ্জস্য করতে হতে পারে, তবে আপনি যদি এই প্রাথমিক নীতিগুলি পেরেক করেন তবে আপনি ভাল থাকবেন।

উদাহরণস্বরূপ, একটি অভিক্ষেপ এবং পথ দেওয়া:

var projection = d3.geo.mercator()
    .scale(1);

var path = d3.geo.path()
    .projection(projection);

boundsথেকে পদ্ধতি pathআয় সীমান্ত বক্স পিক্সেলে । সঠিক মানদণ্ডটি খুঁজে পেতে এটি ব্যবহার করুন, মানচিত্র ইউনিটগুলির আকারের সাথে পিক্সেলের আকারের তুলনা করুন (0.95 আপনাকে প্রস্থ বা উচ্চতার জন্য সেরা ফিটের চেয়ে 5% মার্জিন দেয়)। মূল জ্যামিতিটি এখানে ত্রিভুজ বিরোধী কোণগুলি প্রদত্ত আয়তক্ষেত্র প্রস্থ / উচ্চতা গণনা করে:

var b = path.bounds(feature),
    s = 0.9 / Math.max(
                   (b[1][0] - b[0][0]) / width, 
                   (b[1][1] - b[0][1]) / height
               );
projection.scale(s); 

এখানে চিত্র বর্ণনা লিখুন

d3.geo.boundsমানচিত্র ইউনিটে সীমানা বাক্সটি খুঁজে পেতে পদ্ধতিটি ব্যবহার করুন :

b = d3.geo.bounds(feature);

সীমানা বাক্সের কেন্দ্রে প্রক্ষেপণের কেন্দ্রটি সেট করুন:

projection.center([(b[1][0]+b[0][0])/2, (b[1][1]+b[0][1])/2]);

translateক্যানভাসের কেন্দ্রে মানচিত্রের কেন্দ্র স্থানান্তর করতে পদ্ধতিটি ব্যবহার করুন :

projection.translate([width/2, height/2]);

এখন অবধি আপনার মানচিত্রের কেন্দ্রে একটি বৈশিষ্ট্যটি 5% মার্জিনের সাথে জুম করা উচিত।


কোথাও একটি ব্লক আছে?
হুগলপজ

দুঃখিত, কোন ব্লকস বা টুকরো টুকরো, আপনি কি করতে চেষ্টা করছেন? এটি কি ক্লিক-টু-জুমের মতো? এটি প্রকাশ করুন এবং আমি আপনার কোডটি একবার দেখতে পারি।
পাওলো স্কার্ডাইন

বোস্টকের উত্তর এবং চিত্রগুলি bl.ocks.org উদাহরণগুলিতে লিঙ্ক সরবরাহ করে যা আমাকে পুরো কোডটি ইঞ্জিনিয়ারকে অনুলিপি করতে দেয়। কাজ শেষ. আপনার দুর্দান্ত চিত্রগুলির জন্য +1 এবং ধন্যবাদ!
হুগলপজ

4

একটি কেন্দ্র আছে () পদ্ধতি রয়েছে যা আপনি ব্যবহার করতে পারেন যা কোনও দীর্ঘ / দীর্ঘ জুটি গ্রহণ করে।

আমি যা বুঝতে পারি তা থেকে অনুবাদ () কেবলমাত্র মানচিত্রের পিক্সেলগুলিকে আক্ষরিকভাবে সরানোর জন্য ব্যবহৃত হয়। স্কেল কী তা কীভাবে নির্ধারণ করা যায় তা সম্পর্কে আমি নিশ্চিত নই।


8
আপনি যদি টোপোজেন ব্যবহার করছেন এবং পুরো মানচিত্রটি কেন্দ্র করতে চান, আপনি JSON অবজেক্টে একটি বাক্সের বৈশিষ্ট্য অন্তর্ভুক্ত করতে --bbox দিয়ে টপোজসন চালাতে পারেন। কেন্দ্রের জন্য দীর্ঘ / দীর্ঘ স্থানাঙ্কগুলি [[b [0] + খ [2]) / 2, (খ [1] + বি [3]) / 2] (যেখানে খ বাক্সের মান হয়) হওয়া উচিত।
পাওলো স্কার্ডাইন

3

ছাড়াও সেন্টার D3 থাকা একটি মানচিত্র একটি GeoJSON বস্তুর দেওয়া , নোট আপনি পছন্দ করতে পারে যে fitExtent()ওভার fitSize()যদি আপনি আপনার বস্তুর সীমার কাছাকাছি একটি প্যাডিং উল্লেখ করতে চাই। fitSize()স্বয়ংক্রিয়ভাবে এই প্যাডিং 0 এ সেট করে।


2

আমি আমার মানচিত্রটি কেন্দ্রে ফ্রি-ফ্রি উপায়ের জন্য ইন্টারনেটে ঘুরে দেখছিলাম, এবং জান ভ্যান ডার লান এবং এমবস্টকের উত্তরে অনুপ্রাণিত হয়েছি। আপনি যদি এসভিজির জন্য কোনও ধারক ব্যবহার করেন তবে এখানে jQuery ব্যবহার করার একটি সহজ উপায়। প্যাডিং / সীমানা ইত্যাদির জন্য আমি 95% এর সীমানা তৈরি করেছি

var width = $("#container").width() * 0.95,
    height = $("#container").width() * 0.95 / 1.9 //using height() doesn't work since there's nothing inside

var projection = d3.geo.mercator().translate([width / 2, height / 2]).scale(width);
var path = d3.geo.path().projection(projection);

var svg = d3.select("#container").append("svg").attr("width", width).attr("height", height);

আপনি যদি সঠিক স্কেলিংয়ের সন্ধান করেন তবে এই উত্তরটি আপনার পক্ষে কার্যকর হবে না। তবে যদি আমার মতো, আপনি একটি মানচিত্র প্রদর্শন করতে চান যা একটি পাত্রে কেন্দ্রীভূত হয়, এটি যথেষ্ট হওয়া উচিত। আমি মরেটর মানচিত্রটি প্রদর্শনের চেষ্টা করছিলাম এবং দেখতে পেলাম যে এই পদ্ধতিটি আমার মানচিত্রকে কেন্দ্রীভূত করার ক্ষেত্রে দরকারী এবং আমি খুব সহজেই অ্যান্টার্কটিক অংশটি কেটে ফেলতে পারি যেহেতু আমার এটির প্রয়োজন ছিল না।


1

মানচিত্রটি প্যান / জুম করার জন্য আপনার লিফলেটে এসভিজি ওভারলেলিংয়ের দিকে নজর দেওয়া উচিত। এসভিজির পরিবর্তনের চেয়ে এটি অনেক সহজ হবে। এই উদাহরণটি দেখুন http://bost.ocks.org/mike/leaflet/ এবং তারপরে লিফলেটে মানচিত্রের কেন্দ্রটি কীভাবে পরিবর্তন করা যায়


তাহলে অন্য নির্ভরতা যোগ উদ্বেগের বিষয়, প্যান এবং জুম বিশুদ্ধ D3 সহজে কাজ করা যেতে পারে, দেখুন stackoverflow.com/questions/17093614/...
পাওলো Scardine

এই উত্তরটি সত্যিই ডি 3 এর সাথে ডিল করে না। আপনি d3 এ মানচিত্রটি প্যান / জুম করতে পারেন, লিফলেটটিও প্রয়োজনীয় নয়। (এটি কেবল একটি পুরানো পোস্টটি বুঝতে পেরেছিল, কেবল উত্তরগুলি ব্রাউজ করছে)
JARRRRG

0

এমবস্টকসের জবাব এবং হার্ব কডিলের মন্তব্য দিয়ে আমি আলাস্কার সাথে ইস্যুতে শুরু করি যেহেতু আমি মারটার প্রজেকশনটি ব্যবহার করছি। আমার লক্ষ্য করা উচিত যে আমার নিজের উদ্দেশ্যে, আমি মার্কিন যুক্তরাষ্ট্রের রাজ্যগুলিকে প্রজেক্ট এবং কেন্দ্র করার চেষ্টা করছি। আমি দেখতে পেলাম যে গোল্ডি স্পিরিসকে ওভারল্যাপ করে এমন বহুভুজ (পূর্বের - পশ্চিমের চেয়ে 1 এর চেয়ে বেশি যে পশ্চিমে রয়েছে) বহুভুজগুলির জন্য নিম্নলিখিত ব্যতিক্রমের সাথে জান ভ্যান ডের লানের জবাব দুটি দিয়ে আমাকে বিয়ে করতে হয়েছিল:

  1. মরেটরে একটি সাধারণ অভিক্ষেপ সেট আপ করুন:

    অভিক্ষেপ = d3.geo.mercator ()। স্কেল (1) .পরিবর্তন ([0,0]);

  2. পথ তৈরি করুন:

    পাথ = d3.geo.path ()। প্রক্ষেপণ (অভিক্ষেপ);

আমার সীমানা সেট আপ:

var bounds = path.bounds(topoJson),
  dx = Math.abs(bounds[1][0] - bounds[0][0]),
  dy = Math.abs(bounds[1][1] - bounds[0][1]),
  x = (bounds[1][0] + bounds[0][0]),
  y = (bounds[1][1] + bounds[0][1]);

৪. আলাস্কার জন্য ব্যতিক্রম যুক্ত করুন এবং উল্লেখ করেছেন যে গোলার্ধগুলি ওভারল্যাপ করে:

if(dx > 1){
var center = d3.geo.centroid(topojson.feature(json, json.objects[topoObj]));
scale = height / dy * 0.85;
console.log(scale);
projection = projection
    .scale(scale)
    .center(center)
    .translate([ width/2, height/2]);
}else{
scale = 0.85 / Math.max( dx / width, dy / height );
offset = [ (width - scale * x)/2 , (height - scale * y)/2];

// new projection
projection = projection                     
    .scale(scale)
    .translate(offset);
}

আশা করি এটা কাজে লাগবে.


0

যে লোকগুলি উল্লম্ব এবং অনুভূমিক সমন্বয় করতে চান তাদের জন্য এখানে সমাধানটি এখানে দেওয়া হয়েছে:

  var width  = 300;
  var height = 400;

  var vis = d3.select("#vis").append("svg")
      .attr("width", width).attr("height", height)

  d3.json("nld.json", function(json) {
      // create a first guess for the projection
      var center = d3.geo.centroid(json)
      var scale  = 150;
      var offset = [width/2, height/2];
      var projection = d3.geo.mercator().scale(scale).center(center)
          .translate(offset);

      // create the path
      var path = d3.geo.path().projection(projection);

      // using the path determine the bounds of the current map and use 
      // these to determine better values for the scale and translation
      var bounds  = path.bounds(json);
      var hscale  = scale*width  / (bounds[1][0] - bounds[0][0]);
      var vscale  = scale*height / (bounds[1][1] - bounds[0][1]);
      var scale   = (hscale < vscale) ? hscale : vscale;
      var offset  = [width - (bounds[0][0] + bounds[1][0])/2,
                        height - (bounds[0][1] + bounds[1][1])/2];

      // new projection
      projection = d3.geo.mercator().center(center)
        .scale(scale).translate(offset);
      path = path.projection(projection);

      // adjust projection
      var bounds  = path.bounds(json);
      offset[0] = offset[0] + (width - bounds[1][0] - bounds[0][0]) / 2;
      offset[1] = offset[1] + (height - bounds[1][1] - bounds[0][1]) / 2;

      projection = d3.geo.mercator().center(center)
        .scale(scale).translate(offset);
      path = path.projection(projection);

      // add a rectangle to see the bound of the svg
      vis.append("rect").attr('width', width).attr('height', height)
        .style('stroke', 'black').style('fill', 'none');

      vis.selectAll("path").data(json.features).enter().append("path")
        .attr("d", path)
        .style("fill", "red")
        .style("stroke-width", "1")
        .style("stroke", "black")
    });

0

আমি কীভাবে টপজসনকে কেন্দ্র করেছিলাম, যেখানে আমার বৈশিষ্ট্যটি বের করার দরকার ছিল:

      var projection = d3.geo.albersUsa();

      var path = d3.geo.path()
        .projection(projection);


      var tracts = topojson.feature(mapdata, mapdata.objects.tx_counties);

      projection
          .scale(1)
          .translate([0, 0]);

      var b = path.bounds(tracts),
          s = .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
          t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];

      projection
          .scale(s)
          .translate(t);

        svg.append("path")
            .datum(topojson.feature(mapdata, mapdata.objects.tx_counties))
            .attr("d", path)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.