PerfectVector
लेखक: Irene Kim

Leaflet SVG मार्कर: iconAnchor से नोक मिलाएँ

दिखाई देने वाली नोक को iconAnchor से मैप कर Leaflet में अपना SVG मार्कर रखें। viewBox की खाली जगह, अनुपात फ़िट और आइकन आकार में बदलाव का ध्यान रखें।

9 मिनट का पठन
इस पेज पर

Leaflet के कस्टम SVG मार्कर में iconSize दिखने वाले चित्र के आयाम रखें और iconAnchor चित्र के भीतर दिखाई देती नोक का पिक्सेल स्थान। माप चित्र के ऊपर-बाएँ कोने से लें। पारदर्शी SVG मार्जिन उन आयामों में गिने जाते हैं, इसलिए आधी चौड़ाई और पूरी ऊँचाई असममित या अधिक मार्जिन वाले पिन में गलत हो सकती है।

यह गाइड हमारा मूल पिन लेती है जिसकी नोक उसके मुख्य भाग के केंद्र के दाएँ है। बिना टाइल के ब्राउज़र मानचित्र में दो स्रोत फ़्रेम दो आइकन आकारों पर तुलना करते हैं। साफ़ SVG कलाकृति पहले से हो तो सीधे लें; एंकर रखने के लिए वेक्टराइज़ेशन ज़रूरी नहीं।

कलाकृति, चित्र बॉक्स और मानचित्र बिंदु अलग समझें

यहाँ तीन निर्देशांक तंत्र मिलते हैं। SVG पाथ कलाकृति को स्रोत इकाइयों में बताता है। iconSize उसका दिखने वाला चित्र बॉक्स पिक्सेल में तय करता है। Leaflet उस बॉक्स में iconAnchor से बताए बिंदु को मार्कर की भौगोलिक जगह पर रखता है। Icon संदर्भ ये विकल्प और ऊपर-बाएँ एंकर मूलबिंदु परिभाषित करता है।

साधारण पिन नीचे के किनारे के बीच पहुँच सकता है, लेकिन आपकी कलाकृति कहीं और समाप्त हो सकती है। आकार दिया हो तो Leaflet का प्रलेखित सामान्य मान केंद्रित एंकर है। प्रयोग में नीचे-केंद्र के मान हमारी जाँची गई स्पष्ट धारणा हैं, वह सामान्य मान नहीं।

आधिकारिक कस्टम आइकन ट्यूटोरियल बताता है कि मार्कर को L.icon इंस्टेंस कैसे दें। आयातित कलाकृति का अतिरिक्त काम चित्र के भीतर वह बिंदु खोजना है जिसे मानचित्र निर्देशांक छूना चाहिए।

दिखती नोक और एंकर
अधिक मार्जिन वाले कैनवस में असममित स्थान पिन की वैचारिक तुलना, जिसमें नोक पहले क्रॉसहेयर से दूर और फिर उससे मिलती है
चित्रण: दिखती नोक रखते समय पूरा चित्र फ़्रेम ध्यान में लें। नीचे का मापा गया ब्राउज़र प्रयोग अलग बनाए SVG लेता है।

स्रोत नोक को आइकन पिक्सेल में मैप करें

हमारे पिन की नोक स्रोत निर्देशांक (40, 80) पर है। कम मार्जिन वाला फ़्रेम viewBox="0 0 60 80" है। अधिक मार्जिन वाला संस्करण केवल फ़्रेम viewBox="-20 -10 100 120" करता है; दोनों में वही पाथ और पारदर्शी खुला भाग रहता है।

viewBox संदर्भ स्रोत आयत समझाता है। उसके भीतर की खाली जगह कलाकृति के साथ जाती है। हमारी SVG बाउंडिंग बॉक्स गाइड बताती है कि कैनवस और पेंट आकृति की सीमाएँ अलग क्यों हो सकती हैं।

दोनों संस्करण स्पष्ट preserveAspectRatio="xMidYMid meet" लेते हैं। इससे फ़्रेम viewport में समान स्केल से फ़िट होता है और बची जगह केंद्रित होती है। सेटिंग के लिए MDN का preserveAspectRatio संदर्भ देखें।

