मानचित्रों के लिए डी 3 --- भू में डेटा लाने के लिए किस स्तर पर?


12

मैं डी 3, एक ला के साथ प्रदर्शन के लिए एक विश्व चिरोपेल का नक्शा बनाना चाहता हूं:

मेरे पास एक डेटासेट है जिसे मैं आईएसओ-अल्फा -3 कुंजी के लिए प्रदर्शित करना चाहता हूं। इसलिए...

danger.csv
iso,level
AFG,100
ALB,0
DZA,12

आदि।

Topojson के निर्देशों के बाद, मुझे पता है कि मैं कर सकता हूँ ...

wget "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/cultural/ne_50m_admin_0_countries.zip"
unzip ne_50m_admin_0_countries.zip
ogr2ogr -f "GeoJSON" output_features.json ne_50m_admin_0_countries.shp -select iso_a3
topojson -o topo.json output_features.json --id-property iso_a3

ISO3 द्वारा ID'd कि एक विश्वमैप जसन का उत्पादन करने के लिए।

मेरा सवाल है: वर्कफ़्लो में किस बिंदु पर मुझे खतरे को डेटा से मर्ज करना चाहिए। भू डेटा पर? मैंने पहले जीयूआई के रूप में क्यूजीआईएस के साथ काम किया था, लेकिन कहां / मर्ज होना चाहिए? .Shp में? Ogr2ogr के बाद? डायनामिक रूप से ब्राउज़र में टॉपजनसन सिकुड़ने के बाद (जैसे यहाँ http://bl.ocks.org/mbostock/4060606 http://bl.ocks.org/mbostock/3306362 )?

मैं अजगर के साथ बहुत अच्छा हूं, लेकिन जावास्क्रिप्ट के लिए बहुत नया हूं, और अपने आप को वास्तव में एक जेनरेटर कोडर होने की तुलना में बोस्कॉक के उदाहरणों की नकल करना और चिपकाना है।

(मेरे पास एक संबंधित, लेकिन स्टैकओवरफ़्लो पर अधिक शामिल अनुवर्ती है जो शायद मुझे यहां से पलायन करना चाहिए: /programming/18604877/how-to-do-time-data-in-d3-maps )


मैं सिर्फ @ mbostock के उदाहरणों को देख रहा था और देखा कि कोई ऐसा है जो विशेष रूप से GeoJoins को संबोधित करता है , या "CSV या TSV फ़ाइल में बाहरी गुणों के साथ GeoJSON फ़ाइल में शामिल होने के लिए एक सरल स्क्रिप्ट, TopoJSON से निकाली गई"
रयानकेल्डन

जवाबों:


11

अपने आप से दो सवाल पूछें:

  1. क्या आप कई डेटासेट पर भूगोल का पुन: उपयोग करने जा रहे हैं?

    यदि आप एक ही भूगोल का उपयोग कई डेटासेट के साथ करते हैं, तो यह भूगोल और डेटा को अलग रखने, और उन्हें क्लाइंट में शामिल करने के लिए समझ में आता है। मेरे कई उदाहरणों में इस कारण से अलग CSV (या TSV) फाइलें हैं। इस तरह, अमेरिकी राज्यों और काउंटियों या इसी तरह दुनिया के देशों के लिए TopoJSON को हर उदाहरण के लिए अलग TopoJSON बनाने के बजाय, पुन: उपयोग किया जा सकता है।

    दूसरी ओर, यदि आप केवल एक बार इस भूगोल का उपयोग करेंगे , तो आपको शायद भूगोल में डेटा को गुणों के रूप में "बेक" करना चाहिए, यदि केवल कोड को सरल बनाने के लिए। यह दृष्टिकोण सरल है क्योंकि आपको केवल एक फ़ाइल (ताकि कोई कतार नहीं है ) को लोड करने की आवश्यकता है , और चूंकि डेटा को प्रत्येक सुविधा के गुणों के रूप में संग्रहीत किया जाता है, इसलिए आपको क्लाइंट में डेटा शामिल करने की आवश्यकता नहीं है (इसलिए कोई डी 3)। नक्शा )।

    साइड नोट: टीएसवी और सीएसवी अक्सर जार्जॉन और टोपोजोन की तुलना में संपत्तियों के भंडारण में बहुत अधिक कुशल होते हैं, केवल इसलिए कि बाद वाले को प्रत्येक वस्तु पर संपत्ति के नाम दोहराना चाहिए। फ़ाइल का आकार एक अलग फ़ाइल में आपके डेटा को संग्रहीत करने और क्लाइंट में शामिल होने का एक और कारण हो सकता है।

  2. क्या आपका डेटा पहले से ही भूगोल से जुड़ा है (जैसे, आपके आकार की संपत्ति)?

    यह मानते हुए कि आपने पहले प्रश्न का उत्तर "नहीं" दिया है और डेटा को भूगोल (ग्राहक में करने के बजाय) में सेंकना चाहते हैं, आप यह कैसे करते हैं, यह डेटा के प्रारूप पर निर्भर करता है।

    यदि आपका डेटा पहले से ही आपके topojson -pशेपफाइल का गुण है , तो यह नियंत्रित करने के लिए उपयोग करें कि कौन-सी संपत्तियाँ जेनरेट किए गए TopoJSON फ़ाइल में सहेजी गई हैं। आप इसका उपयोग गुणों का नाम बदलने और उन्हें संख्याओं के साथ-साथ करने के लिए भी कर सकते हैं। उदाहरण के लिए एक मानचित्र बनाते हैं देखें ।

    यदि आपका डेटा एक अलग CSV या TSV फ़ाइल में है, तो एक बाहरी गुण फ़ाइल को निर्दिष्ट करने के लिए topojson -e (इसके अलावा -p) का उपयोग करें जो आपकी भौगोलिक विशेषताओं में शामिल हो सकती है। उदाहरण के लिए विकी से क्रिबिंग करना, अगर आपके पास इस तरह एक TSV फाइल थी:

    FIPS    rate
    1001    .097
    1003    .091
    1005    .134
    1007    .121
    1009    .099
    1011    .164
    1013    .167
    1015    .108
    1017    .186
    1019    .118
    1021    .099
    

    का उपयोग करते हुए -e, आप "बेरोजगारी" नामक एक संख्यात्मक आउटपुट संपत्ति के लिए उन्हें मैप कर सकते हैं:

    topojson \
      -o output.json \
      -e unemployment.tsv \
      --id-property=+FIPS \
      -p unemployment=+rate \
      -- input.shp
    

    इस दृष्टिकोण का एक उदाहरण केंटकी जनसंख्या कोरोप्लेथ , bl.ocks.org/5144735 है