इस फ़िट मोड में W और H आइकन आयाम, (minX, minY, vbW, vbH) viewBox और (tipX, tipY) स्रोत नोक मानें:

s = min(W / vbW, H / vbH)
offsetX = (W - vbW * s) / 2
offsetY = (H - vbH * s) / 2
anchorX = (tipX - minX) * s + offsetX
anchorY = (tipY - minY) * s + offsetY

अधिक मार्जिन वाले 60×80 आइकन में s, 0.6 है। 100×120 स्रोत फ़्रेम 60×72 पिक्सेल लेता है, जिससे ऊपर और नीचे चार-चार पिक्सेल बचते हैं। उस लंबवत ऑफ़सेट सहित नोक [36, 58] बनती है। हर आयाम का अलग अंश लेने से समान फ़िट वाला चरण छूट जाता।

स्रोत फ़्रेमआइकन आकारगणना किया नोक एंकर
कम मार्जिन, 0 0 60 8060×80[40, 80]
कम मार्जिन, 0 0 60 8090×120[60, 120]
अधिक मार्जिन, -20 -10 100 12060×80[36, 58]
अधिक मार्जिन, -20 -10 100 12090×120[54, 87]

गणना हमारे बिना ट्रांसफ़ॉर्म चित्र और स्पष्ट केंद्रित meet पर लागू है। अलग संरेखण, slice या none को उसकी निर्देशांक मैपिंग चाहिए। हमारी अनुपात गाइड विकल्प बताती है। मार्कर चित्र पर अतिरिक्त CSS ट्रांसफ़ॉर्म भी अलग जाँच माँगते हैं।

बिना टाइल वाले मानचित्र में जगह जाँचें

हमने Leaflet 1.9.4 लिया, जिसे आधिकारिक डाउनलोड पेज स्थिर रिलीज़ बताता है। प्रयोग निश्चित JavaScript और CSS स्थानीय लोड करता है और टाइल लेयर नहीं जोड़ता। हर मानचित्र [0, 0] निर्देशांक को नीले क्रॉसहेयर पर प्रोजेक्ट करता है और संदर्भ बिंदु के पास एक SVG चित्र दिखाता है।

स्रोत निरीक्षण में हर SVG में समान compound पाथ और कोई एम्बेडेड रास्टर नहीं मिला। ब्राउज़र चित्र आयाम माँगे अनुसार 60×80 और 90×120 पिक्सेल थे। हर चित्र के देखे आयत से हमने मैप की गई नोक की जगह को प्रोजेक्ट किए भौगोलिक बिंदु से तुलना किया:

स्रोतआइकन आकारअनुमानित नीचे-केंद्र एंकर से त्रुटिगणना किए नोक एंकर से त्रुटि
कम मार्जिन60×8010 px दाएँ0 px
कम मार्जिन90×12015 px दाएँ0 px
अधिक मार्जिन60×806 px दाएँ, 22 px ऊपर0 px
अधिक मार्जिन90×1209 px दाएँ, 33 px ऊपर0 px

क्रॉसहेयर सुधारी नोक से दिखने में भी मिला। ये एक Chrome ब्राउज़र में इस बनाए परीक्षण के अवलोकन हैं, हर SVG, ब्राउज़र या मानचित्र एकीकरण की गारंटी नहीं। एंकर ठीक होने के बाद भी अधिक मार्जिन वाला पिन उसी चित्र बॉक्स में छोटा रहता है। जगह और कलाकृति आकार अलग निर्णय हैं।

काम करता शुरुआती मार्कर कॉपी करें