2
और यहाँ मैं gis.stackexchange के बजाय मेरे हार्ड डी 3 मैपिंग के सवाल स्टैकओवरफ्लो पर पूछ रहा था क्योंकि मुझे लगा कि वहां और विशेषज्ञता थी --- और फिर मास्टर खुद मेरे सवाल का जवाब यहाँ देता है। =) खैर, यह 2 चीजें बनाता है जो मैंने आज सीखा। धन्यवाद!
Mittenchops

3

अच्छा प्रश्न। आपके द्वारा प्रदान किए गए उदाहरणों में से एक चाल को करना प्रतीत होता है, हालांकि इसका पालन करना कठिन है।

आप ध्यान देंगे कि उदाहरण में दो बाहरी डेटा फाइलें हैं, us.json और बेरोजगारी ।tsvआप बेरोज़गारी के बारे में सोच सकते हैं। अपने खतरे की तरह ही एसटीएसवी। us.json भौगोलिक विशेषताएं हैं जिनके साथ आप पैरामीटर को खतरे से जोड़ना चाहते हैं। CS उत्तरार्द्ध, बेरोज़गारी ।tsv , के पास idऔर rateफ़ील्ड्स हैं, जो idहमारे जैसे ही हैं id। json।

यह डी 3 के साथ क्लाइंट में है कि आपको अपने डेटा और विशेषताओं को मर्ज करना चाहिए , कम से कम इस उदाहरण से। यह क्लाइंट में है कि बेरोजगारी दर, इस उदाहरण में, डी 3मैप () फ़ंक्शन का उपयोग करके काउंटी सुविधाओं में शामिल हो गई है । यह वह जगह है जहाँ यह आरंभिक है:

var rateById = d3.map();

और यह वह जगह है जहाँ rateपर मैप किया जाता है id:

queue()
    .defer(d3.json, "/mbostock/raw/4090846/us.json")
    .defer(d3.tsv, "unemployment.tsv", function(d) { rateById.set(d.id, +d.rate); })
    .await(ready);

मुझे स्वीकार करना चाहिए कि मुझे नहीं पता कि queue()इसके लिए क्या है, लेकिन यह इस चर्चा के लिए महत्वपूर्ण नहीं है। क्या टिप्पणी के लिए महत्वपूर्ण है वह यह है कि प्रत्येक काउंटी सुविधा में क्षेत्र बेरोजगारी ने ले ली है अब साझा पहचानकर्ता ( EDIT: @ @ blord-castillo बताते हैं कि यह सुलभ है , यह वास्तव में एक नए साहचर्य सरणी, या कुंजी हैश की पीढ़ी है, जहां मैप किया जाता है )। यह वह जगह है जहाँ सीबम के प्रयोजनों के लिए कहा जाता है (यहाँ, प्रत्येक सीएफएल के लिए पूर्वनिर्धारित सीएसएस कक्षाएं उपलब्ध हैं):idraterateidrateidrate

...
.enter().append("path")
  .attr("class", function(d) { return quantize(rateById.get(d.id)); })
  .attr("d", path);

जहां quantize()फ़ंक्शन सीएसएस वर्ग का नाम देता है जिसे उस बेरोजगारी दर के आधार पर उस विशेषता (काउंटी) को स्टाइल करने के लिए उपयोग किया जाना चाहिए, जिसे अब फीचर के idक्षेत्र में परिभाषित किया गया है ।


1
FYI करें कतार में: bsumm.net/2013/03/31/analyzing-mbostocks-queue-js.html
johanvdw

कतार सीरियल लोडिंग के बजाय डेटा स्रोतों के async समानांतर लोडिंग की अनुमति देती है।
ब्लॉर्ड-कास्टिलो

1
उस उदाहरण में जो चल रहा है वह यह है कि RateById एक प्रमुख हैश है। देश की विशेषताओं और us.json डेटा में कोई बदलाव नहीं किया गया है। इसके बजाय, बेरोजगारी .tsv को 'hasById' नामक एक प्रमुख हैश में परिवर्तित किया जाता है। rateById.set () बेरोजगारी के बारे में अधिक जानकारी प्राप्त की जाती है। इसलिए कि बेरोजगारी में प्रत्येक आईडी के लिए एक कुंजी डाली जाती है। (हम में नहीं)। । बाद में, rateById.get () को आईडी द्वारा बेरोजगारी दर को देखने के लिए हैश का उपयोग करने के लिए कहा जाता है; उस मान का उपयोग us.json विशेषताओं पर शैली सेट करने के लिए किया जाता है, फिर उसे छोड़ दिया जाता है।
ब्लॉर्ड-कास्टिलो

इसे कहीं और विशेषता के रूप में संलग्न करने के बजाय दर के साथ आईडी / प्रतिस्थापित / क्यों करता है? ऐसा लगता है कि बाद में चयन करना कठिन हो जाएगा।
Mittenchops

1
यह आईडी को रेट से रिप्लेस नहीं करता है। यह आईडी से लेकर दर तक एक लुकअप हैश बनाता है।
ब्लॉर्ड-कास्टिलो

2

सबसे पहले, इस विधि का उपयोग करने के लिए आपके सीएसवी की पहली पंक्ति कॉलम नामों की अल्पविराम से अलग की गई सूची होनी चाहिए। यदि यह संभव नहीं है, तो इस बारे में एक टिप्पणी जोड़ें और मैं देखूंगा कि क्या मैं बाहर काम कर सकता हूं d3.csv.parseRowsबजाय इसके कि कैसे उपयोग किया जाए d3.csv.parsed3.csv.parseपर मूल्यांकनकर्ता फ़ंक्शन द्वारा कहा जाता है .defer(function, url, assessor)

मैं मान रहा हूँ कि आपकी फ़ाइल अब इस तरह दिखाई देगी:

danger.csv
iso,level
AFG,100
ALB,0
DZA,12
...

इसका उपयोग करके, आप ISO3 से लुकिंग हैश को खतरे के स्तर तक बना सकते हैं।