पूरा HTML marker.html सहेजें और स्थानीय वेब सर्वर से सर्व करें। वह Leaflet डाउनलोड पेज की CDN से निश्चित Leaflet फ़ाइलें लोड करता है। SVG चित्र URL में एन्कोड है, इसलिए उदाहरण को आइकन फ़ाइल या टाइल सेवा नहीं चाहिए। लाइब्रेरी की उन दो फ़ाइलों के लिए इंटरनेट चाहिए।

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Leaflet SVG tip anchor</title>
<link rel="stylesheet"
      href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<style>
  #map { width: 360px; height: 300px; background: #edf3ef; }
  .cross { position: absolute; z-index: 1000; pointer-events: none;
    width: 24px; height: 24px; transform: translate(-50%, -50%); }
  .cross::before, .cross::after { content: ""; position: absolute;
    background: #006cbe; }
  .cross::before { top: 12px; width: 24px; height: 1px; }
  .cross::after { left: 12px; width: 1px; height: 24px; }
</style>
<div id="map"></div>
<pre id="status">Loading marker…</pre>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="60" height="80" viewBox="-20 -10 100 120" preserveAspectRatio="xMidYMid meet"><path fill="#bf593c" fill-rule="evenodd" d="M30 0 C46 0 60 12 60 28 C60 46 46 54 40 80 C30 62 0 46 0 28 C0 12 14 0 30 0 Z M40 26 A10 10 0 1 0 20 26 A10 10 0 1 0 40 26 Z"/></svg>`;
const size = [60, 80];
const viewBox = [-20, -10, 100, 120];
const sourceTip = [40, 80];
const scale = Math.min(size[0] / viewBox[2], size[1] / viewBox[3]);
const anchor = [
  (sourceTip[0] - viewBox[0]) * scale
    + (size[0] - viewBox[2] * scale) / 2,
  (sourceTip[1] - viewBox[1]) * scale
    + (size[1] - viewBox[3] * scale) / 2
];
const map = L.map("map", {
  zoomControl: false, attributionControl: false,
  dragging: false, scrollWheelZoom: false, doubleClickZoom: false,
  boxZoom: false, keyboard: false, touchZoom: false
}).setView([0, 0], 2);
const position = [0, 0];
const icon = L.icon({
  iconUrl: "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg),
  iconSize: size,
  iconAnchor: anchor
});
const marker = L.marker(position, { icon }).addTo(map);
const container = document.querySelector("#map");
const cross = document.createElement("span");
cross.className = "cross";
container.append(cross);
const point = map.latLngToContainerPoint(position);
cross.style.left = point.x + "px";
cross.style.top = point.y + "px";
(async () => {
  const image = marker.getElement();
  await image.decode();
  const ir = image.getBoundingClientRect();
  const mr = container.getBoundingClientRect();
  const displacement = [
    ir.left + anchor[0] - mr.left - point.x,
    ir.top + anchor[1] - mr.top - point.y
  ];
  document.querySelector("#status").textContent = JSON.stringify({
    version: L.version, size, anchor,
    observedImageSize: [ir.width, ir.height], displacement
  }, null, 2);
})();
</script>
</html>

दिखी स्थिति में anchor: [36, 58], चित्र आकार [60, 80] और शून्य विस्थापन होना चाहिए। size को [90, 120] करें; वही गणना [54, 87] देती है। कम मार्जिन का फ़्रेम लेने के लिए SVG का viewBox और JavaScript viewBox array दोनों 0 0 60 80 करें। दोनों एकसमान रखें।

पाथ में fill-rule="evenodd" के साथ वृत्ताकार भीतरी रूपरेखा है, जो वास्तविक खुला भाग बनाती है। MDN का fill-rule संदर्भ नियम समझाता है। उदाहरण मानचित्र कंटेनर पर बॉर्डर या ट्रांसफ़ॉर्म नहीं जोड़ता; वे हों तो viewport आयतों को कंटेनर निर्देशांक से तुलना करते समय सावधानी चाहिए।

कलाकृति बदलने से पहले गंतव्य जाँचें

मार्कर अभी भी निर्देशांक से चूके तो क्रम से जाँचें:

  1. पुष्टि करें कि SVG लोड हुआ और मार्कर एलिमेंट की पिक्सेल चौड़ाई व ऊँचाई इच्छित है।
  2. SVG के भीतर ट्रांसफ़ॉर्म सहित वास्तविक स्रोत नोक खोजें।
  3. पूरा viewBox, उसके न्यूनतम निर्देशांक और फ़िट मोड जाँचें।
  4. फ़्रेम या आइकन आकार बदलने पर एंकर दोबारा गणना करें।
  5. परीक्षण में असंबंधित CSS ओवरराइड हटाएँ, फिर अंतिम शैली और इच्छित प्रदर्शन आकार फिर जाँचें।

इस जाँच में भौगोलिक निर्देशांक स्थिर रखें। चित्र मार्जिन की भरपाई के लिए उसे खिसकाना कलाकृति की जगह वाली त्रुटि छिपाएगा।

यह ब्राउज़र मार्कर प्रक्रिया है। QGIS SVG मार्कर अपने गंतव्य नियंत्रण और पैरामीटरयुक्त पेंट सिंटैक्स लेता है; सामान्य ब्राउज़र डिलीवरी के लिए साधारण SVG मास्टर रखें।

आइकन केवल PNG या JPG हो और संपादन योग्य रूपरेखा चाहिए तो PerfectVector से कलाकृति बदलें, खुला भाग और नोक जाँचें और साफ़ SVG मास्टर सहेजें। फिर अंतिम स्रोत फ़्रेम से Leaflet एंकर गणना करें। वेक्टराइज़ेशन कलाकृति तैयार करता है; मानचित्र कोड जगह और स्थिति देता है। मौजूदा SVG में केवल ऑफ़सेट की समस्या हो तो फ़्रेम या एंकर सीधे ठीक करें। इमेज वेक्टराइज़ेशन गाइड बताती है कि रास्टर स्रोत बदलना कब उपयोगी है।

अक्सर पूछे जाने वाले प्रश्न

क्या iconAnchor अक्षांश और देशांतर है? नहीं। वह दिखे आइकन चित्र के भीतर ऊपर-बाएँ कोने से मापा पिक्सेल स्थान है। मार्कर की भौगोलिक स्थिति अलग दी जाती है।

एंकर सुधारने पर भी अधिक मार्जिन वाला SVG छोटा क्यों है? खाली स्रोत फ़्रेम अभी चित्र बॉक्स का हिस्सा घेरता है। एंकर सुधारने से नोक की जगह ठीक होती है; खाली जगह नहीं हटती और पेंट आकृति बड़ी नहीं होती।

क्या हमेशा आधी चौड़ाई और पूरी ऊँचाई लें? वह जोड़ा तभी लें जब दिखाई देने वाला संपर्क बिंदु वहीं हो। हमारे असममित पिन और अधिक मार्जिन वाले स्रोत को अलग मान चाहिए, भले दोनों स्थान-मार्कर कलाकृति हैं।

क्या PNG से SVG बदलने पर मार्कर की जगह ठीक होती है? रूपांतरण संपादन योग्य कलाकृति दे सकता है। अंतिम स्रोत फ़्रेम, दिखे आयाम, एंकर और मानचित्र निर्देशांक अभी भी जगह तय करते हैं।

स्रोत

  1. Leaflet — Icon संदर्भ — पिक्सेल आयाम, एंकर मूलबिंदु, सामान्य केंद्रीकरण और भौगोलिक संरेखण।
  2. Leaflet — अपने आइकन वाले मार्कर — आइकन बनाना और मार्कर को देना।
  3. Leaflet — डाउनलोड — स्थिर रिलीज़ और उसके निश्चित JavaScript व CSS लिंक।
  4. MDN — viewBox — दोनों फ़्रेम का स्रोत निर्देशांक आयत।
  5. MDN — preserveAspectRatio — xMidYMid meet में समान फ़िट और केंद्रित बची जगह।
  6. MDN — fill-rule — पारदर्शी खुले भाग के लिए even-odd नियम।

Blog से और

PerfectVector

ऐसे साफ़ SVG से शुरुआत करें
जिसे एडिट करना आसान हो

क्रेडिट कार्ड की ज़रूरत नहीं