var dangerByISO3 = d3.map();
queue()
    .defer(d3.json, "url to topo.json")
    .defer(d3.csv, "url to danger.csv", function(d) {dangerByISO3.set(d.iso, +d.level);})
    .await(ready);
function ready(error, world) {
    //You now have world as your available topojson
    //And you have dangerByISO3 as your danger level hash
    //You can lookup a danger level by dangerByISO3.get(ISO3 code)
}

कोड वॉकथ्रू

var dangerByISO3 = d3.map();

सबसे पहले आप एक d3.map () ऑब्जेक्ट बनाते हैं जो आपके मुख्य हैश के रूप में कार्य करेगा, और इसे चर खतरे में स्टोर करेगा।

queue()

समानांतर लोडिंग के लिए कतार का उपयोग करें।

.defer(d3.json, "url to topo.json")

प्रतीक्षित फ़ंक्शन (त्रुटि के बाद) में पारित होने वाले पहले तर्क के रूप में अपने टॉपोजोन को लोड करें। यहां शैली पर ध्यान दें जहां यह एक जंजीर फ़ंक्शन है queue(), लेकिन एक अलग लाइन पर सूचीबद्ध है (पर कोई समाप्ति अर्धविराम नहीं है queue())।

.defer(d3.csv, "url to danger.csv", function(d) {dangerByISO3.set(d.iso, +d.level);})

यहां दो चीजें हो रही हैं। सबसे पहले, आप खतरे को लोड कर रहे हैं। अपने दूसरे तर्क को प्रतीक्षा समारोह में पारित करने के लिए। जैसा कि आप नीचे देखेंगे, यह तर्क वास्तव में उपयोग नहीं किया गया है। इसके बजाय, लोडिंग फ़ंक्शन, d3.csv को एक आकलनकर्ता तर्क प्रदान किया जाता है। यह मूल्यांकनकर्ता csv की प्रत्येक पंक्ति को संसाधित करेगा। इस मामले में, हम खतरे पर सेट फ़ंक्शन को कॉल करते हैं BISISO3 ताकि एक isoकुंजी के प्रत्येक संयोजन के लिए , हम levelउस कुंजी के साथ जाने के लिए मान सेट करें । +d.levelअंकन एकल का उपयोग करता है +एक नंबर करने के d.level का मूल्य मजबूर करने के लिए।

.await(ready);

एक बार जब दोनों डेटा स्रोत लोड हो जाते हैं, तो उन्हें फ़ंक्शन के लिए दो अलग-अलग तर्क दिए जाते हैं ready()। कॉलबैक के लिए पहला तर्क हमेशा होने वाली पहली त्रुटि है। यदि कोई त्रुटि नहीं हुई, तो अशक्त को पहले तर्क के रूप में पारित किया जाएगा। दूसरा तर्क पहला डेटा स्रोत (पहले कार्य का परिणाम) है, और तीसरा तर्क दूसरा डेटा स्रोत (दूसरे कार्य का परिणाम) है।

function ready(error, world) {...}

यह कॉलबैक फ़ंक्शन है ready()। पहले हम यह errorतर्क लेते हैं कि यदि दो लोडिंग कार्यों को सफलतापूर्वक पूरा किया गया है, तो आपको अशक्त होना चाहिए (आपको त्रुटियों को पकड़ने और संभालने के लिए वास्तव में भाषा को जोड़ना चाहिए)। इसके बाद हम टॉपजोन डेटा को ऑब्जेक्ट के रूप में लेते हैं countries। इस डेटा को फ़ंक्शन के शरीर में कुछ इस तरह से संसाधित किया जाना चाहिए .data(topojson.feature(world,world.objects.countries).features)। चूंकि ready()एक तीसरा तर्क नहीं है, दूसरे कार्य का परिणाम, हमारे सीएसवी, को केवल त्याग दिया गया है। हमने इसे केवल हैश बनाने के लिए इस्तेमाल किया था और उसके बाद इसकी आवश्यकता नहीं थी।


हाँ, आप सही कह रहे हैं, मेरा सीएसवी वास्तव में मेरे द्वारा पोस्ट किए गए लापरवाह डेमो के बजाय एक अच्छी तरह से गठित सीएसवी जैसा दिखता है। =) क्षमा करें, मैं इसे अपडेट करूंगा।
16
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.